diff --git a/.gitignore b/.gitignore
index 5601d3bbb232b817dddb815531d4697e507721ab..8e0205a449e01acb7efd65ef653308fadc31a32a 100644
--- a/.gitignore
+++ b/.gitignore
@@ -2,3 +2,4 @@
.project
.classpath
/.settings
+/.bpmn
\ No newline at end of file
diff --git a/Dockerfile b/Dockerfile
index 4709a015efb079474cf8a24dcb980ecc2307b9c7..c0080330bc70bc04d8fc0b3134ddb3e826dd9586 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -2,7 +2,7 @@ FROM ibm-semeru-runtimes:open-17.0.7_7-jdk
MAINTAINER openslice.io
RUN mkdir /opt/shareclasses
RUN mkdir -p /opt/openslice/lib/
-COPY target/org.etsi.osl.osom-1.1.0.jar /opt/openslice/lib/
-COPY target/org.etsi.osl.osom-1.1.0-exec.jar /opt/openslice/lib/
+COPY target/org.etsi.osl.osom-1.2.0.jar /opt/openslice/lib/
+COPY target/org.etsi.osl.osom-1.2.0-exec.jar /opt/openslice/lib/
COPY . /opt/openslice/lib/
-CMD ["java", "-Xshareclasses:cacheDir=/opt/shareclasses","-jar", "/opt/openslice/lib/org.etsi.osl.osom-1.1.0-exec.jar"]
\ No newline at end of file
+CMD ["java", "-Xshareclasses:cacheDir=/opt/shareclasses","-jar", "/opt/openslice/lib/org.etsi.osl.osom-1.2.0-exec.jar"]
\ No newline at end of file
diff --git a/pom.xml b/pom.xml
index ead5841d3b79af566cde234fa5265e28a20d59f7..441a138032f4f9968cf3a9ee09b1fdad2632ae44 100644
--- a/pom.xml
+++ b/pom.xml
@@ -5,7 +5,7 @@
org.etsi.osl
org.etsi.osl.main
- 2024Q4
+ 2025Q2
../org.etsi.osl.main
diff --git a/src/main/java/org/etsi/osl/osom/lcm/LcmBaseExecutor.java b/src/main/java/org/etsi/osl/osom/lcm/LcmBaseExecutor.java
index 7e7025a8e3f8afa93637d2e72bb42b33722c70b7..741676df2304f99327e3d3124c91552ad930e6a7 100644
--- a/src/main/java/org/etsi/osl/osom/lcm/LcmBaseExecutor.java
+++ b/src/main/java/org/etsi/osl/osom/lcm/LcmBaseExecutor.java
@@ -1,6 +1,9 @@
package org.etsi.osl.osom.lcm;
+import java.io.File;
import java.io.IOException;
+import java.time.LocalDate;
+import java.time.LocalTime;
import java.time.OffsetDateTime;
import java.time.ZoneOffset;
import java.util.ArrayList;
@@ -11,15 +14,20 @@ import java.util.function.Consumer;
import javax.net.ssl.SSLException;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.core.exc.StreamWriteException;
import com.fasterxml.jackson.core.type.TypeReference;
+import com.fasterxml.jackson.core.util.DefaultPrettyPrinter;
+import com.fasterxml.jackson.databind.DatabindException;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.ObjectWriter;
import com.fasterxml.jackson.databind.node.ArrayNode;
import com.jayway.jsonpath.Configuration;
import com.jayway.jsonpath.JsonPath;
import com.jayway.jsonpath.Option;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
+import org.apache.commons.text.StringEscapeUtils;
import org.etsi.osl.osom.partnerservices.GenericClient;
import org.etsi.osl.tmf.common.model.Any;
import org.etsi.osl.tmf.common.model.EValueType;
@@ -126,7 +134,7 @@ public abstract class LcmBaseExecutor {
}
- private Optional getCharacteristicByName(String charName) {
+ protected Optional getCharacteristicByName(String charName) {
List serviceCharacteristic;
if (lcmspec.getLcmrulephase().equals("PRE_PROVISION") || this.vars.getService() == null) {
@@ -225,19 +233,31 @@ public abstract class LcmBaseExecutor {
return -1;
}
+
public String getCharValAsString(String charName) {
- logger.debug("getCharValAsString " + charName);
- Optional c = getCharacteristicByName(charName);
+ Optional characteristic = getCharacteristicByName(charName);
- if (c.isPresent()) {
- logger.debug("getCharValAsString " + c.get().getValue().getValue());
- return c.get().getValue().getValue();
+ logger.info("Getting characteristic value as a string...");
+
+ if (characteristic.isPresent()) {
+ return characteristic.get().getValue().getValue();
}
-
- logger.debug("getCharValAsString NULL ");
+
return null;
+ }
+
+ public String escapeText(String s) {
+ if (s == null || s.isEmpty()) {
+ logger.debug("escapeText NULL ");
+ return null;
+ }
+
+ logger.info("Escaping string...");
+
+ return "\"" + StringEscapeUtils.escapeJava(s) + "\"";
}
+
public Boolean getCharValFromBooleanType(String charName) {
logger.debug("getCharValFromBooleanType " + charName);
diff --git a/src/main/java/org/etsi/osl/osom/management/MetricoOrchestrationService.java b/src/main/java/org/etsi/osl/osom/management/MetricoOrchestrationService.java
index d2ee32a5c4218e3b0723796d2272ce9622702d61..faf1c9ff4ee896b615d390b7cc165658d9ac202a 100644
--- a/src/main/java/org/etsi/osl/osom/management/MetricoOrchestrationService.java
+++ b/src/main/java/org/etsi/osl/osom/management/MetricoOrchestrationService.java
@@ -81,25 +81,16 @@ public class MetricoOrchestrationService implements JavaDelegate {
String cfs_id = String.valueOf(serviceCharacteristic.getValue().getValue());
mcjFVO.setConsumingApplicationId(cfs_id);
- serviceCharacteristic = aService.getServiceCharacteristicByName("_MT_END_TIME");
- String endTimeString = String.valueOf(serviceCharacteristic.getValue().getValue());
ScheduleDefinitionFVO scheduleDefinition = new ScheduleDefinitionFVO();
- if (endTimeString != null && !endTimeString.equals("")) {
- OffsetDateTime endTime = convertStringToOffsetDateTime(endTimeString, DateTimeFormat.ISO.DATE_TIME );
- scheduleDefinition.setScheduleDefinitionEndTime(endTime);
- } else{
- OffsetDateTime endTime = OffsetDateTime.now().plusHours(1);
- scheduleDefinition.setScheduleDefinitionEndTime(endTime);
+ if(aService.getStartDate() != null) {
+ scheduleDefinition.setScheduleDefinitionStartTime(aService.getStartDate());
+ } else {
+ scheduleDefinition.setScheduleDefinitionStartTime(OffsetDateTime.now(ZoneOffset.UTC));
}
-
- serviceCharacteristic = aService.getServiceCharacteristicByName("_MT_START_TIME");
- String startTimeString = String.valueOf(serviceCharacteristic.getValue().getValue());
- if (startTimeString != null&& !startTimeString.equals("")) {
- OffsetDateTime startTime = convertStringToOffsetDateTime(startTimeString, DateTimeFormat.ISO.DATE_TIME );
- scheduleDefinition.setScheduleDefinitionStartTime(startTime);
- } else{
- OffsetDateTime startTime = OffsetDateTime.now();
- scheduleDefinition.setScheduleDefinitionStartTime(startTime);
+ if(aService.getEndDate() != null) {
+ scheduleDefinition.setScheduleDefinitionEndTime(aService.getEndDate());
+ } else {
+ scheduleDefinition.setScheduleDefinitionEndTime(OffsetDateTime.now(ZoneOffset.UTC).plusHours(1));
}
List scheduleDefinitions = new ArrayList<>();
scheduleDefinitions.add(scheduleDefinition);
@@ -161,7 +152,7 @@ public class MetricoOrchestrationService implements JavaDelegate {
su = new ServiceUpdate();// the object to update the service
MeasurementCollectionJob mcj = serviceOrderManager.addMeasurementCollectionJob(mcjFVO);
if (mcj != null){
- logger.info("Measurement Collection Job was not created.");
+ logger.info("Measurement Collection Job was created.");
serviceCharacteristic = new Characteristic();
serviceCharacteristic.setName( "_MT_MCJ_REFID" );
@@ -171,7 +162,15 @@ public class MetricoOrchestrationService implements JavaDelegate {
val.setAlias( "" );
serviceCharacteristic.setValue(val);
su.addServiceCharacteristicItem(serviceCharacteristic);
-
+
+ MeasurementCollectionJobMVO mcjMVO = new MeasurementCollectionJobMVO();
+ mcjMVO.setExecutionState(ExecutionStateType.ACKNOWLEDGED);
+ try {
+ serviceOrderManager.updateMeasurementCollectionJobById(mcj.getUuid(), mcjMVO);
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+
} else {
logger.error("Measurement Collection Job was not created.");
su.setState(ServiceStateType.TERMINATED);
diff --git a/src/main/java/org/etsi/osl/osom/management/ServiceOrderManager.java b/src/main/java/org/etsi/osl/osom/management/ServiceOrderManager.java
index 54bc509931a98b683ede8b543afa2c023a7af1a4..55c4dc0746ec57949651c93b2b94607fc91a5e63 100644
--- a/src/main/java/org/etsi/osl/osom/management/ServiceOrderManager.java
+++ b/src/main/java/org/etsi/osl/osom/management/ServiceOrderManager.java
@@ -37,6 +37,7 @@ import org.etsi.osl.model.nfv.ScaleDescriptor;
import org.etsi.osl.osom.serviceactions.NSActionRequestPayload;
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.etsi.osl.tmf.pm632.model.Organization;
import org.etsi.osl.tmf.rcm634.model.LogicalResourceSpecification;
import org.etsi.osl.tmf.rcm634.model.ResourceSpecification;
@@ -200,6 +201,9 @@ public class ServiceOrderManager {
@Value("${PM_MEASUREMENT_COLLECTION_JOB_ADD}")
private String PM_MEASUREMENT_COLLECTION_JOB_ADD = "";
+ @Value("${PM_MEASUREMENT_COLLECTION_JOB_UPDATE}")
+ private String PM_MEASUREMENT_COLLECTION_JOB_UPDATE;
+
@Transactional
public void processOrder(ServiceOrder serviceOrder) {
@@ -1167,6 +1171,39 @@ public class ServiceOrderManager {
return null;
}
+ /**
+ * Updates a Measurement Collection Job in the database using the given Measurement Collection 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) throws IOException {
+
+ MeasurementCollectionJob measurementCollectionJob;
+ logger.debug("will update MeasurementCollectionJob with id "+ mcjId+" and \nMeasurementCollectionJob.toString():\n"+ toJsonString(mcjMVO));
+
+
+ try {
+ Map map = new HashMap<>();
+ map.put("mcjid", mcjId);
+
+ Object response = template.requestBodyAndHeaders(PM_MEASUREMENT_COLLECTION_JOB_UPDATE, toJsonString(mcjMVO), map);
+ logger.info("JsonUtil.toJsonString(mcjMVO): \n" + toJsonString(mcjMVO));
+ if (!(response instanceof String)) {
+ logger.error("MeasurementCollectionJob object is wrong.");
+ return null;
+ }
+ measurementCollectionJob = toJsonObj((String) response, MeasurementCollectionJob.class);
+ logger.info("response from PM_MEASUREMENT_COLLECTION_JOB_UPDATE: " + response);
+ return measurementCollectionJob;
+ } catch (Exception e) {
+ e.printStackTrace();
+ logger.error("Cannot update MeasurementCollectionJob with id " + mcjId + ":\n" + e.toString());
+ }
+ return null;
+ }
+
diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml
index 55f42c5636cfe3b05067d1761724e6c8d98b354e..baeda0136ce55d5294b0f944dfa4adccf9e7c1d0 100644
--- a/src/main/resources/application.yml
+++ b/src/main/resources/application.yml
@@ -127,4 +127,5 @@ CRD_DELETE_CR_REQ: "jms:queue:CRD.DELETE.CR_REQ"
CRD_PATCH_CR_REQ: "jms:queue:CRD.PATCH.CR_REQ"
#TMF628 ACTIONS
-PM_MEASUREMENT_COLLECTION_JOB_ADD: "jms:queue:PM.MEASUREMENTCOLLECTIONJOB.ADD"
\ No newline at end of file
+PM_MEASUREMENT_COLLECTION_JOB_ADD: "jms:queue:PM.MEASUREMENTCOLLECTIONJOB.ADD"
+PM_MEASUREMENT_COLLECTION_JOB_UPDATE: "jms:queue:PM.MEASUREMENTCOLLECTIONJOB.UPDATE"
\ No newline at end of file
diff --git a/src/main/resources/processes/ServiceActionProcess.bpmn b/src/main/resources/processes/ServiceActionProcess.bpmn
index ef94cc7b313506d72e9738e90552f6d940e14017..5da9421383e53f084403e4b04e0abebda869857b 100644
--- a/src/main/resources/processes/ServiceActionProcess.bpmn
+++ b/src/main/resources/processes/ServiceActionProcess.bpmn
@@ -44,11 +44,11 @@
-
-
+
+
-
+
@@ -98,7 +98,7 @@
-
+
diff --git a/src/test/java/org/etsi/osl/osom/LcmBaseExecutorTest.java b/src/test/java/org/etsi/osl/osom/LcmBaseExecutorTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..1f02c9a8f33aa01d3cd15e6f24dc68dcb8decdff
--- /dev/null
+++ b/src/test/java/org/etsi/osl/osom/LcmBaseExecutorTest.java
@@ -0,0 +1,62 @@
+package org.etsi.osl.osom;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.spy;
+
+import java.util.Optional;
+
+import org.etsi.osl.tmf.common.model.Any;
+import org.etsi.osl.tmf.common.model.service.Characteristic;
+import org.etsi.osl.osom.LcmBaseExecutorTest.TestLcmBaseExecutor;
+import org.etsi.osl.osom.lcm.LcmBaseExecutor;
+import org.junit.Before;
+import org.junit.Test;
+
+public class LcmBaseExecutorTest {
+
+ private LcmBaseExecutor executor;
+
+ @Before
+ public void setUp() {
+ executor = spy(new TestLcmBaseExecutor());
+ }
+
+ @Test
+ public void testGetCharValAsString() {
+ // Test the method
+ String result = executor.getCharValAsString("Parameter");
+ String expected = "[{\"device\": {\"ipv4Address\": {}, \"networkAccessIdentifier\": \"123456789@domain.com\", \"phoneNumber\": \"+123456789\"}, \"provisioningId\": \"3fa85f64-5717-4562-b3fc-2c963f66afa6\", \"qosProfile\": \"QOS_A\", \"status\": \"AVAILABLE\", \"startedAt\": \"2024-12-12T09:52:26Z\"}]";
+ assertEquals(expected, result);
+ }
+
+ @Test
+ public void testEscapeText() {
+ String input = "[{\"device\": {\"ipv4Address\": {}, \"networkAccessIdentifier\": \"123456789@domain.com\", \"phoneNumber\": \"+123456789\"}, \"provisioningId\": \"3fa85f64-5717-4562-b3fc-2c963f66afa6\", \"qosProfile\": \"QOS_A\", \"status\": \"AVAILABLE\", \"startedAt\": \"2024-12-12T09:52:26Z\"}]";
+ String expected = "\"" + input.replace("\"", "\\\"") + "\"";
+ String result = executor.escapeText(input);
+
+ assertEquals(expected, result);
+ }
+
+ static class TestLcmBaseExecutor extends LcmBaseExecutor {
+ @Override
+ public void exec() {
+ }
+
+ @Override
+ protected Optional getCharacteristicByName(String charName) {
+ Any anyValue = new Any();
+ anyValue.setValue(
+ "[{\"device\": {\"ipv4Address\": {}, \"networkAccessIdentifier\": \"123456789@domain.com\", \"phoneNumber\": \"+123456789\"}, \"provisioningId\": \"3fa85f64-5717-4562-b3fc-2c963f66afa6\", \"qosProfile\": \"QOS_A\", \"status\": \"AVAILABLE\", \"startedAt\": \"2024-12-12T09:52:26Z\"}]"
+ );
+
+ Characteristic characteristic = new Characteristic();
+ characteristic.setName("Parameter");
+ characteristic.setValue(anyValue);
+
+ return Optional.of(characteristic);
+ }
+ }
+
+}