/*- * ============LICENSE_START======================================================= * OPENECOMP - SO * ================================================================================ * Copyright (C) 2018 Huawei Technologies Co., Ltd. All rights reserved. * ================================================================================ * Modifications Copyright (c) 2019 Samsung * ================================================================================ * 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.onap.so.bpmn.infrastructure.scripts import org.apache.commons.lang3.* import org.camunda.bpm.engine.delegate.BpmnError import org.camunda.bpm.engine.delegate.DelegateExecution import org.onap.aai.domain.yang.AllottedResource import org.onap.aai.domain.yang.Relationship import org.onap.aai.domain.yang.RelationshipData import org.onap.so.bpmn.common.recipe.ResourceInput import org.onap.so.bpmn.common.resource.ResourceRequestBuilder import org.onap.so.bpmn.common.scripts.AbstractServiceTaskProcessor import org.onap.so.bpmn.common.scripts.ExceptionUtil import org.onap.so.bpmn.common.scripts.MsoUtils import org.onap.so.bpmn.common.scripts.SDNCAdapterUtils import org.onap.so.bpmn.core.domain.ModelInfo import org.onap.so.bpmn.core.domain.ResourceType import org.onap.so.bpmn.core.json.JsonUtils import org.onap.so.bpmn.core.UrnPropertiesReader import org.onap.so.client.aai.AAIObjectType import org.onap.so.client.aai.AAIResourcesClient import org.onap.so.client.aai.entities.AAIResultWrapper import org.onap.so.client.aai.entities.uri.AAIResourceUri import org.onap.so.client.aai.entities.uri.AAIUriFactory import org.slf4j.Logger import org.slf4j.LoggerFactory import javax.ws.rs.NotFoundException import static org.apache.commons.lang3.StringUtils.* /** * This groovy class supports the DeleteSDNCCNetworkResource.bpmn process. * flow for SDNC Network Resource */ public class DeleteSDNCNetworkResource extends AbstractServiceTaskProcessor { private static final Logger logger = LoggerFactory.getLogger( DeleteSDNCNetworkResource.class); String Prefix="DELSDNCRES_" ExceptionUtil exceptionUtil = new ExceptionUtil() JsonUtils jsonUtil = new JsonUtils() SDNCAdapterUtils sdncAdapterUtils = new SDNCAdapterUtils() MsoUtils msoUtils = new MsoUtils() void preProcessRequest(DelegateExecution execution){ logger.info(" ***** Started preProcessRequest *****") try { //get bpmn inputs from resource request. String requestId = execution.getVariable("mso-request-id") String requestAction = execution.getVariable("requestAction") logger.info("The requestAction is: " + requestAction) String recipeParamsFromRequest = execution.getVariable("recipeParams") logger.info("The recipeParams is: " + recipeParamsFromRequest) String resourceInput = execution.getVariable("resourceInput") logger.info("The resourceInput is: " + resourceInput) //Get ResourceInput Object ResourceInput resourceInputObj = ResourceRequestBuilder.getJsonObject(resourceInput, ResourceInput.class) execution.setVariable(Prefix + "resourceInput", resourceInputObj) //Deal with recipeParams String recipeParamsFromWf = execution.getVariable("recipeParamXsd") String resourceModelName = resourceInputObj.getResourceModelInfo().getModelName() String resourceInstanceId = resourceInputObj.getResourceInstancenUuid() String globalCustomerId = resourceInputObj.getGlobalSubscriberId() String serviceType = resourceInputObj.getServiceType() String serviceInstanceId = resourceInputObj.getServiceInstanceId() // fetch parent instance id for allotted resources String modelType = resourceInputObj.getResourceModelInfo().getModelType() switch (modelType) { // sdwanvpnattachment or sotnvpnattachment case "ALLOTTED_RESOURCE": String parentServiceId = fetchParentServiceInstance(globalCustomerId, serviceType, serviceInstanceId, resourceInstanceId) if (null != parentServiceId) { execution.setVariable("allotedParentServiceInstanceId", parentServiceId) } else { logger.warn("Alloted Resource ParentServiceInstanceId not found in AAI response for allotedId: " + resourceInstanceId) } break; default: break; } //For sdnc requestAction default is "NetworkInstance" String operationType = "Network" if(!StringUtils.isBlank(recipeParamsFromRequest) && "null" != recipeParamsFromRequest){ //the operationType from worflow(first node) is second priority. operationType = jsonUtil.getJsonValue(recipeParamsFromRequest, "operationType") } if(!StringUtils.isBlank(recipeParamsFromWf)){ //the operationType from worflow(first node) is highest priority. operationType = jsonUtil.getJsonValue(recipeParamsFromWf, "operationType") } String operationTypeFromConfig = UrnPropertiesReader.getVariable("resource-config." + resourceInputObj.resourceModelInfo.getModelName() + ".operation-type") if (StringUtils.isNotEmpty(operationTypeFromConfig)) { // highest priority if operation type configured operationType = operationTypeFromConfig } //For sdnc, generate svc_action and request_action String sdnc_svcAction = "delete" String sdnc_requestAction = StringUtils.capitalize(sdnc_svcAction) + operationType + "Instance" String isActivateRequired = UrnPropertiesReader.getVariable("resource-config." + resourceInputObj.resourceModelInfo.getModelName() + ".activation-required") execution.setVariable("isActivateRequired", isActivateRequired) execution.setVariable(Prefix + "svcAction", sdnc_svcAction) execution.setVariable(Prefix + "requestAction", sdnc_requestAction) execution.setVariable(Prefix + "serviceInstanceId", resourceInputObj.getServiceInstanceId()) execution.setVariable("mso-request-id", requestId) execution.setVariable("mso-service-instance-id", resourceInputObj.getServiceInstanceId()) } catch (BpmnError e) { throw e; } catch (Exception ex){ String msg = "Exception in preProcessRequest " + ex.getMessage() logger.debug( msg) exceptionUtil.buildAndThrowWorkflowException(execution, 7000, msg) } logger.info(" ***** Exit preProcessRequest *****") } private String fetchParentServiceInstance(String globalCustId, String serviceType, String serviceInstanceId, String allotedResourceId ) { logger.trace("Entered fetchParentServiceInstance") try { String parentServiceId = ""; AAIResourcesClient resourceClient = new AAIResourcesClient(); AAIResourceUri serviceInstanceUri = AAIUriFactory.createResourceUri(AAIObjectType.ALLOTTED_RESOURCE, globalCustId, serviceType, serviceInstanceId, allotedResourceId) AAIResultWrapper aaiResult = resourceClient.get(serviceInstanceUri, NotFoundException.class) Optional si = aaiResult.asBean(AllottedResource.class) if((si.present) && (null != si.get().getRelationshipList()) && (null != si.get().getRelationshipList().getRelationship())) { logger.debug("SI Data relationship-list exists") List relationshipList = si.get().getRelationshipList().getRelationship() for (Relationship relationship : relationshipList) { String rt = relationship.getRelatedTo() List rl_datas = relationship.getRelationshipData() if(rt.equals("service-instance") ){ for (RelationshipData rl_data : rl_datas) { String eKey = rl_data.getRelationshipKey() String eValue = rl_data.getRelationshipValue() if(eKey.equals("service-instance.service-instance-id") && (!eValue.equals(serviceInstanceId))){ return eValue } } } } } logger.trace("Exited fetchParentServiceInstance") }catch(Exception e){ logger.debug("Error occured within deleteServiceInstance method: " + e) exceptionUtil.buildAndThrowWorkflowException(execution, 2500, "Error occured during deleteServiceInstance from aai") } return null } /** * Pre Process the BPMN Flow Request * Includes: * generate the nsOperationKey * generate the nsParameters */ void prepareSDNCRequest (DelegateExecution execution) { logger.info(" ***** Started prepareSDNCRequest *****") try { // get variables String sdnc_svcAction = execution.getVariable(Prefix + "svcAction") String sdnc_requestAction = execution.getVariable(Prefix + "requestAction") String sdncCallback = execution.getVariable("URN_mso_workflow_sdncadapter_callback") String deleteNetworkInput = execution.getVariable(Prefix + "networkRequest") String hdrRequestId = execution.getVariable("mso-request-id") String serviceInstanceId = execution.getVariable(Prefix + "serviceInstanceId") String source = execution.getVariable("source") String sdnc_service_id = execution.getVariable(Prefix + "sdncServiceId") String resourceInput = execution.getVariable(Prefix + "resourceInput") logger.info("The resourceInput is: " + resourceInput) String allotedParentServiceInstanceId = execution.getVariable("allotedParentServiceInstanceId") ResourceInput resourceInputObj = ResourceRequestBuilder.getJsonObject(resourceInput, ResourceInput.class) String serviceType = resourceInputObj.getServiceType() String serviceModelInvariantUuid = resourceInputObj.getServiceModelInfo().getModelInvariantUuid() String serviceModelUuid = resourceInputObj.getServiceModelInfo().getModelUuid() String serviceModelVersion = resourceInputObj.getServiceModelInfo().getModelVersion() String serviceModelName = resourceInputObj.getServiceModelInfo().getModelName() String globalCustomerId = resourceInputObj.getGlobalSubscriberId() String modelInvariantUuid = resourceInputObj.getResourceModelInfo().getModelInvariantUuid(); String modelCustomizationUuid = resourceInputObj.getResourceModelInfo().getModelCustomizationUuid() String modelUuid = resourceInputObj.getResourceModelInfo().getModelUuid() String modelName = resourceInputObj.getResourceModelInfo().getModelName() String modelVersion = resourceInputObj.getResourceModelInfo().getModelVersion() String resourceInstnaceId = resourceInputObj.getResourceInstancenUuid() String modelType = resourceInputObj.getResourceModelInfo().getModelType() // 1. prepare assign topology via SDNC Adapter SUBFLOW call String sdncTopologyDeleteRequest = "" switch (modelType) { case "VNF": sdncTopologyDeleteRequest = """ ${msoUtils.xmlEscape(hdrRequestId)} ${msoUtils.xmlEscape(serviceInstanceId)} ${msoUtils.xmlEscape(sdnc_svcAction)} vnf-topology-operation sdncCallback generic-resource ${msoUtils.xmlEscape(hdrRequestId)} ${msoUtils.xmlEscape(sdnc_requestAction)} ${msoUtils.xmlEscape(source)} ${msoUtils.xmlEscape(serviceInstanceId)} ${msoUtils.xmlEscape(serviceType)} ${msoUtils.xmlEscape(serviceModelInvariantUuid)} ${msoUtils.xmlEscape(serviceModelUuid)} ${msoUtils.xmlEscape(serviceModelVersion)} ${msoUtils.xmlEscape(serviceModelName)} ${msoUtils.xmlEscape(serviceInstanceId)} ${msoUtils.xmlEscape(globalCustomerId)} ${msoUtils.xmlEscape(globalCustomerId)} $resourceInstnaceId ${msoUtils.xmlEscape(modelInvariantUuid)} ${msoUtils.xmlEscape(modelCustomizationUuid)} ${msoUtils.xmlEscape(modelUuid)} ${msoUtils.xmlEscape(modelVersion)} ${msoUtils.xmlEscape(modelName)} """.trim() break case "GROUP" : //When a new resource creation request reaches SO, the parent resources information needs to be provided //while creating the child resource. String vnfid = resourceInputObj.getVnfId() ModelInfo vfModelInfo = resourceInputObj.getVfModelInfo() String vnfmodelInvariantUuid = vfModelInfo.getModelInvariantUuid() String vnfmodelCustomizationUuid = vfModelInfo.getModelCustomizationUuid() String vnfmodelUuid = vfModelInfo.getModelUuid() String vnfmodelVersion = vfModelInfo.getModelVersion() String vnfmodelName = vfModelInfo.getModelName() sdncTopologyDeleteRequest = """ ${msoUtils.xmlEscape(hdrRequestId)} ${msoUtils.xmlEscape(serviceInstanceId)} ${msoUtils.xmlEscape(sdnc_svcAction)} vf-module-topology-operation sdncCallback generic-resource ${msoUtils.xmlEscape(hdrRequestId)} ${msoUtils.xmlEscape(sdnc_requestAction)} ${msoUtils.xmlEscape(source)} ${msoUtils.xmlEscape(serviceInstanceId)} ${msoUtils.xmlEscape(serviceType)} ${msoUtils.xmlEscape(serviceModelInvariantUuid)} ${msoUtils.xmlEscape(serviceModelUuid)} ${msoUtils.xmlEscape(serviceModelVersion)} ${msoUtils.xmlEscape(serviceModelName)} ${msoUtils.xmlEscape(serviceInstanceId)} ${msoUtils.xmlEscape(globalCustomerId)} ${msoUtils.xmlEscape(globalCustomerId)} $vnfid ${msoUtils.xmlEscape(vnfmodelInvariantUuid)} ${msoUtils.xmlEscape(vnfmodelCustomizationUuid)} ${msoUtils.xmlEscape(vnfmodelUuid)} ${msoUtils.xmlEscape(vnfmodelVersion)} ${msoUtils.xmlEscape(vnfmodelName)} $resourceInstnaceId false ${msoUtils.xmlEscape(modelInvariantUuid)} ${msoUtils.xmlEscape(modelCustomizationUuid)} ${msoUtils.xmlEscape(modelUuid)} ${msoUtils.xmlEscape(modelVersion)} ${msoUtils.xmlEscape(modelName)} """.trim() break // sdwanvpnattachment or sotnvpnattachment case "ALLOTTED_RESOURCE" : sdncTopologyDeleteRequest = """ ${msoUtils.xmlEscape(hdrRequestId)} ${msoUtils.xmlEscape(serviceInstanceId)} ${msoUtils.xmlEscape(sdnc_svcAction)} connection-attachment-topology-operation sdncCallback generic-resource ${msoUtils.xmlEscape(hdrRequestId)} ${msoUtils.xmlEscape(sdnc_requestAction)} ${msoUtils.xmlEscape(source)} ${msoUtils.xmlEscape(serviceInstanceId)} ${msoUtils.xmlEscape(serviceType)} ${msoUtils.xmlEscape(serviceModelInvariantUuid)} ${msoUtils.xmlEscape(serviceModelUuid)} ${msoUtils.xmlEscape(serviceModelVersion)} ${msoUtils.xmlEscape(serviceModelName)} ${msoUtils.xmlEscape(serviceInstanceId)} ${msoUtils.xmlEscape(globalCustomerId)} $resourceInstnaceId $allotedParentServiceInstanceId ${msoUtils.xmlEscape(modelInvariantUuid)} ${msoUtils.xmlEscape(modelCustomizationUuid)} ${msoUtils.xmlEscape(modelUuid)} ${msoUtils.xmlEscape(modelVersion)} ${msoUtils.xmlEscape(modelName)} """.trim() break // for SDWANConnectivity and SOTNConnectivity: default: sdncTopologyDeleteRequest = """ ${msoUtils.xmlEscape(hdrRequestId)} ${msoUtils.xmlEscape(serviceInstanceId)} ${msoUtils.xmlEscape(sdnc_svcAction)} network-topology-operation sdncCallback generic-resource ${msoUtils.xmlEscape(hdrRequestId)} ${msoUtils.xmlEscape(sdnc_requestAction)} ${msoUtils.xmlEscape(source)} ${msoUtils.xmlEscape(serviceInstanceId)} ${msoUtils.xmlEscape(serviceType)} ${msoUtils.xmlEscape(serviceModelInvariantUuid)} ${msoUtils.xmlEscape(serviceModelUuid)} ${msoUtils.xmlEscape(serviceModelVersion)} ${msoUtils.xmlEscape(serviceModelName)} ${msoUtils.xmlEscape(serviceInstanceId)} ${msoUtils.xmlEscape(globalCustomerId)} $resourceInstnaceId ${msoUtils.xmlEscape(modelInvariantUuid)} ${msoUtils.xmlEscape(modelCustomizationUuid)} ${msoUtils.xmlEscape(modelUuid)} ${msoUtils.xmlEscape(modelVersion)} ${msoUtils.xmlEscape(modelName)} """.trim() } String sdncTopologyDeleteRequesAsString = utils.formatXml(sdncTopologyDeleteRequest) execution.setVariable("sdncAdapterWorkflowRequest", sdncTopologyDeleteRequesAsString) logger.info("sdncAdapterWorkflowRequest - " + "\n" + sdncTopologyDeleteRequesAsString) } catch (Exception ex) { String exceptionMessage = " Bpmn error encountered in DeleteSDNCCNetworkResource flow. prepareSDNCRequest() - " + ex.getMessage() logger.debug( exceptionMessage) exceptionUtil.buildAndThrowWorkflowException(execution, 7000, exceptionMessage) } logger.info(" ***** Exit prepareSDNCRequest *****") } private void setProgressUpdateVariables(DelegateExecution execution, String body) { def dbAdapterEndpoint = UrnPropertiesReader.getVariable("mso.adapters.openecomp.db.endpoint", execution) execution.setVariable("CVFMI_dbAdapterEndpoint", dbAdapterEndpoint) execution.setVariable("CVFMI_updateResOperStatusRequest", body) } void prepareUpdateBeforeDeleteSDNCResource(DelegateExecution execution) { logger.debug(" *** prepareUpdateBeforeDeleteSDNCResource *** ") String resourceInput = execution.getVariable(Prefix + "resourceInput"); ResourceInput resourceInputObj = ResourceRequestBuilder.getJsonObject(resourceInput, ResourceInput.class) String operType = resourceInputObj.getOperationType() String resourceCustomizationUuid = resourceInputObj.getResourceModelInfo().getModelCustomizationUuid() String serviceInstanceId = resourceInputObj.getServiceInstanceId() String operationId = resourceInputObj.getOperationId() String progress = "20" String status = "processing" String statusDescription = "SDCN resource delete invoked" //String operationId = execution.getVariable("operationId") String body = """ ${msoUtils.xmlEscape(operType)} ${msoUtils.xmlEscape(operationId)} ${msoUtils.xmlEscape(progress)} ${msoUtils.xmlEscape(resourceCustomizationUuid)} ${msoUtils.xmlEscape(serviceInstanceId)} ${msoUtils.xmlEscape(status)} ${msoUtils.xmlEscape(statusDescription)} """; setProgressUpdateVariables(execution, body) logger.debug(" ***** Exit prepareUpdateBeforeDeleteSDNCResource *****") } void prepareUpdateAfterDeleteSDNCResource(DelegateExecution execution) { logger.debug(" *** prepareUpdateAfterDeleteSDNCResource *** ") String resourceInput = execution.getVariable(Prefix + "resourceInput"); ResourceInput resourceInputObj = ResourceRequestBuilder.getJsonObject(resourceInput, ResourceInput.class) String operType = resourceInputObj.getOperationType() String resourceCustomizationUuid = resourceInputObj.getResourceModelInfo().getModelCustomizationUuid() String serviceInstanceId = resourceInputObj.getServiceInstanceId() String operationId = resourceInputObj.getOperationId() String progress = "100" String status = "finished" String statusDescription = "SDCN resource delete and deactivation completed" //String operationId = execution.getVariable("operationId") String body = """ ${msoUtils.xmlEscape(operType)} ${msoUtils.xmlEscape(operationId)} ${msoUtils.xmlEscape(progress)} ${msoUtils.xmlEscape(resourceCustomizationUuid)} ${msoUtils.xmlEscape(serviceInstanceId)} ${msoUtils.xmlEscape(status)} ${msoUtils.xmlEscape(statusDescription)} """; setProgressUpdateVariables(execution, body) logger.debug(" ***** Exit prepareUpdateAfterDeleteSDNCResource *****") } void postDeleteSDNCCall(DelegateExecution execution){ logger.info(" ***** Started postDeleteSDNCCall *****") String responseCode = execution.getVariable(Prefix + "sdncDeleteReturnCode") String responseObj = execution.getVariable(Prefix + "SuccessIndicator") logger.info("response from sdnc, response code :" + responseCode + " response object :" + responseObj) logger.info(" ***** Exit postDeleteSDNCCall *****") } void sendSyncResponse (DelegateExecution execution) { logger.debug( " *** sendSyncResponse *** ") try { String operationStatus = "finished" // RESTResponse for main flow String resourceOperationResp = """{"operationStatus":"${operationStatus}"}""".trim() logger.debug( " sendSyncResponse to APIH:" + "\n" + resourceOperationResp) sendWorkflowResponse(execution, 202, resourceOperationResp) execution.setVariable("sentSyncResponse", true) } catch (Exception ex) { String msg = "Exception in sendSyncResponse:" + ex.getMessage() logger.debug( msg) exceptionUtil.buildAndThrowWorkflowException(execution, 7000, msg) } logger.debug(" ***** Exit sendSyncResponse *****") } }