diff options
Diffstat (limited to 'bpmn/so-bpmn-infrastructure-common/src')
4 files changed, 2239 insertions, 0 deletions
diff --git a/bpmn/so-bpmn-infrastructure-common/src/main/groovy/org/onap/so/bpmn/infrastructure/scripts/ActivateSliceService.groovy b/bpmn/so-bpmn-infrastructure-common/src/main/groovy/org/onap/so/bpmn/infrastructure/scripts/ActivateSliceService.groovy new file mode 100644 index 0000000000..630148e899 --- /dev/null +++ b/bpmn/so-bpmn-infrastructure-common/src/main/groovy/org/onap/so/bpmn/infrastructure/scripts/ActivateSliceService.groovy @@ -0,0 +1,585 @@ +/*- + * ============LICENSE_START======================================================= + * ONAP - SO + * ================================================================================ + * Copyright (C) 2019 Huawei Technologies Co., Ltd. All rights reserved. + * ================================================================================ + * 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 com.google.gson.Gson +import com.google.gson.reflect.TypeToken +import org.camunda.bpm.engine.delegate.BpmnError +import org.camunda.bpm.engine.delegate.DelegateExecution +import org.onap.aai.domain.yang.* +import org.onap.so.beans.nsmf.NSSI +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.RequestDBUtil +import org.onap.so.bpmn.core.WorkflowException +import org.onap.so.bpmn.core.json.JsonUtils +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.onap.so.db.request.beans.OperationStatus +import org.onap.so.logger.ErrorCode +import org.onap.so.logger.LoggingAnchor +import org.onap.so.logger.MessageEnum +import org.slf4j.Logger +import org.slf4j.LoggerFactory + +import javax.ws.rs.NotFoundException +import java.lang.reflect.Type + +import static org.apache.commons.lang3.StringUtils.isBlank + +/** + * This groovy class supports the <class>ActivateSliceService.bpmn</class> process. + * AlaCarte flow for 1702 slice service activate + * + */ + +class ActivateSliceService extends AbstractServiceTaskProcessor { + + + String Prefix = "ACTSS_" + + ExceptionUtil exceptionUtil = new ExceptionUtil() + + JsonUtils jsonUtil = new JsonUtils() + + RequestDBUtil requestDBUtil = new RequestDBUtil() + + private static final Logger logger = LoggerFactory.getLogger(ActivateSliceService.class) + + void preProcessRequest(DelegateExecution execution) { + logger.debug(Prefix + "preProcessRequest Start") + execution.setVariable("prefix", Prefix) + String msg + + try { + // check for incoming json message/input + String siRequest = execution.getVariable("bpmnRequest") + logger.debug(siRequest) + + String requestId = execution.getVariable("mso-request-id") + execution.setVariable("msoRequestId", requestId) + logger.info("Input Request:" + siRequest + " reqId:" + requestId) + + String serviceInstanceId = execution.getVariable("serviceInstanceId") + if (isBlank(serviceInstanceId)) { + msg = "Input serviceInstanceId' is null" + exceptionUtil.buildAndThrowWorkflowException(execution, 500, msg) + } + String source = jsonUtil.getJsonValue(siRequest, "source") + execution.setVariable("source", source) + + //subscriberInfo + String globalSubscriberId = jsonUtil.getJsonValue(siRequest, "globalSubscriberId") + if (isBlank(globalSubscriberId)) { + msg = "Input globalSubscriberId' is null" + logger.info(msg) + } else { + execution.setVariable("globalSubscriberId", globalSubscriberId) + } + + //requestParameters + String subscriptionServiceType = jsonUtil.getJsonValue(siRequest, "serviceType") + if (isBlank(subscriptionServiceType)) { + msg = "Input subscriptionServiceType is null" + logger.debug(msg) + //exceptionUtil.buildAndThrowWorkflowException(execution, 500, msg) + } else { + execution.setVariable("subscriptionServiceType", subscriptionServiceType) + } + String operationId = jsonUtil.getJsonValue(siRequest, "operationId") + execution.setVariable("operationId", operationId) + + execution.getVariable("operationType") + logger.info("operationType is " + execution.getVariable("operationType") ) + } catch (BpmnError e) { + throw e + } catch (Exception ex) { + msg = "Exception in preProcessRequest " + ex.getMessage() + logger.info(msg) + exceptionUtil.buildAndThrowWorkflowException(execution, 7000, msg) + } + logger.debug(Prefix + "preProcessRequest Exit") + } + + + def sendSyncResponse = { DelegateExecution execution -> + logger.debug(Prefix + "sendSyncResponse Start") + try { + String operationId = execution.getVariable("operationId") + // RESTResponse for API Handler (APIH) Reply Task + String Activate5GsliceServiceRestRequest = """{"operationId":"${operationId}"}""".trim() + logger.debug(" sendSyncResponse to APIH:" + "\n" + Activate5GsliceServiceRestRequest) + sendWorkflowResponse(execution, 202, Activate5GsliceServiceRestRequest) + execution.setVariable("sentSyncResponse", true) + } catch (Exception ex) { + String msg = "Exceptuion in sendSyncResponse:" + ex.getMessage() + logger.debug(msg) + exceptionUtil.buildAndThrowWorkflowException(execution, 7000, msg) + } + logger.debug(Prefix + "sendSyncResponse Exit") + } + + + public sendSyncError = { DelegateExecution execution -> + logger.debug("sendSyncError Start") + try { + String errorMessage + if (execution.getVariable("WorkflowException") instanceof WorkflowException) { + WorkflowException wfe = execution.getVariable("WorkflowException") as WorkflowException + errorMessage = wfe.getErrorMessage() + } else { + errorMessage = "Sending Sync Error." + } + + String buildWorkflowException = + """<aetgt:WorkflowException xmlns:aetgt="http://org.onap/so/workflow/schema/v1"> + <aetgt:ErrorMessage>${MsoUtils.xmlEscape(errorMessage)}</aetgt:ErrorMessage> + <aetgt:ErrorCode>7000</aetgt:ErrorCode> + </aetgt:WorkflowException>""" + + logger.debug(buildWorkflowException) + sendWorkflowResponse(execution, 500, buildWorkflowException) + + } catch (Exception ex) { + logger.debug("Sending Sync Error Activity Failed. " + "\n" + ex.getMessage()) + } + logger.debug(Prefix + "sendSyncError Exit") + } + + + def prepareCompletionRequest = { DelegateExecution execution -> + logger.debug(Prefix + "prepareCompletionRequest Start") + String serviceId = execution.getVariable("serviceInstanceId") + String operationId = execution.getVariable("operationId") + String userId = execution.getVariable("globalSubscriberId") + //String result = execution.getVariable("result") + String result = "finished" + String progress = "100" + String reason = "" + String operationContent = execution.getVariable("operationContent") + String operationType = execution.getVariable("operationType") + + OperationStatus initStatus = new OperationStatus() + initStatus.setServiceId(serviceId) + initStatus.setOperationId(operationId) + initStatus.setOperation(operationType) + initStatus.setUserId(userId) + initStatus.setResult(result) + initStatus.setProgress(progress) + initStatus.setReason(reason) + initStatus.setOperationContent(operationContent) + + requestDBUtil.prepareUpdateOperationStatus(execution, initStatus) + + logger.debug(Prefix + "prepareCompletionRequest Exit") + } + + + /** + * Init the service Operation Status + */ + def prepareInitServiceOperationStatus = { DelegateExecution execution -> + logger.debug(Prefix + "prepareActivateServiceOperationStatus Start") + try { + String serviceId = execution.getVariable("serviceInstanceId") + String operationId = execution.getVariable("operationId") + String operationType = execution.getVariable("operationType") + String userId = execution.getVariable("globalSubscriberId") + String result = "processing" + String progress = "0" + String reason = "" + String operationContent = "Prepare service activation" + + execution.setVariable("e2eserviceInstanceId", serviceId) + execution.setVariable("operationType", operationType) + + OperationStatus initStatus = new OperationStatus() + initStatus.setServiceId(serviceId) + initStatus.setOperationId(operationId) + initStatus.setOperation(operationType) + initStatus.setUserId(userId) + initStatus.setResult(result) + initStatus.setProgress(progress) + initStatus.setReason(reason) + initStatus.setOperationContent(operationContent) + + requestDBUtil.prepareUpdateOperationStatus(execution, initStatus) + + } catch (Exception e) { + logger.error(LoggingAnchor.FIVE, MessageEnum.BPMN_GENERAL_EXCEPTION_ARG.toString(), + "Exception Occured Processing prepareInitServiceOperationStatus.", "BPMN", + ErrorCode.UnknownError.getValue(), "Exception is:\n" + e) + execution.setVariable("CVFMI_ErrorResponse", + "Error Occurred during prepareInitServiceOperationStatus Method:\n" + e.getMessage()) + } + logger.debug(Prefix + "prepareInitServiceOperationStatus Exit") + } + + + private getSNSSIStatusByNsi = { DelegateExecution execution, String NSIServiceId -> + + logger.debug(Prefix + "getSNSSIStatusByNsi Start") + String globalSubscriberId = execution.getVariable("globalSubscriberId") + String subscriptionServiceType = execution.getVariable("subscriptionServiceType") + + AAIResourcesClient client = new AAIResourcesClient() + AAIResourceUri uri = AAIUriFactory.createResourceUri(AAIObjectType.SERVICE_INSTANCE, + globalSubscriberId, subscriptionServiceType, NSIServiceId) + if (!client.exists(uri)) { + exceptionUtil.buildAndThrowWorkflowException(execution, 2500, "Service Instance was not found in aai") + } + AAIResultWrapper wrapper = client.get(uri, NotFoundException.class) + Optional<ServiceInstance> si = wrapper.asBean(ServiceInstance.class) + if (si.isPresent()) { + + List<Relationship> relatedList = si.get().getRelationshipList().getRelationship() + for (Relationship relationship : relatedList) { + String relatedTo = relationship.getRelatedTo() + if (relatedTo.toLowerCase() == "allotted-resource") { + //get snssi from allotted resource in list by nsi + List<String> SNSSIList = new ArrayList<>() + List<RelationshipData> relationshipDataList = relationship.getRelationshipData() + for (RelationshipData relationshipData : relationshipDataList) { + if (relationshipData.getRelationshipKey() == "service-instance.service-instance-id") { + SNSSIList.add(relationshipData.getRelationshipValue()) + } + } + for (String snssi : SNSSIList) { + AAIResourcesClient client01 = new AAIResourcesClient() + AAIResourceUri uri01 = AAIUriFactory.createResourceUri(AAIObjectType.SERVICE_INSTANCE, + globalSubscriberId, subscriptionServiceType, snssi) + if (!client.exists(uri01)) { + exceptionUtil.buildAndThrowWorkflowException(execution, 2500, + "Service Instance was not found in aai") + } + AAIResultWrapper wrapper01 = client01.get(uri01, NotFoundException.class) + Optional<ServiceInstance> nssiSi = wrapper01.asBean(ServiceInstance.class) + if (nssiSi.isPresent()) { + return nssiSi.get().getOrchestrationStatus() == "deactivated" + } + } + + } + } + + } + logger.debug(Prefix + "getSNSSIStatusByNsi Exit") + } + + + def updateStatusSNSSAIandNSIandNSSI = { DelegateExecution execution -> + logger.debug(Prefix + "updateStatusSNSSAIandNSIandNSSI Start") + logger.debug(" ***** update SNSSAI NSI NSSI slicing ***** ") + String e2eserviceInstanceId = execution.getVariable("e2eserviceInstanceId") + String NSIserviceInstanceId = execution.getVariable("NSIserviceid") + + String globalCustId = execution.getVariable("globalSubscriberId") + String serviceType = execution.getVariable("serviceType") + String operationType = execution.getVariable("operationType") + + String nssiMap = execution.getVariable("nssiMap") + Type type = new TypeToken<HashMap<String, NSSI>>() {}.getType() + Map<String, NSSI> activateNssiMap = new Gson().fromJson(nssiMap, type) + //update tn/cn/an nssi + for (Map.Entry<String, NSSI> entry : activateNssiMap.entrySet()) { + NSSI nssi = entry.getValue() + String nssiid = nssi.getNssiId() + updateStratus(execution, globalCustId, serviceType, nssiid, operationType) + } + if (operationType == "activation") { + //update the s-nssai + updateStratus(execution, globalCustId, serviceType, e2eserviceInstanceId, operationType) + //update the nsi + updateStratus(execution, globalCustId, serviceType, NSIserviceInstanceId, operationType) + } else { + //update the s-nssai + updateStratus(execution, globalCustId, serviceType, e2eserviceInstanceId, operationType) + boolean flag = getSNSSIStatusByNsi(execution, NSIserviceInstanceId) + if (flag) { + //update the nsi + updateStratus(execution, globalCustId, serviceType, NSIserviceInstanceId, operationType) + } else { + logger.error("Service's status update failed") + String msg = "Service's status update failed" + exceptionUtil.buildAndThrowWorkflowException(execution, 7000, msg) + } + } + logger.debug(Prefix + "updateStatusSNSSAIandNSIandNSSI Exit") + } + + + def updateStratus = { DelegateExecution execution, String globalCustId, + String serviceType, String serviceId, String operationType -> + logger.debug(Prefix + "updateStratus Start") + + try { + AAIResourcesClient client = new AAIResourcesClient() + AAIResourceUri uri = AAIUriFactory.createResourceUri(AAIObjectType.SERVICE_INSTANCE, + globalCustId, serviceType, serviceId) + if (!client.exists(uri)) { + exceptionUtil.buildAndThrowWorkflowException(execution, 2500, "Service Instance was not found in aai") + } + AAIResultWrapper wrapper = client.get(uri, NotFoundException.class) + Optional<ServiceInstance> si = wrapper.asBean(ServiceInstance.class) + + if (si.isPresent()) { + if (operationType == "activation") { + if (si.get().getOrchestrationStatus() == "deactivated") { + si.get().setOrchestrationStatus("activated") + client.update(uri, si.get()) + } + } else { + if (si.get().getOrchestrationStatus() == "activated") { + si.get().setOrchestrationStatus("deactivated") + client.update(uri, si.get()) + } + } + + } + } catch (Exception e) { + logger.info("Service is already in active state") + String msg = "Service is already in active state, " + e.getMessage() + exceptionUtil.buildAndThrowWorkflowException(execution, 7000, msg) + } + + logger.debug(Prefix + "updateStratus Exit") + } + + + def prepareActivation = { DelegateExecution execution -> + logger.debug(Prefix + "prepareActivation Start") + + logger.debug(" ***** prepare active NSI/AN/CN/TN slice ***** ") + String NSIserviceInstanceId = execution.getVariable("NSIserviceid") + + String globalSubscriberId = execution.getVariable("globalSubscriberId") + String subscriptionServiceType = execution.getVariable("subscriptionServiceType") + + Map<String, NSSI> nssiMap = new HashMap<>() + + List<String> activationSequence = new ArrayList<>(Arrays.asList("an", "tn", "cn")) + + def activationCount = activationSequence.size() + + execution.setVariable("activationIndex", "0") + + execution.setVariable("activationCount", activationCount) + try { + //get the TN NSSI id by NSI id, active NSSI TN slicing + AAIResourcesClient client = new AAIResourcesClient() + AAIResourceUri uri = AAIUriFactory.createResourceUri(AAIObjectType.SERVICE_INSTANCE, + globalSubscriberId, subscriptionServiceType, NSIserviceInstanceId) + if (!client.exists(uri)) { + exceptionUtil.buildAndThrowWorkflowException(execution, 2500, "Service Instance was not found in aai") + } + AAIResultWrapper wrapper = client.get(uri, NotFoundException.class) + Optional<ServiceInstance> si = wrapper.asBean(ServiceInstance.class) + if (si.isPresent()) { + + List<Relationship> relatedList = si.get().getRelationshipList().getRelationship() + for (Relationship relationship : relatedList) { + String relatedTo = relationship.getRelatedTo() + if (relatedTo.toLowerCase() == "service-instance") { + String relatioshipurl = relationship.getRelatedLink() + String nssiserviceid = + relatioshipurl.substring(relatioshipurl.lastIndexOf("/") + 1, relatioshipurl.length()) + + AAIResourcesClient client01 = new AAIResourcesClient() + AAIResourceUri uri01 = AAIUriFactory.createResourceUri(AAIObjectType.SERVICE_INSTANCE, + globalSubscriberId, subscriptionServiceType, nssiserviceid) + if (!client.exists(uri01)) { + exceptionUtil.buildAndThrowWorkflowException(execution, 2500, + "Service Instance was not found in aai") + } + AAIResultWrapper wrapper01 = client01.get(uri01, NotFoundException.class) + Optional<ServiceInstance> nssiSi = wrapper01.asBean(ServiceInstance.class) + if (nssiSi.isPresent()) { + if (nssiSi.get().getEnvironmentContext().toLowerCase().contains("an") + || nssiSi.get().getEnvironmentContext().toLowerCase().contains("cn") + || nssiSi.get().getEnvironmentContext().toLowerCase().contains("tn")) { + nssiMap.put(nssiSi.get().getEnvironmentContext(), + new NSSI(nssiSi.get().getServiceInstanceId(), + nssiSi.get().getModelInvariantId(), nssiSi.get().getModelVersionId())) + } + } + } + } + + + } + } catch (Exception e) { + String msg = "Requested service does not exist:" + e.getMessage() + logger.info("Service doesnt exist") + exceptionUtil.buildAndThrowWorkflowException(execution, 7000, msg) + } + + if (nssiMap.size() > 0) { + execution.setVariable("isNSSIActivate", "true") + String nssiMap01 = mapToJsonStr(nssiMap) + execution.setVariable("nssiMap", nssiMap01) + execution.setVariable("operation_type", "activate") + execution.setVariable("activationCount", nssiMap.size()) + logger.info("the nssiMap01 is :" + nssiMap01) + } else { + execution.setVariable("isNSSIActivate", "false") + } + + logger.debug(Prefix + "prepareActivation Exit") + } + + + private mapToJsonStr = { HashMap<String, NSSI> stringNSSIHashMap -> + HashMap<String, NSSI> map = new HashMap<String, NSSI>() + for (Map.Entry<String, NSSI> child : stringNSSIHashMap.entrySet()) { + map.put(child.getKey(), child.getValue()) + } + return new Gson().toJson(map) + } + + + def checkAAIOrchStatusofslice = { DelegateExecution execution -> + logger.debug(Prefix + "CheckAAIOrchStatus Start") + + String msg = "" + String serviceInstanceId = execution.getVariable("serviceInstanceId") + String globalSubscriberId = execution.getVariable("globalSubscriberId") + String subscriptionServiceType = execution.getVariable("subscriptionServiceType") + String operationType = execution.getVariable("operationType") + + logger.debug("serviceInstanceId: " + serviceInstanceId) + + //check the e2e slice status + try { + try { + AAIResourcesClient client = new AAIResourcesClient() + AAIResourceUri uri = AAIUriFactory.createResourceUri(AAIObjectType.SERVICE_INSTANCE, + globalSubscriberId, subscriptionServiceType, serviceInstanceId) + if (!client.exists(uri)) { + exceptionUtil.buildAndThrowWorkflowException(execution, 2500, + "Service Instance was not found in aai") + } + AAIResultWrapper wrapper = client.get(uri, NotFoundException.class) + Optional<ServiceInstance> si = wrapper.asBean(ServiceInstance.class) + if (si.isPresent()) { + if (si.get().getOrchestrationStatus().toLowerCase() == "activated" && + operationType == "deactivation") { + logger.info("Service is in active state") + execution.setVariable("e2eservicestatus", "activated") + execution.setVariable("isContinue", "true") + String snssai = si.get().getEnvironmentContext() + execution.setVariable("snssai", snssai) + } else if ((si.get().getOrchestrationStatus().toLowerCase() == "deactivated" || + si.get().getOrchestrationStatus().toLowerCase() == "created") && + operationType == "activation") { + logger.info("Service is in de-activated state") + execution.setVariable("e2eservicestatus", "deactivated") + execution.setVariable("isContinue", "true") + String snssai = si.get().getEnvironmentContext() + execution.setVariable("snssai", snssai) + } else { + execution.setVariable("isContinue", "false") + } + } + } catch (Exception e) { + msg = "Requested e2eservice does not exist" + logger.info("e2eservice doesnt exist") + execution.setVariable("isContinue", "false") + exceptionUtil.buildAndThrowWorkflowException(execution, 7000, msg) + } + + //check the NSI is exist or the status of NSI is active or de-active + try { + + //get the allotted-resources by e2e slice id + AAIResourcesClient client_allotted = new AAIResourcesClient() + AAIResourceUri uri_allotted = AAIUriFactory.createResourceUri(AAIObjectType.ALLOTTED_RESOURCE_ALL, + globalSubscriberId, subscriptionServiceType, serviceInstanceId) + if (!client_allotted.exists(uri_allotted)) { + exceptionUtil.buildAndThrowWorkflowException(execution, 2500, "Service Instance was not found in aai") + } + AAIResultWrapper wrapper_allotted = client_allotted.get(uri_allotted, NotFoundException.class) + Optional<AllottedResources> all_allotted = wrapper_allotted.asBean(AllottedResources.class) + + if (all_allotted.isPresent() && all_allotted.get().getAllottedResource()) { + List<AllottedResource> AllottedResourceList = all_allotted.get().getAllottedResource() + AllottedResource ar = AllottedResourceList.first() + String relatedLink = ar.getRelationshipList().getRelationship().first().getRelatedLink() + String nsiserviceid = relatedLink.substring(relatedLink.lastIndexOf("/") + 1, relatedLink.length()) + execution.setVariable("NSIserviceid", nsiserviceid) + logger.info("the NSI ID is:" + nsiserviceid) + + //Query nsi by nsi id + try { + //get the NSI id by e2e slice id + AAIResourcesClient client = new AAIResourcesClient() + AAIResourceUri uri = AAIUriFactory.createResourceUri(AAIObjectType.SERVICE_INSTANCE, + globalSubscriberId, subscriptionServiceType, nsiserviceid) + if (!client.exists(uri)) { + exceptionUtil.buildAndThrowWorkflowException(execution, 2500, + "Service Instance was not found in aai") + } + AAIResultWrapper wrapper = client.get(uri, NotFoundException.class) + Optional<ServiceInstance> si = wrapper.asBean(ServiceInstance.class) + + if (si.isPresent()) { + if (si.get().getServiceRole().toLowerCase() == "nsi") { + if (si.get().getOrchestrationStatus() == "activated") { + logger.info("NSI services is in activated state") + execution.setVariable("NSIservicestatus", "activated") + } else { + logger.info("NSI services is in deactivated state") + execution.setVariable("NSIservicestatus", "deactivated") + } + } else { + logger.info("the service id" + si.get().getServiceInstanceId() + "is " + + si.get().getServiceRole()) + exceptionUtil.buildAndThrowWorkflowException(execution, 7000, msg) + } + } + } catch (Exception e) { + msg = "Requested NSI service does not exist:" + e.getMessage() + logger.info("NSI service doesnt exist") + execution.setVariable("isContinue", "false") + exceptionUtil.buildAndThrowWorkflowException(execution, 7000, msg) + } + } + } catch (Exception e) { + msg = "Requested service does not exist: " + e.getMessage() + logger.info("NSI Service doesnt exist") + execution.setVariable("isActivate", "false") + exceptionUtil.buildAndThrowWorkflowException(execution, 7000, msg) + } + } catch (BpmnError e) { + throw e + } catch (Exception ex) { + msg = "Exception in org.onap.so.bpmn.common.scripts.CompleteMsoProcess.CheckAAIOrchStatus " + ex.getMessage() + logger.info(msg) + exceptionUtil.buildAndThrowWorkflowException(execution, 7000, msg) + } + + logger.debug(Prefix + "CheckAAIOrchStatus Exit") + } + +} diff --git a/bpmn/so-bpmn-infrastructure-common/src/main/groovy/org/onap/so/bpmn/infrastructure/scripts/CreateCommunicationService.groovy b/bpmn/so-bpmn-infrastructure-common/src/main/groovy/org/onap/so/bpmn/infrastructure/scripts/CreateCommunicationService.groovy new file mode 100644 index 0000000000..e3470cd011 --- /dev/null +++ b/bpmn/so-bpmn-infrastructure-common/src/main/groovy/org/onap/so/bpmn/infrastructure/scripts/CreateCommunicationService.groovy @@ -0,0 +1,678 @@ +/*- + * ============LICENSE_START======================================================= + * ONAP - SO + * ================================================================================ + # Copyright (c) 2019, CMCC Technologies Co., Ltd. + # + # 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 groovy.json.JsonSlurper +import org.camunda.bpm.engine.delegate.BpmnError +import org.camunda.bpm.engine.delegate.DelegateExecution +import org.json.JSONObject +import org.onap.aai.domain.yang.Relationship +import org.onap.aai.domain.yang.ServiceInstance +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.RequestDBUtil +import org.onap.so.bpmn.core.UrnPropertiesReader +import org.onap.so.bpmn.core.WorkflowException +import org.onap.so.bpmn.core.domain.ServiceDecomposition +import org.onap.so.bpmn.core.domain.ServiceInfo +import org.onap.so.bpmn.core.domain.ServiceProxy +import org.onap.so.bpmn.core.json.JsonUtils +import org.onap.so.client.aai.AAIObjectType +import org.onap.so.client.aai.AAIResourcesClient +import org.onap.so.client.aai.entities.uri.AAIResourceUri +import org.onap.so.client.aai.entities.uri.AAIUriFactory +import org.onap.so.db.request.beans.OperationStatus +import org.slf4j.Logger +import org.slf4j.LoggerFactory +import org.springframework.web.util.UriUtils + +import static org.apache.commons.lang3.StringUtils.isBlank + +/** + * This groovy class supports the <class>DoCreateCommunicationService.bpmn</class> process. + * AlaCarte flow for 1702 ServiceInstance Create + * + */ +class CreateCommunicationService extends AbstractServiceTaskProcessor { + + String Prefix="CRESI_" + + ExceptionUtil exceptionUtil = new ExceptionUtil() + + RequestDBUtil requestDBUtil = new RequestDBUtil() + + JsonUtils jsonUtil = new JsonUtils() + + AAIResourcesClient client = getAAIClient() + + private static final Logger logger = LoggerFactory.getLogger(CreateCommunicationService.class) + + @Override + void preProcessRequest(DelegateExecution execution) { + logger.debug(Prefix + "preProcessRequest Start") + execution.setVariable("prefix", Prefix) + execution.setVariable("startTime", System.currentTimeMillis()) + def msg + //execution.setVariable("bpmnRequest", InputString) + try { + // get request input + String siRequest = execution.getVariable("bpmnRequest") + logger.debug(siRequest) + + //String requestId = execution.getVariable("mso-request-id") + String requestId = execution.getVariable("mso-request-id") + execution.setVariable("msoRequestId", requestId) + logger.debug("Input Request:" + siRequest + " reqId:" + requestId) + + String serviceInstanceId = execution.getVariable("serviceInstanceId") + if (isBlank(serviceInstanceId)) { + serviceInstanceId = UUID.randomUUID().toString() + } + logger.debug("Generated new Service Instance:" + serviceInstanceId) + serviceInstanceId = UriUtils.encode(serviceInstanceId,"UTF-8") + execution.setVariable("serviceInstanceId", serviceInstanceId) + + //subscriberInfo + String globalSubscriberId = jsonUtil.getJsonValue(siRequest, "requestDetails.subscriberInfo.globalSubscriberId") + if (isBlank(globalSubscriberId)) { + msg = "Input globalSubscriberId' is null" + exceptionUtil.buildAndThrowWorkflowException(execution, 500, msg) + } else { + execution.setVariable("globalSubscriberId", globalSubscriberId) + } + + //requestInfo + execution.setVariable("source", jsonUtil.getJsonValue(siRequest, "requestDetails.requestInfo.source")) + execution.setVariable("serviceInstanceName", jsonUtil.getJsonValue(siRequest, "requestDetails.requestInfo.instanceName")) + execution.setVariable("disableRollback", jsonUtil.getJsonValue(siRequest, "requestDetails.requestInfo.suppressRollback")) + String productFamilyId = jsonUtil.getJsonValue(siRequest, "requestDetails.requestInfo.productFamilyId") + if (isBlank(productFamilyId)) + { + msg = "Input productFamilyId is null" + logger.debug(msg) + //exceptionUtil.buildAndThrowWorkflowException(execution, 500, msg) + } else { + execution.setVariable("productFamilyId", productFamilyId) + } + + //modelInfo + String serviceModelInfo = jsonUtil.getJsonValue(siRequest, "requestDetails.modelInfo") + if (isBlank(serviceModelInfo)) { + msg = "Input serviceModelInfo is null" + logger.debug(msg) + exceptionUtil.buildAndThrowWorkflowException(execution, 500, msg) + } else + { + execution.setVariable("csServiceModelInfo", serviceModelInfo) + } + + logger.debug("modelInfo: " + serviceModelInfo) + + //requestParameters, subscriptionServiceType is 5G + String subscriptionServiceType = jsonUtil.getJsonValue(siRequest, "requestDetails.requestParameters.subscriptionServiceType") + if (isBlank(subscriptionServiceType)) { + msg = "Input subscriptionServiceType is null" + logger.debug(msg) + exceptionUtil.buildAndThrowWorkflowException(execution, 500, msg) + } else { + // todo: in create e2e interface, this value is write "MOG", so write it as "5G" + execution.setVariable("subscriptionServiceType", "5G") + } + + + /* + * Extracting User Parameters from incoming Request and converting into a Map + */ + def jsonSlurper = new JsonSlurper() + + Map reqMap = jsonSlurper.parseText(siRequest) as Map + + //InputParams + def userParamsList = reqMap.requestDetails?.requestParameters?.userParams + + Map<String, String> inputMap = [:] + if (userParamsList) { + for (def i=0; i<userParamsList.size(); i++) { + def userParams1 = userParamsList.get(i) + userParams1.each { param -> inputMap.put(param.key, param.value)} + } + } + + logger.debug("User Input Parameters map: " + inputMap.toString()) + execution.setVariable("serviceInputParams", inputMap) + execution.setVariable("uuiRequest", inputMap.get("UUIRequest")) + execution.setVariable("isAllNSMFFinished", "false") + String operationId = UUID.randomUUID().toString() + execution.setVariable("operationId", operationId) + + } catch(BpmnError e) { + throw e + } catch(Exception ex) { + msg = "Exception in CreateCommunicationService.preProcessRequest " + ex.getMessage() + logger.debug(msg) + exceptionUtil.buildAndThrowWorkflowException(execution, 7000, msg) + } + logger.debug(Prefix + "preProcessRequest Exit") + } + + + /** + * create operation status in request db + * + * Init the Operation Status + */ + def prepareInitOperationStatus = { DelegateExecution execution -> + logger.debug(Prefix + "prepareInitOperationStatus Start") + + String serviceId = execution.getVariable("serviceInstanceId") + // 生成 operationId + String operationId = execution.getVariable("operationId") + logger.debug("Generated new operation for Service Instance serviceId:" + serviceId + " operationId:" + operationId) + + OperationStatus initStatus = new OperationStatus() + initStatus.setServiceId(serviceId) + initStatus.setOperationId(operationId) + initStatus.setOperation("CREATE") + initStatus.setUserId(execution.getVariable("globalSubscriberId") as String) + initStatus.setResult("processing") + initStatus.setProgress("0") + initStatus.setReason("") + initStatus.setOperationContent("communication service create operation start") + + requestDBUtil.prepareUpdateOperationStatus(execution, initStatus) + + logger.debug(Prefix + "prepareInitOperationStatus Exit") + } + + + /** + * return sync response + */ + def sendSyncResponse = { DelegateExecution execution -> + logger.debug(Prefix + "sendSyncResponse Start") + try { + String operationId = execution.getVariable("operationId") + String serviceInstanceId = execution.getVariable("serviceInstanceId") + String createServiceRestRequest = """ + { + "service": { + "serviceId":"${serviceInstanceId}", + "operationId":"${operationId}" + } + } + """.trim().replaceAll(" ", "") + + logger.debug("sendSyncResponse to APIH:" + "\n" + createServiceRestRequest) + sendWorkflowResponse(execution, 202, createServiceRestRequest) + + execution.setVariable("sentSyncResponse", true) + } catch (Exception ex) { + String msg = "Exceptuion in sendSyncResponse:" + ex.getMessage() + logger.debug(msg) + exceptionUtil.buildAndThrowWorkflowException(execution, 7000, msg) + } + logger.debug(Prefix + "sendSyncResponse Exit") + } + + + /** + * query e2e service + * @param execution + */ + def prepareDoComposeE2E = { DelegateExecution execution -> + logger.debug(Prefix + "prepareDoComposeE2E Start") + try { + ServiceDecomposition serviceDecomposition = execution.getVariable( + "csServiceDecomposition") as ServiceDecomposition + + logger.debug("serviceDecomposition is:" + serviceDecomposition.toJsonString()) + + List<ServiceProxy> serviceProxies = serviceDecomposition.getServiceProxy() + String sourceModelUuid = serviceProxies.get(0).getSourceModelUuid() + + JSONObject queryJson = new JSONObject() + queryJson.put("modelUuid", sourceModelUuid) + + execution.setVariable("e2eServiceModelInfo", queryJson.toString()) + } catch (BpmnError e) { + throw e + } catch (Exception ex) { + String msg = "Exception in CreateCommunicationService.prepareDoComposeE2E. " + ex.getMessage() + logger.info(msg) + exceptionUtil.buildAndThrowWorkflowException(execution, 7000, msg) + } + + logger.debug(Prefix + "prepareDoComposeE2E Exit") + } + + + /** + * parse communication service params from request + * @param execution + */ + def parseCSParamsFromReq = { DelegateExecution execution -> + logger.debug(Prefix + "parseCSParamsFromReq Start") + try { + //1. CMS info + + String modelInfo = execution.getVariable("csServiceModelInfo") + String modelInvariantUuid = jsonUtil.getJsonValue(modelInfo, "modelInvariantUuid") + String modelUuid = jsonUtil.getJsonValue(modelInfo, "modelUuid") + + //String modelInvariantUuid = execution.getVariable("modelInvariantId") + //String modelUuid = execution.getVariable("modelUuid") + String uuiRequest = execution.getVariable("uuiRequest") + String useInterval = jsonUtil.getJsonValue(uuiRequest, "service.parameters.requestInputs.useInterval") + String csServiceName = jsonUtil.getJsonValue(uuiRequest, "service.name") + String csServiceDescription = jsonUtil.getJsonValue(uuiRequest, "service.description") + + execution.setVariable("modelInvariantUuid", modelInvariantUuid) + execution.setVariable("modelUuid", modelUuid) + execution.setVariable("useInterval", useInterval) + execution.setVariable("csServiceName", csServiceName) + execution.setVariable("csServiceDescription", csServiceDescription) + + + //2. profile info + Integer expDataRateDL = jsonUtil.getJsonIntValue(uuiRequest, "service.parameters.requestInputs.expDataRateDL") + Integer expDataRateUL = jsonUtil.getJsonIntValue(uuiRequest, "service.parameters.requestInputs.expDataRateUL") + Integer latency = jsonUtil.getJsonIntValue(uuiRequest, "service.parameters.requestInputs.latency") + Integer maxNumberOfUEs = jsonUtil.getJsonIntValue(uuiRequest, "service.parameters.requestInputs.maxNumberofUEs") + String uEMobilityLevel = jsonUtil.getJsonValue(uuiRequest, "service.parameters.requestInputs.uemobilityLevel") + String resourceSharingLevel = jsonUtil.getJsonValue(uuiRequest, "service.parameters.requestInputs.resourceSharingLevel") + String coverageArea = jsonUtil.getJsonValue(uuiRequest, "service.parameters.requestInputs.coverageAreaList") + + // from template construct input map + //String cstTemplate = execution.getVariable("cstTemplate") + ServiceDecomposition csServiceDecomposition = execution.getVariable( + "csServiceDecomposition") as ServiceDecomposition + //String csServiceType = jsonUtil.getJsonValue(cstTemplate, "serviceResources.serviceType") + String csServiceType = csServiceDecomposition.getServiceType() + execution.setVariable("csServiceType", csServiceType) + + //String cstTemplateInfo = jsonUtil.getJsonValue(cstTemplate, "serviceResources.serviceInfo.serviceInput") + ServiceInfo csServiceInfo = csServiceDecomposition.getServiceInfo() + String cstTemplateInfo = csServiceInfo.getServiceProperties() + + List<String> csInputs = jsonUtil.StringArrayToList(cstTemplateInfo) + + Map<String, ?> csInputMap = new HashMap<>() + for (String csInput : csInputs) { + def value + if (jsonUtil.getJsonValue(csInput, "type") == "integer") { + value = jsonUtil.getJsonValue(csInput, "default") + csInputMap.put(jsonUtil.getJsonValue(csInput, "name"), isBlank(value) ? 0 : (value as Integer)) + } else if (jsonUtil.getJsonValue(csInput, "type") == "string") { + csInputMap.put(jsonUtil.getJsonValue(csInput, "name"), + jsonUtil.getJsonValue(csInput, "default")) + } + } + csInputMap.put("expDataRateDL", expDataRateDL) + csInputMap.put("expDataRateUL", expDataRateUL) + csInputMap.put("latency", latency) + csInputMap.put("maxNumberofUEs", maxNumberOfUEs) + csInputMap.put("uEMobilityLevel", uEMobilityLevel) + csInputMap.put("resourceSharingLevel", resourceSharingLevel) + csInputMap.put("coverageAreaTAList", coverageArea) + csInputMap.put("useInterval", useInterval) + + execution.setVariable("csInputMap", csInputMap) + } catch (BpmnError e) { + throw e + } catch (Exception ex) { + String msg = "Exception in CreateCommunicationService.parseCSParamsFromReq. " + ex.getMessage() + logger.info(msg) + exceptionUtil.buildAndThrowWorkflowException(execution, 7000, msg) + } + logger.debug(Prefix + "parseCSParamsFromReq Exit") + } + + + /** + * get E2EST id through CST id and change communication profile to E2E service profile + * 1. get E2EST id from cst + * 1.1 查source service id + * 1.2 source service + * 1.3 source service input, init e2e profile + */ + def generateE2EServiceProfile = { DelegateExecution execution -> + logger.debug(Prefix + "generateE2EServiceProfile Start") + try { + ServiceDecomposition e2eServiceDecomposition = execution.getVariable( + "e2eServiceDecomposition") as ServiceDecomposition + String e2estTemplateInfo = e2eServiceDecomposition.getServiceInfo().getServiceProperties() + + List<String> e2eInputs = jsonUtil.StringArrayToList(e2estTemplateInfo) + + Map<String, ?> csInputMap = execution.getVariable("csInputMap") as Map + Map<String, ?> e2eInputMap = new HashMap<>() + String key + def value + + + for (String e2eInput in e2eInputs) { + if (jsonUtil.getJsonValue(e2eInput, "type") == "integer") { + def temp + key = jsonUtil.getJsonValue(e2eInput, "name") + value = csInputMap.containsKey(key) ? csInputMap.getOrDefault(key, 0) : (isBlank(temp = jsonUtil.getJsonValue(e2eInput, "default")) ? 0 : temp) + + e2eInputMap.put(key, value as Integer) + } else { + e2eInputMap.put(key = jsonUtil.getJsonValue(e2eInput, "name"), csInputMap.containsKey(key) + ? csInputMap.getOrDefault(key, null) : (jsonUtil.getJsonValue(e2eInput, "default"))) + } + } + + e2eInputMap.put("sNSSAI", execution.getVariable("sNSSAI_id")) + e2eInputMap.put("areaTrafficCapDL", 100) + e2eInputMap.put("areaTrafficCapUL", 100) + e2eInputMap.put("sST", execution.getVariable("csServiceType")) + + execution.setVariable("e2eInputMap", e2eInputMap) + execution.setVariable("e2eServiceType", e2eServiceDecomposition.getServiceType()) + execution.setVariable("e2eModelInvariantUuid", e2eServiceDecomposition.getModelInfo().getModelInvariantUuid()) + execution.setVariable("e2eModelUuid", e2eServiceDecomposition.getModelInfo().getModelUuid()) + + } catch (BpmnError e) { + throw e + } catch (Exception ex) { + String msg = "Exception in DoCreateE2EServiceInstance.createRelationShipInAAI. " + ex.getMessage() + logger.info(msg) + exceptionUtil.buildAndThrowWorkflowException(execution, 7000, msg) + } + + logger.debug(Prefix + "generateE2EServiceProfile Exit") + } + + + /** + * call createE2EService get operation id, + * created/processing + */ + def preRequestSend2NSMF(DelegateExecution execution) { + logger.debug(Prefix + "preRequestSend2NSMF Start") + try { + + //String NSMF_endpoint = "/onap/so/infra/e2eServiceInstances/v3" + def NSMF_endpoint = UrnPropertiesReader.getVariable("mso.infra.endpoint.url", execution) + def url = NSMF_endpoint + "/e2eServiceInstances/v3" + execution.setVariable("NSMF_endpoint", url) + //get from model catalog inputs + String payload = """ + { + "service":{ + "name": "${execution.getVariable("csServiceName")}", + "description": "e2eService of ${execution.getVariable("modelUuid")}", + "serviceInvariantUuid": "${execution.getVariable("e2eModelInvariantUuid")}", + "serviceUuid": "${execution.getVariable("e2eModelUuid")}", + "globalSubscriberId": "${execution.getVariable("globalSubscriberId")}", + "serviceType": "${execution.getVariable("subscriptionServiceType")}", + "parameters":{ + "requestInputs": ${execution.getVariable("e2eInputMap") as JSONObject} + } + } + } + """ + execution.setVariable("CSMF_NSMFRequest", payload.replaceAll("\\s+", "")) + + } catch (BpmnError e) { + throw e + } catch (Exception ex) { + String msg = "Exception in CreateCommunicationService.preRequestSend2NSMF. " + ex.getMessage() + logger.error(msg) + exceptionUtil.buildAndThrowWorkflowException(execution, 7000, msg) + } + + logger.debug(Prefix + "preRequestSend2NSMF Exit") + } + + + def processNSMFResponse = { DelegateExecution execution -> + logger.debug(Prefix + "processNSMFResponse Start") + //oof + try { + def CSMF_NSMFResponseCode = execution.getVariable("CSMF_NSMFResponseCode") as Integer + if (CSMF_NSMFResponseCode >= 200 && CSMF_NSMFResponseCode < 400) { + def CSMF_NSMFResponse = execution.getVariable("CSMF_NSMFResponse") as String + def e2eServiceInstanceId = jsonUtil.getJsonValue(CSMF_NSMFResponse, "service.serviceId") + def e2eOperationId = jsonUtil.getJsonValue(CSMF_NSMFResponse, "service.operationId") + + execution.setVariable("e2eServiceInstanceId", e2eServiceInstanceId) + execution.setVariable("e2eOperationId", e2eOperationId) + execution.setVariable("ProcessNsmfSuccess", "OK") + } else { + execution.setVariable("ProcessNsmfSuccess", "ERROR") + execution.setVariable("operationStatus", "error") + execution.setVariable("operationContent", + "communication service create operation error: nsmf response fail") + execution.setVariable("orchestrationStatus", "error") + } + + } catch (BpmnError e) { + throw e + } catch (Exception ex) { + String msg = "Exception in " + Prefix + "processOOFResponse. " + ex.getMessage() + logger.info(msg) + exceptionUtil.buildAndThrowWorkflowException(execution, 7000, msg) + } + logger.debug(Prefix + "processNSMFResponse Exit") + } + + + /** + * create communication service and e2e service relationship + * + */ + def createCSAndSSRelationship = { DelegateExecution execution -> + logger.debug(Prefix + "createCSAndSSRelationship Start") + String msg = "" + try { + def e2eServiceInstanceId = execution.getVariable("e2eServiceInstanceId") + String globalSubscriberId = execution.getVariable("globalSubscriberId") + String subscriptionServiceType = execution.getVariable("subscriptionServiceType") + + Relationship relationship = new Relationship() + String relatedLink = "aai/v16/business/customers/customer/${globalSubscriberId}/service-subscriptions/service-subscription/${subscriptionServiceType}/service-instances/service-instance/${e2eServiceInstanceId}" + relationship.setRelatedLink(relatedLink) + + // create CS and SS relationship in AAI + createRelationShipInAAI(execution, relationship) + + } catch (BpmnError e) { + throw e + } catch (Exception ex) { + + msg = "Exception in DoCreateE2EServiceInstance.createCustomRelationship. " + ex.getMessage() + logger.info(msg) + exceptionUtil.buildAndThrowWorkflowException(execution, 7000, msg) + } + logger.debug(Prefix + "createCSAndSSRelationship Exit") + } + + + /** + * prepare update operation status to 50% after create relationship in aai + * @param execution + */ + def prepareUpdateOperationStatus = { DelegateExecution execution -> + logger.debug(Prefix + "prepareUpdateOperationStatus Start") + // update status creating + OperationStatus status = new OperationStatus() + status.setServiceId(execution.getVariable("serviceInstanceId") as String) + status.setOperationId(execution.getVariable("operationId") as String) + status.setOperation("CREATE") + status.setResult("processing") + status.setProgress("20") + status.setOperationContent("communication service create operation processing: waiting nsmf service create finished") + status.setUserId(execution.getVariable("globalSubscriberId") as String) + + requestDBUtil.prepareUpdateOperationStatus(execution, status) + logger.debug(Prefix + "prepareUpdateOperationStatus Exit") + } + + + /** + * create relationship in AAI + */ + private createRelationShipInAAI = { DelegateExecution execution, final Relationship relationship -> + logger.debug(Prefix + "createRelationShipInAAI Start") + String msg + try { + String serviceInstanceId = execution.getVariable("serviceInstanceId") + AAIResourceUri uri = AAIUriFactory.createResourceUri(AAIObjectType.SERVICE_INSTANCE, + execution.getVariable("globalSubscriberId"), + execution.getVariable("subscriptionServiceType"), + serviceInstanceId).relationshipAPI() + client.create(uri, relationship) + + } catch (BpmnError e) { + throw e + } catch (Exception ex) { + msg = "Exception in CreateCommunicationService.createRelationShipInAAI. " + ex.getMessage() + logger.info(msg) + exceptionUtil.buildAndThrowWorkflowException(execution, 7000, msg) + } + logger.debug(Prefix + "createRelationShipInAAI Exit") + + } + + + def prepareCallCheckProcessStatus = { DelegateExecution execution -> + logger.debug(Prefix + "prepareCallCheckProcessStatus Start") + + def successConditions = new ArrayList<>() + successConditions.add("finished") + execution.setVariable("successConditions", successConditions) + + def errorConditions = new ArrayList<>() + errorConditions.add("error") + execution.setVariable("errorConditions", errorConditions) + + execution.setVariable("processServiceType", "communication service") + + execution.setVariable("subOperationType", "CREATE") + + execution.setVariable("timeOut", 3 * 60 * 60 * 1000) + + def successParamMap = new HashMap<String, Object>() + successParamMap.put("orchestrationStatus", "deactivated") + + execution.setVariable("successParamMap", successParamMap) + + def errorParamMap = new HashMap<String, Object>() + errorParamMap.put("orchestrationStatus", "error") + + execution.setVariable("errorParamMap", errorParamMap) + + def timeOutParamMap = new HashMap<String, Object>() + timeOutParamMap.put("orchestrationStatus", "error") + + execution.setVariable("timeOutParamMap", timeOutParamMap) + + execution.setVariable("initProgress", 20) + execution.setVariable("endProgress", 90) + + logger.debug(Prefix + "prepareCallCheckProcessStatus Exit") + } + + + /** + * prepare update operation status to complete after NSMF process success + * @param execution + */ + def prepareCompleteStatus = { DelegateExecution execution -> + logger.debug(Prefix + "prepareCompleteStatus Start") + OperationStatus status = new OperationStatus() + status.setServiceId(execution.getVariable("serviceInstanceId") as String) + status.setOperationId(execution.getVariable("operationId") as String) + status.setOperation("CREATE") + status.setResult(execution.getVariable("operationStatus") as String) + status.setProgress("100") + status.setOperationContent(execution.getVariable("operationContent") as String) + status.setUserId(execution.getVariable("globalSubscriberId") as String) + + requestDBUtil.prepareUpdateOperationStatus(execution, status) + logger.debug("prepareCompleteStatus end, serviceInstanceId: " + execution.getVariable("serviceInstanceId") + + ", operationId: " + execution.getVariable("operationId")) + logger.debug(Prefix + "prepareCompleteStatus Exit") + } + + + /** + * update NSMF complete status to AAI when the NSMF process finished + * @param execution + */ + def updateFinishStatusInAAI = { DelegateExecution execution -> + logger.debug(Prefix + "updateFinishStatusInAAI Start") + String msg + try { + + String serviceInstanceId = execution.getVariable("serviceInstanceId") + String subscriptionServiceType = execution.getVariable("subscriptionServiceType") + String globalSubscriberId = execution.getVariable("globalSubscriberId") + String orchestrationStatus = execution.getVariable("orchestrationStatus") + // create service + ServiceInstance csi = new ServiceInstance() + csi.setOrchestrationStatus(orchestrationStatus) + AAIResourceUri uri = AAIUriFactory.createResourceUri(AAIObjectType.SERVICE_INSTANCE, + globalSubscriberId, subscriptionServiceType, serviceInstanceId) + client.update(uri, csi) + logger.debug(Prefix + "updateFinishStatusInAAI update communication service status to deactivated") + + } catch (BpmnError e) { + throw e + } catch (Exception ex) { + msg = "Exception in complete communication service " + ex.getMessage() + logger.debug(msg) + exceptionUtil.buildAndThrowWorkflowException(execution, 7000, msg) + } + logger.debug(Prefix + "updateFinishStatusInAAI Exit") + } + + + public sendSyncError = { DelegateExecution execution -> + logger.debug("sendSyncError Start") + try { + String errorMessage + if (execution.getVariable("WorkflowException") instanceof WorkflowException) { + WorkflowException wfe = execution.getVariable("WorkflowException") as WorkflowException + errorMessage = wfe.getErrorMessage() + } else { + errorMessage = "Sending Sync Error." + } + + String buildWorkflowException = + """<aetgt:WorkflowException xmlns:aetgt="http://org.onap/so/workflow/schema/v1"> + <aetgt:ErrorMessage>${MsoUtils.xmlEscape(errorMessage)}</aetgt:ErrorMessage> + <aetgt:ErrorCode>7000</aetgt:ErrorCode> + </aetgt:WorkflowException>""" + + logger.debug(buildWorkflowException) + sendWorkflowResponse(execution, 500, buildWorkflowException) + + } catch (Exception ex) { + logger.debug("Sending Sync Error Activity Failed. " + "\n" + ex.getMessage()) + } + logger.debug(Prefix + "sendSyncError Exit") + } + +} diff --git a/bpmn/so-bpmn-infrastructure-common/src/main/groovy/org/onap/so/bpmn/infrastructure/scripts/CreateSliceService.groovy b/bpmn/so-bpmn-infrastructure-common/src/main/groovy/org/onap/so/bpmn/infrastructure/scripts/CreateSliceService.groovy new file mode 100644 index 0000000000..7cc1a559c3 --- /dev/null +++ b/bpmn/so-bpmn-infrastructure-common/src/main/groovy/org/onap/so/bpmn/infrastructure/scripts/CreateSliceService.groovy @@ -0,0 +1,520 @@ +/*- + * ============LICENSE_START======================================================= + * ONAP - SO + * ================================================================================ + * Copyright (C) 2019 Huawei Technologies Co., Ltd. All rights reserved. + * ================================================================================ + * 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 com.fasterxml.jackson.databind.ObjectMapper +import org.onap.aai.domain.yang.ServiceInstance +import org.onap.so.client.HttpClient +import org.onap.so.client.HttpClientFactory +import org.onap.so.client.aai.AAIObjectType +import org.onap.so.client.aai.AAIResourcesClient +import org.onap.so.client.aai.entities.uri.AAIResourceUri +import org.onap.so.client.aai.entities.uri.AAIUriFactory + +import javax.ws.rs.core.Response + +import static org.apache.commons.lang3.StringUtils.* +import org.springframework.web.util.UriUtils +import groovy.json.JsonSlurper +import org.camunda.bpm.engine.delegate.BpmnError +import org.camunda.bpm.engine.delegate.DelegateExecution +import org.onap.logging.filter.base.ONAPComponents +import org.onap.so.beans.nsmf.SliceTaskParams +import org.onap.so.db.request.beans.OrchestrationTask +import org.onap.so.bpmn.common.scripts.AbstractServiceTaskProcessor +import org.onap.so.bpmn.common.scripts.ExceptionUtil +import org.onap.so.bpmn.common.scripts.OofUtils +import org.onap.so.bpmn.core.UrnPropertiesReader +import org.onap.so.bpmn.common.scripts.MsoUtils +import org.onap.so.bpmn.core.json.JsonUtils +import org.onap.so.logger.ErrorCode +import org.onap.so.logger.LoggingAnchor +import org.onap.so.logger.MessageEnum +import org.slf4j.Logger +import org.slf4j.LoggerFactory + +public class CreateSliceService extends AbstractServiceTaskProcessor { + String Prefix = "CRESS_" + + ExceptionUtil exceptionUtil = new ExceptionUtil() + JsonUtils jsonUtil = new JsonUtils() + JsonSlurper jsonSlurper = new JsonSlurper() + ObjectMapper objectMapper = new ObjectMapper() + OofUtils oofUtils = new OofUtils() + private static final Logger logger = LoggerFactory.getLogger(CreateSliceService.class) + + + public void preProcessRequest(DelegateExecution execution) { + logger.debug("Start preProcessRequest") + execution.setVariable("prefix", Prefix) + String msg = "" + + try { + String ssRequest = execution.getVariable("bpmnRequest") + logger.debug(ssRequest) + + String requestId = execution.getVariable("mso-request-id") + execution.setVariable("msoRequestId", requestId) + logger.debug("Input Request:" + ssRequest + " reqId:" + requestId) + + String serviceInstanceId = execution.getVariable("serviceInstanceId") + if (isBlank(serviceInstanceId)) { + serviceInstanceId = UUID.randomUUID().toString() + } + + String operationId = UUID.randomUUID().toString() + execution.setVariable("operationId", operationId) + + logger.debug("Generated new Service Instance:" + serviceInstanceId) + serviceInstanceId = UriUtils.encode(serviceInstanceId, "UTF-8") + execution.setVariable("serviceInstanceId", serviceInstanceId) + + //subscriberInfo + String globalSubscriberId = jsonUtil.getJsonValue(ssRequest, "requestDetails.subscriberInfo.globalSubscriberId") + if (isBlank(globalSubscriberId)) { + msg = "Input globalSubscriberId' is null" + exceptionUtil.buildAndThrowWorkflowException(execution, 500, msg) + } else { + execution.setVariable("globalSubscriberId", globalSubscriberId) + } + + //requestInfo + execution.setVariable("source", jsonUtil.getJsonValue(ssRequest, "requestDetails.requestInfo.source")) + execution.setVariable("serviceInstanceName", jsonUtil.getJsonValue(ssRequest, "requestDetails.requestInfo.instanceName")) + execution.setVariable("disableRollback", jsonUtil.getJsonValue(ssRequest, "requestDetails.requestInfo.suppressRollback")) + String productFamilyId = jsonUtil.getJsonValue(ssRequest, "requestDetails.requestInfo.productFamilyId") + if (isBlank(productFamilyId)) { + msg = "Input productFamilyId is null" + logger.debug(msg) + //exceptionUtil.buildAndThrowWorkflowException(execution, 500, msg) + } else { + execution.setVariable("productFamilyId", productFamilyId) + } + + //modelInfo + String serviceModelInfo = jsonUtil.getJsonValue(ssRequest, "requestDetails.modelInfo") + if (isBlank(serviceModelInfo)) { + msg = "Input serviceModelInfo is null" + logger.debug(msg) + exceptionUtil.buildAndThrowWorkflowException(execution, 500, msg) + } else { + execution.setVariable("serviceModelInfo", serviceModelInfo) + } + + logger.debug("modelInfo: " + serviceModelInfo) + + //requestParameters + String subscriptionServiceType = jsonUtil.getJsonValue(ssRequest, "requestDetails.requestParameters.subscriptionServiceType") + if (isBlank(subscriptionServiceType)) { + msg = "Input subscriptionServiceType is null" + logger.debug(msg) + exceptionUtil.buildAndThrowWorkflowException(execution, 500, msg) + } else { + execution.setVariable("subscriptionServiceType", subscriptionServiceType) + } + logger.debug("subscriptionServiceType: " + subscriptionServiceType) + + /* + * Extracting User Parameters from incoming Request and converting into a Map + */ + Map reqMap = jsonSlurper.parseText(ssRequest) + + //InputParams + def userParamsList = reqMap.requestDetails?.requestParameters?.userParams + + Map<String, String> inputMap = [:] + if (userParamsList) { + for (def i = 0; i < userParamsList.size(); i++) { + def userParams1 = userParamsList.get(i) + userParams1.each { param -> inputMap.put(param.key, param.value) } + } + } + + logger.debug("User Input Parameters map: " + inputMap.toString()) + String uuiRequest = inputMap.get("UUIRequest") + Map uuiReqMap = jsonSlurper.parseText(uuiRequest) + Map<String, Object> serviceObject = (Map<String, Object>) uuiReqMap.get("service") + Map<String, Object> parameterObject = (Map<String, Object>) serviceObject.get("parameters") + Map<String, Object> requestInputs = (Map<String, Object>) parameterObject.get("requestInputs") + + execution.setVariable("serviceInputParams", inputMap) + execution.setVariable("uuiRequest", uuiRequest) + execution.setVariable("serviceProfile", requestInputs) + + //TODO + //execution.setVariable("serviceInputParams", jsonUtil.getJsonValue(siRequest, "requestDetails.requestParameters.userParams")) + //execution.setVariable("failExists", true) + + } catch (BpmnError e) { + throw e + } catch (Exception ex) { + msg = "Exception in preProcessRequest " + ex.getMessage() + logger.debug(msg) + exceptionUtil.buildAndThrowWorkflowException(execution, 7000, msg) + } + logger.debug("Finish preProcessRequest") + } + + public void getNSTSelection(DelegateExecution execution) { + logger.debug("Start getNSTSelection") + String requestId = execution.getVariable("msoRequestId") + Map<String, Object> serviceProfile = execution.getVariable("serviceProfile") + String oofUrl = UrnPropertiesReader.getVariable("mso.oof.endpoint", execution) + + def authHeader = "" + String basicAuth = UrnPropertiesReader.getVariable("mso.oof.auth", execution) + String msokey = UrnPropertiesReader.getVariable("mso.msoKey", execution) + + String basicAuthValue = utils.encrypt(basicAuth, msokey) + if (basicAuthValue != null) { + logger.debug( "Obtained BasicAuth username and password for OOF: " + basicAuthValue) + try { + authHeader = utils.getBasicAuth(basicAuthValue, msokey) + execution.setVariable("BasicAuthHeaderValue", authHeader) + } catch (Exception ex) { + logger.debug( "Unable to encode username and password string: " + ex) + exceptionUtil.buildAndThrowWorkflowException(execution, 401, "Internal Error - Unable to " + + "encode username and password string") + } + } else { + logger.debug( "Unable to obtain BasicAuth - BasicAuth value null") + exceptionUtil.buildAndThrowWorkflowException(execution, 401, "Internal Error - BasicAuth " + + "value null") + } + + URL requestUrl = new URL(oofUrl + "/api/oof/v1/selection/nst") + String oofRequest = oofUtils.buildSelectNSTRequest(requestId, serviceProfile) + HttpClient httpClient = new HttpClientFactory().newJsonClient(requestUrl, ONAPComponents.OOF) + httpClient.addAdditionalHeader("Authorization", authHeader) + Response httpResponse = httpClient.post(oofRequest) + + int responseCode = httpResponse.getStatus() + logger.debug("OOF sync response code is: " + responseCode) + + if(responseCode != 200){ + exceptionUtil.buildAndThrowWorkflowException(execution, responseCode, "Received a Bad Sync Response from OOF.") + } + + Map<String, Object> nstSolution + try { + Map<String, Object> resMap = httpResponse.readEntity(Map.class) + List<Map<String, Object>> nstSolutions = (List<Map<String, Object>>) resMap.get("solutions") + nstSolution = nstSolutions.get(0) + execution.setVariable("nstSolution", nstSolution) + } catch (Exception ex) { + logger.debug( "Failed to get NST solution suggested by OOF.") + exceptionUtil.buildAndThrowWorkflowException(execution, 401, "Failed to get NST solution suggested by OOF.") + } + + logger.debug("Finish getNSTSelection") + + } + + public void prepareDecomposeService(DelegateExecution execution) { + logger.debug("Start prepareDecomposeService") + String uuiRequest = execution.getVariable("uuiRequest") + String ssModelInvariantUuid = jsonUtil.getJsonValue(uuiRequest, "service.serviceInvariantUuid") + String ssModelUuid = jsonUtil.getJsonValue(uuiRequest, "service.serviceUuid") + String ssServiceModelInfo = """{ + "modelInvariantUuid":"${ssModelInvariantUuid}", + "modelUuid":"${ssModelUuid}", + "modelVersion":"" + }""" + execution.setVariable("ssServiceModelInfo", ssServiceModelInfo) + + logger.debug("Finish prepareDecomposeService") + } + + public void processDecomposition(DelegateExecution execution) { + logger.debug("Start processDecomposition") + String uuiRequest = execution.getVariable("uuiRequest") + Map<String, Object> serviceProfile = execution.getVariable("serviceProfile") + Map<String, Object> nstSolution = execution.getVariable("nstSolution") + + Map uuiReqMap = jsonSlurper.parseText(uuiRequest) + Map<String, Object> serviceObject = (Map<String, Object>) uuiReqMap.get("service") + String subscriptionServiceType = serviceObject.get("serviceType") + + String serviceType = (String) serviceProfile.get("sST") + String resourceSharingLevel = (String) serviceProfile.get("resourceSharingLevel") + String nstModelUuid = (String) nstSolution.get("UUID") + String nstModelInvariantUuid = (String) nstSolution.get("invariantUUID") + + execution.setVariable("subscriptionServiceType", subscriptionServiceType) + execution.setVariable("serviceType", serviceType) + execution.setVariable("resourceSharingLevel", resourceSharingLevel) + execution.setVariable("nstModelUuid", nstModelUuid) + execution.setVariable("nstModelInvariantUuid", nstModelInvariantUuid) + + logger.debug("Finish processDecomposition") + } + + public void prepareCreateOrchestrationTask(DelegateExecution execution) { + logger.debug("Start createOrchestrationTask") + String taskId = execution.getBusinessKey() + execution.setVariable("orchestrationTaskId", taskId) + logger.debug("BusinessKey: " + taskId) + String serviceInstanceId = execution.getVariable("serviceInstanceId") + String operationId = execution.getVariable("operationId") + String serviceInstanceName = execution.getVariable("serviceInstanceName") + String taskName = "SliceServiceTask" + String taskStatus = "Planning" + String isManual = "false" + String requestMethod = "POST" + execution.setVariable("CSSOT_taskId", taskId) + execution.setVariable("CSSOT_name", taskName) + execution.setVariable("CSSOT_status", taskStatus) + execution.setVariable("CSSOT_isManual", isManual) + execution.setVariable("CSSOT_requestMethod", requestMethod) + + Map<String, Object> serviceProfile = execution.getVariable("serviceProfile") + Map<String, Object> sliceProfileTn = execution.getVariable("sliceProfileTn") + Map<String, Object> sliceProfileCn = execution.getVariable("sliceProfileCn") + Map<String, Object> sliceProfileAn = execution.getVariable("sliceProfileAn") + + SliceTaskParams sliceTaskParams = new SliceTaskParams() + sliceTaskParams.setServiceId(serviceInstanceId) + sliceTaskParams.setServiceName(serviceInstanceName) + sliceTaskParams.setServiceProfile(serviceProfile) + sliceTaskParams.setSliceProfileTn(sliceProfileTn) + sliceTaskParams.setSliceProfileCn(sliceProfileCn) + sliceTaskParams.setSliceProfileAn(sliceProfileAn) + execution.setVariable("sliceTaskParams", sliceTaskParams) + + String paramJson = sliceTaskParams.convertToJson() + execution.setVariable("CSSOT_paramJson", paramJson) + logger.debug("CSSOT_paramJson: " + paramJson) + + logger.debug("Finish createOrchestrationTask") + } + + public void prepareUpdateOrchestrationTask(DelegateExecution execution) { + logger.debug("Start prepareUpdateOrchestrationTask") + String requestMethod = "PUT" + String taskStatus = execution.getVariable("taskStatus") + SliceTaskParams sliceTaskParams = execution.getVariable("sliceTaskParams") + String paramJson = sliceTaskParams.convertToJson() + execution.setVariable("CSSOT_status", taskStatus) + execution.setVariable("CSSOT_paramJson", paramJson) + execution.setVariable("CSSOT_requestMethod", requestMethod) + logger.debug("Finish prepareUpdateOrchestrationTask") + } + + public void prepareGetUserOptions(DelegateExecution execution) { + logger.debug("Start prepareGetUserOptions") + String requestMethod = "GET" + execution.setVariable("taskAction", "commit") + String taskAction = execution.getVariable("taskAction") + logger.debug("task action is: " + taskAction) + if (!"commit".equals(taskAction) && !"abort".equals(taskAction)) { + String msg = "Unknown task action: " + taskAction + logger.debug(msg) + exceptionUtil.buildAndThrowWorkflowException(execution, 500, msg) + } + execution.setVariable("CSSOT_requestMethod", requestMethod) + logger.debug("Finish prepareGetUserOptions") + } + + public void processUserOptions(DelegateExecution execution) { + logger.debug("Start processUserOptions") + String response = execution.getVariable("CSSOT_dbResponse") + OrchestrationTask orchestrationTask = objectMapper.readValue(response, OrchestrationTask.class) + String paramJson = orchestrationTask.getParams() + logger.debug("paramJson: " + paramJson) + SliceTaskParams sliceTaskParams = new SliceTaskParams() + sliceTaskParams.convertFromJson(paramJson) + execution.setVariable("sliceTaskParams", sliceTaskParams) + logger.debug("Finish processUserOptions") + } + + public void updateAAIOrchStatus(DelegateExecution execution) { + logger.debug("Start updateAAIOrchStatus") + String serviceInstanceId = execution.getVariable("serviceInstanceId") + String orchStatus = execution.getVariable("orchestrationStatus") + + try { + ServiceInstance si = execution.getVariable("serviceInstanceData") + si.setOrchestrationStatus(orchStatus) + AAIResourcesClient client = new AAIResourcesClient() + AAIResourceUri uri = AAIUriFactory.createResourceUri(AAIObjectType.SERVICE_INSTANCE, serviceInstanceId) + client.update(uri, si) + } catch (BpmnError e) { + throw e + } catch (Exception ex) { + String msg = "Exception in CreateSliceService.updateAAIOrchStatus " + ex.getMessage() + logger.info(msg) + exceptionUtil.buildAndThrowWorkflowException(execution, 7000, msg) + } + + logger.debug("Finish updateAAIOrchStatus") + } + + public void prepareInitServiceOperationStatus(DelegateExecution execution) { + logger.debug("Start prepareInitServiceOperationStatus") + try{ + String serviceId = execution.getVariable("serviceInstanceId") + String operationId = execution.getVariable("operationId") + String operationType = "CREATE" + String userId = execution.getVariable("globalSubscriberId") + String result = "processing" + String progress = "0" + String reason = "" + String operationContent = "Prepare service creation" + logger.debug("Generated new operation for Service Instance serviceId:" + serviceId + " operationId:" + operationId) + serviceId = UriUtils.encode(serviceId,"UTF-8") + execution.setVariable("serviceInstanceId", serviceId) + execution.setVariable("operationType", operationType) + + def dbAdapterEndpoint = UrnPropertiesReader.getVariable("mso.adapters.openecomp.db.endpoint",execution) + execution.setVariable("CSSOS_dbAdapterEndpoint", dbAdapterEndpoint) + logger.debug("DB Adapter Endpoint is: " + dbAdapterEndpoint) + def dbAdapterAuth = UrnPropertiesReader.getVariable("mso.requestDb.auth") + Map<String, String> CSSOS_headerMap = [:] + CSSOS_headerMap.put("content-type", "application/soap+xml") + CSSOS_headerMap.put("Authorization", dbAdapterAuth) + execution.setVariable("CSSOS_headerMap", CSSOS_headerMap) + logger.debug("DB Adapter Header is: " + CSSOS_headerMap) + + String payload = + """<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" + xmlns:ns="http://org.onap.so/requestsdb"> + <soapenv:Header/> + <soapenv:Body> + <ns:initServiceOperationStatus xmlns:ns="http://org.onap.so/requestsdb"> + <serviceId>${MsoUtils.xmlEscape(serviceId)}</serviceId> + <operationId>${MsoUtils.xmlEscape(operationId)}</operationId> + <operationType>${MsoUtils.xmlEscape(operationType)}</operationType> + <userId>${MsoUtils.xmlEscape(userId)}</userId> + <result>${MsoUtils.xmlEscape(result)}</result> + <operationContent>${MsoUtils.xmlEscape(operationContent)}</operationContent> + <progress>${MsoUtils.xmlEscape(progress)}</progress> + <reason>${MsoUtils.xmlEscape(reason)}</reason> + </ns:initServiceOperationStatus> + </soapenv:Body> + </soapenv:Envelope>""" + + payload = utils.formatXml(payload) + execution.setVariable("CSSOS_updateServiceOperStatusRequest", payload) + logger.debug("Outgoing updateServiceOperStatusRequest: \n" + payload) + }catch(Exception e){ + logger.error(LoggingAnchor.FIVE, MessageEnum.BPMN_GENERAL_EXCEPTION_ARG.toString(), + "Exception Occured Processing prepareInitServiceOperationStatus.", "BPMN", + ErrorCode.UnknownError.getValue(), "Exception is:\n" + e) + } + logger.debug("Finish prepareInitServiceOperationStatus") + } + + public void prepareUpdateServiceOperationStatus(DelegateExecution execution) { + logger.debug("Start preUpdateServiceOperationStatus") + try{ + String serviceId = execution.getVariable("serviceInstanceId") + String operationId = execution.getVariable("operationId") + String operationType = execution.getVariable("operationType") + String userId = execution.getVariable("globalSubscriberId") + String result = execution.getVariable("operationResult") + String progress = execution.getVariable("operationProgress") + String reason = execution.getVariable("operationReason") + String operationContent = "service: " + result + " progress: " + progress + + String payload = + """<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" + xmlns:ns="http://org.onap.so/requestsdb"> + <soapenv:Header/> + <soapenv:Body> + <ns:initServiceOperationStatus xmlns:ns="http://org.onap.so/requestsdb"> + <serviceId>${MsoUtils.xmlEscape(serviceId)}</serviceId> + <operationId>${MsoUtils.xmlEscape(operationId)}</operationId> + <operationType>${MsoUtils.xmlEscape(operationType)}</operationType> + <userId>${MsoUtils.xmlEscape(userId)}</userId> + <result>${MsoUtils.xmlEscape(result)}</result> + <operationContent>${MsoUtils.xmlEscape(operationContent)}</operationContent> + <progress>${MsoUtils.xmlEscape(progress)}</progress> + <reason>${MsoUtils.xmlEscape(reason)}</reason> + </ns:initServiceOperationStatus> + </soapenv:Body> + </soapenv:Envelope>""" + + payload = utils.formatXml(payload) + execution.setVariable("CSSOS_updateServiceOperStatusRequest", payload) + logger.debug("Outgoing updateServiceOperStatusRequest: \n" + payload) + + }catch(Exception e){ + logger.error(LoggingAnchor.FIVE, MessageEnum.BPMN_GENERAL_EXCEPTION_ARG.toString(), + "Exception Occured Processing preUpdateServiceOperationStatus.", "BPMN", + ErrorCode.UnknownError.getValue(), "Exception is:\n" + e.getMessage()) + } + logger.debug("Finish preUpdateServiceOperationStatus") + } + + public void sendSyncResponse(DelegateExecution execution) { + logger.debug("Start sendSyncResponse") + try { + String operationId = execution.getVariable("operationId") + String serviceInstanceId = execution.getVariable("serviceInstanceId") + // RESTResponse for API Handler (APIH) Reply Task + String createServiceRestRequest = """{"service":{"serviceId":"${serviceInstanceId}","operationId":"${operationId}"}}""".trim() + logger.debug("sendSyncResponse to APIH:" + "\n" + createServiceRestRequest) + sendWorkflowResponse(execution, 202, createServiceRestRequest) + execution.setVariable("sentSyncResponse", true) + } catch (Exception e) { + String msg = "Exceptuion in sendSyncResponse:" + e.getMessage() + logger.debug(msg) + exceptionUtil.buildAndThrowWorkflowException(execution, 7000, msg) + } + logger.debug("Finish sendSyncResponse") + } + + public void prepareCompletionRequest (DelegateExecution execution) { + logger.trace("Start prepareCompletionRequest") + try { + String requestId = execution.getVariable("msoRequestId") + String serviceInstanceId = execution.getVariable("serviceInstanceId") + String source = execution.getVariable("source") + + String msoCompletionRequest = + """<aetgt:MsoCompletionRequest xmlns:aetgt="http://org.onap/so/workflow/schema/v1" + xmlns:ns="http://org.onap/so/request/types/v1"> + <request-info xmlns="http://org.onap/so/infra/vnf-request/v1"> + <request-id>${MsoUtils.xmlEscape(requestId)}</request-id> + <action>CREATE</action> + <source>${MsoUtils.xmlEscape(source)}</source> + </request-info> + <status-message>Service Instance was created successfully.</status-message> + <serviceInstanceId>${MsoUtils.xmlEscape(serviceInstanceId)}</serviceInstanceId> + <mso-bpel-name>CreateGenericALaCarteServiceInstance</mso-bpel-name> + </aetgt:MsoCompletionRequest>""" + + // Format Response + String xmlMsoCompletionRequest = utils.formatXml(msoCompletionRequest) + + execution.setVariable("completionRequest", xmlMsoCompletionRequest) + logger.debug("Overall SUCCESS Response going to CompleteMsoProcess - " + "\n" + xmlMsoCompletionRequest) + + } catch (Exception ex) { + String msg = " Exception in prepareCompletion:" + ex.getMessage() + logger.debug(msg) + exceptionUtil.buildAndThrowWorkflowException(execution, 7000, msg) + } + logger.trace("Finish prepareCompletionRequest") + } + +} + diff --git a/bpmn/so-bpmn-infrastructure-common/src/test/groovy/org/onap/so/bpmn/infrastructure/scripts/CreateCommunicationServiceTest.groovy b/bpmn/so-bpmn-infrastructure-common/src/test/groovy/org/onap/so/bpmn/infrastructure/scripts/CreateCommunicationServiceTest.groovy new file mode 100644 index 0000000000..3622cc0062 --- /dev/null +++ b/bpmn/so-bpmn-infrastructure-common/src/test/groovy/org/onap/so/bpmn/infrastructure/scripts/CreateCommunicationServiceTest.groovy @@ -0,0 +1,456 @@ +/*- + * ============LICENSE_START======================================================= + * ONAP - SO + * ================================================================================ + # Copyright (c) 2019, CMCC Technologies Co., Ltd. + # + # 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.camunda.bpm.engine.impl.persistence.entity.ExecutionEntity +import org.json.JSONObject +import org.junit.Before +import org.junit.Test +import org.mockito.ArgumentCaptor +import org.mockito.Captor +import org.mockito.Mockito +import org.onap.so.bpmn.common.scripts.MsoGroovyTest +import org.onap.so.bpmn.core.domain.ModelInfo +import org.onap.so.bpmn.core.domain.ServiceDecomposition +import org.onap.so.bpmn.core.domain.ServiceInfo +import org.onap.so.bpmn.core.domain.ServiceProxy + +import static org.junit.Assert.assertEquals +import static org.junit.Assert.assertNotNull +import static org.mockito.ArgumentMatchers.eq +import static org.mockito.Mockito.times +import static org.mockito.Mockito.when + +class CreateCommunicationServiceTest extends MsoGroovyTest { + + @Before + void init() throws IOException { + super.init("CreateCommunicationService") + } + + @Captor + static ArgumentCaptor<ExecutionEntity> captor = ArgumentCaptor.forClass(ExecutionEntity.class) + + @Test + void testPreProcessRequest() { + when(mockExecution.getVariable("serviceInstanceId")).thenReturn("12345") + when(mockExecution.getVariable("bpmnRequest")).thenReturn(""" + { + "requestDetails": { + "modelInfo": { + "modelInvariantId": "e75698d9-925a-4cdd-a6c0-edacbe6a0b51", + "modelType": "service", + "modelNameVersionId": "8ee5926d-720b-4bb2-86f9-d20e921c143b", + "modelName": "voLTE", + "modelVersion": "1.0", + "modelVersionId": "8ee5926d-720b-4bb2-86f9-d20e921c143b", + "modelUuid": "8ee5926d-720b-4bb2-86f9-d20e921c143b", + "modelInvariantUuid": "e75698d9-925a-4cdd-a6c0-edacbe6a0b51" + }, + "requestInfo": { + "source": "UUI", + "instanceName": "CSMFService", + "suppressRollback": true + }, + "subscriberInfo": { + "globalSubscriberId": "5GCustomer" + }, + "requestParameters": { + "subscriptionServiceType": "MOG", + "userParams": [{ + "ServiceInstanceName": "CSMFService", + "UUIRequest": "{\\r\\n \\ + "service\\":{\\r\\n \\"name\\":\\"CSMFService\\",\\r\\n + \\"description\\":\\"CSMFService\\",\\r\\n + \\"serviceInvariantUuid\\":\\"e75698d9-925a-4cdd-a6c0-edacbe6a0b51\\",\\r\\n + \\"serviceUuid\\":\\"8ee5926d-720b-4bb2-86f9-d20e921c143b\\",\\r\\n + \\"globalSubscriberId\\":\\"5GCustomer\\",\\r\\n + \\"serviceType\\":\\"5G\\",\\r\\n + \\"parameters\\":{\\r\\n + \\"requestInputs\\":{\\r\\n + \\"expDataRateDL\\":10,\\r\\n + \\"expDataRateUL\\":30,\\r\\n + \\"latency\\":20,\\r\\n + \\"maxNumberofUEs\\":300,\\r\\n + \\"uemobilityLevel\\":\\"stationary\\",\\r\\n + \\"resourceSharingLevel\\":\\"shared\\",\\r\\n + \\"coverageAreaList\\": \\"01001\\",\\r\\n + \\"useInterval\\":\\"3\\"\\r\\n + }\\r\\n + }\\r\\n }\\r\\n}\\r\\n" + }], + "aLaCarte": true, + "usePreload": true + } + }, + "serviceInstanceId": null, + "vnfInstanceId": null, + "networkInstanceId": null, + "volumeGroupInstanceId": null, + "vfModuleInstanceId": null, + "configurationId": null, + "instanceGroupId": null + }""".replaceAll("\\s+", "")) + when(mockExecution.getVariable("mso-request-id")).thenReturn("edb08d97-e0f9-4c71-840a-72080d7be42e") + CreateCommunicationService communicationService = new CreateCommunicationService() + communicationService.preProcessRequest(mockExecution) + Mockito.verify(mockExecution, times(14)).setVariable(captor.capture() as String, captor.capture()) + List<ExecutionEntity> values = captor.getAllValues() + assertNotNull(values) + } + + @Test + void testPrepareInitOperationStatus() { + + when(mockExecution.getVariable("serviceInstanceId")).thenReturn("12345") + when(mockExecution.getVariable("operationId")).thenReturn("54321") + + when(mockExecution.getVariable("globalSubscriberId")).thenReturn("11111") + + CreateCommunicationService communicationService = new CreateCommunicationService() + + communicationService.prepareInitOperationStatus(mockExecution) + Mockito.verify(mockExecution, times(1)).setVariable(eq("updateOperationStatus"), captor.capture()) + String res = captor.getValue() + assertNotNull(res) + } + + + @Test + void testSendSyncResponse() { + when(mockExecution.getVariable("operationId")).thenReturn("123456") + when(mockExecution.getVariable("serviceInstanceId")).thenReturn("12345") + CreateCommunicationService communicationService = new CreateCommunicationService() + communicationService.sendSyncResponse(mockExecution) + Mockito.verify(mockExecution, times(1)).setVariable(eq("sentSyncResponse"), captor.capture()) + def updateVolumeGroupRequest = captor.getValue() + assertEquals(updateVolumeGroupRequest, true) + } + + + @Test + void testPrepareDoComposeE2E() { + ServiceDecomposition serviceDecomposition = new ServiceDecomposition() + ServiceProxy serviceProxy = new ServiceProxy() + serviceProxy.setSourceModelUuid("f2f5967e-72d3-4c5c-b880-e214e71dba4e") + serviceDecomposition.setServiceProxy(Arrays.asList(serviceProxy)) + when(mockExecution.getVariable("csServiceDecomposition")).thenReturn(serviceDecomposition) + CreateCommunicationService communicationService = new CreateCommunicationService() + communicationService.prepareDoComposeE2E(mockExecution) + Mockito.verify(mockExecution, times(1)).setVariable(eq("e2eServiceModelInfo"), captor.capture()) + String e2eServiceModelInfo = captor.getValue() + assertEquals(e2eServiceModelInfo.trim().replaceAll(" ", ""), + """{"modelUuid":"f2f5967e-72d3-4c5c-b880-e214e71dba4e"}""") + } + + @Test + void testParseCSParamsFromReq() { + mockData() + when(mockExecution.getVariable("csServiceModelInfo")).thenReturn(""" + { + "modelInvariantUuid":"e75698d9-925a-4cdd-a6c0-edacbe6a0b51", + "modelName":"voLTE", + "modelNameVersionId":"8ee5926d-720b-4bb2-86f9-d20e921c143b", + "modelVersion":"1.0", + "modelVersionId":"8ee5926d-720b-4bb2-86f9-d20e921c143b", + "modelInvariantId":"e75698d9-925a-4cdd-a6c0-edacbe6a0b51", + "modelType":"service", + "modelUuid":"8ee5926d-720b-4bb2-86f9-d20e921c143b" + }""") + + ServiceDecomposition decomposition = new ServiceDecomposition() + decomposition.setServiceType("embb") + ServiceInfo serviceInfo = new ServiceInfo() + serviceInfo.setServiceProperties(""" + [{"name":"useInterval","type":"string","required":false}, + {"default":"39-00","name":"plmnIdList","type":"string","required":false}, + {"name":"maxNumberofUEs","type":"integer","required":false}, + {"name":"latency","type":"integer","required":false}, + {"name":"uEMobilityLevel","type":"string","required":false}, + {"name":"expDataRateUL","type":"integer","required":false}, + {"name":"expDataRateDL","type":"integer","required":false}, + {"name":"coverageAreaList","type":"string","required":false}, + {"name":"sNSSAI","type":"string","required":false}, + {"name":"resourceSharingLevel","type":"string","required":false}] + """) + decomposition.setServiceInfo(serviceInfo) + + when(mockExecution.getVariable("csServiceDecomposition")).thenReturn(decomposition) + + CreateCommunicationService communicationService = new CreateCommunicationService() + communicationService.parseCSParamsFromReq(mockExecution) + + Mockito.verify(mockExecution, times(1)).setVariable(eq("csInputMap"), captor.capture()) + def csInputMap = captor.getValue() + assertEquals(getExpectCsInputMap(), csInputMap) + + } + + private static Map<String, Object> getExpectCsInputMap() { + Map<String, Object> csInputMap = new HashMap<>() + csInputMap.put("expDataRateDL", 10) + csInputMap.put("expDataRateUL", 30) + csInputMap.put("latency", 20) + csInputMap.put("maxNumberofUEs", 300) + csInputMap.put("uEMobilityLevel", "stationary") + csInputMap.put("resourceSharingLevel", "shared") + csInputMap.put("coverageAreaTAList", "01001") + csInputMap.put("useInterval", "3") + csInputMap.put("coverageAreaList", null) + csInputMap.put("plmnIdList", "39-00") + csInputMap.put("sNSSAI", null) + return csInputMap + } + + @Test + void testGenerateE2EServiceProfile() { + ServiceDecomposition decomposition = new ServiceDecomposition() + decomposition.setServiceType("embb") + ServiceInfo serviceInfo = new ServiceInfo() + serviceInfo.setServiceProperties(""" + [{"name":"nstar0_allottedresource0_providing_service_uuid","type":"string","required":true}, + {"name":"areaTrafficCapDL","type":"integer","required":false}, + {"name":"maxNumberofUEs","type":"integer","required":false}, + {"name":"latency","type":"integer","required":false}, + {"name":"expDataRateUL","type":"integer","required":false}, + {"name":"sNSSAI","type":"string","required":false}, + {"name":"plmnIdList","type":"string","required":false}, + {"name":"sST","type":"integer","required":false}, + {"name":"areaTrafficCapUL","type":"integer","required":false}, + {"name":"uEMobilityLevel","type":"string","required":false}, + {"name":"expDataRateDL","type":"integer","required":false}, + {"name":"nstar0_allottedresource0_providing_service_invariant_uuid","type":"string","required":true}, + {"name":"coverageAreaTAList","type":"string","required":false}, + {"name":"activityFactor","type":"integer","required":false}, + {"name":"resourceSharingLevel","type":"string","required":false}] + """) + decomposition.setServiceInfo(serviceInfo) + + ModelInfo modelInfo = new ModelInfo() + modelInfo.setModelInvariantUuid("e75698d9-925a-4cdd-a6c0-edacbe6a0b51") + modelInfo.setModelUuid("8ee5926d-720b-4bb2-86f9-d20e921c143b") + decomposition.setModelInfo(modelInfo) + + when(mockExecution.getVariable("e2eServiceDecomposition")).thenReturn(decomposition) + when(mockExecution.getVariable("csInputMap")).thenReturn(getExpectCsInputMap()) + + CreateCommunicationService communicationService = new CreateCommunicationService() + communicationService.generateE2EServiceProfile(mockExecution) + + Mockito.verify(mockExecution, times(1)).setVariable(eq("e2eInputMap"), captor.capture()) + def csInputMap = captor.getValue() + assertEquals(csInputMap, getExpectE2eInputMap()) + } + + private static Map<String, Object> getExpectE2eInputMap() { + Map<String, Object> e2eInputMap = new HashMap<>() + e2eInputMap.put("nstar0_allottedresource0_providing_service_uuid", null) + e2eInputMap.put("nstar0_allottedresource0_providing_service_invariant_uuid", null) + e2eInputMap.put("areaTrafficCapDL", 100) + e2eInputMap.put("areaTrafficCapUL", 100) + e2eInputMap.put("expDataRateDL", 10) + e2eInputMap.put("expDataRateUL", 30) + e2eInputMap.put("latency", 20) + e2eInputMap.put("maxNumberofUEs", 300) + e2eInputMap.put("uEMobilityLevel", "stationary") + e2eInputMap.put("resourceSharingLevel", "shared") + e2eInputMap.put("coverageAreaTAList", "01001") + e2eInputMap.put("sST", null) + e2eInputMap.put("activityFactor", 0) + e2eInputMap.put("plmnIdList", "39-00") + e2eInputMap.put("sNSSAI", null) + + return e2eInputMap + } + + @Test + void testPreRequestSend2NSMF() { + when(mockExecution.getVariable("e2eInputMap")).thenReturn(getExpectE2eInputMap()) + when(mockExecution.getVariable("csServiceName")).thenReturn("testName") + when(mockExecution.getVariable("modelUuid")).thenReturn("12345") + when(mockExecution.getVariable("e2eModelInvariantUuid")).thenReturn("54321") + when(mockExecution.getVariable("e2eModelUuid")).thenReturn("11111") + when(mockExecution.getVariable("globalSubscriberId")).thenReturn("test111") + when(mockExecution.getVariable("subscriptionServiceType")).thenReturn("5GConsumer") + CreateCommunicationService communicationService = new CreateCommunicationService() + communicationService.preRequestSend2NSMF(mockExecution) + Mockito.verify(mockExecution, times(1)).setVariable(eq("CSMF_NSMFRequest"), captor.capture()) + String resultSuccess = captor.getValue() + + def expectMap = getExpectE2eInputMap() + expectMap.put("nstar0_allottedresource0_providing_service_uuid", null) + expectMap.put("nstar0_allottedresource0_providing_service_invariant_uuid", null) + + String expect = """ + { + "service":{ + "name": "testName", + "description": "e2eService of 12345", + "serviceInvariantUuid": "54321", + "serviceUuid": "11111", + "globalSubscriberId": "test111", + "serviceType": "5GConsumer", + "parameters":{ + "requestInputs": ${expectMap as JSONObject} + } + } + } + """ + assertEquals(expect.replaceAll("\\s+", ""), resultSuccess.replaceAll("\\s+", "")) + } + + @Test + void testProcessNSMFResponseSuccess() { + when(mockExecution.getVariable("CSMF_NSMFResponseCode")).thenReturn(202) + when(mockExecution.getVariable("CSMF_NSMFResponse")).thenReturn(""" + { + "service": { + "serviceId": "945063ff-1a01-4944-9232-8e7999e0d5e4", + "operationId": "e3819a23-3777-4172-a834-35ee78acf3f4" + } + } + """) + + CreateCommunicationService communicationService = new CreateCommunicationService() + communicationService.processNSMFResponse(mockExecution) + Mockito.verify(mockExecution, times(3)).setVariable(captor.capture(), captor.capture()) + def resultSuccess = captor.getAllValues() + + def expect = new ArrayList<>() + expect.add("e2eServiceInstanceId") + expect.add("945063ff-1a01-4944-9232-8e7999e0d5e4") + expect.add("e2eOperationId") + expect.add("e3819a23-3777-4172-a834-35ee78acf3f4") + expect.add("ProcessNsmfSuccess") + expect.add("OK") + assertEquals(expect, resultSuccess) + } + + @Test + void testProcessNSMFResponseError() { + when(mockExecution.getVariable("CSMF_NSMFResponseCode")).thenReturn(500) + CreateCommunicationService communicationService = new CreateCommunicationService() + communicationService.processNSMFResponse(mockExecution) + Mockito.verify(mockExecution, times(1)).setVariable(eq("ProcessNsmfSuccess"), captor.capture()) + String resultSuccess = captor.getValue() + assertEquals("ERROR", resultSuccess) + } + + @Test + void testPrepareUpdateOperationStatus() { + when(mockExecution.getVariable("serviceInstanceId")).thenReturn("12345") + when(mockExecution.getVariable("operationId")).thenReturn("54321") + + when(mockExecution.getVariable("globalSubscriberId")).thenReturn("11111") + when(mockExecution.getVariable("mso.adapters.openecomp.db.endpoint")) + .thenReturn("http://localhost:28090/dbadapters/RequestsDbAdapter") + CreateCommunicationService communicationService = new CreateCommunicationService() + + communicationService.prepareUpdateOperationStatus(mockExecution) + Mockito.verify(mockExecution, times(1)).setVariable(eq("updateOperationStatus"), captor.capture()) + String res = captor.getValue() + + String expect = getExpectPayload("updateServiceOperationStatus", "processing", "20", + "communication service create operation processing: waiting nsmf service create finished") + + assertEquals(expect.replaceAll("\\s+", ""), res.replaceAll("\\s+", "")) + } + + + @Test + void testPrepareCallCheckProcessStatus() { + CreateCommunicationService communicationService = new CreateCommunicationService() + communicationService.prepareCallCheckProcessStatus(mockExecution) + Mockito.verify(mockExecution, times(10)).setVariable(captor.capture(), captor.capture()) + def resultSuccess = captor.getAllValues() + assertNotNull(resultSuccess) + } + + + @Test + void testPrepareCompleteStatus() { + when(mockExecution.getVariable("serviceInstanceId")).thenReturn("12345") + when(mockExecution.getVariable("operationId")).thenReturn("54321") + when(mockExecution.getVariable("operationContent")) + .thenReturn("communication service create operation finished") + + when(mockExecution.getVariable("globalSubscriberId")).thenReturn("11111") + when(mockExecution.getVariable("operationStatus")) + .thenReturn("processing") + CreateCommunicationService communicationService = new CreateCommunicationService() + + communicationService.prepareCompleteStatus(mockExecution) + Mockito.verify(mockExecution, times(1)).setVariable(eq("updateOperationStatus"), captor.capture()) + String res = captor.getValue() + + String expect = getExpectPayload("updateServiceOperationStatus", "processing", "100", + "communication service create operation finished") + + assertEquals(expect.replaceAll("\\s+", ""), res.replaceAll("\\s+", "")) + } + + private static String getExpectPayload(String type, String result, String progress, String operationContent) { + String expect = + """<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" + xmlns:ns="http://org.onap.so/requestsdb"> + <soapenv:Header/> + <soapenv:Body> + <ns:${type} xmlns:ns="http://org.onap.so/requestsdb"> + <serviceId>12345</serviceId> + <operationId>54321</operationId> + <operationType>CREATE</operationType> + <userId>11111</userId> + <result>${result}</result> + <operationContent>${operationContent}</operationContent> + <progress>${progress}</progress> + <reason></reason> + </ns:${type}> + </soapenv:Body> + </soapenv:Envelope> + """ + return expect + } + + private void mockData() { + when(mockExecution.getVariable("uuiRequest")).thenReturn("""{ + "service":{ + "name":"CSMFService", + "description":"CSMFService", + "serviceInvariantUuid":"e75698d9-925a-4cdd-a6c0-edacbe6a0b51", + "serviceUuid":"8ee5926d-720b-4bb2-86f9-d20e921c143b", + "globalSubscriberId":"5GCustomer", + "serviceType":"5G", + "parameters":{ + "requestInputs":{ + "expDataRateDL":10, + "expDataRateUL":30, + "latency":20, + "maxNumberofUEs":300, + "uemobilityLevel":"stationary", + "resourceSharingLevel":"shared", + "coverageAreaList": "01001", + "useInterval":"3" + } + } + } + }""") + } +} |