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); + } + } + +}