Commit aec7a75a authored by Kostis Trantzas's avatar Kostis Trantzas
Browse files

Merge branch 'tmf628' into 'develop'

Fixes for DB connection leaks for metrico transactions

See merge request !56
parents 8dfaaecd 72fc080d
Loading
Loading
Loading
Loading
Loading
+3 −5
Original line number Diff line number Diff line
package org.etsi.osl.tmf.pm628.repo;

import java.util.Optional;
import org.etsi.osl.tmf.pm628.model.ExecutionStateType;
import org.etsi.osl.tmf.pm628.model.MeasurementCollectionJob;
import org.springframework.data.repository.CrudRepository;
import org.springframework.data.repository.PagingAndSortingRepository;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;

import java.util.Optional;

@Repository
public interface MeasurementCollectionJobRepository extends CrudRepository<MeasurementCollectionJob, Long>, PagingAndSortingRepository<MeasurementCollectionJob, Long> {
public interface MeasurementCollectionJobRepository extends JpaRepository <MeasurementCollectionJob, Long> {
    Optional<MeasurementCollectionJob> findByUuid(String uuid);

    Iterable<MeasurementCollectionJob> findByExecutionState(ExecutionStateType executionState);
+35 −22
Original line number Diff line number Diff line
@@ -6,6 +6,7 @@ import jakarta.validation.Valid;
import org.etsi.osl.tmf.pm628.api.MeasurementCollectionJobApiRouteBuilderEvents;
import org.etsi.osl.tmf.pm628.model.*;
import org.etsi.osl.tmf.pm628.repo.MeasurementCollectionJobRepository;
import org.etsi.osl.tmf.so641.model.ServiceOrder;
import org.hibernate.Hibernate;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
@@ -15,11 +16,13 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.nio.charset.StandardCharsets;
import java.time.OffsetDateTime;
import java.util.*;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
@@ -288,22 +291,23 @@ public class MeasurementCollectionJobService {
      ObjectMapper mapper = new ObjectMapper();
      mapper.registerModule(new Hibernate5JakartaModule());
      String res = mapper.writeValueAsString(mcj);
      
      log.debug("=====> MCJObjectMapper {}", res);
      return res;

    }
    

    @Transactional
    private MeasurementCollectionJob findMeasurementCollectionJobByUuidEager(String id) {
      if (id == null || id.equals("")) {
        return null;
      }
    Session session = sessionFactory.openSession();
    Transaction tx = session.beginTransaction();
      MeasurementCollectionJob s = null;
    try {
      try (Session session = sessionFactory.openSession()) {
        Transaction tx = session.beginTransaction();
        s = (MeasurementCollectionJob) session.get(MeasurementCollectionJob.class, id);
        if (s == null) {
          log.debug("=====> findMeasurementCollectionJobByUuidEager last resort");
          return this.findMeasurementCollectionJobByUuid(id);// last resort
        }

@@ -315,31 +319,35 @@ public class MeasurementCollectionJobService {
        Hibernate.initialize(s.getTrackingRecord());

        tx.commit();
    } finally {
        session.close();
      } catch (Exception e) {
        e.printStackTrace();
      }

      return s;
    }

    @Transactional
    public MeasurementCollectionJob findMeasurementCollectionJobByUuid(String uuid){
        log.debug("MeasurementCollectionJob FIND BY UUID");
        Optional<MeasurementCollectionJob> measurementCollectionJob = measurementCollectionJobRepository.findByUuid(uuid);
        return measurementCollectionJob.orElse(null);
    }

    @Transactional
    public MeasurementCollectionJob createMeasurementCollectionJob(MeasurementCollectionJobFVO measurementCollectionJobFVO){
        log.debug("MeasurementCollectionJob CREATE: {}", measurementCollectionJobFVO);

        MeasurementCollectionJobMapper mapper = Mappers.getMapper(MeasurementCollectionJobMapper.class);
        MeasurementCollectionJob mcj = mapper.createMeasurementCollectionJob(measurementCollectionJobFVO);

        mcj = this.measurementCollectionJobRepository.save(mcj);
        mcj.setCreationTime( OffsetDateTime.now() );
        mcj.setLastModifiedTime( OffsetDateTime.now());
        mcj = this.measurementCollectionJobRepository.saveAndFlush(mcj);
        raiseMCJCreateNotification(mcj);

        return mcj;
    }

    @Transactional
    public MeasurementCollectionJob updateMeasurementCollectionJob(String uuid, @Valid MeasurementCollectionJobMVO measurementCollectionJobUpdate){
        log.debug("MeasurementCollectionJob UPDATE with UUID: {}", uuid);

@@ -352,8 +360,10 @@ public class MeasurementCollectionJobService {
        MeasurementCollectionJobMapper mapper = Mappers.getMapper(MeasurementCollectionJobMapper.class);
        measurementCollectionJob = mapper.updateMeasurementCollectionJob(measurementCollectionJobUpdate, measurementCollectionJob);

        measurementCollectionJob.setLastModifiedTime( OffsetDateTime.now());
        measurementCollectionJob = this.measurementCollectionJobRepository.save(measurementCollectionJob);

        
        // This may be unnecessary since MeasurementCollectionJobMVO doesn't have the executionState attribute
        if ( originalExecutionState!=null) {
          executionStateChanged = !originalExecutionState.equals(measurementCollectionJob.getExecutionState());          
@@ -373,12 +383,12 @@ public class MeasurementCollectionJobService {
        MeasurementCollectionJob measurementCollectionJob = measurementCollectionJobRepository.findByUuid(uuid)
                .orElseThrow(() -> new IllegalArgumentException("No MeasurementCollectionJob with UUID: " + uuid));
        measurementCollectionJobRepository.delete(measurementCollectionJob);

        raiseMCJDeleteNotification(measurementCollectionJob);

        return null;
    }

    @Transactional(propagation = Propagation.REQUIRES_NEW)
    private void raiseMCJCreateNotification(MeasurementCollectionJob mcj){
        // Create the event payload
        MeasurementCollectionJobRef ref = new MeasurementCollectionJobRef();
@@ -399,6 +409,7 @@ public class MeasurementCollectionJobService {
        routeBuilderEvents.publishEvent(event, mcj.getUuid());
    }

    @Transactional
    private void raiseMCJAttributeValueChangeNotification(MeasurementCollectionJob mcj){

        // Create the event payload
@@ -414,6 +425,7 @@ public class MeasurementCollectionJobService {
        routeBuilderEvents.publishEvent(event, mcj.getUuid());
    }

    @Transactional
    private void raiseMCJExecutionStateChangeNotification(MeasurementCollectionJob mcj){

        // Create the event payload
@@ -429,6 +441,7 @@ public class MeasurementCollectionJobService {
        routeBuilderEvents.publishEvent(event, mcj.getUuid());
    }

    @Transactional
    private void raiseMCJDeleteNotification(MeasurementCollectionJob mcj){

        // Create the event payload
+7 −4
Original line number Diff line number Diff line
@@ -49,10 +49,13 @@ spring:
    username: root
    hikari:
       minimumIdle: 2
       maximumPoolSize: 40
       idleTimeout: 120000
       connectionTimeout: 400000
       leakDetectionThreshold: 100000
       maximumPoolSize: 20
       idleTimeout: 20000
       idle-timeout: 20000
       connectionTimeout: 40000
       leakDetectionThreshold: 30000
       
       
  jpa:
    database-platform: org.etsi.osl.tmf.LocalMysqlDialect
    hibernate:
+35 −0
Original line number Diff line number Diff line
package org.etsi.osl.services.api.pm628;

import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.apache.commons.io.IOUtils;
@@ -114,6 +115,7 @@ public class MeasurementCollectionJobApiControllerTest {
        assertThat(mcj2.getReportingPeriod()).isEqualTo(mcj.getReportingPeriod());
    }

    
    @WithMockUser(username="osadmin", roles = {"USER","ADMIN"})
    @Test
    public void testCreateMeasurementCollectionJob() throws Exception {
@@ -126,6 +128,39 @@ public class MeasurementCollectionJobApiControllerTest {
        assertThat(mcj.getExecutionState()).isEqualTo(ExecutionStateType.ACKNOWLEDGED);
        assertThat(mcj.getGranularity()).isEqualTo(Granularity.fromValue("g_1mn"));
        assertThat(mcj.getReportingPeriod()).isEqualTo(ReportingPeriod.fromValue("r_1mn"));
        
        
     // Create the event
        MeasurementCollectionJobRef ref = new MeasurementCollectionJobRef();
        ref.setId(mcj.getUuid());
        ref.setHref(mcj.getHref());
        ref.setName("MeasurementCollectionJob");
        
        MeasurementCollectionJobCreateEventPayload payload = new MeasurementCollectionJobCreateEventPayload();
        payload.setMeasurementCollectionJob(ref);

        MeasurementCollectionJobCreateEvent event = new MeasurementCollectionJobCreateEvent();
        event.setTitle("MeasurementCollectionJob created");
        event.setDescription("MeasurementCollectionJob with UUID: " + mcj.getUuid() + " has been created");
        event.setEvent(payload);

        String apayload = toJsonString(event);
        
        MeasurementCollectionJobCreateEvent eventresponse = toJsonObj (apayload, MeasurementCollectionJobCreateEvent.class);
        assertThat(eventresponse.getEvent().getMeasurementCollectionJob()).isNotNull();
    }
    

    static String toJsonString(Object object) throws IOException {
        ObjectMapper mapper = new ObjectMapper();
        mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
        return mapper.writeValueAsString(object);
    }

    static <T> T toJsonObj(String content, Class<T> valueType)  throws IOException {
        ObjectMapper mapper = new ObjectMapper();
        mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
        return mapper.readValue( content, valueType);
    }

    @WithMockUser(username="osadmin", roles = {"USER","ADMIN"})