diff --git a/.settings/org.eclipse.jdt.apt.core.prefs b/.settings/org.eclipse.jdt.apt.core.prefs new file mode 100644 index 0000000000000000000000000000000000000000..dfa4f3adb289a4f7d73e0694f9045f99325604d7 --- /dev/null +++ b/.settings/org.eclipse.jdt.apt.core.prefs @@ -0,0 +1,4 @@ +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 index cf2cd4590a7b37a700141633a3f00c030130be1e..87f474ba76f5340f448a1601feef33881f04043b 100644 --- a/.settings/org.eclipse.jdt.core.prefs +++ b/.settings/org.eclipse.jdt.core.prefs @@ -4,5 +4,6 @@ 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 new file mode 100644 index 0000000000000000000000000000000000000000..f897a7f1cb2389f85fe6381425d29f0a9866fb65 --- /dev/null +++ b/.settings/org.eclipse.m2e.core.prefs @@ -0,0 +1,4 @@ +activeProfiles= +eclipse.preferences.version=1 +resolveWorkspaceProjects=true +version=1 diff --git a/Documentation/FlowDiagram.puml b/Documentation/FlowDiagram.puml index e525f325a239fa42e9b62abe4854f2a140e6238f..4dbc99295c3bd8aa8c25d3c9ddd7a8897bd2f35c 100644 --- a/Documentation/FlowDiagram.puml +++ b/Documentation/FlowDiagram.puml @@ -9,25 +9,29 @@ participant prometheus as prom actor -> tmf_api: CREATE: Service Order Monitoring aaS osom -> osom: PROCESS ORDER -osom -> tmf_api: CREATE: service instance of monitoring aaS (CFS) -osom -> tmf_api: CREATE: service instance of monitoring aaS (RFS) -osom -> amq: CREATE: TMF628 Measurement Collection Job \n<color:green>queue:PM_MEASUREMENT_COLLECTION_JOB_ADD \n<color:orange>payload: Service Order / Service Specification -amq -> tmf_api: CREATE: TMF628 Measurement Collection Job \n<color:green>queue:PM_MEASUREMENT_COLLECTION_JOB_ADD \n<color:orange>payload: Service Order / Service Specification -tmf_api -> amq: PUBLISH EVENT: Monitoring Job Created\n<color:green>queue: PM_MEASUREMENT_COLLECTION_JOB_CREATED\n<color:green>payload: Measurement Collection Job -amq -> metrico: RECEIVE EVENT: Monitoring Job Created\n<color:green>queue: PM_MEASUREMENT_COLLECTION_JOB_CREATED\n<color:green>payload: Measurement Collection Job +osom -> tmf_api: CREATE: service instance of monitoring aaS (RFS)(Initial Status: Reseved) +osom -> tmf_api: CREATE: service instance of monitoring aaS (CFS)(Initial Status: Reseved) + +osom -> amq: CREATE: TMF628 Measurement Collection Job \n<color:green>queue:PM_MEASUREMENT_COLLECTION_JOB_ADD \n<color:green>payload: MeasurementCollectionJobFVO +amq -> tmf_api: CREATE: TMF628 Measurement Collection Job \n<color:green>queue:PM_MEASUREMENT_COLLECTION_JOB_ADD \n<color:green>payload: MeasurementCollectionJobFVO (Here I can find the MCJ ID) +tmf_api -> amq: CREATE: TMF628 Measurement Collection Job \n<color:green>queue:PM_MEASUREMENT_COLLECTION_JOB_ADD \n<color:green>payload: MeasurementCollectionJob (Here I can find the MCJ ID) +osom -> tmf_api: CREATE: Resource Instance (Initial Status: Reseved)(associate to RFS)(add the MCJ UUID) +amq -> osom: CREATE: TMF628 Measurement Collection Job \n<color:green>queue:PM_MEASUREMENT_COLLECTION_JOB_ADD \n<color:green>payload: MeasurementCollectionJob (Here I can find the MCJ ID) +tmf_api -> amq: PUBLISH EVENT: Monitoring Job Created\n<color:green>topic: PM_MEASUREMENT_COLLECTION_JOB_CREATED\n<color:green>payload: Measurement Collection Job Ref +amq -> metrico: RECEIVE EVENT: Monitoring Job Created\n<color:green>topic: PM_MEASUREMENT_COLLECTION_JOB_CREATED\n<color:green>payload: Measurement Collection Job Ref +metrico -> tmf_api: fetch Measurement Collection Job from ref +tmf_api -> metrico: fetch Measurement Collection Job from ref metrico -> metrico: create METRICO job -metrico -> amq: RESPONSE TO EVENT Monitoring Job Created\n<color:green>queue: PM_MEASUREMENT_COLLECTION_JOB_CREATED\n<color:green>payload: Measurement Collection Job with METRICO JOB_ID -amq -> tmf_api: RESPONSE TO EVENT Monitoring Job Created\n<color:green>queue: PM_MEASUREMENT_COLLECTION_JOB_CREATED\n<color:green>payload: Measurement Collection Job with METRICO JOB_ID +metrico -> amq: UPDATE Measurement Collection Job Status + -metrico -> metrico: Create a java job with refresh rate group "java job" metrico -> metrico : set how often job is done metrico -> prom : send prom req prom -> metrico : reply to prom req - metrico -> metrico : parse data from reply and cast them to performance indicator - metrico -> amq : UPDATE TMF628 Measurement Collection Job\n<color:green>queue: PM_MEASUREMENT_COLLECTION_JOB_UPDATE\n<color:green>payload: Measurement Collection Job with METRICO JOB_ID and METRICS - amq -> tmf_api: UPDATE TMF628 Measurement Collection Job\n<color:green>queue: PM_MEASUREMENT_COLLECTION_JOB_UPDATE\n<color:green>payload: Measurement Collection Job with METRICO JOB_ID and METRICS + metrico -> metrico : parse data from reply and cast them to data access endpoint + metrico -> amq : UPDATE: Related service to the Service Inventory\n<color:red>queue:? \n<color:red>payload: ??? amq -> tmf_api: UPDATE: Related service to the Service Inventory\n<color:red>queue:? \n<color:red>payload: ??? end diff --git a/src/main/java/org/etsi/osl/metrico/JsonUtil.java b/src/main/java/org/etsi/osl/metrico/JsonUtil.java new file mode 100644 index 0000000000000000000000000000000000000000..6b098a50e882a26680eed454129fd1a55ded6ab9 --- /dev/null +++ b/src/main/java/org/etsi/osl/metrico/JsonUtil.java @@ -0,0 +1,15 @@ +package org.etsi.osl.metrico; + +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.databind.ObjectMapper; + +import java.io.IOException; + +public class JsonUtil { + + public static <T> T toJsonObj(String content, Class<T> valueType) throws IOException { + ObjectMapper mapper = new ObjectMapper(); + mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL); + return mapper.readValue( content, valueType); + } +} \ No newline at end of file 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 7f2d14a547eeb45b27ddcfa3ad12ce3179b670c9..a192d4c12bcac3b1291f9b635ef8856ba28c3fc5 100644 --- a/src/main/java/org/etsi/osl/metrico/prometheus/PrometheusQueries.java +++ b/src/main/java/org/etsi/osl/metrico/prometheus/PrometheusQueries.java @@ -33,6 +33,7 @@ public class PrometheusQueries { logger.atInfo().log("Sent query at prometheus with URL: " + prometheusUrl + " with query: " + query); ResponseEntity<String> response = restTemplate.getForEntity(builder.toUriString(), String.class); + logger.atDebug().log("Received " + response.getBody()); return response.getBody(); } 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 13554b046cda88a88630b2e60ab6781ff2073442..595ce1ceb2e8d878179a420f418fdbe0d32383b8 100644 --- a/src/main/java/org/etsi/osl/metrico/services/MetricoService.java +++ b/src/main/java/org/etsi/osl/metrico/services/MetricoService.java @@ -2,15 +2,19 @@ package org.etsi.osl.metrico.services; import jakarta.validation.constraints.NotNull; import org.apache.camel.ProducerTemplate; +import org.etsi.osl.metrico.JsonUtil; 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.pm628.model.*; +import org.etsi.osl.tmf.so641.model.ServiceOrder; 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.stereotype.Service; +import java.io.IOException; import java.time.OffsetDateTime; import java.util.ArrayList; import java.util.List; @@ -23,6 +27,9 @@ public class MetricoService { @Value("{PM_MEASUREMENT_COLLECTION_JOB_UPDATE}") private String PM_MEASUREMENT_COLLECTION_JOB_UPDATE = ""; + @Value("{PM_MEASUREMENT_COLLECTION_JOB_GET_BY_ID}") + private String PM_MEASUREMENT_COLLECTION_JOB_GET_BY_ID = ""; + private final PrometheusQueries prometheusQueries; private final ProducerTemplate producerTemplate; @@ -35,6 +42,9 @@ public class MetricoService { return prometheusQueries.sendQueryToPrometheus(promURL, promQuery); } + @Autowired + private ProducerTemplate template; + public String[] queryToPrometheus(@NotNull MeasurementCollectionJob givenMCJ){ DataAccessEndpoint givenDataAccessEndpoint = givenMCJ.getDataAccessEndpoint().get(0); Job job = JobMapper.measurementCollectionJobMapToJob(givenMCJ); @@ -65,7 +75,7 @@ public class MetricoService { return promResponse; } - public String 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(); @@ -85,11 +95,44 @@ public class MetricoService { if (newPeriodicQuery.getState() == ExecutionStateType.FAILED) { logger.atError().setMessage("Periodic query failed to start due to internal error.").log(); - return "Periodic query failed to start."; + } else { logger.atInfo().setMessage("Periodic query started, with ID: " + newPeriodicQuery.getUuid()).log(); - return "Periodic query started with ID: " + newPeriodicQuery.getUuid(); + + } + + // MCJ UPdate kai stelnw state sto MCJ _ UPDATE + } + + public void startPeriodicQueryToPrometheus(@NotNull MeasurementCollectionJobRef mcjRef){ + MeasurementCollectionJob givenMCJ = retrieveMeasurementCollectionJob(mcjRef); + + startPeriodicQueryToPrometheus(givenMCJ); + } + + 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_JOB_GET_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); } } 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 76f1fbd823f12cfa4c6a95559acd439e06c1355f..2014a084be28e60899a1c433d6cc26c98eb8d6fc 100644 --- a/src/main/java/org/etsi/osl/metrico/services/MetricoServiceRouteBuilder.java +++ b/src/main/java/org/etsi/osl/metrico/services/MetricoServiceRouteBuilder.java @@ -6,7 +6,8 @@ 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.so641.model.ServiceOrderUpdate; +import org.etsi.osl.tmf.pm628.model.MeasurementCollectionJobCreateEvent; +import org.etsi.osl.tmf.pm628.model.MeasurementCollectionJobRef; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Configuration; @@ -21,17 +22,28 @@ public class MetricoServiceRouteBuilder extends RouteBuilder { @Autowired private MetricoService metricoService; - @Value("${PM_MEASUREMENT_COLLECTION_JOB_CREATED}") - private String PM_MEASUREMENT_COLLECTION_JOB_CREATED = ""; + @Value("${EVENT_MEASUREMENT_COLLECTION_JOB_CREATED}") + private String EVENT_MEASUREMENT_COLLECTION_JOB_CREATED = ""; public void configure() throws Exception { - from(PM_MEASUREMENT_COLLECTION_JOB_CREATED) - .log(LoggingLevel.INFO, log, PM_MEASUREMENT_COLLECTION_JOB_CREATED + " message received!") + 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_CREATED) + .log(LoggingLevel.INFO, log, EVENT_MEASUREMENT_COLLECTION_JOB_CREATED + " message received!") + .to("log:DEBUG?showBody=true&showHeaders=true") + .unmarshal().json(JsonLibrary.Jackson, MeasurementCollectionJobCreateEvent.class, true) + .process(exchange -> { + MeasurementCollectionJobCreateEvent event = exchange.getIn().getBody(MeasurementCollectionJobCreateEvent.class); + MeasurementCollectionJobRef jobRef = event.getEvent().getMeasurementCollectionJob(); + exchange.getIn().setBody(jobRef); + }) + .bean(metricoService, "startPeriodicQueryToPrometheus(${body})"); + } diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index 0458f430c2465dfdca9a1ed40fe77f847bf6db86..a8427ff428d4e1cbd5e20f154fa2f0db3ab48e11 100644 --- a/src/main/resources/application.yml +++ b/src/main/resources/application.yml @@ -65,9 +65,12 @@ scheduling.enabled: true METRICO_THREAD_POOL_SIZE: 10 #TMF QUEUES -PM_GET_MEASUREMENT_COLLECTION_JOB_BY_ID: "jms:queue:PM.GET.MEASUREMENTCOLLECTIONJOB_BY_ID" -PM_GET_MEASUREMENT_COLLECTION_JOBS: "jms:queue:PM.GET.MEASUREMENTCOLLECTIONJOBS" -PM_ADD_MEASUREMENT_COLLECTION_JOB: "jms:queue:PM.ADD.MEASUREMENTCOLLECTIONJOB" -PM_UPDATE_MEASUREMENT_COLLECTION_JOB: "jms:queue:PM.UPD.MEASUREMENTCOLLECTIONJOB" -PM_MEASUREMENT_COLLECTION_JOB_CREATED: "jms:queue:PM.MEASUREMENTCOLLECTIONJOB.CREATED" +PM_MEASUREMENT_COLLECTION_GET_JOB_BY_ID: "jms:queue:PM.MEASUREMENTCOLLECTIONJOB.GET_BY_ID" +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" + +EVENT_MEASUREMENT_COLLECTION_JOB_CREATED: "jms:topic:EVENT.MEASUREMENTCOLLECTIONJOB.CREATE" +EVENT_MEASUREMENT_COLLECTION_JOB_EXECUTION_STATE_CHANGED: "jms:topic:EVENT.MEASUREMENTCOLLECTIONJOB.STATECHANGED" +EVENT_MEASUREMENT_COLLECTION_JOB_DELETE: "jms:topic:EVENT.MEASUREMENTCOLLECTIONJOB.DELETE" +EVENT_MEASUREMENT_COLLECTION_JOB_ATTRIBUTE_VALUE_CHANGED: "jms:topic:EVENT.MEASUREMENTCOLLECTIONJOB.ATTRCHANGED" \ No newline at end of file