From 5fd0452387ccff6995c19ec5eeb7866328e34cbc Mon Sep 17 00:00:00 2001 From: sreeja gattagouni Date: Fri, 9 Sep 2022 16:16:30 +0530 Subject: [PATCH] Rollback Scenario for recursive orchestration -Child Services may fail in any of the BB's while creation of composite services, to handle in efficient manner, it is complied with existing rollback logic. -In case of Child Services >1 , when Workflow fails, the instantiated child remains in COMPLETED status, thus rollback changes ensure that such services are Deleted by triggering DeleteChildSvcBB. -Parent Service is ROLLED-BACK in case of any child service failing in the workflow. Instantiated child services are Deleted from AAI as well. Issue-ID: SO-3982 Change-ID:I73f97f986a817d423f92f8d922dcd9647b8a2503 Signed-off-by: sreeja gattagouni --- .../main/resources/db/migration/R__MacroData.sql | 3 +- .../BuildingBlock/DeleteChildServiceBB.bpmn | 173 ++++++++++++++++----- .../service/composition/DeleteChildServiceBB.java | 115 +++++++++++++- 3 files changed, 247 insertions(+), 44 deletions(-) diff --git a/adapters/mso-catalog-db-adapter/src/main/resources/db/migration/R__MacroData.sql b/adapters/mso-catalog-db-adapter/src/main/resources/db/migration/R__MacroData.sql index c1a67a5990..84c746e2f9 100644 --- a/adapters/mso-catalog-db-adapter/src/main/resources/db/migration/R__MacroData.sql +++ b/adapters/mso-catalog-db-adapter/src/main/resources/db/migration/R__MacroData.sql @@ -908,4 +908,5 @@ VALUES ('VNFStopActivity',NULL,'VNFStartActivity',NULL), ('VNFQuiesceTrafficActivity',NULL,'VNFResumeTrafficActivity',NULL), ('EtsiVnfInstantiateBB',NULL,'EtsiVnfDeleteBB',NULL), -('AddFabricConfigurationBB',NULL,'DeleteFabricConfigurationBB',NULL); +('AddFabricConfigurationBB',NULL,'DeleteFabricConfigurationBB',NULL), +('CreateChildServiceBB',NULL,'DeleteChildServiceBB',NULL); \ No newline at end of file diff --git a/bpmn/so-bpmn-building-blocks/src/main/resources/subprocess/BuildingBlock/DeleteChildServiceBB.bpmn b/bpmn/so-bpmn-building-blocks/src/main/resources/subprocess/BuildingBlock/DeleteChildServiceBB.bpmn index 3be6d32792..b065ca1523 100644 --- a/bpmn/so-bpmn-building-blocks/src/main/resources/subprocess/BuildingBlock/DeleteChildServiceBB.bpmn +++ b/bpmn/so-bpmn-building-blocks/src/main/resources/subprocess/BuildingBlock/DeleteChildServiceBB.bpmn @@ -1,5 +1,5 @@ - + SequenceFlow_01wirq3 @@ -18,8 +18,7 @@ PT5H - - + @@ -29,93 +28,185 @@ SequenceFlow_0v4loyx + Flow_0wfcckg ${execution.getVariable("CHILD_SVC_REQ_STATUS")=="COMPLETED"} - - SequenceFlow_01wirq3 - SequenceFlow_0q6aqsk - - SequenceFlow_0q6aqsk + Flow_0b6onv7 + Flow_0o9v00r SequenceFlow_14d89qf SequenceFlow_12rysg7 + + + Flow_1a6111h + Flow_0zrdr8f + + + Flow_0zrdr8f + Flow_0wfcckg + Flow_046pbsy + + + ${execution.getVariable("CHILD_SVC_REQ_STATUS") == "fail" && execution.getVariable("requestAction") == "createInstance" } + + + Flow_046pbsy + Flow_0o9v00r + + + + + Flow_168wu4x + Flow_0b6onv7 + + + Flow_1j43din + Flow_1a6111h + Flow_168wu4x + + + + ${execution.getVariable("requestAction") == "deleteInstance" } + + + + + SequenceFlow_01wirq3 + Flow_1j43din + + + + + + + + + + + + + + + + + + + + - - + + - - + + - + - - + + + - + - - + + - - - - - - + + - - + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - + - + - + - + - + - - + + + + + + + + - + - - + + + + + + + + + + + + + + - + - + diff --git a/bpmn/so-bpmn-tasks/src/main/java/org/onap/so/bpmn/infrastructure/service/composition/DeleteChildServiceBB.java b/bpmn/so-bpmn-tasks/src/main/java/org/onap/so/bpmn/infrastructure/service/composition/DeleteChildServiceBB.java index 52d1b68ccd..9a2da2a748 100644 --- a/bpmn/so-bpmn-tasks/src/main/java/org/onap/so/bpmn/infrastructure/service/composition/DeleteChildServiceBB.java +++ b/bpmn/so-bpmn-tasks/src/main/java/org/onap/so/bpmn/infrastructure/service/composition/DeleteChildServiceBB.java @@ -16,6 +16,15 @@ package org.onap.so.bpmn.infrastructure.service.composition; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.UUID; +import org.onap.aai.domain.yang.ComposedResource; +import org.onap.aai.domain.yang.RelatedToProperty; +import org.onap.aai.domain.yang.Relationship; +import org.onap.aai.domain.yang.RelationshipData; import org.onap.aai.domain.yang.ServiceInstance; import org.onap.aaiclient.client.aai.AAIResourcesClient; import org.onap.aaiclient.client.aai.entities.uri.AAIUriFactory; @@ -35,8 +44,6 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; -import java.util.Map; -import java.util.UUID; import static org.onap.so.bpmn.infrastructure.service.composition.ServiceCompositionConstants.CHILD_SVC_INSTANCE_ID; import static org.onap.so.bpmn.infrastructure.service.composition.ServiceCompositionConstants.CHILD_SVC_REQ_CORRELATION_ID; import static org.onap.so.bpmn.infrastructure.service.composition.ServiceCompositionConstants.CHILD_SVC_REQ_ERROR; @@ -44,9 +51,13 @@ import static org.onap.so.bpmn.infrastructure.service.composition.ServiceComposi import static org.onap.so.bpmn.infrastructure.service.composition.ServiceCompositionConstants.CHILD_SVC_REQ_PAYLOAD; + @Component public class DeleteChildServiceBB { + private static final String ROLLBACK_TARGET_STATE = "rollbackTargetState"; + private static final String REQUEST_ACTION = "requestAction"; + public static final String CHILD_SVC_REQ_STATUS = "CHILD_SVC_REQ_STATUS"; @Autowired protected ExceptionBuilder exceptionBuilder; @@ -57,6 +68,7 @@ public class DeleteChildServiceBB { private final Logger log = LoggerFactory.getLogger(this.getClass()); + public void buildRequest(final BuildingBlockExecution buildingBlockExecution) { log.info("Building Delete Service Request"); Map lookupMap = buildingBlockExecution.getLookupMap(); @@ -90,6 +102,105 @@ public class DeleteChildServiceBB { buildingBlockExecution.setVariable(CHILD_SVC_REQ_PAYLOAD, sir); } + + public void setRequestAction(final BuildingBlockExecution buildingBlockExecution) { + String action = buildingBlockExecution.getGeneralBuildingBlock().getRequestContext().getAction(); + buildingBlockExecution.setVariable(REQUEST_ACTION, action); + } + + public void checkIfChildInstantiated(final BuildingBlockExecution buildingBlockExecution) { + try { + Map lookupMap = buildingBlockExecution.getLookupMap(); + + String parentServiceInstanceId = buildingBlockExecution.getLookupMap().get(ResourceKey.SERVICE_INSTANCE_ID); + + String childSvcInstanceName = lookupMap.get(ResourceKey.CHILD_SERVICE_INSTANCE_NAME); + + ServiceInstance parentInstanceAAI = + aaiResourcesClient.get(ServiceInstance.class, + AAIUriFactory.createResourceUri( + AAIFluentTypeBuilder.Types.SERVICE_INSTANCE.getFragment(parentServiceInstanceId)) + .depth(Depth.TWO)) + .orElse(null); + + + + if (parentInstanceAAI.getComposedResources() != null) { + List composedResources = + parentInstanceAAI.getComposedResources().getComposedResource(); + + + + List> relationship = new ArrayList<>(); + for (ComposedResource composedResource : composedResources) { + if (composedResource.getRelationshipList() != null) { + relationship.add(composedResource.getRelationshipList().getRelationship()); + } + } + + List> relationshipData = new ArrayList<>(); + List> relatedToProperties = new ArrayList<>(); + + for (int i = 0; i < relationship.size(); i++) { + for (Relationship relationshipList : relationship.get(i)) { + relatedToProperties.add(relationshipList.getRelatedToProperty()); + relationshipData.add(relationshipList.getRelationshipData()); + } + } + + + String childInstanceId = null; + for (int i = 0; i < relationship.size(); i++) { + for (RelatedToProperty relatedToProperty1 : relatedToProperties.get(i)) { + if (relatedToProperty1.getPropertyValue().equalsIgnoreCase(childSvcInstanceName)) { + for (RelationshipData relationshipData1 : relationshipData.get(i)) { + if (relationshipData1.getRelationshipKey() + .equals("service-instance.service-instance-id")) { + childInstanceId = relationshipData1.getRelationshipValue(); + break; + } + } + } + } + } + if (childInstanceId != null) { + lookupMap.put(ResourceKey.CHILD_SERVICE_INSTANCE_ID, childInstanceId); + buildingBlockExecution.setVariable(ROLLBACK_TARGET_STATE, "Rollback"); + buildingBlockExecution.setVariable(REQUEST_ACTION, "createInstance"); + } else { + buildingBlockExecution.setVariable(REQUEST_ACTION, "createInstance"); + buildingBlockExecution.setVariable(CHILD_SVC_REQ_STATUS, "fail"); + } + } else { + buildingBlockExecution.setVariable(REQUEST_ACTION, "createInstance"); + buildingBlockExecution.setVariable(CHILD_SVC_REQ_STATUS, "fail"); + } + } catch (Exception e) { + exceptionBuilder.buildAndThrowWorkflowException(buildingBlockExecution, 10005, e.getMessage(), + ONAPComponents.SO); + } + } + + public void buildRequestRollBack(final BuildingBlockExecution buildingBlockExecution) { + try { + log.info("buildRequestRollBack Create Service Request"); + Map lookupMap = buildingBlockExecution.getLookupMap(); + String childSvcInstanceName = lookupMap.get(ResourceKey.CHILD_SERVICE_INSTANCE_NAME); + String childSvcInstanceId = lookupMap.get(ResourceKey.CHILD_SERVICE_INSTANCE_ID); + Objects.requireNonNull(childSvcInstanceName, "Child service instance name is required"); + + ServiceInstancesRequest sir = ChildServiceRequestBuilder + .getInstance(buildingBlockExecution, childSvcInstanceName) + .setParentRequestId( + buildingBlockExecution.getGeneralBuildingBlock().getRequestContext().getMsoRequestId()) + .setChildSvcInstanceId(childSvcInstanceId).setCorrelationId(UUID.randomUUID().toString()).build(); + buildingBlockExecution.setVariable(CHILD_SVC_REQ_PAYLOAD, sir); + } catch (Exception e) { + exceptionBuilder.buildAndThrowWorkflowException(buildingBlockExecution, 10002, e.getMessage(), + ONAPComponents.SO); + } + } + public void sendRequest(final BuildingBlockExecution buildingBlockExecution) { try { ServiceInstancesRequest sir = buildingBlockExecution.getVariable(CHILD_SVC_REQ_PAYLOAD); -- 2.16.6