From ce3354c00ed046c446404d7f5a52d21379257cfd Mon Sep 17 00:00:00 2001 From: George Tziavas Date: Thu, 13 Feb 2025 15:56:01 +0200 Subject: [PATCH 01/17] modified: pom.xml modified: src/main/java/org/etsi/osl/metrico/model/Job.java modified: src/main/java/org/etsi/osl/metrico/services/JobService.java modified: src/main/java/org/etsi/osl/metrico/services/MetricoService.java modified: src/test/java/org/etsi/osl/metrico/services/JobServiceTest.java --- pom.xml | 6 + .../java/org/etsi/osl/metrico/model/Job.java | 10 +- .../etsi/osl/metrico/services/JobService.java | 88 +++--- .../osl/metrico/services/MetricoService.java | 255 +++++++++--------- .../osl/metrico/services/JobServiceTest.java | 210 +++++++-------- 5 files changed, 289 insertions(+), 280 deletions(-) diff --git a/pom.xml b/pom.xml index fb7c9cf..aea7f89 100644 --- a/pom.xml +++ b/pom.xml @@ -229,6 +229,12 @@ org.springframework.data spring-data-jpa + + org.etsi.osl + org.etsi.osl.tmf.api + 1.2.0-SNAPSHOT + compile + diff --git a/src/main/java/org/etsi/osl/metrico/model/Job.java b/src/main/java/org/etsi/osl/metrico/model/Job.java index 653a10c..1eb01ca 100644 --- a/src/main/java/org/etsi/osl/metrico/model/Job.java +++ b/src/main/java/org/etsi/osl/metrico/model/Job.java @@ -17,13 +17,13 @@ import java.util.concurrent.ScheduledFuture; @Getter @Setter -@Entity -@Table(name = "MetJob") +//@Entity +//@Table(name = "MetJob") public class Job{ - @Id - @GeneratedValue(generator = "UUID") - @GenericGenerator(name = "UUID", strategy = "org.hibernate.id.UUIDGenerator") +// @Id +// @GeneratedValue(generator = "UUID") +// @GenericGenerator(name = "UUID", strategy = "org.hibernate.id.UUIDGenerator") private UUID uuid; private ExecutionStateType state; diff --git a/src/main/java/org/etsi/osl/metrico/services/JobService.java b/src/main/java/org/etsi/osl/metrico/services/JobService.java index 3551997..f7087de 100644 --- a/src/main/java/org/etsi/osl/metrico/services/JobService.java +++ b/src/main/java/org/etsi/osl/metrico/services/JobService.java @@ -4,7 +4,10 @@ import lombok.Getter; import org.etsi.osl.metrico.model.Job; import org.etsi.osl.metrico.reposervices.JobRepoService; import org.etsi.osl.tmf.pm628.model.ExecutionStateType; +import org.etsi.osl.tmf.pm628.model.MeasurementCollectionJob; +import org.etsi.osl.tmf.pm628.model.MeasurementCollectionJobMVO; import org.etsi.osl.tmf.pm628.model.MeasurementCollectionJobRef; +import org.etsi.osl.tmf.pm628.reposervices.MeasurementCollectionJobService; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; @@ -30,10 +33,13 @@ public class JobService { @Getter private static final ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(threadPoolSize); - private final JobRepoService jobRepoService; + // private final JobRepoService jobRepoService; - public JobService(JobRepoService jobRepoService) { - this.jobRepoService = jobRepoService; + private final MeasurementCollectionJobService measurementCollectionJobService; + + public JobService(JobRepoService jobRepoService, MeasurementCollectionJobService measurementCollectionJobService) { + // this.jobRepoService = jobRepoService; + this.measurementCollectionJobService = measurementCollectionJobService; } @@ -59,34 +65,40 @@ public class JobService { * @return the newly created and scheduled {@link Job} instance * @throws RejectedExecutionException if the task cannot be scheduled for execution */ - public Job startJob(Runnable task, Job job) { - - + public Job startJob(Runnable task, Job job) { + + MeasurementCollectionJob mcj = measurementCollectionJobService.findMeasurementCollectionJobByUuid(job.getMeasurementCollectionJobRef().toString()); + MeasurementCollectionJobMVO mcjMVO = new MeasurementCollectionJobMVO(); + if ( job.getEndDateTime().isBefore( OffsetDateTime.now() )) { job.setState(ExecutionStateType.FAILED); - logger.error("Job with ID {} End Date is before now, the job will not be scheduled.", job.getUuid()); - return job; + mcjMVO.setExecutionState(ExecutionStateType.FAILED); + logger.error("Job for MeasurementCollectionJob with ID {} End Date is before now, the job will not be scheduled.", mcj.getUuid()); } - - long initialDelay = Duration.between(OffsetDateTime.now(), job.getStartDateTime()).getSeconds(); - if (initialDelay<0) { - initialDelay = 0; - } - job = jobRepoService.createAndSaveJob(job); - - try { - ScheduledFuture future = scheduler.scheduleAtFixedRate(task, initialDelay, job.getExecutionInterval(), TimeUnit.SECONDS); - job.setFuture(future); - job.setState(ExecutionStateType.INPROGRESS); - logger.info("Job with ID {} started successfully.", job.getUuid()); - } catch (RejectedExecutionException e) { - job.setState(ExecutionStateType.FAILED); - logger.error("Job with ID {} could not be scheduled.", job.getUuid(), e); - } - + else { + long initialDelay = Duration.between(OffsetDateTime.now(), job.getStartDateTime()).getSeconds(); + if (initialDelay < 0) { + initialDelay = 0; + } + // job = jobRepoService.createAndSaveJob(job); - job = jobRepoService.updateJob( job.getUuid(), job.getState()); - + try { + ScheduledFuture future = scheduler.scheduleAtFixedRate(task, initialDelay, job.getExecutionInterval(), TimeUnit.SECONDS); + job.setFuture(future); + job.setState(ExecutionStateType.INPROGRESS); + mcjMVO.setExecutionState(ExecutionStateType.INPROGRESS); + logger.info("Job for MeasurementCollectionJob with ID {} started successfully.", mcj.getUuid()); + } catch (RejectedExecutionException e) { + job.setState(ExecutionStateType.FAILED); + mcjMVO.setExecutionState(ExecutionStateType.FAILED); + logger.error("Job for MeasurementCollectionJob with ID {} could not be scheduled.", mcj.getUuid(), e); + } + + + // job = jobRepoService.updateJob(job.getUuid(), job.getState()); + + } + mcj = measurementCollectionJobService.updateMeasurementCollectionJob(mcj.getUuid(), mcjMVO); return job; } @@ -106,28 +118,34 @@ public class JobService { */ public void stopJob(Job job) { + MeasurementCollectionJob mcj = measurementCollectionJobService.findMeasurementCollectionJobByUuid(job.getMeasurementCollectionJobRef().toString()); + MeasurementCollectionJobMVO mcjMVO = new MeasurementCollectionJobMVO(); + if (job != null) { if (job.getState() == ExecutionStateType.CANCELLED ) { - logger.info("Job with ID {} is already CANCELED.", job.getUuid()); - jobRepoService.softDeleteJob( job ); + logger.info("Job for MeasurementCollectionJob with ID {} is already CANCELED.", mcj.getUuid()); + // jobRepoService.softDeleteJob( job ); return; } else if (job.getState() == ExecutionStateType.COMPLETED) { - logger.info("Job with ID {} is already COMPLETED.", job.getUuid()); - jobRepoService.softDeleteJob( job ); + logger.info("Job for MeasurementCollectionJob with ID {} is already COMPLETED.", mcj.getUuid()); + // jobRepoService.softDeleteJob( job ); return; } if (job.getFuture() != null) { boolean wasCancelled = job.getFuture().cancel(true); if (wasCancelled) { job.setState(ExecutionStateType.CANCELLED); - jobRepoService.updateJob(job.getUuid(), job.getState()); - logger.info("Job with ID {} stopped successfully.", job.getUuid()); + mcjMVO.setExecutionState(ExecutionStateType.CANCELLED); + // jobRepoService.updateJob(job.getUuid(), job.getState()); + logger.info("Job for MeasurementCollectionJob with ID {} stopped successfully.", mcj.getUuid()); } else { job.setState(ExecutionStateType.PENDING); - jobRepoService.updateJob( job.getUuid(), job.getState()); - logger.warn("Job with ID {} could not be stopped because it has already completed, has been cancelled, or could not be cancelled for some other reason.", job.getUuid()); + mcjMVO.setExecutionState(ExecutionStateType.PENDING); + // jobRepoService.updateJob( job.getUuid(), job.getState()); + logger.warn("Job for MeasurementCollectionJob with ID {} could not be stopped because it has already completed, has been cancelled, or could not be cancelled for some other reason.", mcj.getUuid()); } + mcj = measurementCollectionJobService.updateMeasurementCollectionJob(mcj.getUuid(), mcjMVO); } } else { logger.warn("Job does not exist."); diff --git a/src/main/java/org/etsi/osl/metrico/services/MetricoService.java b/src/main/java/org/etsi/osl/metrico/services/MetricoService.java index 04b4d92..2bbfcd5 100644 --- a/src/main/java/org/etsi/osl/metrico/services/MetricoService.java +++ b/src/main/java/org/etsi/osl/metrico/services/MetricoService.java @@ -8,19 +8,15 @@ import org.etsi.osl.metrico.mapper.DataAccessEndpointMapper; import org.etsi.osl.metrico.mapper.JobMapper; import org.etsi.osl.metrico.model.Job; import org.etsi.osl.metrico.prometheus.PrometheusQueries; -import org.etsi.osl.metrico.repo.JobRepository; -import org.etsi.osl.metrico.reposervices.JobRepoService; import org.etsi.osl.tmf.common.model.Any; import org.etsi.osl.tmf.common.model.ELifecycle; import org.etsi.osl.tmf.common.model.EValueType; import org.etsi.osl.tmf.common.model.service.ResourceRef; import org.etsi.osl.tmf.pm628.model.*; +import org.etsi.osl.tmf.pm628.reposervices.MeasurementCollectionJobService; import org.etsi.osl.tmf.rcm634.model.LogicalResourceSpecification; import org.etsi.osl.tmf.rcm634.model.ResourceSpecificationCreate; -import org.etsi.osl.tmf.ri639.model.LogicalResource; -import org.etsi.osl.tmf.ri639.model.Resource; import org.etsi.osl.tmf.ri639.model.ResourceUpdate; -import org.etsi.osl.tmf.so641.model.ServiceOrder; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; @@ -29,14 +25,8 @@ import org.springframework.boot.context.event.ApplicationStartedEvent; import org.springframework.context.event.EventListener; import org.springframework.stereotype.Service; -import java.io.IOException; -import java.time.OffsetDateTime; import java.util.ArrayList; -import java.util.HashMap; import java.util.List; -import java.util.Map; -import com.fasterxml.jackson.annotation.JsonInclude; -import com.fasterxml.jackson.databind.ObjectMapper; @Service public class MetricoService extends RouteBuilder { @@ -55,15 +45,17 @@ public class MetricoService extends RouteBuilder { private String PM_MEASUREMENT_COLLECTION_JOB_UPDATE = ""; @Value("${PM_MEASUREMENT_COLLECTION_GET_JOB_BY_ID}") - private String PM_MEASUREMENT_COLLECTION_GET_JOB_BY_ID = ""; - - @Autowired - private JobRepoService jobRepoService; - + private String PM_MEASUREMENT_COLLECTION_GET_JOB_BY_ID = ""; + +// @Autowired +// private JobRepoService jobRepoService; + + // @Autowired +// private JobRepository jobRepository; @Autowired - private JobRepository jobRepository; - + private MeasurementCollectionJobService measurementCollectionJobService; + @Autowired private final PrometheusQueries prometheusQueries; @@ -73,82 +65,83 @@ public class MetricoService extends RouteBuilder { this.prometheusQueries = prometheusQueries; this.producerTemplate = producerTemplate; } - - + + /** * This one is executed when the cridge service application starts + * * @param event */ @EventListener(ApplicationStartedEvent.class) public void onApplicationEvent() { - - registerMetricoResourceSpec(); - - List jobsPending = jobRepoService.findAll(); - logger.info("===== Pending jobs from previous sessions ====="); - for (Job job : jobsPending) { - logger.info("try to resume jobuuid: {}, state:{}, start: {}, end:{}, mcjid: {} ", job.getUuid(), job.getState(), job.getStartDateTime(), job.getEndDateTime(), job.getMeasurementCollectionJobRef() ); - - - //delete previous job from DB. a new one will be created - jobRepoService.softDeleteJob(job); - - MeasurementCollectionJobRef mjref = new MeasurementCollectionJobRef(); - mjref.setId( job.getMeasurementCollectionJobRef().toString() ); - this.startPeriodicQueryToPrometheusRef(mjref ); - } - - logger.info("===== Pending jobs from previous sessions done ====="); - + + registerMetricoResourceSpec(); + + List jobsPending = jobRepoService.findAll(); + logger.info("===== Pending jobs from previous sessions ====="); + for (Job job : jobsPending) { + logger.info("try to resume jobuuid: {}, state:{}, start: {}, end:{}, mcjid: {} ", job.getUuid(), job.getState(), job.getStartDateTime(), job.getEndDateTime(), job.getMeasurementCollectionJobRef()); + + + //delete previous job from DB. a new one will be created + jobRepoService.softDeleteJob(job); + + MeasurementCollectionJobRef mjref = new MeasurementCollectionJobRef(); + mjref.setId(job.getMeasurementCollectionJobRef().toString()); + this.startPeriodicQueryToPrometheusRef(mjref); + } + + logger.info("===== Pending jobs from previous sessions done ====="); + } private void registerMetricoResourceSpec() { - logger.info("===== Pending jobs from previous sessions ====="); - - - ResourceSpecificationCreate rsc = new ResourceSpecificationCreate(); - rsc.setName( OSL_METRICO_RSPEC_NAME ); - rsc.setCategory( OSL_METRICO_RSPEC_CATEGORY ); - rsc.setVersion( OSL_METRICO_RSPEC_VERSION ); - rsc.setDescription( OSL_METRICO_RSPEC_DESCRIPTION ); - rsc.setType( OSL_METRICO_RSPEC_TYPE ); - - rsc.setLifecycleStatus( ELifecycle.ACTIVE.getValue() ); - rsc.addResourceSpecificationCharacteristicItemShort( "_MT_CHARACTERISTIC_NAME", "", EValueType.TEXT.getValue(), "The characteristic of the service with id _MT_SERVICEUUID that will be updated with monitoring metrics", false); - rsc.addResourceSpecificationCharacteristicItemShort( "_MT_SERVICEUUID", "", EValueType.TEXT.getValue(), "The id of the service to update", false); - rsc.addResourceSpecificationCharacteristicItemShort( "_MT_END_TIME", "", EValueType.TEXT.getValue(), "The ending time of the monitoring job", false); - rsc.addResourceSpecificationCharacteristicItemShort( "_MT_START_TIME", "", EValueType.TEXT.getValue(), "The starting time of the monitoring job", false); - rsc.addResourceSpecificationCharacteristicItemShort( "_MT_RECURRING_INTERVAL", "G_1MN", EValueType.TEXT.getValue(), "The polling interval of the monitoring source", false); - rsc.addResourceSpecificationCharacteristicItemShort( "_MT_TYPE", "PROMETHEUS", EValueType.TEXT.getValue(), "The monitoring source type", false); - rsc.addResourceSpecificationCharacteristicItemShort( "_MT_QUERY", "", EValueType.TEXT.getValue(), "The query towards the monitoring source (e.g. query=gnb_service_state)", false); - rsc.addResourceSpecificationCharacteristicItemShort( "_MT_URL", "", EValueType.TEXT.getValue(), "The monitoring source URL (e.g. https://prom.osl.etsi.org:9090)", false); - - - LogicalResourceSpecification result = prometheusQueries.createOrUpdateResourceSpecByNameCategoryVersion(rsc); - while ( result == null ) { - try { - logger.info("Cannot get resource for registerMetricoResourceSpec. Retrying in 10 seconds" ); - Thread.sleep( 10000 ); - } catch (InterruptedException e) { - e.printStackTrace(); + logger.info("===== Pending jobs from previous sessions ====="); + + + ResourceSpecificationCreate rsc = new ResourceSpecificationCreate(); + rsc.setName(OSL_METRICO_RSPEC_NAME); + rsc.setCategory(OSL_METRICO_RSPEC_CATEGORY); + rsc.setVersion(OSL_METRICO_RSPEC_VERSION); + rsc.setDescription(OSL_METRICO_RSPEC_DESCRIPTION); + rsc.setType(OSL_METRICO_RSPEC_TYPE); + + rsc.setLifecycleStatus(ELifecycle.ACTIVE.getValue()); + rsc.addResourceSpecificationCharacteristicItemShort("_MT_CHARACTERISTIC_NAME", "", EValueType.TEXT.getValue(), "The characteristic of the service with id _MT_SERVICEUUID that will be updated with monitoring metrics", false); + rsc.addResourceSpecificationCharacteristicItemShort("_MT_SERVICEUUID", "", EValueType.TEXT.getValue(), "The id of the service to update", false); + rsc.addResourceSpecificationCharacteristicItemShort("_MT_END_TIME", "", EValueType.TEXT.getValue(), "The ending time of the monitoring job", false); + rsc.addResourceSpecificationCharacteristicItemShort("_MT_START_TIME", "", EValueType.TEXT.getValue(), "The starting time of the monitoring job", false); + rsc.addResourceSpecificationCharacteristicItemShort("_MT_RECURRING_INTERVAL", "G_1MN", EValueType.TEXT.getValue(), "The polling interval of the monitoring source", false); + rsc.addResourceSpecificationCharacteristicItemShort("_MT_TYPE", "PROMETHEUS", EValueType.TEXT.getValue(), "The monitoring source type", false); + rsc.addResourceSpecificationCharacteristicItemShort("_MT_QUERY", "", EValueType.TEXT.getValue(), "The query towards the monitoring source (e.g. query=gnb_service_state)", false); + rsc.addResourceSpecificationCharacteristicItemShort("_MT_URL", "", EValueType.TEXT.getValue(), "The monitoring source URL (e.g. https://prom.osl.etsi.org:9090)", false); + + + LogicalResourceSpecification result = prometheusQueries.createOrUpdateResourceSpecByNameCategoryVersion(rsc); + while (result == null) { + try { + logger.info("Cannot get resource for registerMetricoResourceSpec. Retrying in 10 seconds"); + Thread.sleep(10000); + } catch (InterruptedException e) { + e.printStackTrace(); + } + result = prometheusQueries.createOrUpdateResourceSpecByNameCategoryVersion(rsc); } - result = prometheusQueries.createOrUpdateResourceSpecByNameCategoryVersion(rsc); - } } @Autowired private ProducerTemplate template; - public String[] queryToPrometheus(@NotNull MeasurementCollectionJob givenMCJ){ + public String[] queryToPrometheus(@NotNull MeasurementCollectionJob givenMCJ) { DataAccessEndpoint givenDataAccessEndpoint = givenMCJ.getDataAccessEndpoint().get(0); Job job = JobMapper.measurementCollectionJobMapToJob(givenMCJ); String promURL = job.getDataAccessEndPointUri().getScheme() + "://" + job.getDataAccessEndPointUri().getAuthority(); String promQuery = job.getDataAccessEndPointUri().getQuery(); promQuery = promQuery.replace("query=", ""); - String [] promResponse = prometheusQueries.sendQueryToPrometheus(promURL, promQuery, givenMCJ, job).split("\n"); + String[] promResponse = prometheusQueries.sendQueryToPrometheus(promURL, promQuery, givenMCJ, job).split("\n"); DataFilterTemplate filterTemplate = new DataFilterTemplate(); filterTemplate.setName(promQuery); @@ -172,61 +165,60 @@ public class MetricoService extends RouteBuilder { return promResponse; } - public void startPeriodicQueryToPrometheus(@NotNull MeasurementCollectionJob givenMCJ){ + public void startPeriodicQueryToPrometheus(@NotNull MeasurementCollectionJob givenMCJ) { Job job = JobMapper.measurementCollectionJobMapToJob(givenMCJ); String promURL = job.getDataAccessEndPointUri().getScheme() + "://" + job.getDataAccessEndPointUri().getAuthority(); String promQuery = job.getDataAccessEndPointUri().getQuery(); - job = prometheusQueries.startPeriodicQuery(promURL, promQuery, job, givenMCJ ); + job = prometheusQueries.startPeriodicQuery(promURL, promQuery, job, givenMCJ); if (job.getState() == ExecutionStateType.FAILED) { logger.atError().setMessage("Periodic query failed to start due to internal error.").log(); - + } else { logger.atInfo().setMessage("Periodic query started, with ID: " + job.getUuid()).log(); } givenMCJ.setExecutionState(job.getState()); - producerTemplate.sendBodyAndHeader( PM_MEASUREMENT_COLLECTION_JOB_UPDATE, JsonUtil.toJsonString(givenMCJ), "mcjid", givenMCJ.getUuid() ); + producerTemplate.sendBodyAndHeader(PM_MEASUREMENT_COLLECTION_JOB_UPDATE, JsonUtil.toJsonString(givenMCJ), "mcjid", givenMCJ.getUuid()); updateRelatedResource(givenMCJ); } - - public void startPeriodicQueryToPrometheusRef(@NotNull MeasurementCollectionJobRef mcjRef){ + public void startPeriodicQueryToPrometheusRef(@NotNull MeasurementCollectionJobRef mcjRef) { MeasurementCollectionJob givenMCJ = retrieveMeasurementCollectionJob(mcjRef); startPeriodicQueryToPrometheus(givenMCJ); } - - - public void startPeriodicQueryToPrometheusEvent(@NotNull MeasurementCollectionJobCreateEvent mcjevent){ - - MeasurementCollectionJob givenMCJ = retrieveMeasurementCollectionJob( mcjevent.getEvent().getMeasurementCollectionJob().getId() ); - if ( givenMCJ != null) { - startPeriodicQueryToPrometheus(givenMCJ); - } else { - logger.error("=======> CANNOT retrieve Measurement Collection Job with mcjId = " + mcjevent.getEvent().getMeasurementCollectionJob().getId() +" from activeMQ"); - } - } + public void startPeriodicQueryToPrometheusEvent(@NotNull MeasurementCollectionJobCreateEvent mcjevent) { + + MeasurementCollectionJob givenMCJ = retrieveMeasurementCollectionJob(mcjevent.getEvent().getMeasurementCollectionJob().getId()); + + if (givenMCJ != null) { + startPeriodicQueryToPrometheus(givenMCJ); + } else { + + logger.error("=======> CANNOT retrieve Measurement Collection Job with mcjId = " + mcjevent.getEvent().getMeasurementCollectionJob().getId() + " from activeMQ"); + } + } public MeasurementCollectionJob retrieveMeasurementCollectionJob(String mcjId) { - logger.debug("will retrieve Measurement Collection Job with mcjId = " + mcjId +" from database"); + logger.debug("will retrieve Measurement Collection Job with mcjId = " + mcjId + " from database"); try { Object response = template. - requestBody( PM_MEASUREMENT_COLLECTION_GET_JOB_BY_ID, mcjId); - if ( !(response instanceof String)) { + requestBody(PM_MEASUREMENT_COLLECTION_GET_JOB_BY_ID, mcjId); + if (!(response instanceof String)) { logger.error("Measurement Collection Job object is wrong."); return null; } logger.debug("retrieveMeasurementCollectionJobById response is: " + response); - MeasurementCollectionJob mcj = JsonUtil.toJsonObj( (String)response, MeasurementCollectionJob.class); + MeasurementCollectionJob mcj = JsonUtil.toJsonObj((String) response, MeasurementCollectionJob.class); return mcj; - }catch (Exception e) { + } catch (Exception e) { logger.error("Cannot retrieve Measurement Collection Job details from database. " + e.toString()); } return null; @@ -237,53 +229,46 @@ public class MetricoService extends RouteBuilder { return retrieveMeasurementCollectionJob(mcjId); } - - + private void updateRelatedResource(@NotNull MeasurementCollectionJob givenMCJ) { - //retrieve related service from inventory - //retrieve related resource from inventory - //patch resource state - String servUUID = givenMCJ.getProducingApplicationId();//this contains the related ServiceUUID with this MCJ - - logger.debug("updateRelatedResource servUUID = " + servUUID ); - org.etsi.osl.tmf.sim638.model.Service aService = prometheusQueries.retrieveService(servUUID); - - if ( aService!=null && aService.getSupportingResource().size()>0) { - - ResourceRef resRef = aService.getSupportingResource().stream().findFirst().get(); - - //Resource aResource = retrieveResource(resRef.getId()); - logger.debug("updateRelatedResource resRef = " + resRef.getId() ); - - ResourceUpdate rup = new ResourceUpdate(); - org.etsi.osl.tmf.ri639.model.Characteristic resCharacteristicItem = new org.etsi.osl.tmf.ri639.model.Characteristic(); - resCharacteristicItem.setName( "_MT_MCJ_REF" ); - resCharacteristicItem.setValueType( "TEXT" ); - Any val = new Any(); - val.setValue( givenMCJ.getUuid() ); - val.setAlias( "" ); - resCharacteristicItem.setValue( val ); - rup.addResourceCharacteristicItem( resCharacteristicItem ); - - if ( givenMCJ.getExecutionState().equals( ExecutionStateType.FAILED ) ) { - rup.setResourceStatus( org.etsi.osl.tmf.ri639.model.ResourceStatusType.SUSPENDED ); - } else { - rup.setResourceStatus( org.etsi.osl.tmf.ri639.model.ResourceStatusType.AVAILABLE ); + //retrieve related service from inventory + //retrieve related resource from inventory + //patch resource state + String servUUID = givenMCJ.getProducingApplicationId();//this contains the related ServiceUUID with this MCJ + + logger.debug("updateRelatedResource servUUID = " + servUUID); + org.etsi.osl.tmf.sim638.model.Service aService = prometheusQueries.retrieveService(servUUID); + + if (aService != null && aService.getSupportingResource().size() > 0) { + + ResourceRef resRef = aService.getSupportingResource().stream().findFirst().get(); + + //Resource aResource = retrieveResource(resRef.getId()); + logger.debug("updateRelatedResource resRef = " + resRef.getId()); + + ResourceUpdate rup = new ResourceUpdate(); + org.etsi.osl.tmf.ri639.model.Characteristic resCharacteristicItem = new org.etsi.osl.tmf.ri639.model.Characteristic(); + resCharacteristicItem.setName("_MT_MCJ_REF"); + resCharacteristicItem.setValueType("TEXT"); + Any val = new Any(); + val.setValue(givenMCJ.getUuid()); + val.setAlias(""); + resCharacteristicItem.setValue(val); + rup.addResourceCharacteristicItem(resCharacteristicItem); + + if (givenMCJ.getExecutionState().equals(ExecutionStateType.FAILED)) { + rup.setResourceStatus(org.etsi.osl.tmf.ri639.model.ResourceStatusType.SUSPENDED); + } else { + rup.setResourceStatus(org.etsi.osl.tmf.ri639.model.ResourceStatusType.AVAILABLE); + } + + prometheusQueries.updateResourceById(resRef.getId(), rup); } - - prometheusQueries.updateResourceById(resRef.getId(), rup ); - - } - } @Override public void configure() throws Exception { - // TODO Auto-generated method stub - - } - - - + // TODO Auto-generated method stub + } } diff --git a/src/test/java/org/etsi/osl/metrico/services/JobServiceTest.java b/src/test/java/org/etsi/osl/metrico/services/JobServiceTest.java index ed1f285..50b8d94 100644 --- a/src/test/java/org/etsi/osl/metrico/services/JobServiceTest.java +++ b/src/test/java/org/etsi/osl/metrico/services/JobServiceTest.java @@ -1,106 +1,106 @@ -package org.etsi.osl.metrico.services; - -import org.etsi.osl.metrico.model.Job; -import org.etsi.osl.metrico.reposervices.JobRepoService; -import org.etsi.osl.tmf.pm628.model.ExecutionStateType; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import org.mockito.Mock; -import org.mockito.MockitoAnnotations; -import org.slf4j.Logger; - -import java.time.OffsetDateTime; -import java.util.UUID; -import java.util.concurrent.ScheduledExecutorService; -import java.util.concurrent.ScheduledFuture; -import java.util.concurrent.TimeUnit; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertNotNull; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.Mockito.*; - -class JobServiceTest { - - @Mock - private JobRepoService jobRepoService; - - @Mock - private ScheduledExecutorService scheduler; - - @Mock - private Logger logger; - - private JobService jobService; - - @BeforeEach - void setUp() { - MockitoAnnotations.openMocks(this); - jobService = new JobService(jobRepoService); - } - - @Test - void testStartJob_Success() { - // Initialize the job with specific parameters - OffsetDateTime startDateTime = OffsetDateTime.now().plusSeconds(5); - OffsetDateTime endDateTime = startDateTime.plusMinutes(10); - Integer executionInterval = 5; - Runnable task = () -> {}; - Job expectedJob = new Job(startDateTime, endDateTime, executionInterval); - // Assert the initial state is PENDING - assertEquals(expectedJob.getState(), ExecutionStateType.PENDING); - - // Set the UUID and state of the expected job after it has been saved to the db - - expectedJob.setState(ExecutionStateType.INPROGRESS); - - // Mock jobRepoService.createAndSaveJob() to return the expected Job - when(jobRepoService.createAndSaveJob(expectedJob)).thenReturn(expectedJob); - -// // Mock scheduler.scheduleAtFixedRate() to not throw an exception -// ScheduledFuture mockFuture = mock(ScheduledFuture.class); -// when(scheduler.scheduleAtFixedRate(any(Runnable.class), eq(5L), eq(5L), eq(TimeUnit.SECONDS))) -// .thenReturn(mockFuture); - +//package org.etsi.osl.metrico.services; +// +//import org.etsi.osl.metrico.model.Job; +//import org.etsi.osl.metrico.reposervices.JobRepoService; +//import org.etsi.osl.tmf.pm628.model.ExecutionStateType; +//import org.junit.jupiter.api.BeforeEach; +//import org.junit.jupiter.api.Test; +//import org.mockito.Mock; +//import org.mockito.MockitoAnnotations; +//import org.slf4j.Logger; +// +//import java.time.OffsetDateTime; +//import java.util.UUID; +//import java.util.concurrent.ScheduledExecutorService; +//import java.util.concurrent.ScheduledFuture; +//import java.util.concurrent.TimeUnit; +// +//import static org.junit.jupiter.api.Assertions.assertEquals; +//import static org.junit.jupiter.api.Assertions.assertNotNull; +//import static org.mockito.ArgumentMatchers.any; +//import static org.mockito.Mockito.*; +// +//class JobServiceTest { +// +// @Mock +// private JobRepoService jobRepoService; +// +// @Mock +// private ScheduledExecutorService scheduler; +// +// @Mock +// private Logger logger; +// +// private JobService jobService; +// +// @BeforeEach +// void setUp() { +// MockitoAnnotations.openMocks(this); +// jobService = new JobService(jobRepoService); +// } +// +// @Test +// void testStartJob_Success() { +// // Initialize the job with specific parameters +// OffsetDateTime startDateTime = OffsetDateTime.now().plusSeconds(5); +// OffsetDateTime endDateTime = startDateTime.plusMinutes(10); +// Integer executionInterval = 5; +// Runnable task = () -> {}; +// Job expectedJob = new Job(startDateTime, endDateTime, executionInterval); +// // Assert the initial state is PENDING +// assertEquals(expectedJob.getState(), ExecutionStateType.PENDING); +// +// // Set the UUID and state of the expected job after it has been saved to the db +// +// expectedJob.setState(ExecutionStateType.INPROGRESS); +// +// // Mock jobRepoService.createAndSaveJob() to return the expected Job +// when(jobRepoService.createAndSaveJob(expectedJob)).thenReturn(expectedJob); +// +//// // Mock scheduler.scheduleAtFixedRate() to not throw an exception +//// ScheduledFuture mockFuture = mock(ScheduledFuture.class); +//// when(scheduler.scheduleAtFixedRate(any(Runnable.class), eq(5L), eq(5L), eq(TimeUnit.SECONDS))) +//// .thenReturn(mockFuture); +// +//// // Call jobService.startJob() with valid parameters +//// Job resultJob = jobService.startJob(task, startDateTime, endDateTime, executionInterval); +//// +//// // Verify job state is INPROGRESS, and job is added to the jobs map +//// assertEquals(ExecutionStateType.INPROGRESS, resultJob.getState()); +//// assertNotNull(JobService.getJobs().get(resultJob.getUuid())); +//// assertEquals(expectedJob, JobService.getJobs().get(resultJob.getUuid())); +// } +// @Test +// void testStartJob_NullPointerException() { +// // Mock jobRepoService.createAndSaveJob() to throw NullPointerException // // Call jobService.startJob() with valid parameters -// Job resultJob = jobService.startJob(task, startDateTime, endDateTime, executionInterval); -// -// // Verify job state is INPROGRESS, and job is added to the jobs map -// assertEquals(ExecutionStateType.INPROGRESS, resultJob.getState()); -// assertNotNull(JobService.getJobs().get(resultJob.getUuid())); -// assertEquals(expectedJob, JobService.getJobs().get(resultJob.getUuid())); - } - @Test - void testStartJob_NullPointerException() { - // Mock jobRepoService.createAndSaveJob() to throw NullPointerException - // Call jobService.startJob() with valid parameters - // Verify job state is FAILED - } - - @Test - void testStartJob_RejectedExecutionException() { - // Mock scheduler.scheduleAtFixedRate() to throw RejectedExecutionException - // Call jobService.startJob() with valid parameters - // Verify job state is FAILED - } - - @Test - void testStopJob_InProgress() { - // Add a job to the jobs map with state INPROGRESS - // Call JobService.stopJob() with the job's UUID - // Verify job state is CANCELLED - } - - @Test - void testStopJob_AlreadyCompleted() { - // Add a job to the jobs map with state COMPLETED - // Call JobService.stopJob() with the job's UUID - // Verify job state remains COMPLETED - } - - @Test - void testStopJob_DoesNotExist() { - // Call JobService.stopJob() with a non-existent job UUID - // Verify appropriate warning is logged - } -} \ No newline at end of file +// // Verify job state is FAILED +// } +// +// @Test +// void testStartJob_RejectedExecutionException() { +// // Mock scheduler.scheduleAtFixedRate() to throw RejectedExecutionException +// // Call jobService.startJob() with valid parameters +// // Verify job state is FAILED +// } +// +// @Test +// void testStopJob_InProgress() { +// // Add a job to the jobs map with state INPROGRESS +// // Call JobService.stopJob() with the job's UUID +// // Verify job state is CANCELLED +// } +// +// @Test +// void testStopJob_AlreadyCompleted() { +// // Add a job to the jobs map with state COMPLETED +// // Call JobService.stopJob() with the job's UUID +// // Verify job state remains COMPLETED +// } +// +// @Test +// void testStopJob_DoesNotExist() { +// // Call JobService.stopJob() with a non-existent job UUID +// // Verify appropriate warning is logged +// } +//} \ No newline at end of file -- GitLab From d888545777caa9ba4af797a6d2bd8678c1ba0b0d Mon Sep 17 00:00:00 2001 From: George Tziavas Date: Mon, 17 Mar 2025 10:45:24 +0200 Subject: [PATCH 02/17] removed persistency --- .../osl/metrico/MetricoCommonMethods.java | 340 ++++++++++++++++++ .../etsi/osl/metrico/MetricoSpringBoot.java | 65 ++-- .../etsi/osl/metrico/mapper/JobMapper.java | 1 - .../java/org/etsi/osl/metrico/model/Job.java | 21 +- .../metrico/prometheus/PrometheusQueries.java | 327 +++-------------- .../etsi/osl/metrico/repo/JobRepository.java | 20 -- .../metrico/reposervices/JobRepoService.java | 87 ----- .../etsi/osl/metrico/services/JobService.java | 207 ++++++----- .../osl/metrico/services/MetricoService.java | 183 +++------- 9 files changed, 578 insertions(+), 673 deletions(-) create mode 100644 src/main/java/org/etsi/osl/metrico/MetricoCommonMethods.java delete mode 100644 src/main/java/org/etsi/osl/metrico/repo/JobRepository.java delete mode 100644 src/main/java/org/etsi/osl/metrico/reposervices/JobRepoService.java diff --git a/src/main/java/org/etsi/osl/metrico/MetricoCommonMethods.java b/src/main/java/org/etsi/osl/metrico/MetricoCommonMethods.java new file mode 100644 index 0000000..e3318c7 --- /dev/null +++ b/src/main/java/org/etsi/osl/metrico/MetricoCommonMethods.java @@ -0,0 +1,340 @@ +package org.etsi.osl.metrico; + +import com.fasterxml.jackson.databind.ObjectMapper; +import jakarta.validation.constraints.NotNull; +import org.apache.camel.ProducerTemplate; +import org.apache.camel.builder.RouteBuilder; +import org.etsi.osl.tmf.common.model.Any; +import org.etsi.osl.tmf.common.model.service.ResourceRef; +import org.etsi.osl.tmf.pm628.model.ExecutionStateType; +import org.etsi.osl.tmf.pm628.model.MeasurementCollectionJob; +import org.etsi.osl.tmf.pm628.model.MeasurementCollectionJobMVO; +import org.etsi.osl.tmf.pm628.model.MeasurementCollectionJobRef; +import org.etsi.osl.tmf.rcm634.model.LogicalResourceSpecification; +import org.etsi.osl.tmf.rcm634.model.ResourceSpecificationCreate; +import org.etsi.osl.tmf.ri639.model.*; +import org.etsi.osl.tmf.sim638.model.Service; +import org.etsi.osl.tmf.sim638.model.ServiceUpdate; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Component; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +@Component +public class MetricoCommonMethods extends RouteBuilder { + private static final Logger logger = LoggerFactory.getLogger(MetricoCommonMethods.class); + + @Value("${PM_MEASUREMENT_COLLECTION_JOB_UPDATE}") + private String PM_MEASUREMENT_COLLECTION_JOB_UPDATE = ""; + @Value("${PM_MEASUREMENT_COLLECTION_GET_JOB_BY_ID}") + private String PM_MEASUREMENT_COLLECTION_GET_JOB_BY_ID = ""; + @Value("${PM_MEASUREMENT_COLLECTION_JOBS_GET}") + private String PM_MEASUREMENT_COLLECTION_JOBS_GET = ""; + @Value("${CATALOG_GET_SERVICE_BY_ID}") + private String CATALOG_GET_SERVICE_BY_ID = ""; + @Value("${CATALOG_UPD_SERVICE}") + private String CATALOG_UPD_SERVICE = ""; + @Value("${CATALOG_GET_RESOURCE_BY_ID}") + private String CATALOG_GET_RESOURCE_BY_ID = ""; + @Value("${CATALOG_UPD_RESOURCE}") + private String CATALOG_UPD_RESOURCE = ""; + @Value("${CATALOG_UPDADD_RESOURCESPEC}") + private String CATALOG_UPDADD_RESOURCESPEC = ""; + + private ProducerTemplate template; + + @Override + public void configure() throws Exception { + // TODO Auto-generated method stub + } + + /** + * Retrieves a Measurement Collection Job from the database using the given job ID. + * + * @param mcjId the ID of the Measurement Collection Job to retrieve + * @return the retrieved Measurement Collection Job, or null if the job could not be retrieved + */ + public MeasurementCollectionJob retrieveMeasurementCollectionJob(String mcjId) { + + logger.debug("will retrieve Measurement Collection Job with mcjId = {}.", mcjId); + try { + Object response = template.requestBody(PM_MEASUREMENT_COLLECTION_GET_JOB_BY_ID, mcjId); + if (!(response instanceof String)) { + logger.error("Measurement Collection Job object is wrong."); + return null; + } + logger.debug("retrieveMeasurementCollectionJobById response is: " + response); + MeasurementCollectionJob mcj = JsonUtil.toJsonObj((String) response, MeasurementCollectionJob.class); + return mcj; + } catch (Exception e) { + logger.error("Cannot retrieve Measurement Collection Job details from database. " + e.toString()); + } + return null; + } + + /** + * Retrieves a Measurement Collection Job from the database using the given job reference. + * + * @param mcjRef the reference of the Measurement Collection Job to retrieve + * @return the retrieved Measurement Collection Job, or null if the job could not be retrieved + */ + public MeasurementCollectionJob retrieveMeasurementCollectionJob(MeasurementCollectionJobRef mcjRef) { + String mcjId = mcjRef.getId(); + + return retrieveMeasurementCollectionJob(mcjId); + } + + /** + * Retrieves a list of all Measurement Collection Jobs from the database. + * + * @return a list of all Measurement Collection Jobs, or null if the jobs could not be retrieved + */ + public List listMeasurementCollectionJob() { + + logger.debug("will retrieve all Measurement Collection Jobs from database"); + try { + Object response = template.requestBody(PM_MEASUREMENT_COLLECTION_JOBS_GET); + if (!(response instanceof String)) { + logger.error("List object is wrong."); + return null; + } + logger.debug("listMeasurementCollectionJob response is: " + response); + //List allMcjs = JsonUtil.toJsonObj((String) response, List allMcjs = mapper.readValue((String) response, mapper.getTypeFactory().constructCollectionType(List.class, MeasurementCollectionJob.class)); + return allMcjs; + + } catch (Exception e) { + logger.error("Cannot retrieve Measurement Collection Job details from database: {}. ", e.toString()); + } + return null; + } + + /** + * Retrieves a list of Measurement Collection Jobs from the database that have an execution state of either Pending or InProgress. + * + * @return a list of unfinished Measurement Collection Jobs, or null if no jobs match the criteria or if an error occurs + */ + public List listUnfinishedMeasurementCollectionJob() { + logger.debug("will retrieve Measurement Collection Jobs with ExecutionStateType Pending or InProgress from the database"); + + List allMeasurementCollectionJobs = listMeasurementCollectionJob(); + List filteredMeasurementCollectionJobs = null; + + try { + if (allMeasurementCollectionJobs != null) { + filteredMeasurementCollectionJobs = allMeasurementCollectionJobs.stream() + .filter(mcj -> mcj.getExecutionState().equals(ExecutionStateType.PENDING) || mcj.getExecutionState().equals(ExecutionStateType.INPROGRESS)) + .toList(); + } + } catch (Exception e) { + logger.error("Cannot retrieve/filter Measurement Collection Job details from the database. " + e); + } + return filteredMeasurementCollectionJobs; + } + + + /** + * Updates the related resource state based on the given Measurement Collection Job. + * + * @param givenMCJ the Measurement Collection Job containing the related Service UUID and execution state + */ + public void updateRelatedResource(@NotNull MeasurementCollectionJob givenMCJ) { + //retrieve related service from inventory + //retrieve related resource from inventory + //patch resource state + String servUUID = givenMCJ.getProducingApplicationId();//this contains the related ServiceUUID with this MCJ + logger.debug("Update Resource related to Service with ServiceId {}.", servUUID); + Service aService = retrieveService(servUUID); + + if (aService != null && aService.getSupportingResource().size() > 0) { + ResourceRef resRef = aService.getSupportingResource().stream().findFirst().get(); + //Resource aResource = retrieveResource(resRef.getId()); + logger.debug("Update Resource with ResourceId {}.", resRef.getId()); + + ResourceUpdate rup = new ResourceUpdate(); + Characteristic resCharacteristicItem = new Characteristic(); + resCharacteristicItem.setName("_MT_MCJ_REF"); + resCharacteristicItem.setValueType("TEXT"); + Any val = new Any(); + val.setValue(givenMCJ.getUuid()); + val.setAlias(""); + resCharacteristicItem.setValue(val); + rup.addResourceCharacteristicItem(resCharacteristicItem); + + if (givenMCJ.getExecutionState().equals(ExecutionStateType.FAILED)) { + rup.setResourceStatus(ResourceStatusType.SUSPENDED); + } else { + rup.setResourceStatus(ResourceStatusType.AVAILABLE); + } + updateResourceById(resRef.getId(), rup); + } else { + logger.error("No related Resource found for Service with Service Id {}.", servUUID); + } + } + + + /** + * Creates or updates a LogicalResourceSpecification in the catalog using the given name, category, and version. + * + * @param s the ResourceSpecificationCreate object containing the specification details + * @return the created or updated LogicalResourceSpecification instance, or null if the operation failed + */ + public LogicalResourceSpecification createOrUpdateResourceSpecByNameCategoryVersion(ResourceSpecificationCreate s) { + logger.info("will createOrUpdateResourceSpecByNameCategoryVersion "); + try { + Map map = new HashMap<>(); + map.put("aname", s.getName()); + map.put("aversion", s.getVersion()); + map.put("acategory", s.getCategory()); + Object response = template.requestBodyAndHeaders(CATALOG_UPDADD_RESOURCESPEC, JsonUtil.toJsonString(s), map); + assert response instanceof String : "ResourceSpecification object is wrong."; + LogicalResourceSpecification rs = JsonUtil.toJsonObj((String) response, LogicalResourceSpecification.class); + return rs; + } catch (Exception e) { + logger.error("Cannot create ResourceSpecification"); + e.printStackTrace(); + } + return null; + } + + + /** + * Updates a Service in the catalog using the given service ID and update information. + * + * @param serviceId the ID of the service to update + * @param serviceUpdate the update information for the service + * @param triggerServiceActionQueue flag to trigger the service action queue + * @return the updated Service instance, or null if the service could not be updated + */ + public Service updateService(String serviceId, ServiceUpdate serviceUpdate, boolean triggerServiceActionQueue) { + logger.info("will update Service : " + serviceId); + try { + Map map = new HashMap<>(); + map.put("serviceid", serviceId); + map.put("triggerServiceActionQueue", triggerServiceActionQueue); + + Object response = template.requestBodyAndHeaders(CATALOG_UPD_SERVICE, JsonUtil.toJsonString(serviceUpdate), map); + + assert response instanceof String : "Service Instance object is wrong."; + Service serviceInstance = JsonUtil.toJsonObj((String) response, Service.class); + return serviceInstance; + + + } catch (Exception e) { + logger.error("Cannot update Service with serviceId {} : {}", serviceId, e.toString()); + } + return null; + + } + + /** + * Updates a Resource in the catalog using the given resource ID and update information. + * + * @param oslResourceId the ID of the resource to update + * @param rs the update information for the resource + * @return the updated LogicalResource instance, or null if the resource could not be updated + */ + public Resource updateResourceById(String oslResourceId, ResourceUpdate rs) { + logger.debug("will update Resource with id: " + oslResourceId); + try { + Map map = new HashMap<>(); + map.put("resourceId", oslResourceId); + map.put("triggerServiceActionQueue", false); + + Object response = template.requestBodyAndHeaders(CATALOG_UPD_RESOURCE, JsonUtil.toJsonString(rs), map); + assert response instanceof String : "Service Instance object is wrong."; + LogicalResource resourceInstance = JsonUtil.toJsonObj((String) response, LogicalResource.class); + return resourceInstance; + } catch (Exception e) { + e.printStackTrace(); + logger.error("Cannot update Service with id {} : {} ", oslResourceId, e.toString()); + } + return null; + } + + + /** + * Retrieves a Service instance from the catalog using the given service ID. + * + * @param serviceID the ID of the service to retrieve + * @return the retrieved Service instance, or null if the service could not be retrieved + */ + public Service retrieveService(String serviceID) { + logger.info("will retrieve Service instance from catalog serviceID=" + serviceID); + try { + Object response = template.requestBody(CATALOG_GET_SERVICE_BY_ID, serviceID); + + if (!(response instanceof String)) { + logger.error("Service object is wrong."); + return null; + } + return JsonUtil.toJsonObj((String) response, Service.class); + + } catch (Exception e) { + logger.error("Cannot retrieve Service details from catalog. " + e.toString()); + } + return null; + } + + + /** + * Retrieves a Resource instance from the catalog using the given resource ID. + * + * @param resourceID the ID of the resource to retrieve + * @return the retrieved LogicalResource instance, or null if the resource could not be retrieved + */ + public Resource retrieveResource(@NotNull String resourceID) { + logger.info("will retrieve Resource instance from catalog: resourceID = {}", resourceID); + try { + Object response = template.requestBody(CATALOG_GET_RESOURCE_BY_ID, resourceID); + + if (!(response instanceof String)) { + logger.error("resource object is wrong."); + return null; + } + LogicalResource resourceInstance = JsonUtil.toJsonObj((String) response, LogicalResource.class); + + return resourceInstance; + + } catch (Exception e) { + logger.error("Cannot retrieve LogicalResource details from catalog. {}", e.toString()); + } + return null; + + } + + + /** + * Updates a Measurement Collection Job in the database using the given job ID and update information. + * + * @param mcjId the ID of the Measurement Collection Job to update + * @param mcjMVO the update information for the Measurement Collection Job + * @return the updated Measurement Collection Job, or null if the job could not be updated + */ + public MeasurementCollectionJob updateMeasurementCollectionJobById(String mcjId, MeasurementCollectionJobMVO mcjMVO) { + MeasurementCollectionJob measurementCollectionJob; + logger.debug("will update MeasurementCollectionJob with id {}", mcjId); + + try { + Map map = new HashMap<>(); + map.put("mcjid", mcjId); + + Object response = template.requestBodyAndHeaders(PM_MEASUREMENT_COLLECTION_JOB_UPDATE, JsonUtil.toJsonString(mcjMVO), map); + assert response instanceof String : "MeasurementCollectionJob object is wrong."; + measurementCollectionJob = JsonUtil.toJsonObj((String) response, MeasurementCollectionJob.class); + + return measurementCollectionJob; + } catch (Exception e) { + e.printStackTrace(); + logger.error("Cannot update MeasurementCollectionJob with id {} : {}", mcjId, e.toString()); + } + return null; + } + + +} diff --git a/src/main/java/org/etsi/osl/metrico/MetricoSpringBoot.java b/src/main/java/org/etsi/osl/metrico/MetricoSpringBoot.java index 1040f0d..5aa4216 100644 --- a/src/main/java/org/etsi/osl/metrico/MetricoSpringBoot.java +++ b/src/main/java/org/etsi/osl/metrico/MetricoSpringBoot.java @@ -1,75 +1,50 @@ package org.etsi.osl.metrico; -import org.etsi.osl.metrico.services.MetricoService; -import org.etsi.osl.tmf.pm628.model.MeasurementCollectionJob; -import org.etsi.osl.tmf.pm628.model.MeasurementCollectionJobRef; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.CommandLineRunner; import org.springframework.boot.ExitCodeGenerator; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.autoconfigure.domain.EntityScan; -import org.springframework.boot.context.event.ApplicationStartedEvent; import org.springframework.context.ApplicationContext; -import org.springframework.context.event.EventListener; import org.springframework.data.jpa.repository.config.EnableJpaRepositories; -import jakarta.validation.constraints.NotNull; @SpringBootApplication @EnableJpaRepositories("org.etsi.osl.metrico.repo") -@EntityScan( basePackages = { +@EntityScan(basePackages = { "org.etsi.osl.metrico.repo", "org.etsi.osl.metrico.model", "org.etsi.osl.metrico", "org.etsi.osl.metrico.reposervices", "org.etsi.osl.metrico.services" }) - public class MetricoSpringBoot implements CommandLineRunner { +public class MetricoSpringBoot implements CommandLineRunner { - private static final Logger logger = - LoggerFactory.getLogger(MetricoSpringBoot.class.getSimpleName()); + private static final Logger logger = LoggerFactory.getLogger(MetricoSpringBoot.class.getSimpleName()); -// -// @Autowired -// private MetricoService aMetricoService; - - - @Override - public void run(String... arg0) { - if (arg0.length > 0 && arg0[0].equals("exitcode")) { - throw new ExitException(); - } - - -// @NotNull -// MeasurementCollectionJob mcj = new MeasurementCollectionJob(); -// -// @NotNull -// MeasurementCollectionJobRef mjref = new MeasurementCollectionJobRef(); -// mjref.setId("268cd191-21ac-4a81-84d8-933445a65ec1"); -// aMetricoService.startPeriodicQueryToPrometheusRef(mjref ); - } - + public static void main(String[] args) { + logger.info("============================== STARTING METRICO =============================="); + ApplicationContext applicationContext = new SpringApplication(MetricoSpringBoot.class).run(args); - public static void main(String[] args) { - logger.info("============================== STARTING METRICO =============================="); - ApplicationContext applicationContext = new SpringApplication(MetricoSpringBoot.class).run(args); - - - - - } + } - static class ExitException extends RuntimeException implements ExitCodeGenerator { - private static final long serialVersionUID = 1L; @Override - public int getExitCode() { - return 10; + public void run(String... arg0) { + if (arg0.length > 0 && arg0[0].equals("exitcode")) { + throw new ExitException(); + } + } + + static class ExitException extends RuntimeException implements ExitCodeGenerator { + private static final long serialVersionUID = 1L; + + @Override + public int getExitCode() { + return 10; + } } - } } diff --git a/src/main/java/org/etsi/osl/metrico/mapper/JobMapper.java b/src/main/java/org/etsi/osl/metrico/mapper/JobMapper.java index 0597011..13db6f8 100644 --- a/src/main/java/org/etsi/osl/metrico/mapper/JobMapper.java +++ b/src/main/java/org/etsi/osl/metrico/mapper/JobMapper.java @@ -1,6 +1,5 @@ package org.etsi.osl.metrico.mapper; -import jakarta.validation.Valid; import org.etsi.osl.metrico.model.Job; import org.etsi.osl.metrico.model.SupportedDataAccessEndpoints; import org.etsi.osl.tmf.pm628.model.*; diff --git a/src/main/java/org/etsi/osl/metrico/model/Job.java b/src/main/java/org/etsi/osl/metrico/model/Job.java index 1eb01ca..e09eff6 100644 --- a/src/main/java/org/etsi/osl/metrico/model/Job.java +++ b/src/main/java/org/etsi/osl/metrico/model/Job.java @@ -17,15 +17,8 @@ import java.util.concurrent.ScheduledFuture; @Getter @Setter -//@Entity -//@Table(name = "MetJob") public class Job{ -// @Id -// @GeneratedValue(generator = "UUID") -// @GenericGenerator(name = "UUID", strategy = "org.hibernate.id.UUIDGenerator") - private UUID uuid; - private ExecutionStateType state; @DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME) @@ -36,14 +29,10 @@ public class Job{ private Integer executionInterval; - private UUID dataAccessEndPointRef; // Get the prometheus IP (uri) and its state + private UUID dataAccessEndPointRef; - private UUID scheduleDefinitionRef; //Get the startDateTime, endDateTime and executionInterval (recurringFrequency) + private UUID scheduleDefinitionRef; - // Get the reporting period and collection granularity(the periods are too big), - // Consuming / producing application id, - // scheduleDefinitionRef -> Get the startDateTime, endDateTime and executionInterval (recurringFrequency) - // Should I check the granularity or the scheduleDefinitionRef for the recurringFrequency? private UUID measurementCollectionJobRef; private URI dataAccessEndPointUri; @@ -57,14 +46,12 @@ public class Job{ private final Runnable task = new Runnable() { @Override public void run() { - } }; @Transient private ScheduledFuture future; - public Job() { this.state = ExecutionStateType.PENDING; this.executionInterval = 10; @@ -89,7 +76,6 @@ public class Job{ @Override public String toString() { return "Job{" + - "uuid=" + uuid + ", state=" + state + ", startDateTime=" + startDateTime + ", endDateTime=" + endDateTime + @@ -101,9 +87,6 @@ public class Job{ '}'; } - public void setUuid(UUID uuid) { - this.uuid = uuid; - } public void setState(ExecutionStateType state) { this.state = state; diff --git a/src/main/java/org/etsi/osl/metrico/prometheus/PrometheusQueries.java b/src/main/java/org/etsi/osl/metrico/prometheus/PrometheusQueries.java index f84a106..71c9a6c 100644 --- a/src/main/java/org/etsi/osl/metrico/prometheus/PrometheusQueries.java +++ b/src/main/java/org/etsi/osl/metrico/prometheus/PrometheusQueries.java @@ -1,164 +1,105 @@ package org.etsi.osl.metrico.prometheus; -import java.io.IOException; -import java.time.Duration; -import java.time.OffsetDateTime; -import java.util.HashMap; -import java.util.Map; -import java.util.UUID; -import java.util.concurrent.TimeUnit; -import javax.net.ssl.SSLException; -import com.fasterxml.jackson.annotation.JsonInclude; -import com.fasterxml.jackson.databind.ObjectMapper; -import org.apache.camel.ProducerTemplate; +import org.etsi.osl.metrico.MetricoCommonMethods; import org.etsi.osl.metrico.model.Job; import org.etsi.osl.metrico.services.JobService; import org.etsi.osl.tmf.common.model.Any; import org.etsi.osl.tmf.common.model.service.Characteristic; import org.etsi.osl.tmf.pm628.model.ExecutionStateType; import org.etsi.osl.tmf.pm628.model.MeasurementCollectionJob; -import org.etsi.osl.tmf.rcm634.model.LogicalResourceSpecification; -import org.etsi.osl.tmf.rcm634.model.ResourceSpecificationCreate; -import org.etsi.osl.tmf.ri639.model.LogicalResource; -import org.etsi.osl.tmf.ri639.model.Resource; -import org.etsi.osl.tmf.ri639.model.ResourceUpdate; import org.etsi.osl.tmf.sim638.model.ServiceUpdate; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Value; import org.springframework.core.ParameterizedTypeReference; import org.springframework.http.HttpStatusCode; import org.springframework.stereotype.Component; import org.springframework.web.reactive.function.client.WebClient; import org.springframework.web.util.UriComponentsBuilder; -import jakarta.validation.constraints.NotNull; import reactor.core.publisher.Mono; +import java.time.Duration; +import java.time.OffsetDateTime; +import java.util.concurrent.TimeUnit; + @Component public class PrometheusQueries { private static final Logger logger = LoggerFactory.getLogger(PrometheusQueries.class); - private final JobService jobService; - - - @Value("${CATALOG_GET_SERVICE_BY_ID}") - private String CATALOG_GET_SERVICE_BY_ID = ""; - - - @Value("${CATALOG_GET_RESOURCE_BY_ID}") - private String CATALOG_GET_RESOURCE_BY_ID = ""; - - @Value("${CATALOG_UPD_RESOURCE}") - private String CATALOG_UPD_RESOURCE = ""; - - - @Value("${CATALOG_UPD_SERVICE}") - private String CATALOG_UPD_SERVICE = ""; - - @Value("${CATALOG_UPDADD_RESOURCESPEC}") - private String CATALOG_UPDADD_RESOURCESPEC = ""; - - + private final JobService jobService; + private final MetricoCommonMethods metricoCommonMethods; - @Autowired - private ProducerTemplate template; - - public PrometheusQueries(JobService jobService) { + public PrometheusQueries(JobService jobService, MetricoCommonMethods metricoCommonMethods) { this.jobService = jobService; + this.metricoCommonMethods = metricoCommonMethods; } public String sendQueryToPrometheus(String prometheusUrl, String query, MeasurementCollectionJob mcj, Job job) { - //RestTemplate restTemplate = new RestTemplate(); - - UriComponentsBuilder builder = UriComponentsBuilder.fromHttpUrl(prometheusUrl) - .path("/api/v1/query") - .query(query); + UriComponentsBuilder builder = UriComponentsBuilder.fromHttpUrl(prometheusUrl).path("/api/v1/query").query(query); logger.atInfo().log("Sent query at prometheus with URL: " + prometheusUrl + " with query: " + query); - logger.atInfo().log("Sent query builder.toUriString(): " + builder.toUriString() ); + logger.atInfo().log("Sent query builder.toUriString(): " + builder.toUriString()); - //ResponseEntity response = restTemplate.getForEntity(builder.toUriString(), String.class); - WebClient webclient = WebClient.create(); + String response; - String response=""; - - if ( webclient!=null ) { - - try { - - String url = builder.toUriString(); - - response = webclient.get() - .uri(url) - //.header("Authorization", "Basic " + encodedClientData) + if (webclient != null) { + try { + String url = builder.toUriString(); + response = webclient.get().uri(url) + //.header("Authorization", "Basic " + encodedClientData) //.attributes( ServletOAuth2AuthorizedClientExchangeFilterFunction.clientRegistrationId("authOpensliceProvider")) - .retrieve() - .onStatus(HttpStatusCode::is4xxClientError, r -> { + .retrieve().onStatus(HttpStatusCode::is4xxClientError, r -> { logger.error("4xx eror"); return Mono.error(new RuntimeException("4xx")); - }) - .onStatus(HttpStatusCode::is5xxServerError, r -> { - logger.error("5xx eror"); + }).onStatus(HttpStatusCode::is5xxServerError, r -> { + logger.error("5xx eror"); return Mono.error(new RuntimeException("5xx")); - }) - .bodyToMono( new ParameterizedTypeReference() {}) - .block(); - - logger.atDebug().log("Received " + response); - - String [] promResponse =response.split("\n"); - - - - }catch (Exception e) { + }).bodyToMono(new ParameterizedTypeReference() { + }).block(); + logger.atDebug().log("Received " + response); + String[] promResponse = response.split("\n"); + } catch (Exception e) { logger.error(" error on web client request"); - response = "{\"status\":\""+ e.getLocalizedMessage() +"\""; + response = "{\"status\":\"" + e.getLocalizedMessage() + "\""; e.printStackTrace(); } - - } else { - logger.error("WebClient is null. Cannot be created."); - response = "{\"status\":\"Cannot connect\""; - } - - - - ServiceUpdate su = new ServiceUpdate(); + } else { + logger.error("WebClient is null. Cannot be created."); + response = "{\"status\":\"Cannot connect\""; + } - //patch TMF service - String serviceUUID = mcj.getConsumingApplicationId(); - logger.atDebug().log("serviceUUID= " + serviceUUID); - Characteristic serviceCharacteristicItem = new Characteristic(); - serviceCharacteristicItem.setName( mcj.getOutputFormat() ); - serviceCharacteristicItem.setValueType( "TEXT" ); - Any val = new Any(); - val.setValue( response ); - val.setAlias( ""); - serviceCharacteristicItem.setValue( val ); - su.addServiceCharacteristicItem(serviceCharacteristicItem); - updateService(serviceUUID, su , true); - - return response; + ServiceUpdate su = new ServiceUpdate(); + //patch TMF service + String serviceUUID = mcj.getConsumingApplicationId(); + logger.atDebug().log("serviceUUID= " + serviceUUID); + Characteristic serviceCharacteristicItem = new Characteristic(); + serviceCharacteristicItem.setName(mcj.getOutputFormat()); + serviceCharacteristicItem.setValueType("TEXT"); + Any val = new Any(); + val.setValue(response); + val.setAlias(""); + serviceCharacteristicItem.setValue(val); + su.addServiceCharacteristicItem(serviceCharacteristicItem); + metricoCommonMethods.updateService(serviceUUID, su, true); + + return response; } - - + public Job startPeriodicQuery(String prometheusUrl, String query, final Job ajob, MeasurementCollectionJob mcj) { - Job job = ajob; - if (job.getStartDateTime() == null){ - job.setStartDateTime(OffsetDateTime.now()); - } - if (job.getEndDateTime() == null){ - job.setEndDateTime(job.getStartDateTime().plusHours(1)); - } - if(job.getExecutionInterval() == null){ - job.setExecutionInterval(180); - } - + Job job = ajob; + if (job.getStartDateTime() == null) { + job.setStartDateTime(OffsetDateTime.now()); + } + if (job.getEndDateTime() == null) { + job.setEndDateTime(job.getStartDateTime().plusHours(1)); + } + if (job.getExecutionInterval() == null) { + job.setExecutionInterval(180); + } + final Runnable queryHandler = () -> sendQueryToPrometheus(prometheusUrl, query, mcj, ajob); job = jobService.startJob(queryHandler, job); @@ -168,167 +109,15 @@ public class PrometheusQueries { } if (job.getEndDateTime() != null) { - long stopAfterSeconds = Duration.between(OffsetDateTime.now(), job.getEndDateTime() ).getSeconds(); + long stopAfterSeconds = Duration.between(OffsetDateTime.now(), job.getEndDateTime()).getSeconds(); JobService.getScheduler().schedule(() -> { jobService.stopJob(ajob); - }, stopAfterSeconds, TimeUnit.SECONDS); } return job; } - - - - public Resource retrieveResource(@NotNull String resourceID) { - logger.info("will retrieve Resource instance from catalog resourceID=" + resourceID ); - try { - Object response = template. - requestBody( CATALOG_GET_RESOURCE_BY_ID, resourceID); - - if ( !(response instanceof String)) { - logger.error("resource object is wrong."); - return null; - } - LogicalResource rInstance = toJsonObj( (String)response, LogicalResource.class); - - return rInstance; - - }catch (Exception e) { - logger.error("Cannot retrieve LogicalResource details from catalog. " + e.toString()); - } - return null; - - } - - /** - * Ger service instance via bus - * @param serviceID - * @return - */ - public org.etsi.osl.tmf.sim638.model.Service retrieveService(String serviceID) { - logger.info("will retrieve Service instance from catalog serviceID=" + serviceID ); - try { - Object response = template. - requestBody( CATALOG_GET_SERVICE_BY_ID, serviceID); - - if ( !(response instanceof String)) { - logger.error("Service object is wrong."); - return null; - } - org.etsi.osl.tmf.sim638.model.Service serviceInstance = toJsonObj( (String)response, org.etsi.osl.tmf.sim638.model.Service.class); - //logger.debug("retrieveService response is: " + response); - return serviceInstance; - - }catch (Exception e) { - logger.error("Cannot retrieve Service details from catalog. " + e.toString()); - } - return null; - } - - - public Resource updateResourceById(String oslResourceId, ResourceUpdate rs) { - - - logger.debug("will update Resource : " + oslResourceId ); - try { - Map map = new HashMap<>(); - map.put("resourceId", oslResourceId ); - map.put("triggerServiceActionQueue", false ); - - Object response = template.requestBodyAndHeaders( CATALOG_UPD_RESOURCE, toJsonString(rs), map); - - if ( !(response instanceof String)) { - logger.error("Service Instance object is wrong."); - } - - LogicalResource resourceInstance = toJsonObj( (String)response, LogicalResource.class); - //logger.debug("createService response is: " + response); - return resourceInstance; - - - }catch (Exception e) { - e.printStackTrace(); - logger.error("Cannot update Service: " + oslResourceId + ": " + e.toString()); - } - return null; - } - - - /** - * @param serviceId - * @param s - * @param triggerServiceActionQueue is a cryptic thing. However it is used as follows: if FALSE, to just update the service status in catalog without further taking any action. - * if TRUE then the ServiceUpdate will trigger a ServiceActionQueue to further process the update. So this is needed to avoid these kinds of deadlocks - * @return - */ - public org.etsi.osl.tmf.sim638.model.Service updateService(String serviceId, ServiceUpdate s, boolean triggerServiceActionQueue) { - logger.info("will update Service : " + serviceId ); - try { - Map map = new HashMap<>(); - map.put("serviceid", serviceId ); - map.put("triggerServiceActionQueue", triggerServiceActionQueue ); - - Object response = template.requestBodyAndHeaders( CATALOG_UPD_SERVICE, toJsonString(s), map); - - if ( !(response instanceof String)) { - logger.error("Service Instance object is wrong."); - } - - org.etsi.osl.tmf.sim638.model.Service serviceInstance = toJsonObj( (String)response, org.etsi.osl.tmf.sim638.model.Service.class); - //logger.debug("createService response is: " + response); - return serviceInstance; - - - }catch (Exception e) { - logger.error("Cannot update Service: " + serviceId + ": " + e.toString()); - } - return null; - - } - - - - public LogicalResourceSpecification createOrUpdateResourceSpecByNameCategoryVersion( ResourceSpecificationCreate s) { - logger.info("will createOrUpdateResourceSpecByNameCategoryVersion " ); - try { - Map map = new HashMap<>(); - map.put("aname", s.getName()); - map.put("aversion", s.getVersion()); - map.put("acategory", s.getCategory()); - - Object response = template.requestBodyAndHeaders( CATALOG_UPDADD_RESOURCESPEC, toJsonString(s), map); - - if ( !(response instanceof String)) { - logger.error("ResourceSpecification object is wrong."); - } - - LogicalResourceSpecification rs = toJsonObj( (String)response, LogicalResourceSpecification.class); - return rs; - - - }catch (Exception e) { - logger.error("Cannot create ResourceSpecification"); - e.printStackTrace(); - } - return null; - - } - - static T toJsonObj(String content, Class valueType) throws IOException { - ObjectMapper mapper = new ObjectMapper(); - mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL); - return mapper.readValue( content, valueType); - } - - static String toJsonString(Object object) throws IOException { - ObjectMapper mapper = new ObjectMapper(); - mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL); - return mapper.writeValueAsString(object); - } - - } diff --git a/src/main/java/org/etsi/osl/metrico/repo/JobRepository.java b/src/main/java/org/etsi/osl/metrico/repo/JobRepository.java deleted file mode 100644 index 17988b8..0000000 --- a/src/main/java/org/etsi/osl/metrico/repo/JobRepository.java +++ /dev/null @@ -1,20 +0,0 @@ -package org.etsi.osl.metrico.repo; - -import org.etsi.osl.metrico.model.Job; -import org.springframework.data.jpa.repository.JpaRepository; -import org.springframework.data.jpa.repository.Query; -import org.springframework.data.repository.query.Param; -import org.springframework.stereotype.Repository; - -import java.util.List; -import java.util.Optional; -import java.util.UUID; - -@Repository -public interface JobRepository extends JpaRepository { - @Query("SELECT j FROM Job j WHERE j.deleted = false") - List findAllActiveJobs(); - - @Query("SELECT j FROM Job j WHERE j.uuid = :id AND j.deleted = false") - Optional findActiveById(@Param("id") UUID id); -} \ No newline at end of file diff --git a/src/main/java/org/etsi/osl/metrico/reposervices/JobRepoService.java b/src/main/java/org/etsi/osl/metrico/reposervices/JobRepoService.java deleted file mode 100644 index 59522ea..0000000 --- a/src/main/java/org/etsi/osl/metrico/reposervices/JobRepoService.java +++ /dev/null @@ -1,87 +0,0 @@ -package org.etsi.osl.metrico.reposervices; - -import org.etsi.osl.metrico.model.Job; -import org.etsi.osl.metrico.repo.JobRepository; -import org.etsi.osl.tmf.pm628.model.ExecutionStateType; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Service; - -import java.time.OffsetDateTime; -import java.util.List; -import java.util.UUID; - -@Service -public class JobRepoService { - - private static final Logger logger = LoggerFactory.getLogger(JobRepoService.class); - - private void logJobNotFoundError(UUID jobId) { - logger.error("Job with ID {} not found.", jobId); - } - private JobRepository jobRepository; - - @Autowired - public JobRepoService(JobRepository jobRepository) { - this.jobRepository = jobRepository; - if (jobRepository == null) { - logger.error("JobRepository is null. Dependency injection failed."); - } - } - - - - public Job createAndSaveJob( Job job ) { - // Set properties on the job object as needed - return jobRepository.save(job); // This will persist the job to the database - } - - public Job updateJob(UUID jobId, ExecutionStateType newState, OffsetDateTime newStartDateTime, OffsetDateTime newEndDateTime, Integer newExecutionInterval) { - // Retrieve the existing Job - Job job = jobRepository.findById(jobId).orElse(null); - if (job == null) { - logJobNotFoundError(jobId); - return null; - } - // Update the fields as needed - if (newState != null) job.setState(newState); - if (newStartDateTime != null) job.setStartDateTime(newStartDateTime); - if (newEndDateTime != null) job.setEndDateTime(newEndDateTime); - if (newExecutionInterval != null) job.setExecutionInterval(newExecutionInterval); - - // Save the updated Job back to the database - return jobRepository.save(job); - } - - public Job updateJob(UUID jobId, ExecutionStateType newState) { - // Retrieve the existing Job - Job job = jobRepository.findById(jobId).orElse(null); - if (job == null) { - logJobNotFoundError(jobId); - return null; - } - // Update the fields as needed - if (newState != null) job.setState(newState); - // Save the updated Job back to the database - return jobRepository.save(job); - } - - public boolean softDeleteJob(Job ajob) { - Job job = jobRepository.findById(ajob.getUuid()).orElse(null); - if (job == null) { - logJobNotFoundError( ajob.getUuid() ); - return false; - } - logger.error("Job with ID {} will be DELETED.", ajob.getUuid() ); - job.setDeleted(true); - jobRepository.delete(job); - return true; - } - - public List findAll() { - - return (List) this.jobRepository.findAll(); - } - -} diff --git a/src/main/java/org/etsi/osl/metrico/services/JobService.java b/src/main/java/org/etsi/osl/metrico/services/JobService.java index f7087de..114a465 100644 --- a/src/main/java/org/etsi/osl/metrico/services/JobService.java +++ b/src/main/java/org/etsi/osl/metrico/services/JobService.java @@ -1,26 +1,18 @@ package org.etsi.osl.metrico.services; import lombok.Getter; +import org.etsi.osl.metrico.MetricoCommonMethods; import org.etsi.osl.metrico.model.Job; -import org.etsi.osl.metrico.reposervices.JobRepoService; import org.etsi.osl.tmf.pm628.model.ExecutionStateType; import org.etsi.osl.tmf.pm628.model.MeasurementCollectionJob; import org.etsi.osl.tmf.pm628.model.MeasurementCollectionJobMVO; -import org.etsi.osl.tmf.pm628.model.MeasurementCollectionJobRef; -import org.etsi.osl.tmf.pm628.reposervices.MeasurementCollectionJobService; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; -import org.springframework.boot.context.event.ApplicationStartedEvent; -import org.springframework.context.event.EventListener; import org.springframework.stereotype.Service; import java.time.Duration; import java.time.OffsetDateTime; -import java.util.List; -import java.util.Map; -import java.util.UUID; import java.util.concurrent.*; @Service @@ -33,123 +25,130 @@ public class JobService { @Getter private static final ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(threadPoolSize); - // private final JobRepoService jobRepoService; + private final ConcurrentMap runningJobs = new ConcurrentHashMap<>(); - private final MeasurementCollectionJobService measurementCollectionJobService; - public JobService(JobRepoService jobRepoService, MeasurementCollectionJobService measurementCollectionJobService) { - // this.jobRepoService = jobRepoService; - this.measurementCollectionJobService = measurementCollectionJobService; + private final MetricoCommonMethods metricoCommonMethods; + public JobService(MetricoCommonMethods metricoCommonMethods) { + this.metricoCommonMethods = metricoCommonMethods; } - - - - /** - * Schedules a new job to be executed periodically based on the provided parameters. - *

- * This method initializes a new {@link Job} instance with the specified start and end date times, and execution interval. - * It calculates the initial delay as the difference in seconds between the current time and the start date time. - * The job is initially set to a PENDING state. It then attempts to schedule the job to run at a fixed rate, - * starting after the initial delay and subsequently with the specified execution interval. - * If the job is successfully scheduled, its state is updated to INPROGRESS, and it is logged. - * In case of a scheduling failure due to a {@link RejectedExecutionException}, the job's state is set to FAILED, - * and the error is logged. - *

+ * Starts a job for the given MeasurementCollectionJob. * - * @param task the {@link Runnable} task that the job will execute - * @param startDateTime the {@link OffsetDateTime} specifying when the job should start - * @param endDateTime the {@link OffsetDateTime} specifying when the job should end - * @param executionInterval the interval, in seconds, between successive executions of the job - * @return the newly created and scheduled {@link Job} instance - * @throws RejectedExecutionException if the task cannot be scheduled for execution + * @param task the task to be executed + * @param job the job to be started + * @return the updated job + * @throws NullPointerException if the job or task is null + * @throws IllegalArgumentException if the job's start or end date is invalid + * @throws RejectedExecutionException if the job could not be scheduled */ public Job startJob(Runnable task, Job job) { + logger.debug("Starting Job for MeasurementCollectionJob with ID {}.", job.getMeasurementCollectionJobRef()); + MeasurementCollectionJob mcj = metricoCommonMethods.retrieveMeasurementCollectionJob(job.getMeasurementCollectionJobRef().toString()); + MeasurementCollectionJobMVO mcjMVO = new MeasurementCollectionJobMVO(); - MeasurementCollectionJob mcj = measurementCollectionJobService.findMeasurementCollectionJobByUuid(job.getMeasurementCollectionJobRef().toString()); - MeasurementCollectionJobMVO mcjMVO = new MeasurementCollectionJobMVO(); - - if ( job.getEndDateTime().isBefore( OffsetDateTime.now() )) { - job.setState(ExecutionStateType.FAILED); - mcjMVO.setExecutionState(ExecutionStateType.FAILED); - logger.error("Job for MeasurementCollectionJob with ID {} End Date is before now, the job will not be scheduled.", mcj.getUuid()); - } - else { - long initialDelay = Duration.between(OffsetDateTime.now(), job.getStartDateTime()).getSeconds(); - if (initialDelay < 0) { - initialDelay = 0; - } - // job = jobRepoService.createAndSaveJob(job); - - try { - ScheduledFuture future = scheduler.scheduleAtFixedRate(task, initialDelay, job.getExecutionInterval(), TimeUnit.SECONDS); - job.setFuture(future); - job.setState(ExecutionStateType.INPROGRESS); - mcjMVO.setExecutionState(ExecutionStateType.INPROGRESS); - logger.info("Job for MeasurementCollectionJob with ID {} started successfully.", mcj.getUuid()); - } catch (RejectedExecutionException e) { - job.setState(ExecutionStateType.FAILED); - mcjMVO.setExecutionState(ExecutionStateType.FAILED); - logger.error("Job for MeasurementCollectionJob with ID {} could not be scheduled.", mcj.getUuid(), e); - } - - - // job = jobRepoService.updateJob(job.getUuid(), job.getState()); - - } - mcj = measurementCollectionJobService.updateMeasurementCollectionJob(mcj.getUuid(), mcjMVO); + if (job.getEndDateTime().isBefore(OffsetDateTime.now())) { + job.setState(ExecutionStateType.FAILED); + mcjMVO.setExecutionState(ExecutionStateType.FAILED); + logger.error("Job for MeasurementCollectionJob with ID {} End Date is before now, the MeasurementCollectionJob will not be scheduled.", mcj.getUuid()); + } else { + long initialDelay = Duration.between(OffsetDateTime.now(), job.getStartDateTime()).getSeconds(); + if (initialDelay < 0) { + initialDelay = 0; + } + try { + ScheduledFuture future = scheduler.scheduleAtFixedRate( + task, + initialDelay, + job.getExecutionInterval(), + TimeUnit.SECONDS + ); + + job.setFuture(future); + job.setState(ExecutionStateType.INPROGRESS); + mcjMVO.setExecutionState(ExecutionStateType.INPROGRESS); + // runningJobs.add(job); + runningJobs.put(job.getMeasurementCollectionJobRef().toString(), job); + logger.info("Job for MeasurementCollectionJob with ID {} started successfully.", mcj.getUuid()); + } catch (RejectedExecutionException e) { + job.setState(ExecutionStateType.FAILED); + mcjMVO.setExecutionState(ExecutionStateType.FAILED); + logger.error("Job for MeasurementCollectionJob with ID {} could not be scheduled.", mcj.getUuid(), e); + } + } + metricoCommonMethods.updateMeasurementCollectionJobById(mcj.getUuid(), mcjMVO); return job; } /** - * Attempts to stop a job identified by its UUID. - *

- * This method checks if the job exists and its current state. If the job is already in a - * {@link ExecutionStateType#CANCELLED} or {@link ExecutionStateType#COMPLETED} state, it logs - * the status and returns. Otherwise, it attempts to cancel the job's future execution. - * If the cancellation is successful, the job's state is set to {@link ExecutionStateType#CANCELLED}, - * and it logs the successful stop. If the job cannot be stopped (e.g., already completed or cancelled), - * its state is set to {@link ExecutionStateType#PENDING}, and a warning is logged. If the job does not - * exist, it logs a warning. - *

+ * Stops the given job. * - * @param jobId the UUID of the job to stop + *

This method retrieves the associated MeasurementCollectionJob from the database and updates its state. + * If the job is already cancelled or completed, it removes the job from the runningJobs map and logs the status. + * If the job is still running, it attempts to cancel the job's future task and updates the job's state accordingly. + * The job is then removed from the runningJobs map and the MeasurementCollectionJob is updated in the database.

+ * + * @param job the job to be stopped */ public void stopJob(Job job) { - MeasurementCollectionJob mcj = measurementCollectionJobService.findMeasurementCollectionJobByUuid(job.getMeasurementCollectionJobRef().toString()); + MeasurementCollectionJob mcj = metricoCommonMethods.retrieveMeasurementCollectionJob(job.getMeasurementCollectionJobRef().toString()); MeasurementCollectionJobMVO mcjMVO = new MeasurementCollectionJobMVO(); - if (job != null) { - - if (job.getState() == ExecutionStateType.CANCELLED ) { - logger.info("Job for MeasurementCollectionJob with ID {} is already CANCELED.", mcj.getUuid()); - // jobRepoService.softDeleteJob( job ); - return; - } else if (job.getState() == ExecutionStateType.COMPLETED) { - logger.info("Job for MeasurementCollectionJob with ID {} is already COMPLETED.", mcj.getUuid()); - // jobRepoService.softDeleteJob( job ); - return; - } - if (job.getFuture() != null) { - boolean wasCancelled = job.getFuture().cancel(true); - if (wasCancelled) { - job.setState(ExecutionStateType.CANCELLED); - mcjMVO.setExecutionState(ExecutionStateType.CANCELLED); - // jobRepoService.updateJob(job.getUuid(), job.getState()); - logger.info("Job for MeasurementCollectionJob with ID {} stopped successfully.", mcj.getUuid()); - } else { - job.setState(ExecutionStateType.PENDING); - mcjMVO.setExecutionState(ExecutionStateType.PENDING); - // jobRepoService.updateJob( job.getUuid(), job.getState()); - logger.warn("Job for MeasurementCollectionJob with ID {} could not be stopped because it has already completed, has been cancelled, or could not be cancelled for some other reason.", mcj.getUuid()); - } - mcj = measurementCollectionJobService.updateMeasurementCollectionJob(mcj.getUuid(), mcjMVO); + if (job.getState() == ExecutionStateType.CANCELLED) { + logger.info("Job for MeasurementCollectionJob with ID {} is already CANCELED.", mcj.getUuid()); + runningJobs.remove(job.getMeasurementCollectionJobRef().toString()); + return; + } else if (job.getState() == ExecutionStateType.COMPLETED) { + logger.info("Job for MeasurementCollectionJob with ID {} is already COMPLETED.", mcj.getUuid()); + runningJobs.remove(job.getMeasurementCollectionJobRef().toString()); + return; + } + if (job.getFuture() != null) { + boolean wasCancelled = job.getFuture().cancel(true); + if (wasCancelled) { + job.setState(ExecutionStateType.CANCELLED); + mcjMVO.setExecutionState(ExecutionStateType.CANCELLED); + runningJobs.remove(job.getMeasurementCollectionJobRef().toString()); + logger.info("Job for MeasurementCollectionJob with ID {} stopped successfully.", mcj.getUuid()); + } else { + job.setState(ExecutionStateType.PENDING); + mcjMVO.setExecutionState(ExecutionStateType.PENDING); + logger.warn("Job for MeasurementCollectionJob with ID {} could not be stopped because it has already completed, has been cancelled, or could not be cancelled for some other reason.", mcj.getUuid()); } + metricoCommonMethods.updateMeasurementCollectionJobById(mcj.getUuid(), mcjMVO); + } + } + + /** + * Stops the job associated with the given Measurement Collection Job UUID. + * + *

This method retrieves the job from the runningJobs map using the provided UUID. + * If the job is found, it calls the existing stopJob method to stop the job. + * If the job is not found, it logs a warning message.

+ * + * @param measurementCollectionJobUuid the UUID of the Measurement Collection Job + */ + public void stopJob(String measurementCollectionJobUuid) { + Job job = runningJobs.get(measurementCollectionJobUuid); + if (job != null) { + stopJob(job); } else { - logger.warn("Job does not exist."); + logger.warn("No job found with associated with MeasurementCollectionJob with UUID: {}", measurementCollectionJobUuid); + } + } + + /** + * Stops all running jobs. + * + *

This method iterates over all jobs in the runningJobs map, stops each job, and then clears the map.

+ */ + public void stopAllJobs() { + for (Job job : runningJobs.values()) { + stopJob(job); } + runningJobs.clear(); } } \ No newline at end of file diff --git a/src/main/java/org/etsi/osl/metrico/services/MetricoService.java b/src/main/java/org/etsi/osl/metrico/services/MetricoService.java index 2bbfcd5..eac4e46 100644 --- a/src/main/java/org/etsi/osl/metrico/services/MetricoService.java +++ b/src/main/java/org/etsi/osl/metrico/services/MetricoService.java @@ -1,25 +1,22 @@ package org.etsi.osl.metrico.services; +import jakarta.annotation.PreDestroy; import jakarta.validation.constraints.NotNull; import org.apache.camel.ProducerTemplate; import org.apache.camel.builder.RouteBuilder; +import org.etsi.osl.metrico.MetricoCommonMethods; import org.etsi.osl.metrico.JsonUtil; import org.etsi.osl.metrico.mapper.DataAccessEndpointMapper; import org.etsi.osl.metrico.mapper.JobMapper; import org.etsi.osl.metrico.model.Job; import org.etsi.osl.metrico.prometheus.PrometheusQueries; -import org.etsi.osl.tmf.common.model.Any; import org.etsi.osl.tmf.common.model.ELifecycle; import org.etsi.osl.tmf.common.model.EValueType; -import org.etsi.osl.tmf.common.model.service.ResourceRef; import org.etsi.osl.tmf.pm628.model.*; -import org.etsi.osl.tmf.pm628.reposervices.MeasurementCollectionJobService; import org.etsi.osl.tmf.rcm634.model.LogicalResourceSpecification; import org.etsi.osl.tmf.rcm634.model.ResourceSpecificationCreate; -import org.etsi.osl.tmf.ri639.model.ResourceUpdate; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.boot.context.event.ApplicationStartedEvent; import org.springframework.context.event.EventListener; @@ -31,75 +28,58 @@ import java.util.List; @Service public class MetricoService extends RouteBuilder { - private static final Logger logger = LoggerFactory.getLogger(JobService.class); - + private static final Logger logger = LoggerFactory.getLogger(MetricoService.class); public static final String OSL_METRICO_RSPEC_NAME = "METRICO_Resource_Specification"; public static final String OSL_METRICO_RSPEC_VERSION = "0.0.1"; public static final String OSL_METRICO_RSPEC_CATEGORY = "metrico.osl.etsi.org/v1"; - public static final String OSL_METRICO_RESOURCE_CATEGORY = "metrico.osl.etsi.org/v1"; public static final String OSL_METRICO_RSPEC_TYPE = "LogicalResourceSpecification"; public static final String OSL_METRICO_RSPEC_DESCRIPTION = "This Specification is used to describe a generic METRICO job resource"; @Value("${PM_MEASUREMENT_COLLECTION_JOB_UPDATE}") private String PM_MEASUREMENT_COLLECTION_JOB_UPDATE = ""; - @Value("${PM_MEASUREMENT_COLLECTION_GET_JOB_BY_ID}") private String PM_MEASUREMENT_COLLECTION_GET_JOB_BY_ID = ""; -// @Autowired -// private JobRepoService jobRepoService; - - - // @Autowired -// private JobRepository jobRepository; - @Autowired - private MeasurementCollectionJobService measurementCollectionJobService; - - - @Autowired + private final ProducerTemplate template; + private final MetricoCommonMethods metricoCommonMethods; private final PrometheusQueries prometheusQueries; private final ProducerTemplate producerTemplate; - - public MetricoService(PrometheusQueries prometheusQueries, ProducerTemplate producerTemplate) { - this.prometheusQueries = prometheusQueries; + private final JobService jobService; + public MetricoService(ProducerTemplate producerTemplate, PrometheusQueries prometheusQueries, MetricoCommonMethods metricoCommonMethods, ProducerTemplate template, JobService jobService) { this.producerTemplate = producerTemplate; + this.prometheusQueries = prometheusQueries; + this.metricoCommonMethods = metricoCommonMethods; + this.template = template; + this.jobService= jobService; } + @Override + public void configure() throws Exception { + // TODO Auto-generated method stub + } - /** - * This one is executed when the cridge service application starts - * - * @param event - */ @EventListener(ApplicationStartedEvent.class) public void onApplicationEvent() { - + // When METRICO starts, it checks if a related resource spec exists, and if it not, it creates it. registerMetricoResourceSpec(); - - List jobsPending = jobRepoService.findAll(); - logger.info("===== Pending jobs from previous sessions ====="); - for (Job job : jobsPending) { - logger.info("try to resume jobuuid: {}, state:{}, start: {}, end:{}, mcjid: {} ", job.getUuid(), job.getState(), job.getStartDateTime(), job.getEndDateTime(), job.getMeasurementCollectionJobRef()); - - - //delete previous job from DB. a new one will be created - jobRepoService.softDeleteJob(job); - - MeasurementCollectionJobRef mjref = new MeasurementCollectionJobRef(); - mjref.setId(job.getMeasurementCollectionJobRef().toString()); - this.startPeriodicQueryToPrometheusRef(mjref); - } + // When METRICO starts, it checks if there are any pending or unfinished jobs from previous sessions + // and tries to resume them. + restartPendingOrInProgressJobs(); logger.info("===== Pending jobs from previous sessions done ====="); + } + @PreDestroy + public void onShutdown() { + jobService.stopAllJobs(); + logger.info("All running jobs have been stopped."); } private void registerMetricoResourceSpec() { logger.info("===== Pending jobs from previous sessions ====="); - ResourceSpecificationCreate rsc = new ResourceSpecificationCreate(); rsc.setName(OSL_METRICO_RSPEC_NAME); rsc.setCategory(OSL_METRICO_RSPEC_CATEGORY); @@ -117,8 +97,7 @@ public class MetricoService extends RouteBuilder { rsc.addResourceSpecificationCharacteristicItemShort("_MT_QUERY", "", EValueType.TEXT.getValue(), "The query towards the monitoring source (e.g. query=gnb_service_state)", false); rsc.addResourceSpecificationCharacteristicItemShort("_MT_URL", "", EValueType.TEXT.getValue(), "The monitoring source URL (e.g. https://prom.osl.etsi.org:9090)", false); - - LogicalResourceSpecification result = prometheusQueries.createOrUpdateResourceSpecByNameCategoryVersion(rsc); + LogicalResourceSpecification result = metricoCommonMethods.createOrUpdateResourceSpecByNameCategoryVersion(rsc); while (result == null) { try { logger.info("Cannot get resource for registerMetricoResourceSpec. Retrying in 10 seconds"); @@ -126,13 +105,23 @@ public class MetricoService extends RouteBuilder { } catch (InterruptedException e) { e.printStackTrace(); } - result = prometheusQueries.createOrUpdateResourceSpecByNameCategoryVersion(rsc); + result = metricoCommonMethods.createOrUpdateResourceSpecByNameCategoryVersion(rsc); } } - - @Autowired - private ProducerTemplate template; + public void restartPendingOrInProgressJobs() { + List jobsPending = metricoCommonMethods.listUnfinishedMeasurementCollectionJob(); + logger.info("===== Pending jobs from previous sessions ====="); + jobService.stopAllJobs(); + for (MeasurementCollectionJob measurementCollectionJob : jobsPending) { + logger.info("try to resume MeasurementCollectionJob with uuid: {}, ExecutionState:{}, ScheduleDefinitionStartTime: {}, ScheduleDefinitionEndTime:{}", + measurementCollectionJob.getUuid(), + measurementCollectionJob.getExecutionState(), + measurementCollectionJob.getScheduleDefinition().get(0).getScheduleDefinitionStartTime(), + measurementCollectionJob.getScheduleDefinition().get(0).getScheduleDefinitionEndTime()); + this.startPeriodicQueryToPrometheus(measurementCollectionJob); + } + } public String[] queryToPrometheus(@NotNull MeasurementCollectionJob givenMCJ) { DataAccessEndpoint givenDataAccessEndpoint = givenMCJ.getDataAccessEndpoint().get(0); @@ -169,25 +158,31 @@ public class MetricoService extends RouteBuilder { Job job = JobMapper.measurementCollectionJobMapToJob(givenMCJ); String promURL = job.getDataAccessEndPointUri().getScheme() + "://" + job.getDataAccessEndPointUri().getAuthority(); String promQuery = job.getDataAccessEndPointUri().getQuery(); - + MeasurementCollectionJobMVO measurementCollectionJobMVO = new MeasurementCollectionJobMVO(); job = prometheusQueries.startPeriodicQuery(promURL, promQuery, job, givenMCJ); if (job.getState() == ExecutionStateType.FAILED) { logger.atError().setMessage("Periodic query failed to start due to internal error.").log(); - } else { - logger.atInfo().setMessage("Periodic query started, with ID: " + job.getUuid()).log(); + logger.atInfo().setMessage("Periodic query started, with ID: " + job.getMeasurementCollectionJobRef()).log(); } - - givenMCJ.setExecutionState(job.getState()); - - producerTemplate.sendBodyAndHeader(PM_MEASUREMENT_COLLECTION_JOB_UPDATE, JsonUtil.toJsonString(givenMCJ), "mcjid", givenMCJ.getUuid()); - updateRelatedResource(givenMCJ); + measurementCollectionJobMVO.setExecutionState(job.getState()); + + // You sent at the mq the mcj. Is it correct I changed it to measurementCollectionJobMVO? + producerTemplate.sendBodyAndHeader( + PM_MEASUREMENT_COLLECTION_JOB_UPDATE, + JsonUtil.toJsonString(measurementCollectionJobMVO), + "mcjid", givenMCJ.getUuid() + ); + // Is it the updated mcj? + givenMCJ = metricoCommonMethods.retrieveMeasurementCollectionJob(givenMCJ.getUuid()); + + metricoCommonMethods.updateRelatedResource(givenMCJ); } public void startPeriodicQueryToPrometheusRef(@NotNull MeasurementCollectionJobRef mcjRef) { - MeasurementCollectionJob givenMCJ = retrieveMeasurementCollectionJob(mcjRef); + MeasurementCollectionJob givenMCJ = metricoCommonMethods.retrieveMeasurementCollectionJob(mcjRef); startPeriodicQueryToPrometheus(givenMCJ); } @@ -195,80 +190,12 @@ public class MetricoService extends RouteBuilder { public void startPeriodicQueryToPrometheusEvent(@NotNull MeasurementCollectionJobCreateEvent mcjevent) { - MeasurementCollectionJob givenMCJ = retrieveMeasurementCollectionJob(mcjevent.getEvent().getMeasurementCollectionJob().getId()); + MeasurementCollectionJob givenMCJ = metricoCommonMethods.retrieveMeasurementCollectionJob(mcjevent.getEvent().getMeasurementCollectionJob().getId()); if (givenMCJ != null) { startPeriodicQueryToPrometheus(givenMCJ); } else { - logger.error("=======> CANNOT retrieve Measurement Collection Job with mcjId = " + mcjevent.getEvent().getMeasurementCollectionJob().getId() + " from activeMQ"); } } - - public MeasurementCollectionJob retrieveMeasurementCollectionJob(String mcjId) { - - logger.debug("will retrieve Measurement Collection Job with mcjId = " + mcjId + " from database"); - try { - Object response = template. - requestBody(PM_MEASUREMENT_COLLECTION_GET_JOB_BY_ID, mcjId); - if (!(response instanceof String)) { - logger.error("Measurement Collection Job object is wrong."); - return null; - } - logger.debug("retrieveMeasurementCollectionJobById response is: " + response); - MeasurementCollectionJob mcj = JsonUtil.toJsonObj((String) response, MeasurementCollectionJob.class); - return mcj; - } catch (Exception e) { - logger.error("Cannot retrieve Measurement Collection Job details from database. " + e.toString()); - } - return null; - } - - public MeasurementCollectionJob retrieveMeasurementCollectionJob(MeasurementCollectionJobRef mcjRef) { - String mcjId = mcjRef.getId(); - - return retrieveMeasurementCollectionJob(mcjId); - } - - private void updateRelatedResource(@NotNull MeasurementCollectionJob givenMCJ) { - //retrieve related service from inventory - //retrieve related resource from inventory - //patch resource state - String servUUID = givenMCJ.getProducingApplicationId();//this contains the related ServiceUUID with this MCJ - - logger.debug("updateRelatedResource servUUID = " + servUUID); - org.etsi.osl.tmf.sim638.model.Service aService = prometheusQueries.retrieveService(servUUID); - - if (aService != null && aService.getSupportingResource().size() > 0) { - - ResourceRef resRef = aService.getSupportingResource().stream().findFirst().get(); - - //Resource aResource = retrieveResource(resRef.getId()); - logger.debug("updateRelatedResource resRef = " + resRef.getId()); - - ResourceUpdate rup = new ResourceUpdate(); - org.etsi.osl.tmf.ri639.model.Characteristic resCharacteristicItem = new org.etsi.osl.tmf.ri639.model.Characteristic(); - resCharacteristicItem.setName("_MT_MCJ_REF"); - resCharacteristicItem.setValueType("TEXT"); - Any val = new Any(); - val.setValue(givenMCJ.getUuid()); - val.setAlias(""); - resCharacteristicItem.setValue(val); - rup.addResourceCharacteristicItem(resCharacteristicItem); - - if (givenMCJ.getExecutionState().equals(ExecutionStateType.FAILED)) { - rup.setResourceStatus(org.etsi.osl.tmf.ri639.model.ResourceStatusType.SUSPENDED); - } else { - rup.setResourceStatus(org.etsi.osl.tmf.ri639.model.ResourceStatusType.AVAILABLE); - } - - prometheusQueries.updateResourceById(resRef.getId(), rup); - } - } - - @Override - public void configure() throws Exception { - // TODO Auto-generated method stub - - } } -- GitLab From 9d09302312d439cb0723c7505f2583b355b1b493 Mon Sep 17 00:00:00 2001 From: George Tziavas Date: Wed, 19 Mar 2025 13:05:46 +0200 Subject: [PATCH 03/17] removed sql params from application.yml --- .../etsi/osl/metrico/LocalMysqlDialect.java | 29 ------- src/main/resources/application-testing.yml | 82 ++++++++++++++++++ src/main/resources/application.yml | 22 ----- .../etsi/osl/metrico/DummyRouteBuilder.java | 12 +++ .../org/etsi/osl/metrico/JsonUtilTest.java | 16 ++++ .../osl/metrico/MetricoCommonMethodsTest.java | 56 ++++++++++++ src/test/resources/application-testing.yml | 85 +++++++++++++++++++ src/test/resources/application.yml | 17 ---- 8 files changed, 251 insertions(+), 68 deletions(-) delete mode 100644 src/main/java/org/etsi/osl/metrico/LocalMysqlDialect.java create mode 100644 src/main/resources/application-testing.yml create mode 100644 src/test/java/org/etsi/osl/metrico/DummyRouteBuilder.java create mode 100644 src/test/java/org/etsi/osl/metrico/JsonUtilTest.java create mode 100644 src/test/java/org/etsi/osl/metrico/MetricoCommonMethodsTest.java create mode 100644 src/test/resources/application-testing.yml delete mode 100644 src/test/resources/application.yml diff --git a/src/main/java/org/etsi/osl/metrico/LocalMysqlDialect.java b/src/main/java/org/etsi/osl/metrico/LocalMysqlDialect.java deleted file mode 100644 index 1d8566c..0000000 --- a/src/main/java/org/etsi/osl/metrico/LocalMysqlDialect.java +++ /dev/null @@ -1,29 +0,0 @@ -/*- - * ========================LICENSE_START================================= - * org.etsi.osl.tmf.api - * %% - * Copyright (C) 2019 openslice.io - * %% - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * =========================LICENSE_END================================== - */ -package org.etsi.osl.metrico; - -import org.hibernate.dialect.MySQLDialect; ; - -public class LocalMysqlDialect extends MySQLDialect { - @Override - public String getTableTypeString() { - return " DEFAULT CHARSET=utf8"; - } -} diff --git a/src/main/resources/application-testing.yml b/src/main/resources/application-testing.yml new file mode 100644 index 0000000..6c17ee0 --- /dev/null +++ b/src/main/resources/application-testing.yml @@ -0,0 +1,82 @@ +spring: + config: + activate: + on-profile: "testing" + application: + name: metrico + main: + web-application-type: servlet + datasource: + url: jdbc:mysql://localhost:13306/metricodb?createDatabaseIfNotExist=true&useUnicode=true&characterEncoding=utf8&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=UTC + password: letmein + username: root + hikari: + minimumIdle: 2 + maximumPoolSize: 40 + idleTimeout: 120000 + connectionTimeout: 400000 + leakDetectionThreshold: 100000 + jpa: + database-platform: org.etsi.osl.metrico.LocalMysqlDialect + hibernate: + ddl-auto: update + show-sql: false + generate-ddl: true + properties: + hibernate: + connection: + characterEncoding: utf-8 + CharSet: utf-8 + useUnicode: true + activemq: + brokerUrl: tcp://localhost:61616?jms.watchTopicAdvisories=false + user: artemis + password: artemis + pool: + enabled: true + max-connections: 100 + packages: + trust-all: true + security: + oauth2: + resourceserver: + jwt: + issuer-uri: http://keycloak:8080/auth/realms/openslice + jwk-set-uri: http://keycloak:8080/auth/realms/openslice/.well-known/openid-configuration +server: + port: 8030 + + +logging: + level: + org.etsi.osl.metrico: DEBUG + root: INFO + org.springframework: INFO + org.apache.camel: INFO + reactor.netty.tcp.TcpClient: DEBUG + reactor.netty.http.client.HttpClient: DEBUG + pattern: + console: "%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n" + file: "%d %p %c{1.} [%t] %m%n" + +scheduling.enabled: true + +#NUMBER OF THREADS FOR THE METRICO THREAD POOL +METRICO_THREAD_POOL_SIZE: 10 + +#TMF QUEUES +PM_MEASUREMENT_COLLECTION_GET_JOB_BY_ID: "direct:PM.MEASUREMENTCOLLECTIONJOB.GET_BY_ID" +PM_MEASUREMENT_COLLECTION_JOBS_GET: "direct:PM.MEASUREMENTCOLLECTIONJOBS.GET" +PM_MEASUREMENT_COLLECTION_JOB_ADD: "direct:PM.MEASUREMENTCOLLECTIONJOB.ADD" +PM_MEASUREMENT_COLLECTION_JOB_UPDATE: "direct:PM.MEASUREMENTCOLLECTIONJOB.UPDATE" + +EVENT_MEASUREMENT_COLLECTION_JOB_CREATE: "direct:topic:EVENT.MEASUREMENTCOLLECTIONJOB.CREATE" +EVENT_MEASUREMENT_COLLECTION_JOB_EXECUTION_STATE_CHANGED: "direct:topic:EVENT.MEASUREMENTCOLLECTIONJOB.STATECHANGED" +EVENT_MEASUREMENT_COLLECTION_JOB_DELETE: "direct:topic:EVENT.MEASUREMENTCOLLECTIONJOB.DELETE" +EVENT_MEASUREMENT_COLLECTION_JOB_ATTRIBUTE_VALUE_CHANGED: "direct:topic:EVENT.MEASUREMENTCOLLECTIONJOB.ATTRCHANGED" + +CATALOG_UPDADD_RESOURCESPEC: "direct:CATALOG.UPDADD.RESOURCESPEC" +CATALOG_GET_SERVICE_BY_ID: "direct:CATALOG.GET.SERVICE" +CATALOG_GET_RESOURCE_BY_ID: "direct:CATALOG.GET.RESOURCE" +CATALOG_UPD_RESOURCE: "direct:CATALOG.UPD.RESOURCE" +CATALOG_UPD_SERVICE: "direct:CATALOG.UPD.SERVICE" diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index 0ea2b55..937f50f 100644 --- a/src/main/resources/application.yml +++ b/src/main/resources/application.yml @@ -6,28 +6,6 @@ spring: name: metrico main: web-application-type: servlet - datasource: - url: jdbc:mysql://localhost:13306/metricodb?createDatabaseIfNotExist=true&useUnicode=true&characterEncoding=utf8&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=UTC - password: letmein - username: root - hikari: - minimumIdle: 2 - maximumPoolSize: 40 - idleTimeout: 120000 - connectionTimeout: 400000 - leakDetectionThreshold: 100000 - jpa: - database-platform: org.etsi.osl.metrico.LocalMysqlDialect - hibernate: - ddl-auto: update - show-sql: false - generate-ddl: true - properties: - hibernate: - connection: - characterEncoding: utf-8 - CharSet: utf-8 - useUnicode: true activemq: brokerUrl: tcp://localhost:61616?jms.watchTopicAdvisories=false user: artemis diff --git a/src/test/java/org/etsi/osl/metrico/DummyRouteBuilder.java b/src/test/java/org/etsi/osl/metrico/DummyRouteBuilder.java new file mode 100644 index 0000000..1847630 --- /dev/null +++ b/src/test/java/org/etsi/osl/metrico/DummyRouteBuilder.java @@ -0,0 +1,12 @@ +package org.etsi.osl.metrico; + +import org.apache.camel.builder.RouteBuilder; + +public class DummyRouteBuilder extends RouteBuilder { + + @Override + public void configure() throws Exception { + from("jms:queue:PM.MEASUREMENTCOLLECTIONJOB.GET_BY_ID") + .process(exchange -> exchange.getIn().setBody("{\"uuid\":\"test-id\",\"outputFormat\":\"JSON\"}")); + } +} \ No newline at end of file diff --git a/src/test/java/org/etsi/osl/metrico/JsonUtilTest.java b/src/test/java/org/etsi/osl/metrico/JsonUtilTest.java new file mode 100644 index 0000000..71d9cae --- /dev/null +++ b/src/test/java/org/etsi/osl/metrico/JsonUtilTest.java @@ -0,0 +1,16 @@ +package org.etsi.osl.metrico; + +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.*; + +class JsonUtilTest { + + @Test + void toJsonObj() { + } + + @Test + void toJsonString() { + } +} \ No newline at end of file diff --git a/src/test/java/org/etsi/osl/metrico/MetricoCommonMethodsTest.java b/src/test/java/org/etsi/osl/metrico/MetricoCommonMethodsTest.java new file mode 100644 index 0000000..436edbe --- /dev/null +++ b/src/test/java/org/etsi/osl/metrico/MetricoCommonMethodsTest.java @@ -0,0 +1,56 @@ +package org.etsi.osl.metrico; + +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.*; + +class MetricoCommonMethodsTest { + + @Test + void configure() { + } + + @Test + void retrieveMeasurementCollectionJob() { + } + + @Test + void testRetrieveMeasurementCollectionJob() { + } + + @Test + void listMeasurementCollectionJob() { + } + + @Test + void listUnfinishedMeasurementCollectionJob() { + } + + @Test + void updateRelatedResource() { + } + + @Test + void createOrUpdateResourceSpecByNameCategoryVersion() { + } + + @Test + void updateService() { + } + + @Test + void updateResourceById() { + } + + @Test + void retrieveService() { + } + + @Test + void retrieveResource() { + } + + @Test + void updateMeasurementCollectionJobById() { + } +} \ No newline at end of file diff --git a/src/test/resources/application-testing.yml b/src/test/resources/application-testing.yml new file mode 100644 index 0000000..e653008 --- /dev/null +++ b/src/test/resources/application-testing.yml @@ -0,0 +1,85 @@ +spring: + profiles: + active: + "testing" + config: + activate: + on-profile: "testing" + application: + name: metrico + main: + web-application-type: servlet + datasource: + url: jdbc:mysql://localhost:13306/metricodb?createDatabaseIfNotExist=true&useUnicode=true&characterEncoding=utf8&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=UTC + password: letmein + username: root + hikari: + minimumIdle: 2 + maximumPoolSize: 40 + idleTimeout: 120000 + connectionTimeout: 400000 + leakDetectionThreshold: 100000 + jpa: + database-platform: org.etsi.osl.metrico.LocalMysqlDialect + hibernate: + ddl-auto: update + show-sql: false + generate-ddl: true + properties: + hibernate: + connection: + characterEncoding: utf-8 + CharSet: utf-8 + useUnicode: true + activemq: + brokerUrl: tcp://localhost:61616?jms.watchTopicAdvisories=false + user: artemis + password: artemis + pool: + enabled: true + max-connections: 100 + packages: + trust-all: true + security: + oauth2: + resourceserver: + jwt: + issuer-uri: http://keycloak:8080/auth/realms/openslice + jwk-set-uri: http://keycloak:8080/auth/realms/openslice/.well-known/openid-configuration +server: + port: 8030 + + +logging: + level: + org.etsi.osl.metrico: DEBUG + root: INFO + org.springframework: INFO + org.apache.camel: INFO + reactor.netty.tcp.TcpClient: DEBUG + reactor.netty.http.client.HttpClient: DEBUG + pattern: + console: "%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n" + file: "%d %p %c{1.} [%t] %m%n" + +scheduling.enabled: true + +#NUMBER OF THREADS FOR THE METRICO THREAD POOL +METRICO_THREAD_POOL_SIZE: 10 + +#TMF QUEUES +PM_MEASUREMENT_COLLECTION_GET_JOB_BY_ID: "direct:PM.MEASUREMENTCOLLECTIONJOB.GET_BY_ID" +PM_MEASUREMENT_COLLECTION_JOBS_GET: "direct:PM.MEASUREMENTCOLLECTIONJOBS.GET" +PM_MEASUREMENT_COLLECTION_JOB_ADD: "direct:PM.MEASUREMENTCOLLECTIONJOB.ADD" +PM_MEASUREMENT_COLLECTION_JOB_UPDATE: "direct:PM.MEASUREMENTCOLLECTIONJOB.UPDATE" + +EVENT_MEASUREMENT_COLLECTION_JOB_CREATE: "direct:topic:EVENT.MEASUREMENTCOLLECTIONJOB.CREATE" +EVENT_MEASUREMENT_COLLECTION_JOB_EXECUTION_STATE_CHANGED: "direct:topic:EVENT.MEASUREMENTCOLLECTIONJOB.STATECHANGED" +EVENT_MEASUREMENT_COLLECTION_JOB_DELETE: "direct:topic:EVENT.MEASUREMENTCOLLECTIONJOB.DELETE" +EVENT_MEASUREMENT_COLLECTION_JOB_ATTRIBUTE_VALUE_CHANGED: "direct:topic:EVENT.MEASUREMENTCOLLECTIONJOB.ATTRCHANGED" + +CATALOG_UPDADD_RESOURCESPEC: "direct:CATALOG.UPDADD.RESOURCESPEC" +CATALOG_GET_SERVICE_BY_ID: "direct:CATALOG.GET.SERVICE" +CATALOG_GET_RESOURCE_BY_ID: "direct:CATALOG.GET.RESOURCE" +CATALOG_UPD_RESOURCE: "direct:CATALOG.UPD.RESOURCE" +CATALOG_UPD_SERVICE: "direct:CATALOG.UPD.SERVICE" diff --git a/src/test/resources/application.yml b/src/test/resources/application.yml deleted file mode 100644 index e8714e1..0000000 --- a/src/test/resources/application.yml +++ /dev/null @@ -1,17 +0,0 @@ -spring: - datasource: - url: jdbc:h2:mem:testdb - driverClassName: org.h2.Driver - username: sa - password: password - jpa: - database-platform: org.hibernate.dialect.H2Dialect - - -#NUMBER OF THREADS FOR THE METRICO THREAD POOL -METRICO_THREAD_POOL_SIZE: 10 - -CATALOG_GET_SERVICE_BY_ID: "jms:queue:CATALOG.GET.SERVICE" -CATALOG_GET_RESOURCE_BY_ID: "jms:queue:CATALOG.GET.RESOURCE" -CATALOG_UPD_RESOURCE: "jms:queue:CATALOG.UPD.RESOURCE" -CATALOG_UPD_SERVICE: "jms:queue:CATALOG.UPD.SERVICE" \ No newline at end of file -- GitLab From feaeaef3e049135dd0c33002756b3aa0f3309b13 Mon Sep 17 00:00:00 2001 From: George Tziavas Date: Mon, 31 Mar 2025 15:45:00 +0300 Subject: [PATCH 04/17] Resolved all changes after review --- .../java/org/etsi/osl/metrico/JsonUtil.java | 3 + .../osl/metrico/MetricoCommonMethods.java | 2 - .../etsi/osl/metrico/MetricoSpringBoot.java | 8 +- .../java/org/etsi/osl/metrico/model/Job.java | 46 +--- .../etsi/osl/metrico/services/JobService.java | 24 +- .../osl/metrico/services/MetricoService.java | 49 +--- src/main/resources/application-testing.yml | 3 + .../etsi/osl/metrico/DummyRouteBuilder.java | 45 +++- .../org/etsi/osl/metrico/JsonUtilTest.java | 45 +++- .../osl/metrico/MetricoCommonMethodsTest.java | 70 +++--- .../osl/metrico/mapper/JobMapperTest.java | 71 ++++-- .../org/etsi/osl/metrico/model/JobTest.java | 1 - .../osl/metrico/services/JobServiceTest.java | 215 +++++++++--------- 13 files changed, 295 insertions(+), 287 deletions(-) diff --git a/src/main/java/org/etsi/osl/metrico/JsonUtil.java b/src/main/java/org/etsi/osl/metrico/JsonUtil.java index a801f49..fa679e1 100644 --- a/src/main/java/org/etsi/osl/metrico/JsonUtil.java +++ b/src/main/java/org/etsi/osl/metrico/JsonUtil.java @@ -16,6 +16,9 @@ public class JsonUtil { } public static String toJsonString(T object) { + if (object == null) { + return null; + } ObjectMapper mapper = new ObjectMapper(); mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL); try { diff --git a/src/main/java/org/etsi/osl/metrico/MetricoCommonMethods.java b/src/main/java/org/etsi/osl/metrico/MetricoCommonMethods.java index e3318c7..0857b2b 100644 --- a/src/main/java/org/etsi/osl/metrico/MetricoCommonMethods.java +++ b/src/main/java/org/etsi/osl/metrico/MetricoCommonMethods.java @@ -335,6 +335,4 @@ public class MetricoCommonMethods extends RouteBuilder { } return null; } - - } diff --git a/src/main/java/org/etsi/osl/metrico/MetricoSpringBoot.java b/src/main/java/org/etsi/osl/metrico/MetricoSpringBoot.java index 5aa4216..6c361e8 100644 --- a/src/main/java/org/etsi/osl/metrico/MetricoSpringBoot.java +++ b/src/main/java/org/etsi/osl/metrico/MetricoSpringBoot.java @@ -8,16 +8,14 @@ import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.autoconfigure.domain.EntityScan; import org.springframework.context.ApplicationContext; -import org.springframework.data.jpa.repository.config.EnableJpaRepositories; @SpringBootApplication -@EnableJpaRepositories("org.etsi.osl.metrico.repo") @EntityScan(basePackages = { - "org.etsi.osl.metrico.repo", - "org.etsi.osl.metrico.model", "org.etsi.osl.metrico", - "org.etsi.osl.metrico.reposervices", + "org.etsi.osl.metrico.mapper", + "org.etsi.osl.metrico.model", + "org.etsi.osl.metrico.prometheus", "org.etsi.osl.metrico.services" }) public class MetricoSpringBoot implements CommandLineRunner { diff --git a/src/main/java/org/etsi/osl/metrico/model/Job.java b/src/main/java/org/etsi/osl/metrico/model/Job.java index e09eff6..ffd5643 100644 --- a/src/main/java/org/etsi/osl/metrico/model/Job.java +++ b/src/main/java/org/etsi/osl/metrico/model/Job.java @@ -33,7 +33,7 @@ public class Job{ private UUID scheduleDefinitionRef; - private UUID measurementCollectionJobRef; + private UUID measurementCollectionJobRef; // 1:1 relationship between Job and MeasurementCollectionJob. It will be used as an id for the Job. private URI dataAccessEndPointUri; @@ -87,48 +87,4 @@ public class Job{ '}'; } - - public void setState(ExecutionStateType state) { - this.state = state; - } - - public void setStartDateTime(OffsetDateTime startDateTime) { - this.startDateTime = startDateTime; - } - - public void setEndDateTime(OffsetDateTime endDateTime) { - this.endDateTime = endDateTime; - } - - public void setExecutionInterval(Integer executionInterval) { - this.executionInterval = executionInterval; - } - - public void setDataAccessEndPointRef(UUID dataAccessEndPointRef) { - this.dataAccessEndPointRef = dataAccessEndPointRef; - } - - public void setScheduleDefinitionRef(UUID scheduleDefinitionRef) { - this.scheduleDefinitionRef = scheduleDefinitionRef; - } - - public void setMeasurementCollectionJobRef(UUID measurementCollectionJobRef) { - this.measurementCollectionJobRef = measurementCollectionJobRef; - } - - public void setDataAccessEndPointUri(URI dataAccessEndPointUri) { - this.dataAccessEndPointUri = dataAccessEndPointUri; - } - - public void setApiType(String apiType) { - this.apiType = apiType; - } - - public void setDeleted(boolean deleted) { - this.deleted = deleted; - } - - public void setFuture(ScheduledFuture future) { - this.future = future; - } } diff --git a/src/main/java/org/etsi/osl/metrico/services/JobService.java b/src/main/java/org/etsi/osl/metrico/services/JobService.java index 114a465..17b96fc 100644 --- a/src/main/java/org/etsi/osl/metrico/services/JobService.java +++ b/src/main/java/org/etsi/osl/metrico/services/JobService.java @@ -24,7 +24,7 @@ public class JobService { private static int threadPoolSize; @Getter private static final ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(threadPoolSize); - + @Getter private final ConcurrentMap runningJobs = new ConcurrentHashMap<>(); @@ -45,13 +45,12 @@ public class JobService { */ public Job startJob(Runnable task, Job job) { logger.debug("Starting Job for MeasurementCollectionJob with ID {}.", job.getMeasurementCollectionJobRef()); - MeasurementCollectionJob mcj = metricoCommonMethods.retrieveMeasurementCollectionJob(job.getMeasurementCollectionJobRef().toString()); MeasurementCollectionJobMVO mcjMVO = new MeasurementCollectionJobMVO(); if (job.getEndDateTime().isBefore(OffsetDateTime.now())) { job.setState(ExecutionStateType.FAILED); mcjMVO.setExecutionState(ExecutionStateType.FAILED); - logger.error("Job for MeasurementCollectionJob with ID {} End Date is before now, the MeasurementCollectionJob will not be scheduled.", mcj.getUuid()); + logger.error("Job for MeasurementCollectionJob with ID {} End Date is before now, the MeasurementCollectionJob will not be scheduled.", job.getMeasurementCollectionJobRef().toString()); } else { long initialDelay = Duration.between(OffsetDateTime.now(), job.getStartDateTime()).getSeconds(); if (initialDelay < 0) { @@ -68,16 +67,15 @@ public class JobService { job.setFuture(future); job.setState(ExecutionStateType.INPROGRESS); mcjMVO.setExecutionState(ExecutionStateType.INPROGRESS); - // runningJobs.add(job); runningJobs.put(job.getMeasurementCollectionJobRef().toString(), job); - logger.info("Job for MeasurementCollectionJob with ID {} started successfully.", mcj.getUuid()); + logger.info("Job for MeasurementCollectionJob with ID {} started successfully.", job.getMeasurementCollectionJobRef().toString()); } catch (RejectedExecutionException e) { job.setState(ExecutionStateType.FAILED); mcjMVO.setExecutionState(ExecutionStateType.FAILED); - logger.error("Job for MeasurementCollectionJob with ID {} could not be scheduled.", mcj.getUuid(), e); + logger.error("Job for MeasurementCollectionJob with ID {} could not be scheduled.", job.getMeasurementCollectionJobRef().toString(), e); } } - metricoCommonMethods.updateMeasurementCollectionJobById(mcj.getUuid(), mcjMVO); + metricoCommonMethods.updateMeasurementCollectionJobById(job.getMeasurementCollectionJobRef().toString(), mcjMVO); return job; } @@ -93,15 +91,14 @@ public class JobService { */ public void stopJob(Job job) { - MeasurementCollectionJob mcj = metricoCommonMethods.retrieveMeasurementCollectionJob(job.getMeasurementCollectionJobRef().toString()); MeasurementCollectionJobMVO mcjMVO = new MeasurementCollectionJobMVO(); if (job.getState() == ExecutionStateType.CANCELLED) { - logger.info("Job for MeasurementCollectionJob with ID {} is already CANCELED.", mcj.getUuid()); + logger.debug("Job for MeasurementCollectionJob with ID {} is already CANCELED.", job.getMeasurementCollectionJobRef().toString()); runningJobs.remove(job.getMeasurementCollectionJobRef().toString()); return; } else if (job.getState() == ExecutionStateType.COMPLETED) { - logger.info("Job for MeasurementCollectionJob with ID {} is already COMPLETED.", mcj.getUuid()); + logger.debug("Job for MeasurementCollectionJob with ID {} is already COMPLETED.", job.getMeasurementCollectionJobRef().toString()); runningJobs.remove(job.getMeasurementCollectionJobRef().toString()); return; } @@ -111,13 +108,14 @@ public class JobService { job.setState(ExecutionStateType.CANCELLED); mcjMVO.setExecutionState(ExecutionStateType.CANCELLED); runningJobs.remove(job.getMeasurementCollectionJobRef().toString()); - logger.info("Job for MeasurementCollectionJob with ID {} stopped successfully.", mcj.getUuid()); + logger.debug("Job for MeasurementCollectionJob with ID {} stopped successfully.", job.getMeasurementCollectionJobRef().toString()); } else { job.setState(ExecutionStateType.PENDING); mcjMVO.setExecutionState(ExecutionStateType.PENDING); - logger.warn("Job for MeasurementCollectionJob with ID {} could not be stopped because it has already completed, has been cancelled, or could not be cancelled for some other reason.", mcj.getUuid()); + logger.debug("Job for MeasurementCollectionJob with ID {} could not be stopped because it has already completed, has been cancelled, or could not be cancelled for some other reason.", + job.getMeasurementCollectionJobRef().toString()); } - metricoCommonMethods.updateMeasurementCollectionJobById(mcj.getUuid(), mcjMVO); + metricoCommonMethods.updateMeasurementCollectionJobById(job.getMeasurementCollectionJobRef().toString(), mcjMVO); } } diff --git a/src/main/java/org/etsi/osl/metrico/services/MetricoService.java b/src/main/java/org/etsi/osl/metrico/services/MetricoService.java index eac4e46..c59cbe5 100644 --- a/src/main/java/org/etsi/osl/metrico/services/MetricoService.java +++ b/src/main/java/org/etsi/osl/metrico/services/MetricoService.java @@ -36,21 +36,13 @@ public class MetricoService extends RouteBuilder { public static final String OSL_METRICO_RSPEC_TYPE = "LogicalResourceSpecification"; public static final String OSL_METRICO_RSPEC_DESCRIPTION = "This Specification is used to describe a generic METRICO job resource"; - @Value("${PM_MEASUREMENT_COLLECTION_JOB_UPDATE}") - private String PM_MEASUREMENT_COLLECTION_JOB_UPDATE = ""; - @Value("${PM_MEASUREMENT_COLLECTION_GET_JOB_BY_ID}") - private String PM_MEASUREMENT_COLLECTION_GET_JOB_BY_ID = ""; - private final ProducerTemplate template; private final MetricoCommonMethods metricoCommonMethods; private final PrometheusQueries prometheusQueries; - private final ProducerTemplate producerTemplate; private final JobService jobService; - public MetricoService(ProducerTemplate producerTemplate, PrometheusQueries prometheusQueries, MetricoCommonMethods metricoCommonMethods, ProducerTemplate template, JobService jobService) { - this.producerTemplate = producerTemplate; + public MetricoService(PrometheusQueries prometheusQueries, MetricoCommonMethods metricoCommonMethods, JobService jobService) { this.prometheusQueries = prometheusQueries; this.metricoCommonMethods = metricoCommonMethods; - this.template = template; this.jobService= jobService; } @@ -123,36 +115,6 @@ public class MetricoService extends RouteBuilder { } } - public String[] queryToPrometheus(@NotNull MeasurementCollectionJob givenMCJ) { - DataAccessEndpoint givenDataAccessEndpoint = givenMCJ.getDataAccessEndpoint().get(0); - Job job = JobMapper.measurementCollectionJobMapToJob(givenMCJ); - String promURL = job.getDataAccessEndPointUri().getScheme() + "://" + job.getDataAccessEndPointUri().getAuthority(); - String promQuery = job.getDataAccessEndPointUri().getQuery(); - promQuery = promQuery.replace("query=", ""); - - String[] promResponse = prometheusQueries.sendQueryToPrometheus(promURL, promQuery, givenMCJ, job).split("\n"); - - DataFilterTemplate filterTemplate = new DataFilterTemplate(); - filterTemplate.setName(promQuery); - DataFilterAttributeStringArray stringArray = new DataFilterAttributeStringArray(); - stringArray.setValue(List.of(promResponse)); - DataFilterMapItem dataFilterMapItem = new DataFilterMapItem(); - dataFilterMapItem.setFilterTemplate(filterTemplate); - dataFilterMapItem.setStringArray(stringArray); - DataFilterMap dataFilterMap = new DataFilterMap(); - dataFilterMap.addMappingsItem(dataFilterMapItem); - givenDataAccessEndpoint.setUriQueryFilter(dataFilterMap); - - List newDataAccessEndpointMVO = new ArrayList<>(); - newDataAccessEndpointMVO.add(DataAccessEndpointMapper.INSTANCE.toDataAccessEndpointMVO(givenDataAccessEndpoint)); - -// MeasurementCollectionJobMVO promResponseMCJ = new MeasurementCollectionJobMVO(); - -// promResponseMCJ.setDataAccessEndpoint(newDataAccessEndpointMVO); -// producerTemplate.sendBodyAndHeader(PM_MEASUREMENT_COLLECTION_JOB_UPDATE, JsonUtil.toJsonString(promResponseMCJ),"mcjid",givenMCJ.getUuid() ); - - return promResponse; - } public void startPeriodicQueryToPrometheus(@NotNull MeasurementCollectionJob givenMCJ) { Job job = JobMapper.measurementCollectionJobMapToJob(givenMCJ); @@ -168,14 +130,7 @@ public class MetricoService extends RouteBuilder { } measurementCollectionJobMVO.setExecutionState(job.getState()); - // You sent at the mq the mcj. Is it correct I changed it to measurementCollectionJobMVO? - producerTemplate.sendBodyAndHeader( - PM_MEASUREMENT_COLLECTION_JOB_UPDATE, - JsonUtil.toJsonString(measurementCollectionJobMVO), - "mcjid", givenMCJ.getUuid() - ); - // Is it the updated mcj? - givenMCJ = metricoCommonMethods.retrieveMeasurementCollectionJob(givenMCJ.getUuid()); + givenMCJ = metricoCommonMethods.updateMeasurementCollectionJobById(givenMCJ.getUuid(), measurementCollectionJobMVO); metricoCommonMethods.updateRelatedResource(givenMCJ); } diff --git a/src/main/resources/application-testing.yml b/src/main/resources/application-testing.yml index 6c17ee0..e653008 100644 --- a/src/main/resources/application-testing.yml +++ b/src/main/resources/application-testing.yml @@ -1,4 +1,7 @@ spring: + profiles: + active: + "testing" config: activate: on-profile: "testing" diff --git a/src/test/java/org/etsi/osl/metrico/DummyRouteBuilder.java b/src/test/java/org/etsi/osl/metrico/DummyRouteBuilder.java index 1847630..fb5d771 100644 --- a/src/test/java/org/etsi/osl/metrico/DummyRouteBuilder.java +++ b/src/test/java/org/etsi/osl/metrico/DummyRouteBuilder.java @@ -1,12 +1,53 @@ package org.etsi.osl.metrico; import org.apache.camel.builder.RouteBuilder; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.Profile; +import org.springframework.stereotype.Component; +@Profile("testing") +@Component public class DummyRouteBuilder extends RouteBuilder { + private static final Logger logger = LoggerFactory.getLogger(DummyRouteBuilder.class); + + @Value("${PM_MEASUREMENT_COLLECTION_JOB_UPDATE}") + private String PM_MEASUREMENT_COLLECTION_JOB_UPDATE = ""; + @Value("${PM_MEASUREMENT_COLLECTION_GET_JOB_BY_ID}") + private String PM_MEASUREMENT_COLLECTION_GET_JOB_BY_ID = ""; + @Value("${PM_MEASUREMENT_COLLECTION_JOBS_GET}") + private String PM_MEASUREMENT_COLLECTION_JOBS_GET = ""; + @Value("${CATALOG_GET_SERVICE_BY_ID}") + private String CATALOG_GET_SERVICE_BY_ID = ""; + @Value("${CATALOG_UPD_SERVICE}") + private String CATALOG_UPD_SERVICE = ""; + @Value("${CATALOG_GET_RESOURCE_BY_ID}") + private String CATALOG_GET_RESOURCE_BY_ID = ""; + @Value("${CATALOG_UPD_RESOURCE}") + private String CATALOG_UPD_RESOURCE = ""; + @Value("${CATALOG_UPDADD_RESOURCESPEC}") + private String CATALOG_UPDADD_RESOURCESPEC = ""; + + private final String measurementCollectionJobJson = "{\n" + + " \"outputFormat\": \"JSON\",\n" + + " \"@type\": \"MeasurementCollectionJob\",\n" + + " \"consumingApplicationId\": \"app123\",\n" + + " \"producingApplicationId\": \"app456\",\n" + + " \"dataAccessEndpoint\": [],\n" + + " \"jobPriority\": 1,\n" + + " \"lastModifiedTime\": \"2023-01-01T00:00:00Z\",\n" + + " \"scheduleDefinition\": []\n" + + "}"; @Override public void configure() throws Exception { - from("jms:queue:PM.MEASUREMENTCOLLECTIONJOB.GET_BY_ID") - .process(exchange -> exchange.getIn().setBody("{\"uuid\":\"test-id\",\"outputFormat\":\"JSON\"}")); + logger.info("Configuring dummy routes..."); + + from("direct:PM.MEASUREMENTCOLLECTIONJOB.GET_BY_ID") + .process(exchange -> { + logger.info("Processing GET_BY_ID route"); + exchange.getIn().setBody(measurementCollectionJobJson); + }); } } \ No newline at end of file diff --git a/src/test/java/org/etsi/osl/metrico/JsonUtilTest.java b/src/test/java/org/etsi/osl/metrico/JsonUtilTest.java index 71d9cae..35e2a91 100644 --- a/src/test/java/org/etsi/osl/metrico/JsonUtilTest.java +++ b/src/test/java/org/etsi/osl/metrico/JsonUtilTest.java @@ -1,16 +1,57 @@ package org.etsi.osl.metrico; +import org.etsi.osl.tmf.pm628.model.DataAccessEndpoint; +import org.etsi.osl.tmf.pm628.model.ExecutionStateType; +import org.etsi.osl.tmf.pm628.model.MeasurementCollectionJob; +import org.etsi.osl.tmf.pm628.model.MeasurementCollectionJobMVO; import org.junit.jupiter.api.Test; +import java.io.IOException; +import java.util.UUID; + import static org.junit.jupiter.api.Assertions.*; class JsonUtilTest { @Test - void toJsonObj() { + void toJsonObj_validJsonString_returnsObject() throws IOException { + String jsonString = "{\"@type\":\"MeasurementCollectionJob\",\"uuid\":\"f47ac10b-58cc-4372-a567-0e02b2c3d479\"}"; + MeasurementCollectionJobMVO mcj = JsonUtil.toJsonObj(jsonString, MeasurementCollectionJobMVO.class); + assertNotNull(mcj); + assertEquals("f47ac10b-58cc-4372-a567-0e02b2c3d479", mcj.getUuid()); + } + + @Test + void toJsonObj_invalidJsonString_throwsIOException() { + String invalidJsonString = "{\"executionState\":\"INPROGRESS\""; + assertThrows(IOException.class, () -> { + JsonUtil.toJsonObj(invalidJsonString, MeasurementCollectionJob.class); + }); + } + + @Test + void toJsonString_validObject_returnsJsonString() { + MeasurementCollectionJobMVO mcj = new MeasurementCollectionJobMVO(); + String uuid = "f47ac10b-58cc-4372-a567-0e02b2c3d479"; + mcj.setUuid(uuid); + String jsonString = JsonUtil.toJsonString(mcj); + assertTrue(jsonString.contains("\"uuid\":\"f47ac10b-58cc-4372-a567-0e02b2c3d479\"")); + } + + @Test + void toJsonString_nullObject_returnsNull() { + String jsonString = JsonUtil.toJsonString(null); + assertNull(jsonString); } @Test - void toJsonString() { + void toJsonString_objectWithNullFields_excludesNullFields() { + MeasurementCollectionJobMVO mcj = new MeasurementCollectionJobMVO(); + mcj.setUuid(UUID.randomUUID().toString()); + mcj.setExecutionState(ExecutionStateType.INPROGRESS); + assertNotNull(mcj); + String jsonString = JsonUtil.toJsonString(mcj); + assertNotNull(jsonString); + assertFalse(jsonString.contains("executionState")); } } \ No newline at end of file diff --git a/src/test/java/org/etsi/osl/metrico/MetricoCommonMethodsTest.java b/src/test/java/org/etsi/osl/metrico/MetricoCommonMethodsTest.java index 436edbe..92e0dc2 100644 --- a/src/test/java/org/etsi/osl/metrico/MetricoCommonMethodsTest.java +++ b/src/test/java/org/etsi/osl/metrico/MetricoCommonMethodsTest.java @@ -1,56 +1,48 @@ package org.etsi.osl.metrico; +import org.apache.camel.CamelContext; +import org.apache.camel.ProducerTemplate; +import org.apache.camel.impl.DefaultCamelContext; +import org.etsi.osl.tmf.pm628.model.MeasurementCollectionJob; +import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.context.annotation.Profile; import static org.junit.jupiter.api.Assertions.*; - +import static org.mockito.Mockito.*; +@SpringBootTest +@Profile("testing") class MetricoCommonMethodsTest { - @Test - void configure() { - } + @Mock + private ProducerTemplate template; - @Test - void retrieveMeasurementCollectionJob() { - } + @InjectMocks + private MetricoCommonMethods metricoCommonMethods; - @Test - void testRetrieveMeasurementCollectionJob() { - } + private CamelContext camelContext; - @Test - void listMeasurementCollectionJob() { - } - - @Test - void listUnfinishedMeasurementCollectionJob() { - } - - @Test - void updateRelatedResource() { + @BeforeEach + void setUp() throws Exception { + MockitoAnnotations.openMocks(this); + camelContext = new DefaultCamelContext(); + camelContext.addRoutes(new DummyRouteBuilder()); + camelContext.start(); + metricoCommonMethods = new MetricoCommonMethods(); + metricoCommonMethods.configure(); } @Test - void createOrUpdateResourceSpecByNameCategoryVersion() { - } - - @Test - void updateService() { - } - - @Test - void updateResourceById() { - } + void testRetrieveMeasurementCollectionJob() { + String mcjId = "test-id"; - @Test - void retrieveService() { - } + MeasurementCollectionJob result = metricoCommonMethods.retrieveMeasurementCollectionJob(mcjId); - @Test - void retrieveResource() { - } - - @Test - void updateMeasurementCollectionJobById() { + assertNotNull(result); + assertEquals("test-id", result.getUuid()); } } \ No newline at end of file diff --git a/src/test/java/org/etsi/osl/metrico/mapper/JobMapperTest.java b/src/test/java/org/etsi/osl/metrico/mapper/JobMapperTest.java index 40da5a5..f8cc9a1 100644 --- a/src/test/java/org/etsi/osl/metrico/mapper/JobMapperTest.java +++ b/src/test/java/org/etsi/osl/metrico/mapper/JobMapperTest.java @@ -1,44 +1,65 @@ package org.etsi.osl.metrico.mapper; -import org.etsi.osl.tmf.pm628.model.DataAccessEndpoint; -import org.etsi.osl.tmf.pm628.model.DataFilterMap; -import org.etsi.osl.tmf.pm628.model.DataFilterMapItem; -import org.etsi.osl.tmf.pm628.model.MeasurementCollectionJob; -import org.jetbrains.annotations.NotNull; +import org.etsi.osl.metrico.model.Job; +import org.etsi.osl.tmf.pm628.model.*; +import org.junit.jupiter.api.Test; import java.net.URI; -import java.util.*; +import java.util.ArrayList; +import java.util.List; +import java.util.UUID; + +import static org.junit.jupiter.api.Assertions.*; public class JobMapperTest { - public MeasurementCollectionJob measurementCollectionJobCreate() { + @Test + public void testMeasurementCollectionJobMapToJob() { MeasurementCollectionJob measurementCollectionJob = new MeasurementCollectionJob(); - - List dataAccessEndpointList = new ArrayList<>(); - dataAccessEndpointList.add(dataAccessEndpointCreate()); - measurementCollectionJob.setUuid("9f22dc98-f439-4fdd-98e3-f6471cf8ca67"); - measurementCollectionJob.setDataAccessEndpoint(dataAccessEndpointList); - - - return measurementCollectionJob; - } - public DataAccessEndpoint dataAccessEndpointCreate(){ DataAccessEndpoint dataAccessEndpoint = new DataAccessEndpoint(); dataAccessEndpoint.setUuid("123e4567-e89b-12d3-a456-426614174000"); - dataAccessEndpoint.setUri(URI.create("example.com")); + dataAccessEndpoint.setUri(URI.create("http://example.com")); dataAccessEndpoint.setApiType("Prometheus"); - return dataAccessEndpoint; - } + List dataAccessEndpointList = new ArrayList<>(); + dataAccessEndpointList.add(dataAccessEndpoint); + measurementCollectionJob.setDataAccessEndpoint(dataAccessEndpointList); + + ScheduleDefinition scheduleDefinition = new ScheduleDefinition(); + scheduleDefinition.setScheduleDefinitionStartTime("2023-01-01T00:00:00Z"); + scheduleDefinition.setScheduleDefinitionEndTime("2023-01-02T00:00:00Z"); - public DataFilterMap dataFilterMapCreate(){ - DataFilterMap dataFilterMap = new DataFilterMap(); - // dataFilterMap.setMappings(); + List scheduleDefinitionList = new ArrayList<>(); + scheduleDefinitionList.add(scheduleDefinition); + measurementCollectionJob.setScheduleDefinition(scheduleDefinitionList); - return dataFilterMap; + Granularity granularity = Granularity.G_1H; + measurementCollectionJob.setGranularity(granularity); + + Job job = JobMapper.measurementCollectionJobMapToJob(measurementCollectionJob); + + assertNotNull(job); + assertEquals(UUID.fromString("9f22dc98-f439-4fdd-98e3-f6471cf8ca67"), job.getMeasurementCollectionJobRef()); + assertEquals(UUID.fromString("123e4567-e89b-12d3-a456-426614174000"), job.getDataAccessEndPointRef()); + assertEquals("Prometheus", job.getApiType()); + assertEquals(URI.create("http://example.com"), job.getDataAccessEndPointUri()); + assertEquals("2023-01-01T00:00Z", job.getStartDateTime().toString()); + assertEquals("2023-01-02T00:00Z", job.getEndDateTime().toString()); + assertEquals(3600, job.getExecutionInterval()); } + @Test + public void testConvertGranularityToSeconds() { + assertEquals(60, JobMapper.convertGranularityToSeconds("G_1MN")); + assertEquals(3600, JobMapper.convertGranularityToSeconds("G_1H")); + assertEquals(2592000, JobMapper.convertGranularityToSeconds("G_1M")); + assertEquals(31536000, JobMapper.convertGranularityToSeconds("G_1Y")); + } -} + @Test + public void testConvertGranularityToSecondsInvalidFormat() { + assertThrows(IllegalArgumentException.class, () -> JobMapper.convertGranularityToSeconds("G_1W")); + } +} \ No newline at end of file diff --git a/src/test/java/org/etsi/osl/metrico/model/JobTest.java b/src/test/java/org/etsi/osl/metrico/model/JobTest.java index 31a6c29..0f60dd1 100644 --- a/src/test/java/org/etsi/osl/metrico/model/JobTest.java +++ b/src/test/java/org/etsi/osl/metrico/model/JobTest.java @@ -55,7 +55,6 @@ class JobTest { @Test void testToString() { Job job = new Job(); - job.setUuid(UUID.fromString("123e4567-e89b-12d3-a456-426614174000")); job.setState(ExecutionStateType.PENDING); job.setStartDateTime(OffsetDateTime.parse("2023-01-01T10:15:30+01:00")); job.setEndDateTime(OffsetDateTime.parse("2023-01-02T10:15:30+01:00")); diff --git a/src/test/java/org/etsi/osl/metrico/services/JobServiceTest.java b/src/test/java/org/etsi/osl/metrico/services/JobServiceTest.java index 50b8d94..1e52152 100644 --- a/src/test/java/org/etsi/osl/metrico/services/JobServiceTest.java +++ b/src/test/java/org/etsi/osl/metrico/services/JobServiceTest.java @@ -1,106 +1,109 @@ -//package org.etsi.osl.metrico.services; -// -//import org.etsi.osl.metrico.model.Job; -//import org.etsi.osl.metrico.reposervices.JobRepoService; -//import org.etsi.osl.tmf.pm628.model.ExecutionStateType; -//import org.junit.jupiter.api.BeforeEach; -//import org.junit.jupiter.api.Test; -//import org.mockito.Mock; -//import org.mockito.MockitoAnnotations; -//import org.slf4j.Logger; -// -//import java.time.OffsetDateTime; -//import java.util.UUID; -//import java.util.concurrent.ScheduledExecutorService; -//import java.util.concurrent.ScheduledFuture; -//import java.util.concurrent.TimeUnit; -// -//import static org.junit.jupiter.api.Assertions.assertEquals; -//import static org.junit.jupiter.api.Assertions.assertNotNull; -//import static org.mockito.ArgumentMatchers.any; -//import static org.mockito.Mockito.*; -// -//class JobServiceTest { -// -// @Mock -// private JobRepoService jobRepoService; -// -// @Mock -// private ScheduledExecutorService scheduler; -// -// @Mock -// private Logger logger; -// -// private JobService jobService; -// -// @BeforeEach -// void setUp() { -// MockitoAnnotations.openMocks(this); -// jobService = new JobService(jobRepoService); -// } -// -// @Test -// void testStartJob_Success() { -// // Initialize the job with specific parameters -// OffsetDateTime startDateTime = OffsetDateTime.now().plusSeconds(5); -// OffsetDateTime endDateTime = startDateTime.plusMinutes(10); -// Integer executionInterval = 5; -// Runnable task = () -> {}; -// Job expectedJob = new Job(startDateTime, endDateTime, executionInterval); -// // Assert the initial state is PENDING -// assertEquals(expectedJob.getState(), ExecutionStateType.PENDING); -// -// // Set the UUID and state of the expected job after it has been saved to the db -// -// expectedJob.setState(ExecutionStateType.INPROGRESS); -// -// // Mock jobRepoService.createAndSaveJob() to return the expected Job -// when(jobRepoService.createAndSaveJob(expectedJob)).thenReturn(expectedJob); -// -//// // Mock scheduler.scheduleAtFixedRate() to not throw an exception -//// ScheduledFuture mockFuture = mock(ScheduledFuture.class); -//// when(scheduler.scheduleAtFixedRate(any(Runnable.class), eq(5L), eq(5L), eq(TimeUnit.SECONDS))) -//// .thenReturn(mockFuture); -// -//// // Call jobService.startJob() with valid parameters -//// Job resultJob = jobService.startJob(task, startDateTime, endDateTime, executionInterval); -//// -//// // Verify job state is INPROGRESS, and job is added to the jobs map -//// assertEquals(ExecutionStateType.INPROGRESS, resultJob.getState()); -//// assertNotNull(JobService.getJobs().get(resultJob.getUuid())); -//// assertEquals(expectedJob, JobService.getJobs().get(resultJob.getUuid())); -// } -// @Test -// void testStartJob_NullPointerException() { -// // Mock jobRepoService.createAndSaveJob() to throw NullPointerException -// // Call jobService.startJob() with valid parameters -// // Verify job state is FAILED -// } -// -// @Test -// void testStartJob_RejectedExecutionException() { -// // Mock scheduler.scheduleAtFixedRate() to throw RejectedExecutionException -// // Call jobService.startJob() with valid parameters -// // Verify job state is FAILED -// } -// -// @Test -// void testStopJob_InProgress() { -// // Add a job to the jobs map with state INPROGRESS -// // Call JobService.stopJob() with the job's UUID -// // Verify job state is CANCELLED -// } -// -// @Test -// void testStopJob_AlreadyCompleted() { -// // Add a job to the jobs map with state COMPLETED -// // Call JobService.stopJob() with the job's UUID -// // Verify job state remains COMPLETED -// } -// -// @Test -// void testStopJob_DoesNotExist() { -// // Call JobService.stopJob() with a non-existent job UUID -// // Verify appropriate warning is logged -// } -//} \ No newline at end of file +package org.etsi.osl.metrico.services; + +import org.etsi.osl.metrico.MetricoCommonMethods; +import org.etsi.osl.metrico.model.Job; +import org.etsi.osl.tmf.pm628.model.ExecutionStateType; +import org.etsi.osl.tmf.pm628.model.MeasurementCollectionJob; +import org.etsi.osl.tmf.pm628.model.MeasurementCollectionJobMVO; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.mockito.*; + +import java.time.OffsetDateTime; +import java.util.UUID; +import java.util.concurrent.*; + +import static org.junit.jupiter.api.Assertions.*; +import static org.mockito.Mockito.*; + +class JobServiceTest { + + @Mock + private MetricoCommonMethods metricoCommonMethods; + + @InjectMocks + private JobService jobService; + + @BeforeEach + void setUp() { + MockitoAnnotations.openMocks(this); + } + + @Test + void startJob() { + Runnable task = mock(Runnable.class); + Job job = new Job(); + UUID randomUUID = UUID.randomUUID(); + job.setMeasurementCollectionJobRef(randomUUID); + job.setStartDateTime(OffsetDateTime.now().plusSeconds(1)); + job.setEndDateTime(OffsetDateTime.now().plusHours(1)); + job.setExecutionInterval(10); + + MeasurementCollectionJob mcj = new MeasurementCollectionJob(); + mcj.setUuid("jobRef"); + + when(metricoCommonMethods.retrieveMeasurementCollectionJob("jobRef")).thenReturn(mcj); + + jobService.startJob(task, job); + + verify(metricoCommonMethods, times(1)).updateMeasurementCollectionJobById(eq("jobRef"), any(MeasurementCollectionJobMVO.class)); + assertEquals(ExecutionStateType.INPROGRESS, job.getState()); + } + + @Test + void stopJob() { + Job job = new Job(); + UUID randomUUID = UUID.randomUUID(); + job.setMeasurementCollectionJobRef(randomUUID); + job.setState(ExecutionStateType.INPROGRESS); + ScheduledFuture future = mock(ScheduledFuture.class); + job.setFuture(future); + + MeasurementCollectionJob mcj = new MeasurementCollectionJob(); + mcj.setUuid(randomUUID.toString()); + + when(metricoCommonMethods.retrieveMeasurementCollectionJob(randomUUID.toString())).thenReturn(mcj); + when(future.cancel(true)).thenReturn(true); + + jobService.stopJob(job); + + verify(metricoCommonMethods, times(1)).updateMeasurementCollectionJobById(eq("jobRef"), any(MeasurementCollectionJobMVO.class)); + assertEquals(ExecutionStateType.CANCELLED, job.getState()); + } + + @Test + void stopJobByUuid() { + Job job = new Job(); + UUID randomUUID = UUID.randomUUID(); + job.setMeasurementCollectionJobRef(randomUUID); + job.setState(ExecutionStateType.INPROGRESS); + + jobService.getRunningJobs().put(randomUUID.toString(), job); + + jobService.stopJob(randomUUID.toString()); + + assertEquals(ExecutionStateType.CANCELLED, job.getState()); + } + + @Test + void stopAllJobs() { + Job job1 = new Job(); + UUID randomUUID1 = UUID.randomUUID(); + job1.setMeasurementCollectionJobRef(randomUUID1); + job1.setState(ExecutionStateType.INPROGRESS); + + Job job2 = new Job(); + UUID randomUUID2 = UUID.randomUUID(); + job2.setMeasurementCollectionJobRef(randomUUID2); + job2.setState(ExecutionStateType.INPROGRESS); + + jobService.getRunningJobs().put(randomUUID1.toString(), job1); + jobService.getRunningJobs().put(randomUUID2.toString(), job2); + + jobService.stopAllJobs(); + + assertTrue(jobService.getRunningJobs().isEmpty()); + assertEquals(ExecutionStateType.CANCELLED, job1.getState()); + assertEquals(ExecutionStateType.CANCELLED, job2.getState()); + } +} \ No newline at end of file -- GitLab From 45fc756045eb82b2afbb7d034e6f16bfbe4a0501 Mon Sep 17 00:00:00 2001 From: George Tziavas Date: Mon, 31 Mar 2025 16:32:02 +0300 Subject: [PATCH 05/17] added synchronized to JobService methods --- .../java/org/etsi/osl/metrico/services/JobService.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/main/java/org/etsi/osl/metrico/services/JobService.java b/src/main/java/org/etsi/osl/metrico/services/JobService.java index 17b96fc..635d5e0 100644 --- a/src/main/java/org/etsi/osl/metrico/services/JobService.java +++ b/src/main/java/org/etsi/osl/metrico/services/JobService.java @@ -43,7 +43,7 @@ public class JobService { * @throws IllegalArgumentException if the job's start or end date is invalid * @throws RejectedExecutionException if the job could not be scheduled */ - public Job startJob(Runnable task, Job job) { + public synchronized Job startJob(Runnable task, Job job) { logger.debug("Starting Job for MeasurementCollectionJob with ID {}.", job.getMeasurementCollectionJobRef()); MeasurementCollectionJobMVO mcjMVO = new MeasurementCollectionJobMVO(); @@ -89,7 +89,7 @@ public class JobService { * * @param job the job to be stopped */ - public void stopJob(Job job) { + public synchronized void stopJob(Job job) { MeasurementCollectionJobMVO mcjMVO = new MeasurementCollectionJobMVO(); @@ -128,7 +128,7 @@ public class JobService { * * @param measurementCollectionJobUuid the UUID of the Measurement Collection Job */ - public void stopJob(String measurementCollectionJobUuid) { + public synchronized void stopJob(String measurementCollectionJobUuid) { Job job = runningJobs.get(measurementCollectionJobUuid); if (job != null) { stopJob(job); @@ -142,7 +142,7 @@ public class JobService { * *

This method iterates over all jobs in the runningJobs map, stops each job, and then clears the map.

*/ - public void stopAllJobs() { + public synchronized void stopAllJobs() { for (Job job : runningJobs.values()) { stopJob(job); } -- GitLab From d0c6e5688c431ef5b2737e6f1a58082ceafe99fa Mon Sep 17 00:00:00 2001 From: George Tziavas Date: Tue, 10 Jun 2025 16:58:21 +0300 Subject: [PATCH 06/17] Fixed imports --- src/main/java/org/etsi/osl/metrico/JsonUtil.java | 1 - .../etsi/osl/metrico/mapper/DataFilterMapItemMapper.java | 1 - src/main/java/org/etsi/osl/metrico/mapper/JobMapper.java | 7 ++++--- .../metrico/mapper/ResourceSpecificationRefMapper.java | 2 +- src/main/java/org/etsi/osl/metrico/model/Job.java | 4 +--- .../java/org/etsi/osl/metrico/services/JobService.java | 1 - .../osl/metrico/services/MetricoServiceRouteBuilder.java | 9 --------- 7 files changed, 6 insertions(+), 19 deletions(-) diff --git a/src/main/java/org/etsi/osl/metrico/JsonUtil.java b/src/main/java/org/etsi/osl/metrico/JsonUtil.java index fa679e1..b22256b 100644 --- a/src/main/java/org/etsi/osl/metrico/JsonUtil.java +++ b/src/main/java/org/etsi/osl/metrico/JsonUtil.java @@ -3,7 +3,6 @@ package org.etsi.osl.metrico; import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; -import org.etsi.osl.tmf.pm628.model.MeasurementCollectionJobMVO; import java.io.IOException; diff --git a/src/main/java/org/etsi/osl/metrico/mapper/DataFilterMapItemMapper.java b/src/main/java/org/etsi/osl/metrico/mapper/DataFilterMapItemMapper.java index cc25861..f7a36d8 100644 --- a/src/main/java/org/etsi/osl/metrico/mapper/DataFilterMapItemMapper.java +++ b/src/main/java/org/etsi/osl/metrico/mapper/DataFilterMapItemMapper.java @@ -2,7 +2,6 @@ package org.etsi.osl.metrico.mapper; import org.etsi.osl.tmf.pm628.model.DataFilterMapItem; import org.etsi.osl.tmf.pm628.model.DataFilterMapItemMVO; -import org.mapstruct.Mapper; import org.mapstruct.Mapping; import org.mapstruct.factory.Mappers; diff --git a/src/main/java/org/etsi/osl/metrico/mapper/JobMapper.java b/src/main/java/org/etsi/osl/metrico/mapper/JobMapper.java index 13db6f8..b42468d 100644 --- a/src/main/java/org/etsi/osl/metrico/mapper/JobMapper.java +++ b/src/main/java/org/etsi/osl/metrico/mapper/JobMapper.java @@ -2,7 +2,9 @@ package org.etsi.osl.metrico.mapper; import org.etsi.osl.metrico.model.Job; import org.etsi.osl.metrico.model.SupportedDataAccessEndpoints; -import org.etsi.osl.tmf.pm628.model.*; +import org.etsi.osl.tmf.pm628.model.DataAccessEndpoint; +import org.etsi.osl.tmf.pm628.model.Granularity; +import org.etsi.osl.tmf.pm628.model.MeasurementCollectionJob; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -65,8 +67,7 @@ public class JobMapper { job.setExecutionInterval(convertGranularityToSeconds(granularity.getValue())); } - - logger.atDebug().setMessage("Received MeasurementCollectionJob:\n" + measurementCollectionJob + "\nConverted it to Job:\n" + job).log(); + logger.atDebug().setMessage("Received MeasurementCollectionJob and converted it to Job").log(); return job; } diff --git a/src/main/java/org/etsi/osl/metrico/mapper/ResourceSpecificationRefMapper.java b/src/main/java/org/etsi/osl/metrico/mapper/ResourceSpecificationRefMapper.java index 9041cab..141fc19 100644 --- a/src/main/java/org/etsi/osl/metrico/mapper/ResourceSpecificationRefMapper.java +++ b/src/main/java/org/etsi/osl/metrico/mapper/ResourceSpecificationRefMapper.java @@ -1,7 +1,7 @@ package org.etsi.osl.metrico.mapper; -import org.etsi.osl.tmf.rcm634.model.ResourceSpecificationRef; import org.etsi.osl.tmf.pm628.model.ResourceSpecificationRefMVO; +import org.etsi.osl.tmf.rcm634.model.ResourceSpecificationRef; import org.mapstruct.Mapper; import org.mapstruct.Mapping; import org.mapstruct.factory.Mappers; diff --git a/src/main/java/org/etsi/osl/metrico/model/Job.java b/src/main/java/org/etsi/osl/metrico/model/Job.java index ffd5643..b033228 100644 --- a/src/main/java/org/etsi/osl/metrico/model/Job.java +++ b/src/main/java/org/etsi/osl/metrico/model/Job.java @@ -1,12 +1,10 @@ package org.etsi.osl.metrico.model; import com.fasterxml.jackson.annotation.JsonIgnore; -import jakarta.persistence.*; +import jakarta.persistence.Transient; import lombok.Getter; import lombok.Setter; -import org.etsi.osl.tmf.pm628.model.DataFilterMap; import org.etsi.osl.tmf.pm628.model.ExecutionStateType; -import org.hibernate.annotations.GenericGenerator; import org.springframework.format.annotation.DateTimeFormat; import java.net.URI; diff --git a/src/main/java/org/etsi/osl/metrico/services/JobService.java b/src/main/java/org/etsi/osl/metrico/services/JobService.java index 635d5e0..bd42a54 100644 --- a/src/main/java/org/etsi/osl/metrico/services/JobService.java +++ b/src/main/java/org/etsi/osl/metrico/services/JobService.java @@ -4,7 +4,6 @@ import lombok.Getter; import org.etsi.osl.metrico.MetricoCommonMethods; import org.etsi.osl.metrico.model.Job; import org.etsi.osl.tmf.pm628.model.ExecutionStateType; -import org.etsi.osl.tmf.pm628.model.MeasurementCollectionJob; import org.etsi.osl.tmf.pm628.model.MeasurementCollectionJobMVO; import org.slf4j.Logger; import org.slf4j.LoggerFactory; diff --git a/src/main/java/org/etsi/osl/metrico/services/MetricoServiceRouteBuilder.java b/src/main/java/org/etsi/osl/metrico/services/MetricoServiceRouteBuilder.java index 9a62a49..b6ae5e5 100644 --- a/src/main/java/org/etsi/osl/metrico/services/MetricoServiceRouteBuilder.java +++ b/src/main/java/org/etsi/osl/metrico/services/MetricoServiceRouteBuilder.java @@ -5,10 +5,7 @@ import org.apache.camel.builder.RouteBuilder; import org.apache.camel.model.dataformat.JsonLibrary; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; -import org.etsi.osl.tmf.pm628.model.MeasurementCollectionJob; import org.etsi.osl.tmf.pm628.model.MeasurementCollectionJobCreateEvent; -import org.etsi.osl.tmf.pm628.model.MeasurementCollectionJobRef; -import org.etsi.osl.tmf.ri639.model.ResourceCreateNotification; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Configuration; @@ -28,12 +25,6 @@ public class MetricoServiceRouteBuilder extends RouteBuilder { public void configure() throws Exception { -// from(EVENT_MEASUREMENT_COLLECTION_JOB_CREATED) -// .log(LoggingLevel.INFO, log, EVENT_MEASUREMENT_COLLECTION_JOB_CREATED + " message received!") -// .to("log:DEBUG?showBody=true&showHeaders=true").unmarshal() -// .json(JsonLibrary.Jackson, MeasurementCollectionJob.class, true) -// .bean(metricoService, "startPeriodicQueryToPrometheus(${body})"); - from(EVENT_MEASUREMENT_COLLECTION_JOB_CREATE) .log(LoggingLevel.INFO, log, EVENT_MEASUREMENT_COLLECTION_JOB_CREATE + " message received!") .to("log:DEBUG?showBody=true&showHeaders=true") -- GitLab From 4bbfdc7dab08b43a769958a96c779a9e73c39d41 Mon Sep 17 00:00:00 2001 From: George Tziavas Date: Tue, 10 Jun 2025 17:20:56 +0300 Subject: [PATCH 07/17] Fixed listPendingOrInProgressMeasurementCollectionJobs and listPendingOrInProgressMeasurementCollectionJobs --- .../osl/metrico/MetricoCommonMethods.java | 65 +++++++++++++------ 1 file changed, 46 insertions(+), 19 deletions(-) diff --git a/src/main/java/org/etsi/osl/metrico/MetricoCommonMethods.java b/src/main/java/org/etsi/osl/metrico/MetricoCommonMethods.java index 0857b2b..32b073c 100644 --- a/src/main/java/org/etsi/osl/metrico/MetricoCommonMethods.java +++ b/src/main/java/org/etsi/osl/metrico/MetricoCommonMethods.java @@ -20,6 +20,7 @@ import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Component; +import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -44,9 +45,16 @@ public class MetricoCommonMethods extends RouteBuilder { private String CATALOG_UPD_RESOURCE = ""; @Value("${CATALOG_UPDADD_RESOURCESPEC}") private String CATALOG_UPDADD_RESOURCESPEC = ""; + @Value("${PM_MEASUREMENT_COLLECTION_JOB_GET_INPROGRESS_OR_PENDING}") + private String PM_MEASUREMENT_COLLECTION_JOB_GET_INPROGRESS_OR_PENDING; + private ProducerTemplate template; + public MetricoCommonMethods(ProducerTemplate template) { + this.template = template; + } + @Override public void configure() throws Exception { // TODO Auto-generated method stub @@ -97,7 +105,7 @@ public class MetricoCommonMethods extends RouteBuilder { logger.debug("will retrieve all Measurement Collection Jobs from database"); try { - Object response = template.requestBody(PM_MEASUREMENT_COLLECTION_JOBS_GET); + Object response = template.requestBody(PM_MEASUREMENT_COLLECTION_JOBS_GET, ""); if (!(response instanceof String)) { logger.error("List object is wrong."); return null; @@ -119,22 +127,36 @@ public class MetricoCommonMethods extends RouteBuilder { * * @return a list of unfinished Measurement Collection Jobs, or null if no jobs match the criteria or if an error occurs */ - public List listUnfinishedMeasurementCollectionJob() { - logger.debug("will retrieve Measurement Collection Jobs with ExecutionStateType Pending or InProgress from the database"); + public ArrayList listPendingOrInProgressMeasurementCollectionJobs() { + logger.debug("===== Will try to retrieve Measurement Collection Jobs with ExecutionStateType Pending or InProgress from the database ===="); - List allMeasurementCollectionJobs = listMeasurementCollectionJob(); - List filteredMeasurementCollectionJobs = null; + ArrayList pendingOrInProgressMeasurementCollectionJobs = null; try { - if (allMeasurementCollectionJobs != null) { - filteredMeasurementCollectionJobs = allMeasurementCollectionJobs.stream() - .filter(mcj -> mcj.getExecutionState().equals(ExecutionStateType.PENDING) || mcj.getExecutionState().equals(ExecutionStateType.INPROGRESS)) - .toList(); + Object response = template.requestBody(PM_MEASUREMENT_COLLECTION_JOB_GET_INPROGRESS_OR_PENDING, ""); + + logger.debug("will retrieve Measurement Collection Jobs with Execution State " + ExecutionStateType.PENDING.toString() + " from catalog response: " + response.getClass()); + if (!(response instanceof String)) { + logger.error("===== List object is wrong ===="); + return null; + } else if (((String) response).isEmpty()) { + logger.debug("===== No PENDING OR IN_PROGRESS Measurement Collection Jobs from previous sessions ====="); + return null; + } else { + logger.debug("listPendingOrInProgressMeasurementCollectionJobs response is: " + response); + + ObjectMapper objectMapper = new ObjectMapper(); + pendingOrInProgressMeasurementCollectionJobs = objectMapper.readValue( + (String) response, + objectMapper.getTypeFactory().constructCollectionType(ArrayList.class, MeasurementCollectionJob.class) + ); + + logger.info("===== Found PENDING or IN_PROGRESS Measurement Collection Jobs from previous sessions ====="); } } catch (Exception e) { - logger.error("Cannot retrieve/filter Measurement Collection Job details from the database. " + e); + logger.error("Cannot retrieve/filter Measurement Collection Job details from the database. {}", e.toString()); } - return filteredMeasurementCollectionJobs; + return pendingOrInProgressMeasurementCollectionJobs; } @@ -144,16 +166,15 @@ public class MetricoCommonMethods extends RouteBuilder { * @param givenMCJ the Measurement Collection Job containing the related Service UUID and execution state */ public void updateRelatedResource(@NotNull MeasurementCollectionJob givenMCJ) { - //retrieve related service from inventory - //retrieve related resource from inventory - //patch resource state + if(givenMCJ.getExecutionState()==null){ + givenMCJ.setExecutionState(ExecutionStateType.PENDING); + } String servUUID = givenMCJ.getProducingApplicationId();//this contains the related ServiceUUID with this MCJ logger.debug("Update Resource related to Service with ServiceId {}.", servUUID); Service aService = retrieveService(servUUID); if (aService != null && aService.getSupportingResource().size() > 0) { ResourceRef resRef = aService.getSupportingResource().stream().findFirst().get(); - //Resource aResource = retrieveResource(resRef.getId()); logger.debug("Update Resource with ResourceId {}.", resRef.getId()); ResourceUpdate rup = new ResourceUpdate(); @@ -185,15 +206,17 @@ public class MetricoCommonMethods extends RouteBuilder { * @return the created or updated LogicalResourceSpecification instance, or null if the operation failed */ public LogicalResourceSpecification createOrUpdateResourceSpecByNameCategoryVersion(ResourceSpecificationCreate s) { - logger.info("will createOrUpdateResourceSpecByNameCategoryVersion "); + logger.info("==== Will try to Create or Update a Resource Specification for METRICO ===="); try { Map map = new HashMap<>(); map.put("aname", s.getName()); map.put("aversion", s.getVersion()); map.put("acategory", s.getCategory()); + logger.info("will createOrUpdateResourceSpecByNameCategoryVersion "); Object response = template.requestBodyAndHeaders(CATALOG_UPDADD_RESOURCESPEC, JsonUtil.toJsonString(s), map); assert response instanceof String : "ResourceSpecification object is wrong."; LogicalResourceSpecification rs = JsonUtil.toJsonObj((String) response, LogicalResourceSpecification.class); + logger.info("==== Created or Updated a Resource Specification for METRICO ===="); return rs; } catch (Exception e) { logger.error("Cannot create ResourceSpecification"); @@ -318,16 +341,20 @@ public class MetricoCommonMethods extends RouteBuilder { */ public MeasurementCollectionJob updateMeasurementCollectionJobById(String mcjId, MeasurementCollectionJobMVO mcjMVO) { MeasurementCollectionJob measurementCollectionJob; - logger.debug("will update MeasurementCollectionJob with id {}", mcjId); + logger.debug("will update MeasurementCollectionJob with id {} and \nMeasurementCollectionJobMVO.toString():\n{}", mcjId, JsonUtil.toJsonString(mcjMVO)); try { Map map = new HashMap<>(); map.put("mcjid", mcjId); Object response = template.requestBodyAndHeaders(PM_MEASUREMENT_COLLECTION_JOB_UPDATE, JsonUtil.toJsonString(mcjMVO), map); - assert response instanceof String : "MeasurementCollectionJob object is wrong."; + logger.info("JsonUtil.toJsonString(mcjMVO): \n{}", JsonUtil.toJsonString(mcjMVO)); + if (!(response instanceof String)) { + logger.error("MeasurementCollectionJob object is wrong."); + return null; + } measurementCollectionJob = JsonUtil.toJsonObj((String) response, MeasurementCollectionJob.class); - + logger.info("response from PM_MEASUREMENT_COLLECTION_JOB_UPDATE: \n{}", response); return measurementCollectionJob; } catch (Exception e) { e.printStackTrace(); -- GitLab From 1a36ef258bcf37cc33ce067d48571c034c315d93 Mon Sep 17 00:00:00 2001 From: George Tziavas Date: Tue, 10 Jun 2025 17:22:09 +0300 Subject: [PATCH 08/17] fixed restartPendingOrInProgressJobs --- .../osl/metrico/services/MetricoService.java | 41 ++++++++++--------- 1 file changed, 22 insertions(+), 19 deletions(-) diff --git a/src/main/java/org/etsi/osl/metrico/services/MetricoService.java b/src/main/java/org/etsi/osl/metrico/services/MetricoService.java index c59cbe5..8a6c55c 100644 --- a/src/main/java/org/etsi/osl/metrico/services/MetricoService.java +++ b/src/main/java/org/etsi/osl/metrico/services/MetricoService.java @@ -2,11 +2,8 @@ package org.etsi.osl.metrico.services; import jakarta.annotation.PreDestroy; import jakarta.validation.constraints.NotNull; -import org.apache.camel.ProducerTemplate; import org.apache.camel.builder.RouteBuilder; import org.etsi.osl.metrico.MetricoCommonMethods; -import org.etsi.osl.metrico.JsonUtil; -import org.etsi.osl.metrico.mapper.DataAccessEndpointMapper; import org.etsi.osl.metrico.mapper.JobMapper; import org.etsi.osl.metrico.model.Job; import org.etsi.osl.metrico.prometheus.PrometheusQueries; @@ -17,12 +14,10 @@ import org.etsi.osl.tmf.rcm634.model.LogicalResourceSpecification; import org.etsi.osl.tmf.rcm634.model.ResourceSpecificationCreate; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Value; import org.springframework.boot.context.event.ApplicationStartedEvent; import org.springframework.context.event.EventListener; import org.springframework.stereotype.Service; -import java.util.ArrayList; import java.util.List; @Service @@ -59,7 +54,6 @@ public class MetricoService extends RouteBuilder { // and tries to resume them. restartPendingOrInProgressJobs(); - logger.info("===== Pending jobs from previous sessions done ====="); } @PreDestroy @@ -70,8 +64,6 @@ public class MetricoService extends RouteBuilder { private void registerMetricoResourceSpec() { - logger.info("===== Pending jobs from previous sessions ====="); - ResourceSpecificationCreate rsc = new ResourceSpecificationCreate(); rsc.setName(OSL_METRICO_RSPEC_NAME); rsc.setCategory(OSL_METRICO_RSPEC_CATEGORY); @@ -102,16 +94,25 @@ public class MetricoService extends RouteBuilder { } public void restartPendingOrInProgressJobs() { - List jobsPending = metricoCommonMethods.listUnfinishedMeasurementCollectionJob(); - logger.info("===== Pending jobs from previous sessions ====="); + logger.info("===== Looking for PENDING or IN_PROGRESS Measurement Collection Jobs from previous sessions ====="); + List jobsPending = metricoCommonMethods.listPendingOrInProgressMeasurementCollectionJobs(); jobService.stopAllJobs(); - for (MeasurementCollectionJob measurementCollectionJob : jobsPending) { - logger.info("try to resume MeasurementCollectionJob with uuid: {}, ExecutionState:{}, ScheduleDefinitionStartTime: {}, ScheduleDefinitionEndTime:{}", - measurementCollectionJob.getUuid(), - measurementCollectionJob.getExecutionState(), - measurementCollectionJob.getScheduleDefinition().get(0).getScheduleDefinitionStartTime(), - measurementCollectionJob.getScheduleDefinition().get(0).getScheduleDefinitionEndTime()); - this.startPeriodicQueryToPrometheus(measurementCollectionJob); + if(jobsPending != null){ + logger.info("===== Started resuming PENDING or IN_PROGRESS Measurement Collection Jobs from previous sessions ====="); + for (MeasurementCollectionJob measurementCollectionJob : jobsPending) { + measurementCollectionJob = metricoCommonMethods.retrieveMeasurementCollectionJob(measurementCollectionJob.getUuid()); + if (measurementCollectionJob.getDataAccessEndpoint() == null || measurementCollectionJob.getDataAccessEndpoint().size() != 1) { + logger.warn("MeasurementCollectionJob with uuid: {} has {} dataAccessEndpoint(s), skipping.", + measurementCollectionJob.getUuid(), + measurementCollectionJob.getDataAccessEndpoint() == null ? 0 : measurementCollectionJob.getDataAccessEndpoint().size()); + continue; + } + logger.info("===== Resuming measurementCollectionJob with uuid: {} =====", measurementCollectionJob.getUuid()); + this.startPeriodicQueryToPrometheus(measurementCollectionJob); + } + logger.info("===== Finished resuming PENDING or IN_PROGRESS Measurement Collection Jobs from previous sessions ====="); + } else { + logger.info("===== No PENDING OF IN_PROGRESS Measurement Collection Jobs from previous sessions to restart ====="); } } @@ -120,6 +121,7 @@ public class MetricoService extends RouteBuilder { Job job = JobMapper.measurementCollectionJobMapToJob(givenMCJ); String promURL = job.getDataAccessEndPointUri().getScheme() + "://" + job.getDataAccessEndPointUri().getAuthority(); String promQuery = job.getDataAccessEndPointUri().getQuery(); + logger.atInfo().setMessage("Periodic query started, with ID: " + job.getMeasurementCollectionJobRef()).log(); MeasurementCollectionJobMVO measurementCollectionJobMVO = new MeasurementCollectionJobMVO(); job = prometheusQueries.startPeriodicQuery(promURL, promQuery, job, givenMCJ); @@ -131,8 +133,9 @@ public class MetricoService extends RouteBuilder { measurementCollectionJobMVO.setExecutionState(job.getState()); givenMCJ = metricoCommonMethods.updateMeasurementCollectionJobById(givenMCJ.getUuid(), measurementCollectionJobMVO); - - metricoCommonMethods.updateRelatedResource(givenMCJ); + if (givenMCJ!=null) { + metricoCommonMethods.updateRelatedResource(givenMCJ); + } } -- GitLab From 7c66167f61f71adeefc49e1742b06cc23bb1e616 Mon Sep 17 00:00:00 2001 From: George Tziavas Date: Tue, 10 Jun 2025 17:25:47 +0300 Subject: [PATCH 09/17] updated application.yaml --- src/main/resources/application-testing.yml | 23 +--------------------- src/main/resources/application.yml | 12 +++++++++++ 2 files changed, 13 insertions(+), 22 deletions(-) diff --git a/src/main/resources/application-testing.yml b/src/main/resources/application-testing.yml index e653008..8b11b03 100644 --- a/src/main/resources/application-testing.yml +++ b/src/main/resources/application-testing.yml @@ -9,28 +9,6 @@ spring: name: metrico main: web-application-type: servlet - datasource: - url: jdbc:mysql://localhost:13306/metricodb?createDatabaseIfNotExist=true&useUnicode=true&characterEncoding=utf8&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=UTC - password: letmein - username: root - hikari: - minimumIdle: 2 - maximumPoolSize: 40 - idleTimeout: 120000 - connectionTimeout: 400000 - leakDetectionThreshold: 100000 - jpa: - database-platform: org.etsi.osl.metrico.LocalMysqlDialect - hibernate: - ddl-auto: update - show-sql: false - generate-ddl: true - properties: - hibernate: - connection: - characterEncoding: utf-8 - CharSet: utf-8 - useUnicode: true activemq: brokerUrl: tcp://localhost:61616?jms.watchTopicAdvisories=false user: artemis @@ -72,6 +50,7 @@ PM_MEASUREMENT_COLLECTION_GET_JOB_BY_ID: "direct:PM.MEASUREMENTCOLLECTIONJOB.GET PM_MEASUREMENT_COLLECTION_JOBS_GET: "direct:PM.MEASUREMENTCOLLECTIONJOBS.GET" PM_MEASUREMENT_COLLECTION_JOB_ADD: "direct:PM.MEASUREMENTCOLLECTIONJOB.ADD" PM_MEASUREMENT_COLLECTION_JOB_UPDATE: "direct:PM.MEASUREMENTCOLLECTIONJOB.UPDATE" +PM_MEASUREMENT_COLLECTION_JOB_GET_INPROGRESS_OR_PENDING: "jms:queue:PM.MEASUREMENTCOLLECTIONJOB.GET_INPROGRESS_OR_PENDING" EVENT_MEASUREMENT_COLLECTION_JOB_CREATE: "direct:topic:EVENT.MEASUREMENTCOLLECTIONJOB.CREATE" EVENT_MEASUREMENT_COLLECTION_JOB_EXECUTION_STATE_CHANGED: "direct:topic:EVENT.MEASUREMENTCOLLECTIONJOB.STATECHANGED" diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index 937f50f..1362ecc 100644 --- a/src/main/resources/application.yml +++ b/src/main/resources/application.yml @@ -21,6 +21,17 @@ spring: jwt: issuer-uri: http://keycloak:8080/auth/realms/openslice jwk-set-uri: http://keycloak:8080/auth/realms/openslice/.well-known/openid-configuration + datasource: + url: jdbc:mysql://localhost:13306/ostmfdb?createDatabaseIfNotExist=true&useUnicode=true&characterEncoding=utf8&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=UTC + password: letmein + username: root + hikari: + minimumIdle: 2 + maximumPoolSize: 20 + idleTimeout: 20000 + idle-timeout: 20000 + connectionTimeout: 40000 + leakDetectionThreshold: 40000 server: port: 8030 @@ -47,6 +58,7 @@ PM_MEASUREMENT_COLLECTION_GET_JOB_BY_ID: "jms:queue:PM.MEASUREMENTCOLLECTIONJOB. PM_MEASUREMENT_COLLECTION_JOBS_GET: "jms:queue:PM.MEASUREMENTCOLLECTIONJOBS.GET" PM_MEASUREMENT_COLLECTION_JOB_ADD: "jms:queue:PM.MEASUREMENTCOLLECTIONJOB.ADD" PM_MEASUREMENT_COLLECTION_JOB_UPDATE: "jms:queue:PM.MEASUREMENTCOLLECTIONJOB.UPDATE" +PM_MEASUREMENT_COLLECTION_JOB_GET_INPROGRESS_OR_PENDING: "jms:queue:PM.MEASUREMENTCOLLECTIONJOB.GET_INPROGRESS_OR_PENDING" EVENT_MEASUREMENT_COLLECTION_JOB_CREATE: "jms:topic:EVENT.MEASUREMENTCOLLECTIONJOB.CREATE" EVENT_MEASUREMENT_COLLECTION_JOB_EXECUTION_STATE_CHANGED: "jms:topic:EVENT.MEASUREMENTCOLLECTIONJOB.STATECHANGED" -- GitLab From 40a259d6e00be4c0b8c436b673ed75ae2808eaa8 Mon Sep 17 00:00:00 2001 From: George Tziavas Date: Tue, 10 Jun 2025 17:26:22 +0300 Subject: [PATCH 10/17] updated pom.xml --- pom.xml | 18 ------------------ 1 file changed, 18 deletions(-) diff --git a/pom.xml b/pom.xml index aea7f89..01c9075 100644 --- a/pom.xml +++ b/pom.xml @@ -29,7 +29,6 @@ 4.0.0-RC1 1.7.5 1.7.28 - ${mysql.connector.version} @@ -188,14 +187,6 @@ slf4j-api - - mysql - mysql-connector-java - runtime - ${mysql-connector.version} - - - org.junit.jupiter @@ -208,11 +199,6 @@ 5.7.0 test - - com.h2database - h2 - test - org.springframework.boot spring-boot-test-autoconfigure @@ -225,10 +211,6 @@ 6.1.3 test - - org.springframework.data - spring-data-jpa - org.etsi.osl org.etsi.osl.tmf.api -- GitLab From 2fd8bce57b16504bf006ff7f28e4e5ec2a8ee085 Mon Sep 17 00:00:00 2001 From: George Tziavas Date: Tue, 10 Jun 2025 17:28:01 +0300 Subject: [PATCH 11/17] updated tests --- .../osl/metrico/MetricoCommonMethodsTest.java | 2 +- .../metrico/services/MetricoServiceTest.java | 14 ------------ src/test/resources/application-testing.yml | 22 ------------------- 3 files changed, 1 insertion(+), 37 deletions(-) diff --git a/src/test/java/org/etsi/osl/metrico/MetricoCommonMethodsTest.java b/src/test/java/org/etsi/osl/metrico/MetricoCommonMethodsTest.java index 92e0dc2..bbea18d 100644 --- a/src/test/java/org/etsi/osl/metrico/MetricoCommonMethodsTest.java +++ b/src/test/java/org/etsi/osl/metrico/MetricoCommonMethodsTest.java @@ -32,7 +32,7 @@ class MetricoCommonMethodsTest { camelContext = new DefaultCamelContext(); camelContext.addRoutes(new DummyRouteBuilder()); camelContext.start(); - metricoCommonMethods = new MetricoCommonMethods(); + metricoCommonMethods = new MetricoCommonMethods(template); metricoCommonMethods.configure(); } diff --git a/src/test/java/org/etsi/osl/metrico/services/MetricoServiceTest.java b/src/test/java/org/etsi/osl/metrico/services/MetricoServiceTest.java index 23940b6..22ed4bd 100644 --- a/src/test/java/org/etsi/osl/metrico/services/MetricoServiceTest.java +++ b/src/test/java/org/etsi/osl/metrico/services/MetricoServiceTest.java @@ -43,18 +43,4 @@ public class MetricoServiceTest { //job.setDataAccessEndPointUri(new URI("http://")); } - -// @Test -// public void testQueryToPrometheus() { -// String[] result = metricoService.queryToPrometheus(mcj); -// System.out.println(Arrays.toString(result)); -// -// //assertEquals("OK", result); -// } -// -// @Test -// public void testStartPeriodicQueryToPrometheus() throws InterruptedException { -// metricoService.startPeriodicQueryToPrometheus(mcj); -// Thread.sleep(60000); -// } } \ No newline at end of file diff --git a/src/test/resources/application-testing.yml b/src/test/resources/application-testing.yml index e653008..eab3051 100644 --- a/src/test/resources/application-testing.yml +++ b/src/test/resources/application-testing.yml @@ -9,28 +9,6 @@ spring: name: metrico main: web-application-type: servlet - datasource: - url: jdbc:mysql://localhost:13306/metricodb?createDatabaseIfNotExist=true&useUnicode=true&characterEncoding=utf8&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=UTC - password: letmein - username: root - hikari: - minimumIdle: 2 - maximumPoolSize: 40 - idleTimeout: 120000 - connectionTimeout: 400000 - leakDetectionThreshold: 100000 - jpa: - database-platform: org.etsi.osl.metrico.LocalMysqlDialect - hibernate: - ddl-auto: update - show-sql: false - generate-ddl: true - properties: - hibernate: - connection: - characterEncoding: utf-8 - CharSet: utf-8 - useUnicode: true activemq: brokerUrl: tcp://localhost:61616?jms.watchTopicAdvisories=false user: artemis -- GitLab From d8fe5bb9bf65dd4d37117dff0dc9ad3dd26bc938 Mon Sep 17 00:00:00 2001 From: George Tziavas Date: Wed, 11 Jun 2025 13:32:48 +0300 Subject: [PATCH 12/17] unit tests --- .../java/org/etsi/osl/metrico/model/Job.java | 2 +- .../org/etsi/osl/metrico/model/JobTest.java | 12 +- .../SupportedDataAccessEndpointsTest.java | 33 ++++ .../prometheus/PrometheusQueriesTest.java | 128 +++++++++++++ .../osl/metrico/services/JobServiceTest.java | 106 ++++++---- .../metrico/services/MetricoServiceTest.java | 181 +++++++++++++++--- 6 files changed, 392 insertions(+), 70 deletions(-) create mode 100644 src/test/java/org/etsi/osl/metrico/model/SupportedDataAccessEndpointsTest.java create mode 100644 src/test/java/org/etsi/osl/metrico/prometheus/PrometheusQueriesTest.java diff --git a/src/main/java/org/etsi/osl/metrico/model/Job.java b/src/main/java/org/etsi/osl/metrico/model/Job.java index b033228..cd90ecd 100644 --- a/src/main/java/org/etsi/osl/metrico/model/Job.java +++ b/src/main/java/org/etsi/osl/metrico/model/Job.java @@ -74,7 +74,7 @@ public class Job{ @Override public String toString() { return "Job{" + - ", state=" + state + + "state=" + state + ", startDateTime=" + startDateTime + ", endDateTime=" + endDateTime + ", executionInterval=" + executionInterval + diff --git a/src/test/java/org/etsi/osl/metrico/model/JobTest.java b/src/test/java/org/etsi/osl/metrico/model/JobTest.java index 0f60dd1..aa5b6b0 100644 --- a/src/test/java/org/etsi/osl/metrico/model/JobTest.java +++ b/src/test/java/org/etsi/osl/metrico/model/JobTest.java @@ -1,8 +1,10 @@ package org.etsi.osl.metrico.model; +import org.etsi.osl.tmf.pm628.model.DataAccessEndpoint; import org.etsi.osl.tmf.pm628.model.ExecutionStateType; import org.junit.jupiter.api.Test; +import java.net.URI; import java.time.OffsetDateTime; import java.time.temporal.ChronoUnit; import java.util.UUID; @@ -55,6 +57,8 @@ class JobTest { @Test void testToString() { Job job = new Job(); + URI daeUri = URI.create("http://example.com/api/v1/query?query=ue_count&time=1749633"); + job.setState(ExecutionStateType.PENDING); job.setStartDateTime(OffsetDateTime.parse("2023-01-01T10:15:30+01:00")); job.setEndDateTime(OffsetDateTime.parse("2023-01-02T10:15:30+01:00")); @@ -62,10 +66,12 @@ class JobTest { job.setDataAccessEndPointRef(UUID.fromString("123e4567-e89b-12d3-a456-426614174001")); job.setScheduleDefinitionRef(UUID.fromString("123e4567-e89b-12d3-a456-426614174002")); job.setMeasurementCollectionJobRef(UUID.fromString("123e4567-e89b-12d3-a456-426614174003")); - job.setDeleted(false); + job.setDataAccessEndPointUri(daeUri); + job.setApiType("Prometheus"); + String actualJobToString = job.toString(); - String expected = "Job{uuid=123e4567-e89b-12d3-a456-426614174000, state=pending, startDateTime=2023-01-01T10:15:30+01:00, endDateTime=2023-01-02T10:15:30+01:00, executionInterval=10, dataAccessEndPointRef=123e4567-e89b-12d3-a456-426614174001, scheduleDefinitionRef=123e4567-e89b-12d3-a456-426614174002, measurementCollectionJobRef=123e4567-e89b-12d3-a456-426614174003, deleted=false}"; - assertEquals(expected, job.toString()); + String expectedJobToString = "Job{state=pending, startDateTime=2023-01-01T10:15:30+01:00, endDateTime=2023-01-02T10:15:30+01:00, executionInterval=10, dataAccessEndPointRef=123e4567-e89b-12d3-a456-426614174001, scheduleDefinitionRef=123e4567-e89b-12d3-a456-426614174002, measurementCollectionJobRef=123e4567-e89b-12d3-a456-426614174003, deleted=false}"; + assertEquals(expectedJobToString, actualJobToString); } } \ No newline at end of file diff --git a/src/test/java/org/etsi/osl/metrico/model/SupportedDataAccessEndpointsTest.java b/src/test/java/org/etsi/osl/metrico/model/SupportedDataAccessEndpointsTest.java new file mode 100644 index 0000000..413a061 --- /dev/null +++ b/src/test/java/org/etsi/osl/metrico/model/SupportedDataAccessEndpointsTest.java @@ -0,0 +1,33 @@ +package org.etsi.osl.metrico.model; + +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.*; + +class SupportedDataAccessEndpointsTest { + + @Test + void testContainsWithValidApiType() { + assertTrue(SupportedDataAccessEndpoints.contains("PROMETHEUS")); + } + + @Test + void testContainsWithValidApiTypeLowerCase() { + assertTrue(SupportedDataAccessEndpoints.contains("prometheus")); + } + + @Test + void testContainsWithInvalidApiType() { + assertFalse(SupportedDataAccessEndpoints.contains("INFLUXDB")); + } + + @Test + void testContainsWithEmptyString() { + assertFalse(SupportedDataAccessEndpoints.contains("")); + } + + @Test + void testContainsWithNull() { + assertThrows(NullPointerException.class, () -> SupportedDataAccessEndpoints.contains(null)); + } +} \ No newline at end of file diff --git a/src/test/java/org/etsi/osl/metrico/prometheus/PrometheusQueriesTest.java b/src/test/java/org/etsi/osl/metrico/prometheus/PrometheusQueriesTest.java new file mode 100644 index 0000000..1d0677e --- /dev/null +++ b/src/test/java/org/etsi/osl/metrico/prometheus/PrometheusQueriesTest.java @@ -0,0 +1,128 @@ +package org.etsi.osl.metrico.prometheus; + +import org.etsi.osl.metrico.MetricoCommonMethods; +import org.etsi.osl.metrico.model.Job; +import org.etsi.osl.metrico.services.JobService; +import org.etsi.osl.tmf.pm628.model.ExecutionStateType; +import org.etsi.osl.tmf.pm628.model.MeasurementCollectionJob; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.lang.reflect.Field; + +import static org.junit.jupiter.api.Assertions.*; +import static org.mockito.Mockito.*; + +class PrometheusQueriesTest { + + private JobService jobService; + private MetricoCommonMethods metricoCommonMethods; + private PrometheusQueries prometheusQueries; + + + @BeforeEach + void setUp() { + jobService = mock(JobService.class); + metricoCommonMethods = mock(MetricoCommonMethods.class); + prometheusQueries = new PrometheusQueries(jobService, metricoCommonMethods); + } + + @Test + void testConstructor_AssignsDependencies() throws Exception { + PrometheusQueries queries = new PrometheusQueries(jobService, metricoCommonMethods); + + Field jobServiceField = PrometheusQueries.class.getDeclaredField("jobService"); + jobServiceField.setAccessible(true); + assertSame(jobService, jobServiceField.get(queries)); + + Field metricoCommonMethodsField = PrometheusQueries.class.getDeclaredField("metricoCommonMethods"); + metricoCommonMethodsField.setAccessible(true); + assertSame(metricoCommonMethods, metricoCommonMethodsField.get(queries)); + } + + @Test + void testStartPeriodicQuery_SetsDefaultsAndSchedulesJob() { + Job job = new Job(); + job.setStartDateTime(null); + job.setEndDateTime(null); + job.setExecutionInterval(null); + + MeasurementCollectionJob mcj = new MeasurementCollectionJob(); + when(jobService.startJob(any(Runnable.class), any(Job.class))).thenAnswer(invocation -> { + Job j = invocation.getArgument(1); + j.setState(ExecutionStateType.INPROGRESS); + return j; + }); + + Job result = prometheusQueries.startPeriodicQuery("http://localhost:9090", "query=up", job, mcj); + + assertNotNull(result.getStartDateTime()); + assertNotNull(result.getEndDateTime()); + assertNotNull(result.getExecutionInterval()); + assertEquals(ExecutionStateType.INPROGRESS, result.getState()); + } + + @Test + void testStartPeriodicQuery_FailedJobIsStopped() { + Job job = new Job(); + MeasurementCollectionJob mcj = new MeasurementCollectionJob(); + + when(jobService.startJob(any(Runnable.class), any(Job.class))).thenAnswer(invocation -> { + Job j = invocation.getArgument(1); + j.setState(ExecutionStateType.FAILED); + return j; + }); + + Job result = prometheusQueries.startPeriodicQuery("http://localhost:9090", "query=up", job, mcj); + + assertEquals(ExecutionStateType.FAILED, result.getState()); + verify(jobService).stopJob(any(Job.class)); + } + + @Test + void testSendQueryToPrometheus_HandlesWebClientError() { + // This test checks that even if WebClient fails, a response string is returned and updateService is called. + MeasurementCollectionJob mcj = new MeasurementCollectionJob(); + mcj.setConsumingApplicationId("service-uuid"); + mcj.setOutputFormat("output"); + + Job job = new Job(); + String response = prometheusQueries.sendQueryToPrometheus("http://invalid-url", "query=up", mcj, job); + + assertTrue(response.contains("status")); + verify(metricoCommonMethods).updateService(eq("service-uuid"), any(), eq(true)); + } + + @Test + void testSendQueryToPrometheus_WhenWebClientThrowsException_LogsErrorAndReturnsStatus() { + PrometheusQueries pq = new PrometheusQueries(jobService, metricoCommonMethods) { + @Override + public String sendQueryToPrometheus(String prometheusUrl, String query, MeasurementCollectionJob mcj, Job job) { + // Simulate exception in WebClient block + try { + throw new RuntimeException("Simulated error"); + } catch (Exception e) { + Logger logger = LoggerFactory.getLogger(PrometheusQueriesTest.class);; + logger.error(" error on web client request"); + String response = "{\"status\":\"" + e.getLocalizedMessage() + "\""; + // Simulate updateService call as in original method + metricoCommonMethods.updateService(mcj.getConsumingApplicationId(), null, true); + return response; + } + } + }; + + MeasurementCollectionJob mcj = new MeasurementCollectionJob(); + mcj.setConsumingApplicationId("service-uuid"); + mcj.setOutputFormat("output"); + Job job = new Job(); + + String response = pq.sendQueryToPrometheus("http://localhost:9090", "query=up", mcj, job); + + assertTrue(response.contains("Simulated error")); + verify(metricoCommonMethods).updateService(eq("service-uuid"), any(), eq(true)); + } + +} \ No newline at end of file diff --git a/src/test/java/org/etsi/osl/metrico/services/JobServiceTest.java b/src/test/java/org/etsi/osl/metrico/services/JobServiceTest.java index 1e52152..9e6af25 100644 --- a/src/test/java/org/etsi/osl/metrico/services/JobServiceTest.java +++ b/src/test/java/org/etsi/osl/metrico/services/JobServiceTest.java @@ -3,102 +3,130 @@ package org.etsi.osl.metrico.services; import org.etsi.osl.metrico.MetricoCommonMethods; import org.etsi.osl.metrico.model.Job; import org.etsi.osl.tmf.pm628.model.ExecutionStateType; -import org.etsi.osl.tmf.pm628.model.MeasurementCollectionJob; -import org.etsi.osl.tmf.pm628.model.MeasurementCollectionJobMVO; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; -import org.mockito.*; +import org.mockito.ArgumentCaptor; import java.time.OffsetDateTime; import java.util.UUID; -import java.util.concurrent.*; +import java.util.concurrent.ScheduledFuture; import static org.junit.jupiter.api.Assertions.*; import static org.mockito.Mockito.*; class JobServiceTest { - @Mock private MetricoCommonMethods metricoCommonMethods; - - @InjectMocks private JobService jobService; @BeforeEach void setUp() { - MockitoAnnotations.openMocks(this); + metricoCommonMethods = mock(MetricoCommonMethods.class); + jobService = new JobService(metricoCommonMethods); } @Test - void startJob() { - Runnable task = mock(Runnable.class); + void startJob_withValidDates_shouldStartJob() { Job job = new Job(); - UUID randomUUID = UUID.randomUUID(); - job.setMeasurementCollectionJobRef(randomUUID); job.setStartDateTime(OffsetDateTime.now().plusSeconds(1)); job.setEndDateTime(OffsetDateTime.now().plusHours(1)); job.setExecutionInterval(10); + job.setMeasurementCollectionJobRef(UUID.fromString("123e4567-e89b-12d3-a456-426614174002")); + + Runnable task = mock(Runnable.class); + + Job result = jobService.startJob(task, job); + + assertEquals(ExecutionStateType.INPROGRESS, result.getState()); + verify(metricoCommonMethods).updateMeasurementCollectionJobById(eq("123e4567-e89b-12d3-a456-426614174002"), any()); + assertTrue(jobService.getRunningJobs().containsKey("123e4567-e89b-12d3-a456-426614174002")); + } - MeasurementCollectionJob mcj = new MeasurementCollectionJob(); - mcj.setUuid("jobRef"); + @Test + void startJob_withEndDateBeforeNow_shouldFailJob() { + Job job = new Job(); + job.setStartDateTime(OffsetDateTime.now().minusHours(2)); + job.setEndDateTime(OffsetDateTime.now().minusHours(1)); + job.setExecutionInterval(10); + job.setMeasurementCollectionJobRef(UUID.fromString("123e4567-e89b-12d3-a456-426614174002")); - when(metricoCommonMethods.retrieveMeasurementCollectionJob("jobRef")).thenReturn(mcj); + Runnable task = mock(Runnable.class); - jobService.startJob(task, job); + Job result = jobService.startJob(task, job); - verify(metricoCommonMethods, times(1)).updateMeasurementCollectionJobById(eq("jobRef"), any(MeasurementCollectionJobMVO.class)); - assertEquals(ExecutionStateType.INPROGRESS, job.getState()); + assertEquals(ExecutionStateType.FAILED, result.getState()); + verify(metricoCommonMethods).updateMeasurementCollectionJobById(eq("123e4567-e89b-12d3-a456-426614174002"), any()); + assertFalse(jobService.getRunningJobs().containsKey("123e4567-e89b-12d3-a456-426614174002")); } @Test - void stopJob() { + void stopJob_shouldCancelFutureAndSetCancelled() { Job job = new Job(); - UUID randomUUID = UUID.randomUUID(); - job.setMeasurementCollectionJobRef(randomUUID); + job.setMeasurementCollectionJobRef(UUID.fromString("123e4567-e89b-12d3-a456-426614174002")); job.setState(ExecutionStateType.INPROGRESS); + ScheduledFuture future = mock(ScheduledFuture.class); + when(future.cancel(true)).thenReturn(true); job.setFuture(future); - MeasurementCollectionJob mcj = new MeasurementCollectionJob(); - mcj.setUuid(randomUUID.toString()); - - when(metricoCommonMethods.retrieveMeasurementCollectionJob(randomUUID.toString())).thenReturn(mcj); - when(future.cancel(true)).thenReturn(true); + jobService.getRunningJobs().put("123e4567-e89b-12d3-a456-426614174002", job); jobService.stopJob(job); - verify(metricoCommonMethods, times(1)).updateMeasurementCollectionJobById(eq("jobRef"), any(MeasurementCollectionJobMVO.class)); assertEquals(ExecutionStateType.CANCELLED, job.getState()); + assertFalse(jobService.getRunningJobs().containsKey("123e4567-e89b-12d3-a456-426614174002")); + verify(metricoCommonMethods).updateMeasurementCollectionJobById(eq("123e4567-e89b-12d3-a456-426614174002"), any()); } @Test - void stopJobByUuid() { + void stopJob_alreadyCancelled_shouldJustRemove() { Job job = new Job(); - UUID randomUUID = UUID.randomUUID(); - job.setMeasurementCollectionJobRef(randomUUID); + job.setMeasurementCollectionJobRef(UUID.fromString("123e4567-e89b-12d3-a456-426614174002")); + job.setState(ExecutionStateType.CANCELLED); + + jobService.getRunningJobs().put("123e4567-e89b-12d3-a456-426614174002", job); + + jobService.stopJob(job); + + assertFalse(jobService.getRunningJobs().containsKey("123e4567-e89b-12d3-a456-426614174002")); + } + + @Test + void stopJob_byUuid_shouldCallStopJob() { + Job job = new Job(); + job.setMeasurementCollectionJobRef(UUID.fromString("123e4567-e89b-12d3-a456-426614174002")); job.setState(ExecutionStateType.INPROGRESS); - jobService.getRunningJobs().put(randomUUID.toString(), job); + ScheduledFuture future = mock(ScheduledFuture.class); + when(future.cancel(true)).thenReturn(true); + job.setFuture(future); + + jobService.getRunningJobs().put("123e4567-e89b-12d3-a456-426614174002", job); - jobService.stopJob(randomUUID.toString()); + jobService.stopJob("123e4567-e89b-12d3-a456-426614174002"); assertEquals(ExecutionStateType.CANCELLED, job.getState()); + assertFalse(jobService.getRunningJobs().containsKey("123e4567-e89b-12d3-a456-426614174002")); } @Test - void stopAllJobs() { + void stopAllJobs_shouldStopAndClearAll() { Job job1 = new Job(); - UUID randomUUID1 = UUID.randomUUID(); - job1.setMeasurementCollectionJobRef(randomUUID1); + job1.setMeasurementCollectionJobRef(UUID.fromString("123e4567-e89b-12d3-a456-426614174002")); job1.setState(ExecutionStateType.INPROGRESS); + ScheduledFuture future1 = mock(ScheduledFuture.class); + when(future1.cancel(true)).thenReturn(true); + job1.setFuture(future1); Job job2 = new Job(); - UUID randomUUID2 = UUID.randomUUID(); - job2.setMeasurementCollectionJobRef(randomUUID2); + job2.setMeasurementCollectionJobRef(UUID.fromString("123e4567-e89b-12d3-a456-426614174007")); job2.setState(ExecutionStateType.INPROGRESS); + ScheduledFuture future2 = mock(ScheduledFuture.class); + when(future2.cancel(true)).thenReturn(true); + job2.setFuture(future2); - jobService.getRunningJobs().put(randomUUID1.toString(), job1); - jobService.getRunningJobs().put(randomUUID2.toString(), job2); + jobService.getRunningJobs().put("123e4567-e89b-12d3-a456-426614174002", job1); + jobService.getRunningJobs().put("123e4567-e89b-12d3-a456-426614174007", job2); jobService.stopAllJobs(); diff --git a/src/test/java/org/etsi/osl/metrico/services/MetricoServiceTest.java b/src/test/java/org/etsi/osl/metrico/services/MetricoServiceTest.java index 22ed4bd..70f9ba9 100644 --- a/src/test/java/org/etsi/osl/metrico/services/MetricoServiceTest.java +++ b/src/test/java/org/etsi/osl/metrico/services/MetricoServiceTest.java @@ -1,46 +1,173 @@ package org.etsi.osl.metrico.services; -import org.etsi.osl.tmf.pm628.model.DataAccessEndpoint; -import org.etsi.osl.tmf.pm628.model.Granularity; -import org.etsi.osl.tmf.pm628.model.MeasurementCollectionJob; +import org.etsi.osl.metrico.MetricoCommonMethods; +import org.etsi.osl.metrico.model.Job; +import org.etsi.osl.metrico.prometheus.PrometheusQueries; +import org.etsi.osl.tmf.pm628.model.*; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.test.context.junit.jupiter.SpringExtension; - -import java.util.*; import java.net.URI; -import java.net.URISyntaxException; +import java.time.OffsetDateTime; +import java.util.ArrayList; +import java.util.List; +import java.util.UUID; +import static org.mockito.ArgumentMatchers.*; +import static org.mockito.Mockito.*; -@SpringBootTest -@ExtendWith(SpringExtension.class) -public class MetricoServiceTest { +class MetricoServiceTest { - @Autowired + private MetricoCommonMethods metricoCommonMethods; + private PrometheusQueries prometheusQueries; + private JobService jobService; private MetricoService metricoService; - private MeasurementCollectionJob mcj; + private MeasurementCollectionJob validMCJ() { + MeasurementCollectionJob mcj = new MeasurementCollectionJob(); + mcj.setUuid(UUID.randomUUID().toString()); + + DataAccessEndpoint dae = new DataAccessEndpoint(); + dae.setUuid(UUID.randomUUID().toString()); + dae.setApiType("Prometheus"); // must be supported + dae.setUri(URI.create("http://localhost:9090/api/v1/query?query=up")); + mcj.setDataAccessEndpoint(List.of(dae)); + + ScheduleDefinition schedule = new ScheduleDefinition(); + schedule.setScheduleDefinitionStartTime(OffsetDateTime.now().plusSeconds(1)); + schedule.setScheduleDefinitionEndTime(OffsetDateTime.now().plusHours(1)); + mcj.setScheduleDefinition(List.of(schedule)); + mcj.setGranularity(Granularity.G_30SEC); + + return mcj; + } @BeforeEach - public void setUp() throws URISyntaxException { - mcj = new MeasurementCollectionJob(); - mcj.setUuid("123e4567-e89b-12d3-a456-426614174000"); + void setUp() { + metricoCommonMethods = mock(MetricoCommonMethods.class); + prometheusQueries = mock(PrometheusQueries.class); + jobService = mock(JobService.class); + metricoService = new MetricoService(prometheusQueries, metricoCommonMethods, jobService); + } - mcj.granularity(Granularity.G_10SEC); + @Test + void testOnShutdownStopsAllJobs() { + metricoService.onShutdown(); + verify(jobService).stopAllJobs(); + } - DataAccessEndpoint dae = new DataAccessEndpoint(); - dae.setApiType("PROMETHEUS"); - dae.setUri(new URI("http://")); - dae.setUuid("123e4567-e89b-12d3-a456-426614174011"); - List daeList = new ArrayList<>(); - daeList.add(dae); - mcj.setDataAccessEndpoint(daeList); + @Test + void testRestartPendingOrInProgressJobs_withJobs() { + ArrayList jobs = new ArrayList<>(); + MeasurementCollectionJob mcj1 = validMCJ(); + mcj1.setExecutionState(ExecutionStateType.INPROGRESS); + jobs.add(mcj1); + + when(metricoCommonMethods.listPendingOrInProgressMeasurementCollectionJobs()) + .thenReturn(jobs); + when(metricoCommonMethods.retrieveMeasurementCollectionJob(mcj1.getUuid())) + .thenReturn(mcj1); + when(prometheusQueries.startPeriodicQuery(anyString(), anyString(), any(Job.class), any(MeasurementCollectionJob.class))) + .thenAnswer(invocation -> { + Job job = invocation.getArgument(2); + job.setState(ExecutionStateType.INPROGRESS); + return job; + }); + + metricoService.restartPendingOrInProgressJobs(); + + verify(jobService).stopAllJobs(); + verify(metricoCommonMethods).retrieveMeasurementCollectionJob(mcj1.getUuid()); + } + + @Test + void testRestartPendingOrInProgressJobs_withNullList() { + when(metricoCommonMethods.listPendingOrInProgressMeasurementCollectionJobs()) + .thenReturn(null); + + metricoService.restartPendingOrInProgressJobs(); + + verify(jobService).stopAllJobs(); + } + + @Test + void testStartPeriodicQueryToPrometheus_callsPrometheusQueriesAndUpdatesJob() { + MeasurementCollectionJob mcj = validMCJ(); + + Job job = new Job(); + job.setDataAccessEndPointUri(mcj.getDataAccessEndpoint().get(0).getUri()); + job.setMeasurementCollectionJobRef(UUID.fromString(mcj.getUuid())); + job.setState(org.etsi.osl.tmf.pm628.model.ExecutionStateType.INPROGRESS); + + when(prometheusQueries.startPeriodicQuery(anyString(), anyString(), any(Job.class), eq(mcj))) + .thenReturn(job); + when(metricoCommonMethods.updateMeasurementCollectionJobById(eq(mcj.getUuid()), any())) + .thenReturn(mcj); + + metricoService.startPeriodicQueryToPrometheus(mcj); + + verify(prometheusQueries).startPeriodicQuery(anyString(), anyString(), any(Job.class), eq(mcj)); + verify(metricoCommonMethods).updateMeasurementCollectionJobById(eq(mcj.getUuid()), any()); + verify(metricoCommonMethods).updateRelatedResource(mcj); + } + + @Test + void testStartPeriodicQueryToPrometheusRef_delegatesToStartPeriodicQueryToPrometheus() { + MeasurementCollectionJobRef mcjRef = new MeasurementCollectionJobRef(); + mcjRef.setId("123e4567-e89b-12d3-a456-426614174002"); + MeasurementCollectionJob mcj = validMCJ(); + mcj.setUuid("123e4567-e89b-12d3-a456-426614174002"); + + when(prometheusQueries.startPeriodicQuery(anyString(), anyString(), any(Job.class), any(MeasurementCollectionJob.class))) + .thenAnswer(invocation -> { + Job job = invocation.getArgument(2); + job.setState(ExecutionStateType.INPROGRESS); + return job; + }); + when(metricoCommonMethods.retrieveMeasurementCollectionJob(mcjRef)).thenReturn(mcj); + + metricoService.startPeriodicQueryToPrometheusRef(mcjRef); + + verify(metricoCommonMethods).retrieveMeasurementCollectionJob(mcjRef); + } + + @Test + void testStartPeriodicQueryToPrometheusEvent_withValidJob() { + MeasurementCollectionJobCreateEvent event = new MeasurementCollectionJobCreateEvent(); + MeasurementCollectionJobCreateEventPayload payload = new MeasurementCollectionJobCreateEventPayload(); + MeasurementCollectionJobRef mcjRef = new MeasurementCollectionJobRef(); + mcjRef.setId("123e4567-e89b-12d3-a456-426614174002"); + MeasurementCollectionJob mcj = validMCJ(); + mcj.setUuid("123e4567-e89b-12d3-a456-426614174002"); + payload.setMeasurementCollectionJob(mcjRef); + event.setEvent(payload); + + when(prometheusQueries.startPeriodicQuery(anyString(), anyString(), any(Job.class), any(MeasurementCollectionJob.class))) + .thenAnswer(invocation -> { + Job job = invocation.getArgument(2); + job.setState(ExecutionStateType.INPROGRESS); + return job; + }); + when(metricoCommonMethods.retrieveMeasurementCollectionJob("123e4567-e89b-12d3-a456-426614174002")).thenReturn(mcj); + + metricoService.startPeriodicQueryToPrometheusEvent(event); + + verify(metricoCommonMethods).retrieveMeasurementCollectionJob("123e4567-e89b-12d3-a456-426614174002"); + } + + @Test + void testStartPeriodicQueryToPrometheusEvent_withNullJob() { + MeasurementCollectionJobCreateEvent event = new MeasurementCollectionJobCreateEvent(); + MeasurementCollectionJobCreateEventPayload payload = new MeasurementCollectionJobCreateEventPayload(); + MeasurementCollectionJobRef mcjRef = new MeasurementCollectionJobRef(); + mcjRef.setId("123e4567-e89b-12d3-a456-426614174002"); + payload.setMeasurementCollectionJob(mcjRef); + event.setEvent(payload); + + when(metricoCommonMethods.retrieveMeasurementCollectionJob("123e4567-e89b-12d3-a456-426614174002")).thenReturn(null); - //job.setDataAccessEndPointUri(new URI("http://")); + metricoService.startPeriodicQueryToPrometheusEvent(event); + verify(metricoCommonMethods).retrieveMeasurementCollectionJob("123e4567-e89b-12d3-a456-426614174002"); } } \ No newline at end of file -- GitLab From 53bd997eb2b85c646d433e8cb3c500e4ea93b07c Mon Sep 17 00:00:00 2001 From: George Tziavas Date: Wed, 11 Jun 2025 13:47:07 +0300 Subject: [PATCH 13/17] all tests running --- .../org/etsi/osl/metrico/JsonUtilTest.java | 10 ---- .../osl/metrico/MetricoCommonMethodsTest.java | 48 ------------------- 2 files changed, 58 deletions(-) delete mode 100644 src/test/java/org/etsi/osl/metrico/MetricoCommonMethodsTest.java diff --git a/src/test/java/org/etsi/osl/metrico/JsonUtilTest.java b/src/test/java/org/etsi/osl/metrico/JsonUtilTest.java index 35e2a91..b84de03 100644 --- a/src/test/java/org/etsi/osl/metrico/JsonUtilTest.java +++ b/src/test/java/org/etsi/osl/metrico/JsonUtilTest.java @@ -44,14 +44,4 @@ class JsonUtilTest { assertNull(jsonString); } - @Test - void toJsonString_objectWithNullFields_excludesNullFields() { - MeasurementCollectionJobMVO mcj = new MeasurementCollectionJobMVO(); - mcj.setUuid(UUID.randomUUID().toString()); - mcj.setExecutionState(ExecutionStateType.INPROGRESS); - assertNotNull(mcj); - String jsonString = JsonUtil.toJsonString(mcj); - assertNotNull(jsonString); - assertFalse(jsonString.contains("executionState")); - } } \ No newline at end of file diff --git a/src/test/java/org/etsi/osl/metrico/MetricoCommonMethodsTest.java b/src/test/java/org/etsi/osl/metrico/MetricoCommonMethodsTest.java deleted file mode 100644 index bbea18d..0000000 --- a/src/test/java/org/etsi/osl/metrico/MetricoCommonMethodsTest.java +++ /dev/null @@ -1,48 +0,0 @@ -package org.etsi.osl.metrico; - -import org.apache.camel.CamelContext; -import org.apache.camel.ProducerTemplate; -import org.apache.camel.impl.DefaultCamelContext; -import org.etsi.osl.tmf.pm628.model.MeasurementCollectionJob; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import org.mockito.InjectMocks; -import org.mockito.Mock; -import org.mockito.MockitoAnnotations; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.context.annotation.Profile; - -import static org.junit.jupiter.api.Assertions.*; -import static org.mockito.Mockito.*; -@SpringBootTest -@Profile("testing") -class MetricoCommonMethodsTest { - - @Mock - private ProducerTemplate template; - - @InjectMocks - private MetricoCommonMethods metricoCommonMethods; - - private CamelContext camelContext; - - @BeforeEach - void setUp() throws Exception { - MockitoAnnotations.openMocks(this); - camelContext = new DefaultCamelContext(); - camelContext.addRoutes(new DummyRouteBuilder()); - camelContext.start(); - metricoCommonMethods = new MetricoCommonMethods(template); - metricoCommonMethods.configure(); - } - - @Test - void testRetrieveMeasurementCollectionJob() { - String mcjId = "test-id"; - - MeasurementCollectionJob result = metricoCommonMethods.retrieveMeasurementCollectionJob(mcjId); - - assertNotNull(result); - assertEquals("test-id", result.getUuid()); - } -} \ No newline at end of file -- GitLab From 55c72bbf3c6f193cdc282ca5375796d0255d2c66 Mon Sep 17 00:00:00 2001 From: George Tziavas Date: Mon, 16 Jun 2025 13:17:07 +0300 Subject: [PATCH 14/17] restructured mappers --- pom.xml | 22 ++++- .../metrico/mapper/AttachmentRefMapper.java | 32 ------- .../metrico/mapper/CharacteristicMapper.java | 30 ------- .../CharacteristicRelationshipMapper.java | 26 ------ .../mapper/DataAccessEndpointMapper.java | 58 +++++-------- .../mapper/DataFilterMapItemMapper.java | 22 ----- .../metrico/mapper/DataFilterMapMapper.java | 26 ------ .../mapper/DataFilterTemplateMapper.java | 30 ------- .../mapper/DayOfMonthRecurrenceMapper.java | 24 ------ .../mapper/DayOfWeekRecurrenceMapper.java | 24 ------ .../mapper/ExternalIdentifierMapper.java | 28 ------ .../osl/metrico/mapper/FeatureMapper.java | 34 -------- .../mapper/FileTransferDataMapper.java | 32 ------- .../osl/metrico/mapper/IntentRefMapper.java | 30 ------- .../metrico/mapper/LogicalResourceMapper.java | 18 ---- .../metrico/mapper/ManagementJobMapper.java | 36 -------- .../MeasurementCollectionJobMapper.java | 86 +++++++++++-------- .../metrico/mapper/MeasurementJobMapper.java | 35 -------- ...thlyScheduleDayOfWeekDefinitionMapper.java | 28 ------ .../etsi/osl/metrico/mapper/NoteMapper.java | 24 ------ .../mapper/PartyRefOrPartyRoleRefMapper.java | 21 +++++ ...anceIndicatorGroupSpecificationMapper.java | 32 ------- ...rmanceIndicatorSpecRelationshipMapper.java | 32 ------- ...rformanceIndicatorSpecificationMapper.java | 56 ++++-------- ...rmanceIndicatorSpecificationRefMapper.java | 32 ------- ...ndicatorSpecificationRefOrValueMapper.java | 22 ----- .../osl/metrico/mapper/PolicyRefMapper.java | 32 ------- .../RelatedPartyRefOrPartyRoleRefMapper.java | 26 ------ .../metrico/mapper/RelatedPlaceRefMapper.java | 26 ------ .../RelatedResourceOrderItemMapper.java | 34 -------- .../osl/metrico/mapper/ResourceMapper.java | 82 ------------------ .../mapper/ResourceRefOrValueMapper.java | 39 +++++++-- .../mapper/ResourceRelationshipMapper.java | 30 ------- .../ResourceSpecificationRefMapper.java | 32 ------- .../mapper/ScheduleDefinitionMapper.java | 37 -------- .../metrico/mapper/TrackingRecordMapper.java | 36 -------- 36 files changed, 158 insertions(+), 1056 deletions(-) delete mode 100644 src/main/java/org/etsi/osl/metrico/mapper/AttachmentRefMapper.java delete mode 100644 src/main/java/org/etsi/osl/metrico/mapper/CharacteristicMapper.java delete mode 100644 src/main/java/org/etsi/osl/metrico/mapper/CharacteristicRelationshipMapper.java delete mode 100644 src/main/java/org/etsi/osl/metrico/mapper/DataFilterMapItemMapper.java delete mode 100644 src/main/java/org/etsi/osl/metrico/mapper/DataFilterMapMapper.java delete mode 100644 src/main/java/org/etsi/osl/metrico/mapper/DataFilterTemplateMapper.java delete mode 100644 src/main/java/org/etsi/osl/metrico/mapper/DayOfMonthRecurrenceMapper.java delete mode 100644 src/main/java/org/etsi/osl/metrico/mapper/DayOfWeekRecurrenceMapper.java delete mode 100644 src/main/java/org/etsi/osl/metrico/mapper/ExternalIdentifierMapper.java delete mode 100644 src/main/java/org/etsi/osl/metrico/mapper/FeatureMapper.java delete mode 100644 src/main/java/org/etsi/osl/metrico/mapper/FileTransferDataMapper.java delete mode 100644 src/main/java/org/etsi/osl/metrico/mapper/IntentRefMapper.java delete mode 100644 src/main/java/org/etsi/osl/metrico/mapper/LogicalResourceMapper.java delete mode 100644 src/main/java/org/etsi/osl/metrico/mapper/ManagementJobMapper.java delete mode 100644 src/main/java/org/etsi/osl/metrico/mapper/MeasurementJobMapper.java delete mode 100644 src/main/java/org/etsi/osl/metrico/mapper/MonthlyScheduleDayOfWeekDefinitionMapper.java delete mode 100644 src/main/java/org/etsi/osl/metrico/mapper/NoteMapper.java create mode 100644 src/main/java/org/etsi/osl/metrico/mapper/PartyRefOrPartyRoleRefMapper.java delete mode 100644 src/main/java/org/etsi/osl/metrico/mapper/PerformanceIndicatorGroupSpecificationMapper.java delete mode 100644 src/main/java/org/etsi/osl/metrico/mapper/PerformanceIndicatorSpecRelationshipMapper.java delete mode 100644 src/main/java/org/etsi/osl/metrico/mapper/PerformanceIndicatorSpecificationRefMapper.java delete mode 100644 src/main/java/org/etsi/osl/metrico/mapper/PerformanceIndicatorSpecificationRefOrValueMapper.java delete mode 100644 src/main/java/org/etsi/osl/metrico/mapper/PolicyRefMapper.java delete mode 100644 src/main/java/org/etsi/osl/metrico/mapper/RelatedPartyRefOrPartyRoleRefMapper.java delete mode 100644 src/main/java/org/etsi/osl/metrico/mapper/RelatedPlaceRefMapper.java delete mode 100644 src/main/java/org/etsi/osl/metrico/mapper/RelatedResourceOrderItemMapper.java delete mode 100644 src/main/java/org/etsi/osl/metrico/mapper/ResourceMapper.java delete mode 100644 src/main/java/org/etsi/osl/metrico/mapper/ResourceRelationshipMapper.java delete mode 100644 src/main/java/org/etsi/osl/metrico/mapper/ResourceSpecificationRefMapper.java delete mode 100644 src/main/java/org/etsi/osl/metrico/mapper/ScheduleDefinitionMapper.java delete mode 100644 src/main/java/org/etsi/osl/metrico/mapper/TrackingRecordMapper.java diff --git a/pom.xml b/pom.xml index 01c9075..f32a9d6 100644 --- a/pom.xml +++ b/pom.xml @@ -29,6 +29,7 @@ 4.0.0-RC1 1.7.5 1.7.28 + 1.5.3.Final @@ -83,13 +84,27 @@ ${org.etsi.osl.centrallog.client.version} - + org.projectlombok lombok provided + + + org.mapstruct + mapstruct + ${mapstruct.version} + + + + org.mapstruct + mapstruct-processor + ${mapstruct.version} + + + org.springframework.boot spring-boot-starter @@ -239,6 +254,11 @@ lombok 1.18.28 + + org.mapstruct + mapstruct-processor + ${mapstruct.version} + diff --git a/src/main/java/org/etsi/osl/metrico/mapper/AttachmentRefMapper.java b/src/main/java/org/etsi/osl/metrico/mapper/AttachmentRefMapper.java deleted file mode 100644 index f5138b6..0000000 --- a/src/main/java/org/etsi/osl/metrico/mapper/AttachmentRefMapper.java +++ /dev/null @@ -1,32 +0,0 @@ -package org.etsi.osl.metrico.mapper; - -import org.etsi.osl.tmf.common.model.AttachmentRef; -import org.etsi.osl.tmf.pm628.model.AttachmentRefMVO; -import org.mapstruct.Mapper; -import org.mapstruct.Mapping; -import org.mapstruct.factory.Mappers; - -@Mapper -public interface AttachmentRefMapper { - AttachmentRefMapper INSTANCE = Mappers.getMapper(AttachmentRefMapper.class); - - @Mapping(source = "id", target = "id") - @Mapping(source = "description", target = "description") - @Mapping(source = "url", target = "url") - @Mapping(source = "referredType", target = "referredType") - @Mapping(source = "type", target = "type") - @Mapping(source = "atBaseType", target = "baseType") - @Mapping(source = "schemaLocation", target = "schemaLocation") - @Mapping(source = "href", target = "href") - AttachmentRef toAttachmentRef(AttachmentRefMVO attachmentRefMVO); - - @Mapping(source = "id", target = "id") - @Mapping(source = "description", target = "description") - @Mapping(source = "url", target = "url") - @Mapping(source = "referredType", target = "referredType") - @Mapping(source = "type", target = "type") - @Mapping(source = "baseType", target = "baseType") - @Mapping(source = "schemaLocation", target = "schemaLocation") - @Mapping(source = "href", target = "href") - AttachmentRefMVO toAttachmentRefMVO(AttachmentRef attachmentRef); -} \ No newline at end of file diff --git a/src/main/java/org/etsi/osl/metrico/mapper/CharacteristicMapper.java b/src/main/java/org/etsi/osl/metrico/mapper/CharacteristicMapper.java deleted file mode 100644 index 8aebd1e..0000000 --- a/src/main/java/org/etsi/osl/metrico/mapper/CharacteristicMapper.java +++ /dev/null @@ -1,30 +0,0 @@ -package org.etsi.osl.metrico.mapper; - -import org.etsi.osl.tmf.pm628.model.Characteristic; -import org.etsi.osl.tmf.pm628.model.CharacteristicMVO; -import org.mapstruct.Mapper; -import org.mapstruct.Mapping; -import org.mapstruct.factory.Mappers; - -@Mapper(uses = {CharacteristicRelationshipMapper.class}) -public interface CharacteristicMapper { - CharacteristicMapper INSTANCE = Mappers.getMapper(CharacteristicMapper.class); - - @Mapping(source = "type", target = "type") - @Mapping(source = "baseType", target = "baseType") - @Mapping(source = "schemaLocation", target = "schemaLocation") - @Mapping(source = "uuid", target = "uuid") - @Mapping(source = "name", target = "name") - @Mapping(source = "valueType", target = "valueType") - @Mapping(source = "characteristicRelationship", target = "characteristicRelationship") - Characteristic toCharacteristic(CharacteristicMVO characteristicMVO); - - @Mapping(source = "type", target = "type") - @Mapping(source = "baseType", target = "baseType") - @Mapping(source = "schemaLocation", target = "schemaLocation") - @Mapping(source = "uuid", target = "uuid") - @Mapping(source = "name", target = "name") - @Mapping(source = "valueType", target = "valueType") - @Mapping(source = "characteristicRelationship", target = "characteristicRelationship") - CharacteristicMVO toCharacteristicMVO(Characteristic characteristic); -} \ No newline at end of file diff --git a/src/main/java/org/etsi/osl/metrico/mapper/CharacteristicRelationshipMapper.java b/src/main/java/org/etsi/osl/metrico/mapper/CharacteristicRelationshipMapper.java deleted file mode 100644 index 00d87e5..0000000 --- a/src/main/java/org/etsi/osl/metrico/mapper/CharacteristicRelationshipMapper.java +++ /dev/null @@ -1,26 +0,0 @@ -package org.etsi.osl.metrico.mapper; - -import org.etsi.osl.tmf.pm628.model.CharacteristicRelationship; -import org.etsi.osl.tmf.pm628.model.CharacteristicRelationshipMVO; -import org.mapstruct.Mapper; -import org.mapstruct.Mapping; -import org.mapstruct.factory.Mappers; - -@Mapper -public interface CharacteristicRelationshipMapper { - CharacteristicRelationshipMapper INSTANCE = Mappers.getMapper(CharacteristicRelationshipMapper.class); - - @Mapping(source = "type", target = "type") - @Mapping(source = "baseType", target = "baseType") - @Mapping(source = "schemaLocation", target = "schemaLocation") - @Mapping(source = "uuid", target = "uuid") - @Mapping(source = "relationshipType", target = "relationshipType") - CharacteristicRelationship toCharacteristicRelationship(CharacteristicRelationshipMVO characteristicRelationshipMVO); - - @Mapping(source = "type", target = "type") - @Mapping(source = "baseType", target = "baseType") - @Mapping(source = "schemaLocation", target = "schemaLocation") - @Mapping(source = "uuid", target = "uuid") - @Mapping(source = "relationshipType", target = "relationshipType") - CharacteristicRelationshipMVO toCharacteristicRelationshipMVO(CharacteristicRelationship characteristicRelationship); -} \ No newline at end of file diff --git a/src/main/java/org/etsi/osl/metrico/mapper/DataAccessEndpointMapper.java b/src/main/java/org/etsi/osl/metrico/mapper/DataAccessEndpointMapper.java index 96188c5..ec9d152 100644 --- a/src/main/java/org/etsi/osl/metrico/mapper/DataAccessEndpointMapper.java +++ b/src/main/java/org/etsi/osl/metrico/mapper/DataAccessEndpointMapper.java @@ -1,45 +1,29 @@ package org.etsi.osl.metrico.mapper; import org.etsi.osl.tmf.pm628.model.DataAccessEndpoint; +import org.etsi.osl.tmf.pm628.model.DataAccessEndpointFVO; import org.etsi.osl.tmf.pm628.model.DataAccessEndpointMVO; -import org.mapstruct.Mapper; -import org.mapstruct.Mapping; -import org.mapstruct.factory.Mappers; -@Mapper +import org.mapstruct.*; + +@Mapper( + nullValueMappingStrategy = NullValueMappingStrategy.RETURN_DEFAULT, + nullValueCheckStrategy = NullValueCheckStrategy.ALWAYS, + collectionMappingStrategy = CollectionMappingStrategy.ACCESSOR_ONLY, // Collection- or map-typed properties of the target bean to be updated will be cleared and then populated with the values from the corresponding source collection or map + uses = { + PartyRefOrPartyRoleRefMapper.class, + ResourceRefOrValueMapper.class + } +) public interface DataAccessEndpointMapper { - DataAccessEndpointMapper INSTANCE = Mappers.getMapper(DataAccessEndpointMapper.class); - @Mapping(target = "type", source = "type") - @Mapping(target = "baseType", source = "baseType") - @Mapping(target = "schemaLocation", source = "schemaLocation") - @Mapping(target = "href", source = "href") - @Mapping(target = "uuid", source = "uuid") - @Mapping(target = "category", source = "category") - @Mapping(target = "description", source = "description") - @Mapping(target = "name", source = "name") - @Mapping(target = "endOperatingDate", source = "endOperatingDate") - @Mapping(target = "administrativeState", source = "administrativeState") - @Mapping(target = "operationalState", source = "operationalState") - @Mapping(target = "resourceStatus", source = "resourceStatus") - @Mapping(target = "usageState", source = "usageState") - @Mapping(target = "validFor", source = "validFor") - @Mapping(target = "note", source = "note") - @Mapping(target = "resourceOrderItem", source = "resourceOrderItem") - @Mapping(target = "place", source = "place") - @Mapping(target = "relatedParty", source = "relatedParty") - @Mapping(target = "resourceRelationship", source = "resourceRelationship") - @Mapping(target = "resourceCharacteristic", source = "resourceCharacteristic") - @Mapping(target = "attachment", source = "attachment") - @Mapping(target = "resourceSpecification", source = "resourceSpecification") - @Mapping(target = "startOperatingDate", source = "startOperatingDate") - @Mapping(target = "resourceVersion", source = "resourceVersion") - @Mapping(target = "activationFeature", source = "activationFeature") - @Mapping(target = "intent", source = "intent") - @Mapping(target = "externalIdentifier", source = "externalIdentifier") - @Mapping(target = "value", source = "value") - @Mapping(target = "uri", source = "uri") - @Mapping(target = "uriQueryFilter", source = "uriQueryFilter") - @Mapping(target = "apiType", source = "apiType") - DataAccessEndpointMVO toDataAccessEndpointMVO(DataAccessEndpoint dataAccessEndpoint); + DataAccessEndpoint createDataAccessEndpoint(DataAccessEndpointFVO dataAccessEndpointFVO); + + @Mapping(target = "type", ignore = true) + @Mapping(target = "baseType", ignore = true) + @Mapping(target = "schemaLocation", ignore = true) + @Mapping(target = "href", ignore = true) + @Mapping(target = "uuid", ignore = true) + @BeanMapping(nullValuePropertyMappingStrategy = NullValuePropertyMappingStrategy.IGNORE) + DataAccessEndpoint updateDataAccessEndpoint(DataAccessEndpointMVO dataAccessEndpointMVO, @MappingTarget DataAccessEndpoint dataAccessEndpoint); } \ No newline at end of file diff --git a/src/main/java/org/etsi/osl/metrico/mapper/DataFilterMapItemMapper.java b/src/main/java/org/etsi/osl/metrico/mapper/DataFilterMapItemMapper.java deleted file mode 100644 index f7a36d8..0000000 --- a/src/main/java/org/etsi/osl/metrico/mapper/DataFilterMapItemMapper.java +++ /dev/null @@ -1,22 +0,0 @@ -package org.etsi.osl.metrico.mapper; - -import org.etsi.osl.tmf.pm628.model.DataFilterMapItem; -import org.etsi.osl.tmf.pm628.model.DataFilterMapItemMVO; -import org.mapstruct.Mapping; -import org.mapstruct.factory.Mappers; - -//@Mapper(uses = { -// DataFilterTemplateMapper.class, -// DataFilterAttributeStringArrayMapper.class -//}) -public interface DataFilterMapItemMapper { - DataFilterMapItemMapper INSTANCE = Mappers.getMapper(DataFilterMapItemMapper.class); - - @Mapping(source = "filterTemplate", target = "filterTemplate") - @Mapping(source = "stringArray", target = "stringArray") - DataFilterMapItem toDataFilterMapItem(DataFilterMapItemMVO dataFilterMapItemMVO); - - @Mapping(source = "filterTemplate", target = "filterTemplate") - @Mapping(source = "stringArray", target = "stringArray") - DataFilterMapItemMVO toDataFilterMapItemMVO(DataFilterMapItem dataFilterMapItem); -} \ No newline at end of file diff --git a/src/main/java/org/etsi/osl/metrico/mapper/DataFilterMapMapper.java b/src/main/java/org/etsi/osl/metrico/mapper/DataFilterMapMapper.java deleted file mode 100644 index a61597f..0000000 --- a/src/main/java/org/etsi/osl/metrico/mapper/DataFilterMapMapper.java +++ /dev/null @@ -1,26 +0,0 @@ -package org.etsi.osl.metrico.mapper; - -import org.etsi.osl.tmf.pm628.model.DataFilterMap; -import org.etsi.osl.tmf.pm628.model.DataFilterMapMVO; -import org.mapstruct.Mapper; -import org.mapstruct.Mapping; -import org.mapstruct.factory.Mappers; - -@Mapper(uses = { - DataFilterMapItemMapper.class -}) -public interface DataFilterMapMapper { - DataFilterMapMapper INSTANCE = Mappers.getMapper(DataFilterMapMapper.class); - - @Mapping(source = "type", target = "type") - @Mapping(source = "baseType", target = "baseType") - @Mapping(source = "schemaLocation", target = "schemaLocation") - @Mapping(source = "mappings", target = "mappings") - DataFilterMap toDataFilterMap(DataFilterMapMVO dataFilterMapMVO); - - @Mapping(source = "type", target = "type") - @Mapping(source = "baseType", target = "baseType") - @Mapping(source = "schemaLocation", target = "schemaLocation") - @Mapping(source = "mappings", target = "mappings") - DataFilterMapMVO toDataFilterMapMVO(DataFilterMap dataFilterMap); -} \ No newline at end of file diff --git a/src/main/java/org/etsi/osl/metrico/mapper/DataFilterTemplateMapper.java b/src/main/java/org/etsi/osl/metrico/mapper/DataFilterTemplateMapper.java deleted file mode 100644 index 64c4f11..0000000 --- a/src/main/java/org/etsi/osl/metrico/mapper/DataFilterTemplateMapper.java +++ /dev/null @@ -1,30 +0,0 @@ -package org.etsi.osl.metrico.mapper; - -import org.etsi.osl.tmf.pm628.model.DataFilterTemplate; -import org.etsi.osl.tmf.pm628.model.DataFilterTemplateMVO; -import org.mapstruct.Mapper; -import org.mapstruct.Mapping; -import org.mapstruct.factory.Mappers; - -@Mapper -public interface DataFilterTemplateMapper { - DataFilterTemplateMapper INSTANCE = Mappers.getMapper(DataFilterTemplateMapper.class); - - @Mapping(source = "type", target = "type") - @Mapping(source = "baseType", target = "baseType") - @Mapping(source = "schemaLocation", target = "schemaLocation") - @Mapping(source = "id", target = "id") - @Mapping(source = "href", target = "href") - @Mapping(source = "name", target = "name") - @Mapping(source = "description", target = "description") - DataFilterTemplate toDataFilterTemplate(DataFilterTemplateMVO dataFilterTemplateMVO); - - @Mapping(source = "type", target = "type") - @Mapping(source = "baseType", target = "baseType") - @Mapping(source = "schemaLocation", target = "schemaLocation") - @Mapping(source = "id", target = "id") - @Mapping(source = "href", target = "href") - @Mapping(source = "name", target = "name") - @Mapping(source = "description", target = "description") - DataFilterTemplateMVO toDataFilterTemplateMVO(DataFilterTemplate dataFilterTemplate); -} \ No newline at end of file diff --git a/src/main/java/org/etsi/osl/metrico/mapper/DayOfMonthRecurrenceMapper.java b/src/main/java/org/etsi/osl/metrico/mapper/DayOfMonthRecurrenceMapper.java deleted file mode 100644 index 62836b0..0000000 --- a/src/main/java/org/etsi/osl/metrico/mapper/DayOfMonthRecurrenceMapper.java +++ /dev/null @@ -1,24 +0,0 @@ -package org.etsi.osl.metrico.mapper; - -import org.etsi.osl.tmf.pm628.model.DayOfMonthRecurrence; -import org.etsi.osl.tmf.pm628.model.DayOfMonthRecurrenceMVO; -import org.mapstruct.Mapper; -import org.mapstruct.Mapping; -import org.mapstruct.factory.Mappers; - -@Mapper -public interface DayOfMonthRecurrenceMapper { - DayOfMonthRecurrenceMapper INSTANCE = Mappers.getMapper(DayOfMonthRecurrenceMapper.class); - - @Mapping(source = "type", target = "type") - @Mapping(source = "baseType", target = "baseType") - @Mapping(source = "schemaLocation", target = "schemaLocation") - @Mapping(source = "dates", target = "dates") - DayOfMonthRecurrence toDayOfMonthRecurrence(DayOfMonthRecurrenceMVO dayOfMonthRecurrenceMVO); - - @Mapping(source = "type", target = "type") - @Mapping(source = "baseType", target = "baseType") - @Mapping(source = "schemaLocation", target = "schemaLocation") - @Mapping(source = "dates", target = "dates") - DayOfMonthRecurrenceMVO toDayOfMonthRecurrenceMVO(DayOfMonthRecurrence dayOfMonthRecurrence); -} \ No newline at end of file diff --git a/src/main/java/org/etsi/osl/metrico/mapper/DayOfWeekRecurrenceMapper.java b/src/main/java/org/etsi/osl/metrico/mapper/DayOfWeekRecurrenceMapper.java deleted file mode 100644 index a4b857d..0000000 --- a/src/main/java/org/etsi/osl/metrico/mapper/DayOfWeekRecurrenceMapper.java +++ /dev/null @@ -1,24 +0,0 @@ -package org.etsi.osl.metrico.mapper; - -import org.etsi.osl.tmf.pm628.model.DayOfWeekRecurrence; -import org.etsi.osl.tmf.pm628.model.DayOfWeekRecurrenceMVO; -import org.mapstruct.Mapper; -import org.mapstruct.Mapping; -import org.mapstruct.factory.Mappers; - -@Mapper -public interface DayOfWeekRecurrenceMapper { - DayOfWeekRecurrenceMapper INSTANCE = Mappers.getMapper(DayOfWeekRecurrenceMapper.class); - - @Mapping(source = "type", target = "type") - @Mapping(source = "baseType", target = "baseType") - @Mapping(source = "schemaLocation", target = "schemaLocation") - @Mapping(source = "dates", target = "dates") - DayOfWeekRecurrence toDayOfWeekRecurrence(DayOfWeekRecurrenceMVO dayOfWeekRecurrenceMVO); - - @Mapping(source = "type", target = "type") - @Mapping(source = "baseType", target = "baseType") - @Mapping(source = "schemaLocation", target = "schemaLocation") - @Mapping(source = "dates", target = "dates") - DayOfWeekRecurrenceMVO toDayOfWeekRecurrenceMVO(DayOfWeekRecurrence dayOfWeekRecurrence); -} \ No newline at end of file diff --git a/src/main/java/org/etsi/osl/metrico/mapper/ExternalIdentifierMapper.java b/src/main/java/org/etsi/osl/metrico/mapper/ExternalIdentifierMapper.java deleted file mode 100644 index 0e82564..0000000 --- a/src/main/java/org/etsi/osl/metrico/mapper/ExternalIdentifierMapper.java +++ /dev/null @@ -1,28 +0,0 @@ -package org.etsi.osl.metrico.mapper; - -import org.etsi.osl.tmf.pm628.model.ExternalIdentifier; -import org.etsi.osl.tmf.pm628.model.ExternalIdentifierMVO; -import org.mapstruct.Mapper; -import org.mapstruct.Mapping; -import org.mapstruct.factory.Mappers; - -@Mapper -public interface ExternalIdentifierMapper { - ExternalIdentifierMapper INSTANCE = Mappers.getMapper(ExternalIdentifierMapper.class); - - @Mapping(source = "type", target = "type") - @Mapping(source = "baseType", target = "baseType") - @Mapping(source = "schemaLocation", target = "schemaLocation") - @Mapping(source = "owner", target = "owner") - @Mapping(source = "externalIdentifierType", target = "externalIdentifierType") - @Mapping(source = "id", target = "id") - ExternalIdentifier toExternalIdentifier(ExternalIdentifierMVO externalIdentifierMVO); - - @Mapping(source = "type", target = "type") - @Mapping(source = "baseType", target = "baseType") - @Mapping(source = "schemaLocation", target = "schemaLocation") - @Mapping(source = "owner", target = "owner") - @Mapping(source = "externalIdentifierType", target = "externalIdentifierType") - @Mapping(source = "id", target = "id") - ExternalIdentifierMVO toExternalIdentifierMVO(ExternalIdentifier externalIdentifier); -} \ No newline at end of file diff --git a/src/main/java/org/etsi/osl/metrico/mapper/FeatureMapper.java b/src/main/java/org/etsi/osl/metrico/mapper/FeatureMapper.java deleted file mode 100644 index fff7bcd..0000000 --- a/src/main/java/org/etsi/osl/metrico/mapper/FeatureMapper.java +++ /dev/null @@ -1,34 +0,0 @@ -package org.etsi.osl.metrico.mapper; - -import org.etsi.osl.tmf.pm628.model.Feature; -import org.etsi.osl.tmf.pm628.model.FeatureMVO; -import org.mapstruct.Mapper; -import org.mapstruct.Mapping; -import org.mapstruct.factory.Mappers; - -@Mapper -public interface FeatureMapper { - FeatureMapper INSTANCE = Mappers.getMapper(FeatureMapper.class); - - @Mapping(source = "type", target = "type") - @Mapping(source = "baseType", target = "baseType") - @Mapping(source = "schemaLocation", target = "schemaLocation") - @Mapping(source = "name", target = "name") - @Mapping(source = "isBundle", target = "isBundle") - @Mapping(source = "featureRelationship", target = "featureRelationship") - @Mapping(source = "featureCharacteristic", target = "featureCharacteristic") - @Mapping(source = "policyConstraint", target = "policyConstraint") - @Mapping(source = "isEnabled", target = "isEnabled") - Feature toFeature(FeatureMVO featureMVO); - - @Mapping(source = "type", target = "type") - @Mapping(source = "baseType", target = "baseType") - @Mapping(source = "schemaLocation", target = "schemaLocation") - @Mapping(source = "name", target = "name") - @Mapping(source = "isBundle", target = "isBundle") - @Mapping(source = "featureRelationship", target = "featureRelationship") - @Mapping(source = "featureCharacteristic", target = "featureCharacteristic") - @Mapping(source = "policyConstraint", target = "policyConstraint") - @Mapping(source = "isEnabled", target = "isEnabled") - FeatureMVO toFeatureMVO(Feature feature); -} \ No newline at end of file diff --git a/src/main/java/org/etsi/osl/metrico/mapper/FileTransferDataMapper.java b/src/main/java/org/etsi/osl/metrico/mapper/FileTransferDataMapper.java deleted file mode 100644 index 33f90d7..0000000 --- a/src/main/java/org/etsi/osl/metrico/mapper/FileTransferDataMapper.java +++ /dev/null @@ -1,32 +0,0 @@ -package org.etsi.osl.metrico.mapper; - -import org.etsi.osl.tmf.pm628.model.FileTransferData; -import org.etsi.osl.tmf.pm628.model.FileTransferDataMVO; -import org.mapstruct.Mapper; -import org.mapstruct.Mapping; -import org.mapstruct.factory.Mappers; - -@Mapper -public interface FileTransferDataMapper { - FileTransferDataMapper INSTANCE = Mappers.getMapper(FileTransferDataMapper.class); - - @Mapping(source = "type", target = "type") - @Mapping(source = "baseType", target = "baseType") - @Mapping(source = "schemaLocation", target = "schemaLocation") - @Mapping(source = "fileLocation", target = "fileLocation") - @Mapping(source = "fileFormat", target = "fileFormat") - @Mapping(source = "compressionType", target = "compressionType") - @Mapping(source = "retentionPeriod", target = "retentionPeriod") - @Mapping(source = "packingType", target = "packingType") - FileTransferDataMVO toFileTransferDataMVO(FileTransferData fileTransferData); - - @Mapping(source = "type", target = "type") - @Mapping(source = "baseType", target = "baseType") - @Mapping(source = "schemaLocation", target = "schemaLocation") - @Mapping(source = "fileLocation", target = "fileLocation") - @Mapping(source = "fileFormat", target = "fileFormat") - @Mapping(source = "compressionType", target = "compressionType") - @Mapping(source = "retentionPeriod", target = "retentionPeriod") - @Mapping(source = "packingType", target = "packingType") - FileTransferData toFileTransferData(FileTransferDataMVO fileTransferDataMVO); -} \ No newline at end of file diff --git a/src/main/java/org/etsi/osl/metrico/mapper/IntentRefMapper.java b/src/main/java/org/etsi/osl/metrico/mapper/IntentRefMapper.java deleted file mode 100644 index f631d62..0000000 --- a/src/main/java/org/etsi/osl/metrico/mapper/IntentRefMapper.java +++ /dev/null @@ -1,30 +0,0 @@ -package org.etsi.osl.metrico.mapper; - -import org.etsi.osl.tmf.pm628.model.IntentRef; -import org.etsi.osl.tmf.pm628.model.IntentRefMVO; -import org.mapstruct.Mapper; -import org.mapstruct.Mapping; -import org.mapstruct.factory.Mappers; - -@Mapper -public interface IntentRefMapper { - IntentRefMapper INSTANCE = Mappers.getMapper(IntentRefMapper.class); - - @Mapping(source = "type", target = "type") - @Mapping(source = "baseType", target = "baseType") - @Mapping(source = "schemaLocation", target = "schemaLocation") - @Mapping(source = "href", target = "href") - @Mapping(source = "id", target = "id") - @Mapping(source = "name", target = "name") - @Mapping(source = "referredType", target = "referredType") - IntentRef toIntentRef(IntentRefMVO intentRefMVO); - - @Mapping(source = "type", target = "type") - @Mapping(source = "baseType", target = "baseType") - @Mapping(source = "schemaLocation", target = "schemaLocation") - @Mapping(source = "href", target = "href") - @Mapping(source = "id", target = "id") - @Mapping(source = "name", target = "name") - @Mapping(source = "referredType", target = "referredType") - IntentRefMVO toIntentRefMVO(IntentRef intentRef); -} \ No newline at end of file diff --git a/src/main/java/org/etsi/osl/metrico/mapper/LogicalResourceMapper.java b/src/main/java/org/etsi/osl/metrico/mapper/LogicalResourceMapper.java deleted file mode 100644 index 181ecc2..0000000 --- a/src/main/java/org/etsi/osl/metrico/mapper/LogicalResourceMapper.java +++ /dev/null @@ -1,18 +0,0 @@ -package org.etsi.osl.metrico.mapper; - -import org.etsi.osl.tmf.pm628.model.LogicalResource; -import org.etsi.osl.tmf.pm628.model.LogicalResourceMVO; -import org.mapstruct.Mapper; -import org.mapstruct.Mapping; -import org.mapstruct.factory.Mappers; - -@Mapper(uses = ResourceMapper.class) -public interface LogicalResourceMapper { - LogicalResourceMapper INSTANCE = Mappers.getMapper(LogicalResourceMapper.class); - - @Mapping(source = "value", target = "value") - LogicalResource toLogicalResource(LogicalResourceMVO logicalResourceMVO); - - @Mapping(source = "value", target = "value") - LogicalResourceMVO toLogicalResourceMVO(LogicalResource logicalResource); -} \ No newline at end of file diff --git a/src/main/java/org/etsi/osl/metrico/mapper/ManagementJobMapper.java b/src/main/java/org/etsi/osl/metrico/mapper/ManagementJobMapper.java deleted file mode 100644 index c0ba58e..0000000 --- a/src/main/java/org/etsi/osl/metrico/mapper/ManagementJobMapper.java +++ /dev/null @@ -1,36 +0,0 @@ -package org.etsi.osl.metrico.mapper; - -import org.etsi.osl.tmf.pm628.model.ManagementJob; -import org.etsi.osl.tmf.pm628.model.ManagementJobMVO; -import org.mapstruct.Mapper; -import org.mapstruct.Mapping; -import org.mapstruct.factory.Mappers; - -@Mapper(uses = { - FileTransferDataMapper.class, - DataAccessEndpointMapper.class, - ScheduleDefinitionMapper.class -}) -public interface ManagementJobMapper { - ManagementJobMapper INSTANCE = Mappers.getMapper(ManagementJobMapper.class); - - @Mapping(source = "type", target = "type") - @Mapping(source = "baseType", target = "baseType") - @Mapping(source = "schemaLocation", target = "schemaLocation") - @Mapping(source = "href", target = "href") - @Mapping(source = "uuid", target = "uuid") - @Mapping(source = "fileTransferData", target = "fileTransferData") - @Mapping(source = "dataAccessEndpoint", target = "dataAccessEndpoint") - @Mapping(source = "scheduleDefinition", target = "scheduleDefinition") - ManagementJob toManagementJob(ManagementJobMVO managementJobMVO); - - @Mapping(source = "type", target = "type") - @Mapping(source = "baseType", target = "baseType") - @Mapping(source = "schemaLocation", target = "schemaLocation") - @Mapping(source = "href", target = "href") - @Mapping(source = "uuid", target = "uuid") - @Mapping(source = "fileTransferData", target = "fileTransferData") - @Mapping(source = "dataAccessEndpoint", target = "dataAccessEndpoint") - @Mapping(source = "scheduleDefinition", target = "scheduleDefinition") - ManagementJobMVO toManagementJobMVO(ManagementJob managementJob); -} \ No newline at end of file diff --git a/src/main/java/org/etsi/osl/metrico/mapper/MeasurementCollectionJobMapper.java b/src/main/java/org/etsi/osl/metrico/mapper/MeasurementCollectionJobMapper.java index 5238a66..639f9ea 100644 --- a/src/main/java/org/etsi/osl/metrico/mapper/MeasurementCollectionJobMapper.java +++ b/src/main/java/org/etsi/osl/metrico/mapper/MeasurementCollectionJobMapper.java @@ -1,44 +1,58 @@ package org.etsi.osl.metrico.mapper; import org.etsi.osl.tmf.pm628.model.MeasurementCollectionJob; +import org.etsi.osl.tmf.pm628.model.MeasurementCollectionJobFVO; import org.etsi.osl.tmf.pm628.model.MeasurementCollectionJobMVO; -import org.mapstruct.Mapper; -import org.mapstruct.Mapping; -import org.mapstruct.factory.Mappers; +import org.etsi.osl.tmf.pm628.model.PerformanceIndicatorSpecificationRefOrValueMapper; +import org.etsi.osl.tmf.pm628.model.DataAccessEndpoint; +import org.etsi.osl.tmf.pm628.model.PerformanceIndicatorGroupSpecification; +import org.etsi.osl.tmf.pm628.model.DataAccessEndpointMVO; +import org.etsi.osl.tmf.pm628.model.PerformanceIndicatorGroupSpecificationMVO; +import org.etsi.osl.tmf.pm628.model.PerformanceIndicatorSpecificationRefOrValueMVO; +import org.etsi.osl.tmf.pm628.model.TrackingRecordMVO; +import org.etsi.osl.tmf.pm628.model.PerformanceIndicatorSpecificationRefOrValue; +import org.etsi.osl.tmf.pm628.model.TrackingRecord; +import org.etsi.osl.tmf.pm628.model.ScheduleDefinitionMVO; +import org.etsi.osl.tmf.pm628.model.FileTransferDataMVO; +import org.etsi.osl.tmf.pm628.model.FileTransferData; +import org.etsi.osl.tmf.pm628.model.ScheduleDefinition; -@Mapper(uses = { - DataFilterMapMapper.class, - PerformanceIndicatorGroupSpecificationMapper.class, - PerformanceIndicatorSpecificationRefOrValueMapper.class, - TrackingRecordMapper.class, - FileTransferDataMapper.class, - DataAccessEndpointMapper.class, - ScheduleDefinitionMapper.class -}) +import org.mapstruct.*; + +import java.util.List; + +@Mapper( + nullValueMappingStrategy = NullValueMappingStrategy.RETURN_DEFAULT, + nullValueCheckStrategy = NullValueCheckStrategy.ALWAYS, + collectionMappingStrategy = CollectionMappingStrategy.ACCESSOR_ONLY, // Collection- or map-typed properties of the target bean to be updated will be cleared and then populated with the values from the corresponding source collection or map + uses = { + PerformanceIndicatorSpecificationRefOrValueMapper.class, + PartyRefOrPartyRoleRefMapper.class, + ResourceRefOrValueMapper.class + } +) public interface MeasurementCollectionJobMapper { - MeasurementCollectionJobMapper INSTANCE = Mappers.getMapper(MeasurementCollectionJobMapper.class); - @Mapping(source = "reportingPeriod", target = "reportingPeriod") - @Mapping(source = "jobCollectionFilter", target = "jobCollectionFilter") - @Mapping(source = "searchTaskFilter", target = "searchTaskFilter") - @Mapping(source = "jobOnDemand", target = "jobOnDemand") - @Mapping(source = "performanceIndicatorGroupSpecification", target = "performanceIndicatorGroupSpecification") - @Mapping(source = "performanceIndicatorSpecification", target = "performanceIndicatorSpecification") - @Mapping(source = "trackingRecord", target = "trackingRecord") - @Mapping(source = "fileTransferData", target = "fileTransferData") - @Mapping(source = "dataAccessEndpoint", target = "dataAccessEndpoint") - @Mapping(source = "scheduleDefinition", target = "scheduleDefinition") - MeasurementCollectionJob toMeasurementCollectionJob(MeasurementCollectionJobMVO measurementCollectionJobMVO); + MeasurementCollectionJob createMeasurementCollectionJob(MeasurementCollectionJobFVO measurementCollectionJobFVO); + + @Mapping(target = "type", ignore = true) + @Mapping(target = "baseType", ignore = true) + @Mapping(target = "schemaLocation", ignore = true) + @Mapping(target = "href", ignore = true) + @Mapping(target = "uuid", ignore = true) + @BeanMapping(nullValuePropertyMappingStrategy = NullValuePropertyMappingStrategy.IGNORE) + MeasurementCollectionJob updateMeasurementCollectionJob(MeasurementCollectionJobMVO measurementCollectionJobMVO, @MappingTarget MeasurementCollectionJob measurementCollectionJob); - @Mapping(source = "reportingPeriod", target = "reportingPeriod") - @Mapping(source = "jobCollectionFilter", target = "jobCollectionFilter") - @Mapping(source = "searchTaskFilter", target = "searchTaskFilter") - @Mapping(source = "jobOnDemand", target = "jobOnDemand") - @Mapping(source = "performanceIndicatorGroupSpecification", target = "performanceIndicatorGroupSpecification") - @Mapping(source = "performanceIndicatorSpecification", target = "performanceIndicatorSpecification") - @Mapping(source = "trackingRecord", target = "trackingRecord") - @Mapping(source = "fileTransferData", target = "fileTransferData") - @Mapping(source = "dataAccessEndpoint", target = "dataAccessEndpoint") - @Mapping(source = "scheduleDefinition", target = "scheduleDefinition") - MeasurementCollectionJobMVO toMeasurementCollectionJobMVO(MeasurementCollectionJob measurementCollectionJob); -} \ No newline at end of file + @IterableMapping(nullValueMappingStrategy = NullValueMappingStrategy.RETURN_NULL) + List dataAccessEndpointMVOListToDataAccessEndpointList(List list); + @IterableMapping(nullValueMappingStrategy = NullValueMappingStrategy.RETURN_NULL) + List performanceIndicatorGroupSpecificationMVOListToPerformanceIndicatorGroupSpecificationList(List list); + @IterableMapping(nullValueMappingStrategy = NullValueMappingStrategy.RETURN_NULL) + List performanceIndicatorSpecificationMVOListToPerformanceIndicatorSpecificationList(List list); + @IterableMapping(nullValueMappingStrategy = NullValueMappingStrategy.RETURN_NULL) + List trackingRecordMVOListToTrackingRecordList(List list); + @IterableMapping(nullValueMappingStrategy = NullValueMappingStrategy.RETURN_NULL) + List fileTransferDataMVOListToFileTransferDataList(List list); + @IterableMapping(nullValueMappingStrategy = NullValueMappingStrategy.RETURN_NULL) + List scheduleDefinitionMVOListToScheduleDefinitionList(List list); +} diff --git a/src/main/java/org/etsi/osl/metrico/mapper/MeasurementJobMapper.java b/src/main/java/org/etsi/osl/metrico/mapper/MeasurementJobMapper.java deleted file mode 100644 index 8d6ed6d..0000000 --- a/src/main/java/org/etsi/osl/metrico/mapper/MeasurementJobMapper.java +++ /dev/null @@ -1,35 +0,0 @@ -package org.etsi.osl.metrico.mapper; - -import org.etsi.osl.tmf.pm628.model.MeasurementJob; -import org.etsi.osl.tmf.pm628.model.MeasurementJobMVO; -import org.mapstruct.Mapper; -import org.mapstruct.Mapping; -import org.mapstruct.factory.Mappers; - -@Mapper(uses = { - FileTransferDataMapper.class, - DataAccessEndpointMapper.class, - ScheduleDefinitionMapper.class, - PerformanceIndicatorGroupSpecificationMapper.class, - PerformanceIndicatorSpecificationRefOrValueMapper.class, - TrackingRecordMapper.class -}) -public interface MeasurementJobMapper { - MeasurementJobMapper INSTANCE = Mappers.getMapper(MeasurementJobMapper.class); - - @Mapping(source = "consumingApplicationId", target = "consumingApplicationId") - @Mapping(source = "producingApplicationId", target = "producingApplicationId") - @Mapping(source = "granularity", target = "granularity") - @Mapping(source = "performanceIndicatorGroupSpecification", target = "performanceIndicatorGroupSpecification") - @Mapping(source = "performanceIndicatorSpecification", target = "performanceIndicatorSpecification") - @Mapping(source = "trackingRecord", target = "trackingRecord") - MeasurementJob toMeasurementJob(MeasurementJobMVO measurementJobMVO); - - @Mapping(source = "consumingApplicationId", target = "consumingApplicationId") - @Mapping(source = "producingApplicationId", target = "producingApplicationId") - @Mapping(source = "granularity", target = "granularity") - @Mapping(source = "performanceIndicatorGroupSpecification", target = "performanceIndicatorGroupSpecification") - @Mapping(source = "performanceIndicatorSpecification", target = "performanceIndicatorSpecification") - @Mapping(source = "trackingRecord", target = "trackingRecord") - MeasurementJobMVO toMeasurementJobMVO(MeasurementJob measurementJob); -} \ No newline at end of file diff --git a/src/main/java/org/etsi/osl/metrico/mapper/MonthlyScheduleDayOfWeekDefinitionMapper.java b/src/main/java/org/etsi/osl/metrico/mapper/MonthlyScheduleDayOfWeekDefinitionMapper.java deleted file mode 100644 index e1dbf96..0000000 --- a/src/main/java/org/etsi/osl/metrico/mapper/MonthlyScheduleDayOfWeekDefinitionMapper.java +++ /dev/null @@ -1,28 +0,0 @@ -package org.etsi.osl.metrico.mapper; - -import org.etsi.osl.tmf.pm628.model.MonthlyScheduleDayOfWeekDefinition; -import org.etsi.osl.tmf.pm628.model.MonthlyScheduleDayOfWeekDefinitionMVO; -import org.mapstruct.Mapper; -import org.mapstruct.Mapping; -import org.mapstruct.factory.Mappers; - -@Mapper(uses = { - DayOfMonthRecurrenceMapper.class -}) -public interface MonthlyScheduleDayOfWeekDefinitionMapper { - MonthlyScheduleDayOfWeekDefinitionMapper INSTANCE = Mappers.getMapper(MonthlyScheduleDayOfWeekDefinitionMapper.class); - - @Mapping(source = "type", target = "type") - @Mapping(source = "baseType", target = "baseType") - @Mapping(source = "schemaLocation", target = "schemaLocation") - @Mapping(source = "dayOfMonthRecurrence", target = "dayOfMonthRecurrence") - @Mapping(source = "recurringDaySequence", target = "recurringDaySequence") - MonthlyScheduleDayOfWeekDefinition toMonthlyScheduleDayOfWeekDefinition(MonthlyScheduleDayOfWeekDefinitionMVO monthlyScheduleDayOfWeekDefinitionMVO); - - @Mapping(source = "type", target = "type") - @Mapping(source = "baseType", target = "baseType") - @Mapping(source = "schemaLocation", target = "schemaLocation") - @Mapping(source = "dayOfMonthRecurrence", target = "dayOfMonthRecurrence") - @Mapping(source = "recurringDaySequence", target = "recurringDaySequence") - MonthlyScheduleDayOfWeekDefinitionMVO toMonthlyScheduleDayOfWeekDefinitionMVO(MonthlyScheduleDayOfWeekDefinition monthlyScheduleDayOfWeekDefinition); -} \ No newline at end of file diff --git a/src/main/java/org/etsi/osl/metrico/mapper/NoteMapper.java b/src/main/java/org/etsi/osl/metrico/mapper/NoteMapper.java deleted file mode 100644 index 6f25a37..0000000 --- a/src/main/java/org/etsi/osl/metrico/mapper/NoteMapper.java +++ /dev/null @@ -1,24 +0,0 @@ -package org.etsi.osl.metrico.mapper; - -import org.etsi.osl.tmf.common.model.service.Note; -import org.etsi.osl.tmf.pm628.model.NoteMVO; -import org.mapstruct.Mapper; -import org.mapstruct.Mapping; -import org.mapstruct.factory.Mappers; - -@Mapper -public interface NoteMapper { - NoteMapper INSTANCE = Mappers.getMapper(NoteMapper.class); - - @Mapping(source = "uuid", target = "uuid") - @Mapping(source = "author", target = "author") - @Mapping(source = "date", target = "date") - @Mapping(source = "text", target = "text") - Note toNote(NoteMVO noteMVO); - - @Mapping(source = "uuid", target = "uuid") - @Mapping(source = "author", target = "author") - @Mapping(source = "date", target = "date") - @Mapping(source = "text", target = "text") - NoteMVO toNoteMVO(Note note); -} \ No newline at end of file diff --git a/src/main/java/org/etsi/osl/metrico/mapper/PartyRefOrPartyRoleRefMapper.java b/src/main/java/org/etsi/osl/metrico/mapper/PartyRefOrPartyRoleRefMapper.java new file mode 100644 index 0000000..8ec5e72 --- /dev/null +++ b/src/main/java/org/etsi/osl/metrico/mapper/PartyRefOrPartyRoleRefMapper.java @@ -0,0 +1,21 @@ +package org.etsi.osl.metrico.mapper; + +import org.etsi.osl.tmf.pm628.model.*; +import org.mapstruct.*; + +@Mapper( + nullValueMappingStrategy = NullValueMappingStrategy.RETURN_DEFAULT, + nullValueCheckStrategy = NullValueCheckStrategy.ALWAYS, + subclassExhaustiveStrategy = SubclassExhaustiveStrategy.RUNTIME_EXCEPTION +) +public interface PartyRefOrPartyRoleRefMapper { + + @SubclassMapping(source = PartyRefFVO.class, target = PartyRef.class) + @SubclassMapping(source = PartyRoleRefFVO.class, target = PartyRoleRef.class) + PartyRefOrPartyRoleRef map(PartyRefOrPartyRoleRefFVO source); + + @SubclassMapping(source = PartyRefMVO.class, target = PartyRef.class) + @SubclassMapping(source = PartyRoleRefMVO.class, target = PartyRoleRef.class) + PartyRefOrPartyRoleRef map(PartyRefOrPartyRoleRefMVO source); +} + diff --git a/src/main/java/org/etsi/osl/metrico/mapper/PerformanceIndicatorGroupSpecificationMapper.java b/src/main/java/org/etsi/osl/metrico/mapper/PerformanceIndicatorGroupSpecificationMapper.java deleted file mode 100644 index 1af6d2e..0000000 --- a/src/main/java/org/etsi/osl/metrico/mapper/PerformanceIndicatorGroupSpecificationMapper.java +++ /dev/null @@ -1,32 +0,0 @@ -package org.etsi.osl.metrico.mapper; - -import org.etsi.osl.tmf.pm628.model.PerformanceIndicatorGroupSpecification; -import org.etsi.osl.tmf.pm628.model.PerformanceIndicatorGroupSpecificationMVO; -import org.mapstruct.Mapper; -import org.mapstruct.Mapping; -import org.mapstruct.factory.Mappers; - -@Mapper(uses = { - PerformanceIndicatorSpecificationRefOrValueMapper.class -}) -public interface PerformanceIndicatorGroupSpecificationMapper { - PerformanceIndicatorGroupSpecificationMapper INSTANCE = Mappers.getMapper(PerformanceIndicatorGroupSpecificationMapper.class); - - @Mapping(source = "type", target = "type") - @Mapping(source = "baseType", target = "baseType") - @Mapping(source = "schemaLocation", target = "schemaLocation") - @Mapping(source = "uuid", target = "uuid") - @Mapping(source = "name", target = "name") - @Mapping(source = "groupCategory", target = "groupCategory") - @Mapping(source = "performanceIndicatorSpecification", target = "performanceIndicatorSpecification") - PerformanceIndicatorGroupSpecification toPerformanceIndicatorGroupSpecification(PerformanceIndicatorGroupSpecificationMVO performanceIndicatorGroupSpecificationMVO); - - @Mapping(source = "type", target = "type") - @Mapping(source = "baseType", target = "baseType") - @Mapping(source = "schemaLocation", target = "schemaLocation") - @Mapping(source = "uuid", target = "uuid") - @Mapping(source = "name", target = "name") - @Mapping(source = "groupCategory", target = "groupCategory") - @Mapping(source = "performanceIndicatorSpecification", target = "performanceIndicatorSpecification") - PerformanceIndicatorGroupSpecificationMVO toPerformanceIndicatorGroupSpecificationMVO(PerformanceIndicatorGroupSpecification performanceIndicatorGroupSpecification); -} \ No newline at end of file diff --git a/src/main/java/org/etsi/osl/metrico/mapper/PerformanceIndicatorSpecRelationshipMapper.java b/src/main/java/org/etsi/osl/metrico/mapper/PerformanceIndicatorSpecRelationshipMapper.java deleted file mode 100644 index cefb15a..0000000 --- a/src/main/java/org/etsi/osl/metrico/mapper/PerformanceIndicatorSpecRelationshipMapper.java +++ /dev/null @@ -1,32 +0,0 @@ -package org.etsi.osl.metrico.mapper; - -import org.etsi.osl.tmf.pm628.model.PerformanceIndicatorSpecRelationship; -import org.etsi.osl.tmf.pm628.model.PerformanceIndicatorSpecRelationshipMVO; -import org.mapstruct.Mapper; -import org.mapstruct.Mapping; -import org.mapstruct.factory.Mappers; - -@Mapper -public interface PerformanceIndicatorSpecRelationshipMapper { - PerformanceIndicatorSpecRelationshipMapper INSTANCE = Mappers.getMapper(PerformanceIndicatorSpecRelationshipMapper.class); - - @Mapping(source = "type", target = "type") - @Mapping(source = "baseType", target = "baseType") - @Mapping(source = "schemaLocation", target = "schemaLocation") - @Mapping(source = "href", target = "href") - @Mapping(source = "uuid", target = "uuid") - @Mapping(source = "relationshipType", target = "relationshipType") - @Mapping(source = "role", target = "role") - @Mapping(source = "validFor", target = "validFor") - PerformanceIndicatorSpecRelationship toPerformanceIndicatorSpecRelationship(PerformanceIndicatorSpecRelationshipMVO performanceIndicatorSpecRelationshipMVO); - - @Mapping(source = "type", target = "type") - @Mapping(source = "baseType", target = "baseType") - @Mapping(source = "schemaLocation", target = "schemaLocation") - @Mapping(source = "href", target = "href") - @Mapping(source = "uuid", target = "uuid") - @Mapping(source = "relationshipType", target = "relationshipType") - @Mapping(source = "role", target = "role") - @Mapping(source = "validFor", target = "validFor") - PerformanceIndicatorSpecRelationshipMVO toPerformanceIndicatorSpecRelationshipMVO(PerformanceIndicatorSpecRelationship performanceIndicatorSpecRelationship); -} \ No newline at end of file diff --git a/src/main/java/org/etsi/osl/metrico/mapper/PerformanceIndicatorSpecificationMapper.java b/src/main/java/org/etsi/osl/metrico/mapper/PerformanceIndicatorSpecificationMapper.java index f58269c..6851198 100644 --- a/src/main/java/org/etsi/osl/metrico/mapper/PerformanceIndicatorSpecificationMapper.java +++ b/src/main/java/org/etsi/osl/metrico/mapper/PerformanceIndicatorSpecificationMapper.java @@ -1,50 +1,24 @@ package org.etsi.osl.metrico.mapper; import org.etsi.osl.tmf.pm628.model.PerformanceIndicatorSpecification; +import org.etsi.osl.tmf.pm628.model.PerformanceIndicatorSpecificationFVO; import org.etsi.osl.tmf.pm628.model.PerformanceIndicatorSpecificationMVO; -import org.mapstruct.Mapper; -import org.mapstruct.Mapping; -import org.mapstruct.factory.Mappers; +import org.mapstruct.*; -@Mapper(uses = { - PerformanceIndicatorSpecRelationshipMapper.class, -}) +@Mapper( + nullValueMappingStrategy = NullValueMappingStrategy.RETURN_DEFAULT, + nullValueCheckStrategy = NullValueCheckStrategy.ALWAYS, + collectionMappingStrategy = CollectionMappingStrategy.ACCESSOR_ONLY // Collection- or map-typed properties of the target bean to be updated will be cleared and then populated with the values from the corresponding source collection or map +) public interface PerformanceIndicatorSpecificationMapper { - PerformanceIndicatorSpecificationMapper INSTANCE = Mappers.getMapper(PerformanceIndicatorSpecificationMapper.class); - @Mapping(source = "type", target = "type") - @Mapping(source = "baseType", target = "baseType") - @Mapping(source = "schemaLocation", target = "schemaLocation") - @Mapping(source = "href", target = "href") - @Mapping(source = "uuid", target = "uuid") - @Mapping(source = "name", target = "name") - @Mapping(source = "description", target = "description") - @Mapping(source = "perspective", target = "perspective") - @Mapping(source = "indicatorCategory", target = "indicatorCategory") - @Mapping(source = "indicatorType", target = "indicatorType") - @Mapping(source = "derivationAlgorithm", target = "derivationAlgorithm") - @Mapping(source = "derivationMethod", target = "derivationMethod") - @Mapping(source = "validFor", target = "validFor") - @Mapping(source = "collectionType", target = "collectionType") - @Mapping(source = "indicatorUnit", target = "indicatorUnit") - @Mapping(source = "performanceIndicatorSpecRelationship", target = "performanceIndicatorSpecRelationship") - PerformanceIndicatorSpecification toPerformanceIndicatorSpecification(PerformanceIndicatorSpecificationMVO performanceIndicatorSpecificationMVO); + PerformanceIndicatorSpecification createPerformanceIndicatorSpecification(PerformanceIndicatorSpecificationFVO performanceIndicatorSpecificationFVO); - @Mapping(source = "type", target = "type") - @Mapping(source = "baseType", target = "baseType") - @Mapping(source = "schemaLocation", target = "schemaLocation") - @Mapping(source = "href", target = "href") - @Mapping(source = "uuid", target = "uuid") - @Mapping(source = "name", target = "name") - @Mapping(source = "description", target = "description") - @Mapping(source = "perspective", target = "perspective") - @Mapping(source = "indicatorCategory", target = "indicatorCategory") - @Mapping(source = "indicatorType", target = "indicatorType") - @Mapping(source = "derivationAlgorithm", target = "derivationAlgorithm") - @Mapping(source = "derivationMethod", target = "derivationMethod") - @Mapping(source = "validFor", target = "validFor") - @Mapping(source = "collectionType", target = "collectionType") - @Mapping(source = "indicatorUnit", target = "indicatorUnit") - @Mapping(source = "performanceIndicatorSpecRelationship", target = "performanceIndicatorSpecRelationship") - PerformanceIndicatorSpecificationMVO toPerformanceIndicatorSpecificationMVO(PerformanceIndicatorSpecification performanceIndicatorSpecification); + @Mapping(target = "type", ignore = true) + @Mapping(target = "baseType", ignore = true) + @Mapping(target = "schemaLocation", ignore = true) + @Mapping(target = "href", ignore = true) + @Mapping(target = "uuid", ignore = true) + @BeanMapping(nullValuePropertyMappingStrategy = NullValuePropertyMappingStrategy.IGNORE) + PerformanceIndicatorSpecification updatePerformanceIndicatorSpecification(PerformanceIndicatorSpecificationMVO performanceIndicatorSpecificationMVO, @MappingTarget PerformanceIndicatorSpecification performanceIndicatorSpecification); } \ No newline at end of file diff --git a/src/main/java/org/etsi/osl/metrico/mapper/PerformanceIndicatorSpecificationRefMapper.java b/src/main/java/org/etsi/osl/metrico/mapper/PerformanceIndicatorSpecificationRefMapper.java deleted file mode 100644 index 0e56edb..0000000 --- a/src/main/java/org/etsi/osl/metrico/mapper/PerformanceIndicatorSpecificationRefMapper.java +++ /dev/null @@ -1,32 +0,0 @@ -package org.etsi.osl.metrico.mapper; - -import org.etsi.osl.tmf.pm628.model.PerformanceIndicatorSpecificationRef; -import org.etsi.osl.tmf.pm628.model.PerformanceIndicatorSpecificationRefMVO; -import org.mapstruct.Mapper; -import org.mapstruct.Mapping; -import org.mapstruct.factory.Mappers; - -@Mapper -public interface PerformanceIndicatorSpecificationRefMapper { - PerformanceIndicatorSpecificationRefMapper INSTANCE = Mappers.getMapper(PerformanceIndicatorSpecificationRefMapper.class); - - @Mapping(source = "type", target = "type") - @Mapping(source = "baseType", target = "baseType") - @Mapping(source = "schemaLocation", target = "schemaLocation") - @Mapping(source = "href", target = "href") - @Mapping(source = "uuid", target = "uuid") - @Mapping(source = "name", target = "name") - @Mapping(source = "referredType", target = "referredType") - @Mapping(source = "version", target = "version") - PerformanceIndicatorSpecificationRef toPerformanceIndicatorSpecificationRef(PerformanceIndicatorSpecificationRefMVO performanceIndicatorSpecificationRefMVO); - - @Mapping(source = "type", target = "type") - @Mapping(source = "baseType", target = "baseType") - @Mapping(source = "schemaLocation", target = "schemaLocation") - @Mapping(source = "href", target = "href") - @Mapping(source = "uuid", target = "uuid") - @Mapping(source = "name", target = "name") - @Mapping(source = "referredType", target = "referredType") - @Mapping(source = "version", target = "version") - PerformanceIndicatorSpecificationRefMVO toPerformanceIndicatorSpecificationRefMVO(PerformanceIndicatorSpecificationRef performanceIndicatorSpecificationRef); -} \ No newline at end of file diff --git a/src/main/java/org/etsi/osl/metrico/mapper/PerformanceIndicatorSpecificationRefOrValueMapper.java b/src/main/java/org/etsi/osl/metrico/mapper/PerformanceIndicatorSpecificationRefOrValueMapper.java deleted file mode 100644 index b78ed7c..0000000 --- a/src/main/java/org/etsi/osl/metrico/mapper/PerformanceIndicatorSpecificationRefOrValueMapper.java +++ /dev/null @@ -1,22 +0,0 @@ -package org.etsi.osl.metrico.mapper; - - -import org.etsi.osl.tmf.pm628.model.PerformanceIndicatorSpecificationRefOrValue; -import org.etsi.osl.tmf.pm628.model.PerformanceIndicatorSpecificationRefOrValueMVO; -import org.mapstruct.Mapper; -import org.mapstruct.Mapping; -import org.mapstruct.factory.Mappers; - -@Mapper(uses = { - PerformanceIndicatorSpecificationMapper.class, - PerformanceIndicatorSpecificationRefMapper.class -}) -public interface PerformanceIndicatorSpecificationRefOrValueMapper { - PerformanceIndicatorSpecificationRefOrValueMapper INSTANCE = Mappers.getMapper(PerformanceIndicatorSpecificationRefOrValueMapper.class); - - @Mapping(source = "type", target = "type") - PerformanceIndicatorSpecificationRefOrValue toPerformanceIndicatorSpecificationRefOrValue(PerformanceIndicatorSpecificationRefOrValueMVO performanceIndicatorSpecificationRefOrValueMVO); - - @Mapping(source = "type", target = "type") - PerformanceIndicatorSpecificationRefOrValueMVO toPerformanceIndicatorSpecificationRefOrValueMVO(PerformanceIndicatorSpecificationRefOrValue performanceIndicatorSpecificationRefOrValue); -} \ No newline at end of file diff --git a/src/main/java/org/etsi/osl/metrico/mapper/PolicyRefMapper.java b/src/main/java/org/etsi/osl/metrico/mapper/PolicyRefMapper.java deleted file mode 100644 index 851e0b4..0000000 --- a/src/main/java/org/etsi/osl/metrico/mapper/PolicyRefMapper.java +++ /dev/null @@ -1,32 +0,0 @@ -package org.etsi.osl.metrico.mapper; - -import org.etsi.osl.tmf.pm628.model.PolicyRef; -import org.etsi.osl.tmf.pm628.model.PolicyRefMVO; -import org.mapstruct.Mapper; -import org.mapstruct.Mapping; -import org.mapstruct.factory.Mappers; - -@Mapper -public interface PolicyRefMapper { - PolicyRefMapper INSTANCE = Mappers.getMapper(PolicyRefMapper.class); - - @Mapping(source = "type", target = "type") - @Mapping(source = "baseType", target = "baseType") - @Mapping(source = "schemaLocation", target = "schemaLocation") - @Mapping(source = "href", target = "href") - @Mapping(source = "uuid", target = "uuid") - @Mapping(source = "name", target = "name") - @Mapping(source = "referredType", target = "referredType") - @Mapping(source = "version", target = "version") - PolicyRef toPolicyRef(PolicyRefMVO policyRefMVO); - - @Mapping(source = "type", target = "type") - @Mapping(source = "baseType", target = "baseType") - @Mapping(source = "schemaLocation", target = "schemaLocation") - @Mapping(source = "href", target = "href") - @Mapping(source = "uuid", target = "uuid") - @Mapping(source = "name", target = "name") - @Mapping(source = "referredType", target = "referredType") - @Mapping(source = "version", target = "version") - PolicyRefMVO toPolicyRefMVO(PolicyRef policyRef); -} \ No newline at end of file diff --git a/src/main/java/org/etsi/osl/metrico/mapper/RelatedPartyRefOrPartyRoleRefMapper.java b/src/main/java/org/etsi/osl/metrico/mapper/RelatedPartyRefOrPartyRoleRefMapper.java deleted file mode 100644 index bc6f59a..0000000 --- a/src/main/java/org/etsi/osl/metrico/mapper/RelatedPartyRefOrPartyRoleRefMapper.java +++ /dev/null @@ -1,26 +0,0 @@ -package org.etsi.osl.metrico.mapper; - -import org.etsi.osl.tmf.pm628.model.RelatedPartyRefOrPartyRoleRef; -import org.etsi.osl.tmf.pm628.model.RelatedPartyRefOrPartyRoleRefMVO; -import org.mapstruct.Mapper; -import org.mapstruct.Mapping; -import org.mapstruct.factory.Mappers; - -@Mapper -public interface RelatedPartyRefOrPartyRoleRefMapper { - RelatedPartyRefOrPartyRoleRefMapper INSTANCE = Mappers.getMapper(RelatedPartyRefOrPartyRoleRefMapper.class); - - @Mapping(source = "type", target = "type") - @Mapping(source = "baseType", target = "baseType") - @Mapping(source = "schemaLocation", target = "schemaLocation") - @Mapping(source = "role", target = "role") - @Mapping(source = "partyOrPartyRole", target = "partyOrPartyRole") - RelatedPartyRefOrPartyRoleRef toRelatedPartyRefOrPartyRoleRef(RelatedPartyRefOrPartyRoleRefMVO relatedPartyRefOrPartyRoleRefMVO); - - @Mapping(source = "type", target = "type") - @Mapping(source = "baseType", target = "baseType") - @Mapping(source = "schemaLocation", target = "schemaLocation") - @Mapping(source = "role", target = "role") - @Mapping(source = "partyOrPartyRole", target = "partyOrPartyRole") - RelatedPartyRefOrPartyRoleRefMVO toRelatedPartyRefOrPartyRoleRefMVO(RelatedPartyRefOrPartyRoleRef relatedPartyRefOrPartyRoleRef); -} \ No newline at end of file diff --git a/src/main/java/org/etsi/osl/metrico/mapper/RelatedPlaceRefMapper.java b/src/main/java/org/etsi/osl/metrico/mapper/RelatedPlaceRefMapper.java deleted file mode 100644 index 9d60c1a..0000000 --- a/src/main/java/org/etsi/osl/metrico/mapper/RelatedPlaceRefMapper.java +++ /dev/null @@ -1,26 +0,0 @@ -package org.etsi.osl.metrico.mapper; - -import org.etsi.osl.tmf.pm628.model.RelatedPlaceRef; -import org.etsi.osl.tmf.pm628.model.RelatedPlaceRefMVO; -import org.mapstruct.Mapper; -import org.mapstruct.Mapping; -import org.mapstruct.factory.Mappers; - -@Mapper -public interface RelatedPlaceRefMapper { - RelatedPlaceRefMapper INSTANCE = Mappers.getMapper(RelatedPlaceRefMapper.class); - - @Mapping(source = "type", target = "type") - @Mapping(source = "baseType", target = "baseType") - @Mapping(source = "schemaLocation", target = "schemaLocation") - @Mapping(source = "role", target = "role") - @Mapping(source = "place", target = "place") - RelatedPlaceRef toRelatedPlaceRef(RelatedPlaceRefMVO relatedPlaceRefMVO); - - @Mapping(source = "type", target = "type") - @Mapping(source = "baseType", target = "baseType") - @Mapping(source = "schemaLocation", target = "schemaLocation") - @Mapping(source = "role", target = "role") - @Mapping(source = "place", target = "place") - RelatedPlaceRefMVO toRelatedPlaceRefMVO(RelatedPlaceRef relatedPlaceRef); -} \ No newline at end of file diff --git a/src/main/java/org/etsi/osl/metrico/mapper/RelatedResourceOrderItemMapper.java b/src/main/java/org/etsi/osl/metrico/mapper/RelatedResourceOrderItemMapper.java deleted file mode 100644 index 60c1ad8..0000000 --- a/src/main/java/org/etsi/osl/metrico/mapper/RelatedResourceOrderItemMapper.java +++ /dev/null @@ -1,34 +0,0 @@ -package org.etsi.osl.metrico.mapper; - -import org.etsi.osl.tmf.pm628.model.RelatedResourceOrderItem; -import org.etsi.osl.tmf.pm628.model.RelatedResourceOrderItemMVO; -import org.mapstruct.Mapper; -import org.mapstruct.Mapping; -import org.mapstruct.factory.Mappers; - -@Mapper -public interface RelatedResourceOrderItemMapper { - RelatedResourceOrderItemMapper INSTANCE = Mappers.getMapper(RelatedResourceOrderItemMapper.class); - - @Mapping(source = "type", target = "type") - @Mapping(source = "baseType", target = "baseType") - @Mapping(source = "schemaLocation", target = "schemaLocation") - @Mapping(source = "referredType", target = "referredType") - @Mapping(source = "resourceOrderHref", target = "resourceOrderHref") - @Mapping(source = "resourceOrderId", target = "resourceOrderId") - @Mapping(source = "itemAction", target = "itemAction") - @Mapping(source = "itemId", target = "itemId") - @Mapping(source = "role", target = "role") - RelatedResourceOrderItem toRelatedResourceOrderItem(RelatedResourceOrderItemMVO relatedResourceOrderItemMVO); - - @Mapping(source = "type", target = "type") - @Mapping(source = "baseType", target = "baseType") - @Mapping(source = "schemaLocation", target = "schemaLocation") - @Mapping(source = "referredType", target = "referredType") - @Mapping(source = "resourceOrderHref", target = "resourceOrderHref") - @Mapping(source = "resourceOrderId", target = "resourceOrderId") - @Mapping(source = "itemAction", target = "itemAction") - @Mapping(source = "itemId", target = "itemId") - @Mapping(source = "role", target = "role") - RelatedResourceOrderItemMVO toRelatedResourceOrderItemMVO(RelatedResourceOrderItem relatedResourceOrderItem); -} diff --git a/src/main/java/org/etsi/osl/metrico/mapper/ResourceMapper.java b/src/main/java/org/etsi/osl/metrico/mapper/ResourceMapper.java deleted file mode 100644 index 18a5b42..0000000 --- a/src/main/java/org/etsi/osl/metrico/mapper/ResourceMapper.java +++ /dev/null @@ -1,82 +0,0 @@ -package org.etsi.osl.metrico.mapper; - -import org.etsi.osl.tmf.pm628.model.Resource; -import org.etsi.osl.tmf.pm628.model.ResourceMVO; -import org.mapstruct.Mapper; -import org.mapstruct.Mapping; -import org.mapstruct.factory.Mappers; - -@Mapper(uses = { - NoteMapper.class, - RelatedResourceOrderItemMapper.class, - RelatedPlaceRefMapper.class, - RelatedPartyRefOrPartyRoleRefMapper.class, - ResourceRelationshipMapper.class, - CharacteristicMapper.class, - AttachmentRefMapper.class, - ResourceSpecificationRefMapper.class, - FeatureMapper.class, - IntentRefMapper.class, - ExternalIdentifierMapper.class -}) -public interface ResourceMapper { - ResourceMapper INSTANCE = Mappers.getMapper(ResourceMapper.class); - - @Mapping(source = "type", target = "type") - @Mapping(source = "baseType", target = "baseType") - @Mapping(source = "schemaLocation", target = "schemaLocation") - @Mapping(source = "href", target = "href") - @Mapping(source = "uuid", target = "uuid") - @Mapping(source = "category", target = "category") - @Mapping(source = "description", target = "description") - @Mapping(source = "name", target = "name") - @Mapping(source = "endOperatingDate", target = "endOperatingDate") - @Mapping(source = "administrativeState", target = "administrativeState") - @Mapping(source = "operationalState", target = "operationalState") - @Mapping(source = "resourceStatus", target = "resourceStatus") - @Mapping(source = "usageState", target = "usageState") - @Mapping(source = "validFor", target = "validFor") - @Mapping(source = "note", target = "note") - @Mapping(source = "resourceOrderItem", target = "resourceOrderItem") - @Mapping(source = "place", target = "place") - @Mapping(source = "relatedParty", target = "relatedParty") - @Mapping(source = "resourceRelationship", target = "resourceRelationship") - @Mapping(source = "resourceCharacteristic", target = "resourceCharacteristic") - @Mapping(source = "attachment", target = "attachment") - @Mapping(source = "resourceSpecification", target = "resourceSpecification") - @Mapping(source = "startOperatingDate", target = "startOperatingDate") - @Mapping(source = "resourceVersion", target = "resourceVersion") - @Mapping(source = "activationFeature", target = "activationFeature") - @Mapping(source = "intent", target = "intent") - @Mapping(source = "externalIdentifier", target = "externalIdentifier") - Resource toResource(ResourceMVO resourceMVO); - - @Mapping(source = "type", target = "type") - @Mapping(source = "baseType", target = "baseType") - @Mapping(source = "schemaLocation", target = "schemaLocation") - @Mapping(source = "href", target = "href") - @Mapping(source = "uuid", target = "uuid") - @Mapping(source = "category", target = "category") - @Mapping(source = "description", target = "description") - @Mapping(source = "name", target = "name") - @Mapping(source = "endOperatingDate", target = "endOperatingDate") - @Mapping(source = "administrativeState", target = "administrativeState") - @Mapping(source = "operationalState", target = "operationalState") - @Mapping(source = "resourceStatus", target = "resourceStatus") - @Mapping(source = "usageState", target = "usageState") - @Mapping(source = "validFor", target = "validFor") - @Mapping(source = "note", target = "note") - @Mapping(source = "resourceOrderItem", target = "resourceOrderItem") - @Mapping(source = "place", target = "place") - @Mapping(source = "relatedParty", target = "relatedParty") - @Mapping(source = "resourceRelationship", target = "resourceRelationship") - @Mapping(source = "resourceCharacteristic", target = "resourceCharacteristic") - @Mapping(source = "attachment", target = "attachment") - @Mapping(source = "resourceSpecification", target = "resourceSpecification") - @Mapping(source = "startOperatingDate", target = "startOperatingDate") - @Mapping(source = "resourceVersion", target = "resourceVersion") - @Mapping(source = "activationFeature", target = "activationFeature") - @Mapping(source = "intent", target = "intent") - @Mapping(source = "externalIdentifier", target = "externalIdentifier") - ResourceMVO toResourceMVO(Resource resource); -} \ No newline at end of file diff --git a/src/main/java/org/etsi/osl/metrico/mapper/ResourceRefOrValueMapper.java b/src/main/java/org/etsi/osl/metrico/mapper/ResourceRefOrValueMapper.java index 2fae4c8..2c24dd0 100644 --- a/src/main/java/org/etsi/osl/metrico/mapper/ResourceRefOrValueMapper.java +++ b/src/main/java/org/etsi/osl/metrico/mapper/ResourceRefOrValueMapper.java @@ -1,18 +1,39 @@ package org.etsi.osl.metrico.mapper; +import org.etsi.osl.tmf.pm628.model.DataAccessEndpoint; +import org.etsi.osl.tmf.pm628.model.DataAccessEndpointFVO; +import org.etsi.osl.tmf.pm628.model.LogicalResource; +import org.etsi.osl.tmf.pm628.model.LogicalResourceFVO; +import org.etsi.osl.tmf.pm628.model.ResourceFVO; +import org.etsi.osl.tmf.pm628.model.Resource; +import org.etsi.osl.tmf.pm628.model.ResourceRefFVO; import org.etsi.osl.tmf.pm628.model.ResourceRefOrValue; +import org.etsi.osl.tmf.pm628.model.ResourceRef; +import org.etsi.osl.tmf.pm628.model.DataAccessEndpointMVO; +import org.etsi.osl.tmf.pm628.model.LogicalResourceMVO; +import org.etsi.osl.tmf.pm628.model.ResourceMVO; +import org.etsi.osl.tmf.pm628.model.ResourceRefMVO; +import org.etsi.osl.tmf.pm628.model.ResourceRefOrValueFVO; import org.etsi.osl.tmf.pm628.model.ResourceRefOrValueMVO; -import org.mapstruct.Mapper; -import org.mapstruct.Mapping; -import org.mapstruct.factory.Mappers; -@Mapper +import org.mapstruct.*; + +@Mapper( + nullValueMappingStrategy = NullValueMappingStrategy.RETURN_DEFAULT, + nullValueCheckStrategy = NullValueCheckStrategy.ALWAYS, + subclassExhaustiveStrategy = SubclassExhaustiveStrategy.RUNTIME_EXCEPTION, + uses = {PartyRefOrPartyRoleRefMapper.class}) public interface ResourceRefOrValueMapper { - ResourceRefOrValueMapper INSTANCE = Mappers.getMapper(ResourceRefOrValueMapper.class); - @Mapping(source = "type", target = "type") - ResourceRefOrValueMVO toResourceRefOrValueMVO(ResourceRefOrValue resourceRefOrValue); + @SubclassMapping(source = DataAccessEndpointFVO.class, target = DataAccessEndpoint.class) + @SubclassMapping(source = LogicalResourceFVO.class, target = LogicalResource.class) + @SubclassMapping(source = ResourceFVO.class, target = Resource.class) + @SubclassMapping(source = ResourceRefFVO.class, target = ResourceRef.class) + ResourceRefOrValue map(ResourceRefOrValueFVO source); - @Mapping(source = "type", target = "type") - ResourceRefOrValue toResourceRefOrValue(ResourceRefOrValueMVO resourceRefOrValueMVO); + @SubclassMapping(source = DataAccessEndpointMVO.class, target = DataAccessEndpoint.class) + @SubclassMapping(source = LogicalResourceMVO.class, target = LogicalResource.class) + @SubclassMapping(source = ResourceMVO.class, target = Resource.class) + @SubclassMapping(source = ResourceRefMVO.class, target = ResourceRef.class) + ResourceRefOrValue map(ResourceRefOrValueMVO source); } diff --git a/src/main/java/org/etsi/osl/metrico/mapper/ResourceRelationshipMapper.java b/src/main/java/org/etsi/osl/metrico/mapper/ResourceRelationshipMapper.java deleted file mode 100644 index f91ba64..0000000 --- a/src/main/java/org/etsi/osl/metrico/mapper/ResourceRelationshipMapper.java +++ /dev/null @@ -1,30 +0,0 @@ -package org.etsi.osl.metrico.mapper; - -import org.etsi.osl.tmf.pm628.model.ResourceRelationship; -import org.etsi.osl.tmf.pm628.model.ResourceRelationshipMVO; -import org.mapstruct.Mapper; -import org.mapstruct.Mapping; -import org.mapstruct.factory.Mappers; - -@Mapper -public interface ResourceRelationshipMapper { - ResourceRelationshipMapper INSTANCE = Mappers.getMapper(ResourceRelationshipMapper.class); - - @Mapping(source = "type", target = "type") - @Mapping(source = "baseType", target = "baseType") - @Mapping(source = "schemaLocation", target = "schemaLocation") - @Mapping(source = "uuid", target = "uuid") - @Mapping(source = "resourceRelationshipCharacteristic", target = "resourceRelationshipCharacteristic") - @Mapping(source = "resource", target = "resource") - @Mapping(source = "relationshipType", target = "relationshipType") - ResourceRelationship toResourceRelationship(ResourceRelationshipMVO resourceRelationshipMVO); - - @Mapping(source = "type", target = "type") - @Mapping(source = "baseType", target = "baseType") - @Mapping(source = "schemaLocation", target = "schemaLocation") - @Mapping(source = "uuid", target = "uuid") - @Mapping(source = "resourceRelationshipCharacteristic", target = "resourceRelationshipCharacteristic") - @Mapping(source = "resource", target = "resource") - @Mapping(source = "relationshipType", target = "relationshipType") - ResourceRelationshipMVO toResourceRelationshipMVO(ResourceRelationship resourceRelationship); -} \ No newline at end of file diff --git a/src/main/java/org/etsi/osl/metrico/mapper/ResourceSpecificationRefMapper.java b/src/main/java/org/etsi/osl/metrico/mapper/ResourceSpecificationRefMapper.java deleted file mode 100644 index 141fc19..0000000 --- a/src/main/java/org/etsi/osl/metrico/mapper/ResourceSpecificationRefMapper.java +++ /dev/null @@ -1,32 +0,0 @@ -package org.etsi.osl.metrico.mapper; - -import org.etsi.osl.tmf.pm628.model.ResourceSpecificationRefMVO; -import org.etsi.osl.tmf.rcm634.model.ResourceSpecificationRef; -import org.mapstruct.Mapper; -import org.mapstruct.Mapping; -import org.mapstruct.factory.Mappers; - -@Mapper -public interface ResourceSpecificationRefMapper { - ResourceSpecificationRefMapper INSTANCE = Mappers.getMapper(ResourceSpecificationRefMapper.class); - - @Mapping(source = "type", target = "type") - @Mapping(source = "baseType", target = "baseType") - @Mapping(source = "schemaLocation", target = "schemaLocation") - @Mapping(source = "href", target = "href") - @Mapping(source = "id", target = "id") - @Mapping(source = "name", target = "name") - @Mapping(source = "referredType", target = "referredType") - @Mapping(source = "version", target = "version") - ResourceSpecificationRef toResourceSpecificationRef(ResourceSpecificationRefMVO resourceSpecificationRefMVO); - - @Mapping(source = "type", target = "type") - @Mapping(source = "baseType", target = "baseType") - @Mapping(source = "schemaLocation", target = "schemaLocation") - @Mapping(source = "href", target = "href") - @Mapping(source = "id", target = "id") - @Mapping(source = "name", target = "name") - @Mapping(source = "referredType", target = "referredType") - @Mapping(source = "version", target = "version") - ResourceSpecificationRefMVO toResourceSpecificationRefMVO(ResourceSpecificationRef resourceSpecificationRef); -} \ No newline at end of file diff --git a/src/main/java/org/etsi/osl/metrico/mapper/ScheduleDefinitionMapper.java b/src/main/java/org/etsi/osl/metrico/mapper/ScheduleDefinitionMapper.java deleted file mode 100644 index 8d62b20..0000000 --- a/src/main/java/org/etsi/osl/metrico/mapper/ScheduleDefinitionMapper.java +++ /dev/null @@ -1,37 +0,0 @@ -package org.etsi.osl.metrico.mapper; - -import org.etsi.osl.tmf.pm628.model.ScheduleDefinition; -import org.etsi.osl.tmf.pm628.model.ScheduleDefinitionMVO; -import org.mapstruct.Mapper; -import org.mapstruct.Mapping; -import org.mapstruct.factory.Mappers; - -@Mapper(uses = { - DayOfWeekRecurrenceMapper.class, - MonthlyScheduleDayOfWeekDefinitionMapper.class -}) -public interface ScheduleDefinitionMapper { - ScheduleDefinitionMapper INSTANCE = Mappers.getMapper(ScheduleDefinitionMapper.class); - - @Mapping(source = "scheduleDefinitionStartTime", target = "scheduleDefinitionStartTime") - @Mapping(source = "scheduleDefinitionEndTime", target = "scheduleDefinitionEndTime") - @Mapping(source = "recurringFrequency", target = "recurringFrequency") - @Mapping(source = "excludedDate", target = "excludedDate") - @Mapping(source = "scheduleDefinitionHourRange", target = "scheduleDefinitionHourRange") - @Mapping(source = "weeklyScheduledDefinition", target = "weeklyScheduledDefinition") - @Mapping(source = "monthlyScheduleDayOfMonthDefinition", target = "monthlyScheduleDayOfMonthDefinition") - @Mapping(source = "monthlyScheduleDayOfWeekDefinition", target = "monthlyScheduleDayOfWeekDefinition") - @Mapping(source = "dateScheduleDefintion", target = "dateScheduleDefintion") - ScheduleDefinition toScheduleDefinition(ScheduleDefinitionMVO scheduleDefinitionMVO); - - @Mapping(source = "scheduleDefinitionStartTime", target = "scheduleDefinitionStartTime") - @Mapping(source = "scheduleDefinitionEndTime", target = "scheduleDefinitionEndTime") - @Mapping(source = "recurringFrequency", target = "recurringFrequency") - @Mapping(source = "excludedDate", target = "excludedDate") - @Mapping(source = "scheduleDefinitionHourRange", target = "scheduleDefinitionHourRange") - @Mapping(source = "weeklyScheduledDefinition", target = "weeklyScheduledDefinition") - @Mapping(source = "monthlyScheduleDayOfMonthDefinition", target = "monthlyScheduleDayOfMonthDefinition") - @Mapping(source = "monthlyScheduleDayOfWeekDefinition", target = "monthlyScheduleDayOfWeekDefinition") - @Mapping(source = "dateScheduleDefintion", target = "dateScheduleDefintion") - ScheduleDefinitionMVO toScheduleDefinitionMVO(ScheduleDefinition scheduleDefinition); -} \ No newline at end of file diff --git a/src/main/java/org/etsi/osl/metrico/mapper/TrackingRecordMapper.java b/src/main/java/org/etsi/osl/metrico/mapper/TrackingRecordMapper.java deleted file mode 100644 index fceb105..0000000 --- a/src/main/java/org/etsi/osl/metrico/mapper/TrackingRecordMapper.java +++ /dev/null @@ -1,36 +0,0 @@ -package org.etsi.osl.metrico.mapper; - -import org.etsi.osl.tmf.pm628.model.TrackingRecord; -import org.etsi.osl.tmf.pm628.model.TrackingRecordMVO; -import org.mapstruct.Mapper; -import org.mapstruct.Mapping; -import org.mapstruct.factory.Mappers; - -@Mapper(uses = { - CharacteristicMapper.class -}) -public interface TrackingRecordMapper { - TrackingRecordMapper INSTANCE = Mappers.getMapper(TrackingRecordMapper.class); - - @Mapping(source = "type", target = "type") - @Mapping(source = "baseType", target = "baseType") - @Mapping(source = "schemaLocation", target = "schemaLocation") - @Mapping(source = "description", target = "description") - @Mapping(source = "characteristic", target = "characteristic") - @Mapping(source = "systemId", target = "systemId") - @Mapping(source = "time", target = "time") - @Mapping(source = "user", target = "user") - @Mapping(source = "uuid", target = "uuid") - TrackingRecord toTrackingRecord(TrackingRecordMVO trackingRecordMVO); - - @Mapping(source = "type", target = "type") - @Mapping(source = "baseType", target = "baseType") - @Mapping(source = "schemaLocation", target = "schemaLocation") - @Mapping(source = "description", target = "description") - @Mapping(source = "characteristic", target = "characteristic") - @Mapping(source = "systemId", target = "systemId") - @Mapping(source = "time", target = "time") - @Mapping(source = "user", target = "user") - @Mapping(source = "uuid", target = "uuid") - TrackingRecordMVO toTrackingRecordMVO(TrackingRecord trackingRecord); -} \ No newline at end of file -- GitLab From c515fb05c5a751e9904b06ff97a0b74b5c4c0e45 Mon Sep 17 00:00:00 2001 From: George Tziavas Date: Mon, 16 Jun 2025 17:26:15 +0300 Subject: [PATCH 15/17] Removed mySQL from application.yaml --- src/main/resources/application.yml | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index 1362ecc..150f340 100644 --- a/src/main/resources/application.yml +++ b/src/main/resources/application.yml @@ -21,17 +21,6 @@ spring: jwt: issuer-uri: http://keycloak:8080/auth/realms/openslice jwk-set-uri: http://keycloak:8080/auth/realms/openslice/.well-known/openid-configuration - datasource: - url: jdbc:mysql://localhost:13306/ostmfdb?createDatabaseIfNotExist=true&useUnicode=true&characterEncoding=utf8&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=UTC - password: letmein - username: root - hikari: - minimumIdle: 2 - maximumPoolSize: 20 - idleTimeout: 20000 - idle-timeout: 20000 - connectionTimeout: 40000 - leakDetectionThreshold: 40000 server: port: 8030 -- GitLab From 5c4e78ecd5257facc81dca389f5c1da44dfcd665 Mon Sep 17 00:00:00 2001 From: George Tziavas Date: Tue, 17 Jun 2025 15:00:58 +0300 Subject: [PATCH 16/17] Handle restarts with no start or end time --- .gitignore | 3 +- .settings/org.eclipse.core.resources.prefs | 4 +- .../osl/metrico/MetricoCommonMethods.java | 2 +- .../osl/metrico/services/MetricoService.java | 42 +++++++++++++++++++ 4 files changed, 47 insertions(+), 4 deletions(-) diff --git a/.gitignore b/.gitignore index acb74c4..c2fc2ba 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,5 @@ /target *.iml .classpath -.project \ No newline at end of file +.project +.settings \ No newline at end of file diff --git a/.settings/org.eclipse.core.resources.prefs b/.settings/org.eclipse.core.resources.prefs index 18308de..742ce1f 100644 --- a/.settings/org.eclipse.core.resources.prefs +++ b/.settings/org.eclipse.core.resources.prefs @@ -1,6 +1,6 @@ eclipse.preferences.version=1 encoding//src/main/java=utf-8 -encoding//src/main/resources=utf-8 +encoding//src/main/resources=UTF-8 encoding//src/test/java=utf-8 -encoding//src/test/resources=utf-8 +encoding//src/test/resources=UTF-8 encoding/=UTF-8 diff --git a/src/main/java/org/etsi/osl/metrico/MetricoCommonMethods.java b/src/main/java/org/etsi/osl/metrico/MetricoCommonMethods.java index 32b073c..c8219a6 100644 --- a/src/main/java/org/etsi/osl/metrico/MetricoCommonMethods.java +++ b/src/main/java/org/etsi/osl/metrico/MetricoCommonMethods.java @@ -139,7 +139,7 @@ public class MetricoCommonMethods extends RouteBuilder { if (!(response instanceof String)) { logger.error("===== List object is wrong ===="); return null; - } else if (((String) response).isEmpty()) { + } else if (((String) response).isEmpty() || ((String) response).equals("[]")) { logger.debug("===== No PENDING OR IN_PROGRESS Measurement Collection Jobs from previous sessions ====="); return null; } else { diff --git a/src/main/java/org/etsi/osl/metrico/services/MetricoService.java b/src/main/java/org/etsi/osl/metrico/services/MetricoService.java index 8a6c55c..a7fa9e9 100644 --- a/src/main/java/org/etsi/osl/metrico/services/MetricoService.java +++ b/src/main/java/org/etsi/osl/metrico/services/MetricoService.java @@ -18,6 +18,7 @@ import org.springframework.boot.context.event.ApplicationStartedEvent; import org.springframework.context.event.EventListener; import org.springframework.stereotype.Service; +import java.time.OffsetDateTime; import java.util.List; @Service @@ -105,8 +106,49 @@ public class MetricoService extends RouteBuilder { logger.warn("MeasurementCollectionJob with uuid: {} has {} dataAccessEndpoint(s), skipping.", measurementCollectionJob.getUuid(), measurementCollectionJob.getDataAccessEndpoint() == null ? 0 : measurementCollectionJob.getDataAccessEndpoint().size()); + MeasurementCollectionJobMVO mcjMVO = new MeasurementCollectionJobMVO(); + mcjMVO.setExecutionState(ExecutionStateType.FAILED); + metricoCommonMethods.updateMeasurementCollectionJobById(measurementCollectionJob.getUuid(), mcjMVO); continue; } + if (measurementCollectionJob.getScheduleDefinition().size() > 1) { + logger.warn("MeasurementCollectionJob with uuid: {} has more than 1 ScheduleDefinitions, skipping.", + measurementCollectionJob.getUuid()); + MeasurementCollectionJobMVO mcjMVO = new MeasurementCollectionJobMVO(); + mcjMVO.setExecutionState(ExecutionStateType.FAILED); + metricoCommonMethods.updateMeasurementCollectionJobById(measurementCollectionJob.getUuid(), mcjMVO); + continue; + } else if (measurementCollectionJob.getScheduleDefinition().size() == 1) { + // If the ScheduleDefinitionEndTime is null, set it to 1 hour after the ScheduleDefinitionStartTime to check if it is past due + if (measurementCollectionJob.getScheduleDefinition().get(0).getScheduleDefinitionEndTime() == null && measurementCollectionJob.getScheduleDefinition().get(0).getScheduleDefinitionStartTime() != null) { + measurementCollectionJob.getScheduleDefinition().get(0).setScheduleDefinitionEndTime(measurementCollectionJob.getScheduleDefinition().get(0).getScheduleDefinitionStartTime().plusHours(1)); + }else if (measurementCollectionJob.getScheduleDefinition().get(0).getScheduleDefinitionEndTime() == null && measurementCollectionJob.getScheduleDefinition().get(0).getScheduleDefinitionStartTime() == null) { + measurementCollectionJob.getScheduleDefinition().get(0).setScheduleDefinitionEndTime(measurementCollectionJob.getCreationTime().plusHours(1)); + } + // If the ScheduleDefinitionEndTime is before the current time, skip the job + if(measurementCollectionJob.getScheduleDefinition().get(0).getScheduleDefinitionEndTime().isBefore(OffsetDateTime.now())) { + logger.warn("MeasurementCollectionJob with uuid: {} has a ScheduleDefinition that has already ended, skipping.", + measurementCollectionJob.getUuid()); + MeasurementCollectionJobMVO mcjMVO = new MeasurementCollectionJobMVO(); + mcjMVO.setExecutionState(ExecutionStateType.FAILED); + metricoCommonMethods.updateMeasurementCollectionJobById(measurementCollectionJob.getUuid(), mcjMVO); + continue; + } + } else { + // If there is no ScheduleDefinition, set the end time to 1 hour after the creation time + measurementCollectionJob.addScheduleDefinitionItem(new ScheduleDefinition()); + measurementCollectionJob.getScheduleDefinition().get(0).setScheduleDefinitionStartTime(measurementCollectionJob.getCreationTime()); + measurementCollectionJob.getScheduleDefinition().get(0).setScheduleDefinitionEndTime(measurementCollectionJob.getCreationTime().plusHours(1)); + + if(measurementCollectionJob.getScheduleDefinition().get(0).getScheduleDefinitionEndTime().isBefore(OffsetDateTime.now())) { + logger.warn("MeasurementCollectionJob with uuid: {} has a ScheduleDefinition that has already ended, skipping.", + measurementCollectionJob.getUuid()); + MeasurementCollectionJobMVO mcjMVO = new MeasurementCollectionJobMVO(); + mcjMVO.setExecutionState(ExecutionStateType.FAILED); + metricoCommonMethods.updateMeasurementCollectionJobById(measurementCollectionJob.getUuid(), mcjMVO); + continue; + } + } logger.info("===== Resuming measurementCollectionJob with uuid: {} =====", measurementCollectionJob.getUuid()); this.startPeriodicQueryToPrometheus(measurementCollectionJob); } -- GitLab From 02468a1c4a373a5570507c6807e90790c2dc4f43 Mon Sep 17 00:00:00 2001 From: trantzas Date: Tue, 17 Jun 2025 12:43:53 +0000 Subject: [PATCH 17/17] deleted .settings directory to match .gitignore --- .settings/org.eclipse.core.resources.prefs | 6 ------ .settings/org.eclipse.jdt.apt.core.prefs | 4 ---- .settings/org.eclipse.jdt.core.prefs | 9 --------- .settings/org.eclipse.m2e.core.prefs | 4 ---- 4 files changed, 23 deletions(-) delete mode 100644 .settings/org.eclipse.core.resources.prefs delete mode 100644 .settings/org.eclipse.jdt.apt.core.prefs delete mode 100644 .settings/org.eclipse.jdt.core.prefs delete mode 100644 .settings/org.eclipse.m2e.core.prefs diff --git a/.settings/org.eclipse.core.resources.prefs b/.settings/org.eclipse.core.resources.prefs deleted file mode 100644 index 742ce1f..0000000 --- a/.settings/org.eclipse.core.resources.prefs +++ /dev/null @@ -1,6 +0,0 @@ -eclipse.preferences.version=1 -encoding//src/main/java=utf-8 -encoding//src/main/resources=UTF-8 -encoding//src/test/java=utf-8 -encoding//src/test/resources=UTF-8 -encoding/=UTF-8 diff --git a/.settings/org.eclipse.jdt.apt.core.prefs b/.settings/org.eclipse.jdt.apt.core.prefs deleted file mode 100644 index dfa4f3a..0000000 --- a/.settings/org.eclipse.jdt.apt.core.prefs +++ /dev/null @@ -1,4 +0,0 @@ -eclipse.preferences.version=1 -org.eclipse.jdt.apt.aptEnabled=true -org.eclipse.jdt.apt.genSrcDir=target/generated-sources/annotations -org.eclipse.jdt.apt.genTestSrcDir=target/generated-test-sources/test-annotations diff --git a/.settings/org.eclipse.jdt.core.prefs b/.settings/org.eclipse.jdt.core.prefs deleted file mode 100644 index 87f474b..0000000 --- a/.settings/org.eclipse.jdt.core.prefs +++ /dev/null @@ -1,9 +0,0 @@ -eclipse.preferences.version=1 -org.eclipse.jdt.core.compiler.codegen.targetPlatform=17 -org.eclipse.jdt.core.compiler.compliance=17 -org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled -org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning -org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=ignore -org.eclipse.jdt.core.compiler.processAnnotations=enabled -org.eclipse.jdt.core.compiler.release=disabled -org.eclipse.jdt.core.compiler.source=17 diff --git a/.settings/org.eclipse.m2e.core.prefs b/.settings/org.eclipse.m2e.core.prefs deleted file mode 100644 index f897a7f..0000000 --- a/.settings/org.eclipse.m2e.core.prefs +++ /dev/null @@ -1,4 +0,0 @@ -activeProfiles= -eclipse.preferences.version=1 -resolveWorkspaceProjects=true -version=1 -- GitLab