/*- * ============LICENSE_START======================================================= * ONAP - SO * ================================================================================ * Copyright (C) 2020 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 org.camunda.bpm.engine.delegate.BpmnError import org.camunda.bpm.engine.delegate.DelegateExecution import org.onap.aai.domain.yang.AllottedResources import org.onap.aai.domain.yang.LogicalLink import org.onap.aai.domain.yang.NetworkPolicy import org.onap.aai.domain.yang.Relationship import org.onap.aai.domain.yang.ServiceInstance import org.onap.aaiclient.client.aai.AAIResourcesClient import org.onap.aaiclient.client.aai.AAIVersion import org.onap.aaiclient.client.aai.entities.AAIResultWrapper import org.onap.aaiclient.client.aai.entities.Relationships import org.onap.aaiclient.client.aai.entities.uri.AAIPluralResourceUri import org.onap.aaiclient.client.aai.entities.uri.AAIResourceUri import org.onap.aaiclient.client.aai.entities.uri.AAIUriFactory import org.onap.aaiclient.client.generated.fluentbuilders.AAIFluentTypeBuilder import org.onap.so.bpmn.common.scripts.ExceptionUtil import org.onap.so.bpmn.common.scripts.MsoUtils import org.onap.so.bpmn.common.scripts.SDNCAdapterUtils import org.onap.so.bpmn.core.RollbackData import org.onap.so.bpmn.core.UrnPropertiesReader import org.onap.so.bpmn.core.WorkflowException import org.onap.so.bpmn.core.json.JsonUtils import org.onap.so.db.request.beans.ResourceOperationStatus import org.slf4j.Logger import org.slf4j.LoggerFactory import static org.apache.commons.lang3.StringUtils.isBlank import static org.apache.commons.lang3.StringUtils.isNotBlank class ServiceIntentUtils { static final String AAI_VERSION = AAIVersion.LATEST private static final Logger logger = LoggerFactory.getLogger(ServiceIntentUtils.class); ExceptionUtil exceptionUtil = new ExceptionUtil() JsonUtils jsonUtil = new JsonUtils() MsoUtils msoUtils = new MsoUtils() SDNCAdapterUtils sdncAdapterUtils = new SDNCAdapterUtils() ServiceIntentUtils() { } void setCommonExecutionVars(DelegateExecution execution) { setCommonExecutionVars(execution, true) } void setCommonExecutionVars(DelegateExecution execution, boolean exceptionOnErr) { def msg try { // get request input String bpmnRequestStr = execution.getVariable("bpmnRequest") logger.debug("Input Request: " + bpmnRequestStr) String requestId = execution.getVariable("mso-request-id") execution.setVariable("msoRequestId", requestId) logger.debug("requestId: " + requestId) //subscriberInfo String globalSubscriberId = jsonUtil.getJsonValue(bpmnRequestStr, "globalSubscriberId") if (isBlank(globalSubscriberId) && exceptionOnErr) { msg = "Input globalSubscriberId' is null" exceptionUtil.buildAndThrowWorkflowException(execution, 500, msg) } else { execution.setVariable("globalSubscriberId", globalSubscriberId) } String serviceType = jsonUtil.getJsonValue(bpmnRequestStr, "serviceType") if (isBlank(serviceType) && exceptionOnErr) { msg = "Input serviceType is null" logger.debug(msg) exceptionUtil.buildAndThrowWorkflowException(execution, 500, msg) } else { execution.setVariable("serviceType", serviceType) } String servicename = jsonUtil.getJsonValue(bpmnRequestStr, "name") if (isNotBlank(servicename)) { execution.setVariable("servicename", servicename) } else { logger.debug("erviceIntentUtils.setCommonExecutionVars: servicename is NOT set") } //requestParameters, subscriptionServiceType is 5G String subscriptionServiceType = jsonUtil.getJsonValue(bpmnRequestStr, "subscriptionServiceType") if (isBlank(subscriptionServiceType)) { msg = "Input subscriptionServiceType is null" logger.debug(msg) exceptionUtil.buildAndThrowWorkflowException(execution, 500, msg) } else { execution.setVariable("subscriptionServiceType", subscriptionServiceType) } String jobId = UUID.randomUUID().toString() execution.setVariable("jobId", jobId) String sliceParams = jsonUtil.getJsonValue(bpmnRequestStr, "additionalProperties") execution.setVariable("serviceIntentParams", sliceParams) } catch (BpmnError e) { throw e } catch (Exception ex) { msg = "Exception in ServiceIntentUtils.setCommonExecutionVars: " + ex.getMessage() logger.debug(msg) if (exceptionOnErr) { exceptionUtil.buildAndThrowWorkflowException(execution, 7000, msg) } } } void setSdncCallbackUrl(DelegateExecution execution, boolean exceptionOnErr) { setSdncCallbackUrl(execution, "sdncCallbackUrl", exceptionOnErr) } void setSdncCallbackUrl(DelegateExecution execution, String variableName, boolean exceptionOnErr) { String sdncCallbackUrl = UrnPropertiesReader.getVariable('mso.workflow.sdncadapter.callback', execution) if (isBlank(sdncCallbackUrl) && exceptionOnErr) { String msg = "mso.workflow.sdncadapter.callback is null" logger.debug(msg) exceptionUtil.buildAndThrowWorkflowException(execution, 500, msg) } else { execution.setVariable(variableName, sdncCallbackUrl) } } String buildSDNCRequest(DelegateExecution execution, String svcInstId, String svcAction) { String reqAction switch (svcAction) { case "create": reqAction = "CreateCloudLeasedLineInstance" break case "delete": reqAction = "DeleteCloudLeasedLineInstance" break case "activate": reqAction = "ActivateCloudLeasedLineInstance" break case "deactivate": reqAction = "DeactivateCloudLeasedLineInstance" break case "update": reqAction = "ModifyCloudLeasedLineInstance" break default: reqAction = svcAction } buildSDNCRequest(execution, svcInstId, svcAction, reqAction) } String buildSDNCRequest(DelegateExecution execution, String svcInstId, String svcAction, String reqAction) { String uuid = execution.getVariable('testReqId') // for junits if (uuid == null) { uuid = execution.getVariable("msoRequestId") + "-" + System.currentTimeMillis() } def callbackURL = execution.getVariable("sdncCallbackUrl") def requestId = execution.getVariable("msoRequestId") def serviceId = execution.getVariable("sliceServiceInstanceId") def subServiceType = execution.getVariable("subscriptionServiceType") def vnfType = execution.getVariable("serviceType") def vnfName = execution.getVariable("sliceServiceInstanceName") def tenantId = execution.getVariable("sliceServiceInstanceId") def source = execution.getVariable("sliceServiceInstanceId") def vnfId = execution.getVariable("sliceServiceInstanceId") def cloudSiteId = execution.getVariable("sliceServiceInstanceId") def serviceModelInfo = execution.getVariable("serviceModelInfo") def vnfModelInfo = execution.getVariable("serviceModelInfo") def globalSubscriberId = execution.getVariable("globalSubscriberId") String vnfNameString = """${MsoUtils.xmlEscape(vnfName)}""" String serviceEcompModelInformation = sdncAdapterUtils.modelInfoToEcompModelInformation(serviceModelInfo) String vnfEcompModelInformation = sdncAdapterUtils.modelInfoToEcompModelInformation(vnfModelInfo) String sdncVNFParamsXml = "" if (execution.getVariable("vnfParamsExistFlag") == true) { sdncVNFParamsXml = buildSDNCParamsXml(execution) } else { sdncVNFParamsXml = buildDefaultVnfInputParams(vnfId) } String sdncRequest = """ ${MsoUtils.xmlEscape(uuid)} ${MsoUtils.xmlEscape(svcInstId)} ${MsoUtils.xmlEscape(svcAction)} vnf-topology-operation ${MsoUtils.xmlEscape(callbackURL)} generic-resource ${MsoUtils.xmlEscape(requestId)} ${MsoUtils.xmlEscape(reqAction)} ${MsoUtils.xmlEscape(source)} ${MsoUtils.xmlEscape(serviceId)} ${MsoUtils.xmlEscape(subServiceType)} ${serviceEcompModelInformation} ${MsoUtils.xmlEscape(svcInstId)} ${MsoUtils.xmlEscape(globalSubscriberId)} ${MsoUtils.xmlEscape(vnfId)} ${MsoUtils.xmlEscape(vnfType)} ${vnfEcompModelInformation} ${vnfNameString} ${MsoUtils.xmlEscape(tenantId)} ${MsoUtils.xmlEscape(cloudSiteId)} ${sdncVNFParamsXml} """ logger.debug("sdncRequest: " + sdncRequest) return sdncRequest } String buildDefaultVnfInputParams(String vnfName) { String res = """ ${MsoUtils.xmlEscape(vnfName)} """ return res } String buildSDNCParamsXml(DelegateExecution execution) { String params = "" StringBuilder sb = new StringBuilder() Map paramsMap = execution.getVariable("TNNSSMF_vnfParamsMap") for (Map.Entry entry : paramsMap.entrySet()) { String paramsXml String key = entry.getKey(); String value = entry.getValue() paramsXml = """<${key}>$value""" params = sb.append(paramsXml) } return params } void validateSDNCResponse(DelegateExecution execution, String response, String method) { validateSDNCResponse(execution, response, method, true) } void validateSDNCResponse(DelegateExecution execution, String response, String method, boolean exceptionOnErr) { logger.debug("STARTED ValidateSDNCResponse Process") String msg String prefix = execution.getVariable("prefix") if (isBlank(prefix)) { if (exceptionOnErr) { msg = "validateSDNCResponse: prefix is null" logger.error(msg) exceptionUtil.buildAndThrowWorkflowException(execution, 500, msg) } return } WorkflowException workflowException = execution.getVariable("WorkflowException") boolean successIndicator = execution.getVariable("SDNCA_SuccessIndicator") logger.debug("ServiceIntentUtils.validateSDNCResponse: SDNCResponse: " + response) logger.debug("ServiceIntentUtils.validateSDNCResponse: workflowException: " + workflowException) sdncAdapterUtils.validateSDNCResponse(execution, response, workflowException, successIndicator) String sdncResponse = response if (execution.getVariable(prefix + 'sdncResponseSuccess') == true) { logger.debug("Received a Good Response from SDNC Adapter for " + method + " SDNC Call. Response is: \n" + sdncResponse) RollbackData rollbackData = execution.getVariable("rollbackData") if (rollbackData == null) { rollbackData = new RollbackData() } if (method.equals("allocate")) { rollbackData.put("VNFMODULE", "rollbackSDNCRequestAllocate", "true") } else if (method.equals("deallocate")) { rollbackData.put("VNFMODULE", "rollbackSDNCRequestDeallocate", "true") } else if (method.equals("activate")) { rollbackData.put("VNFMODULE", "rollbackSDNCRequestActivate", "true") } else if (method.equals("deactivate")) { rollbackData.put("VNFMODULE", "rollbackSDNCRequestDeactivate", "true") } else if (method.equals("modify")) { rollbackData.put("VNFMODULE", "rollbackSDNCRequestModify", "true") } execution.setVariable("rollbackData", rollbackData) } else { if (exceptionOnErr) { msg = "ServiceIntentUtils.validateSDNCResponse: bad Response from SDNC Adapter for " + method + " SDNC Call." logger.error(msg) exceptionUtil.buildAndThrowWorkflowException(execution, 500, msg) } } logger.debug("COMPLETED ValidateSDNCResponse Process") } String getExecutionInputParams(DelegateExecution execution) { String res = "\n msoRequestId=" + execution.getVariable("msoRequestId") + "\n modelInvariantUuid=" + execution.getVariable("modelInvariantUuid") + "\n modelUuid=" + execution.getVariable("modelUuid") + "\n serviceInstanceID=" + execution.getVariable("serviceInstanceID") + "\n operationType=" + execution.getVariable("operationType") + "\n globalSubscriberId=" + execution.getVariable("globalSubscriberId") + "\n dummyServiceId=" + execution.getVariable("dummyServiceId") + "\n nsiId=" + execution.getVariable("nsiId") + "\n serviceType=" + execution.getVariable("serviceType") + "\n subscriptionServiceType=" + execution.getVariable("subscriptionServiceType") + "\n jobId=" + execution.getVariable("jobId") + "\n serviceIntentParams=" + execution.getVariable("serviceIntentParams") + "\n servicename=" + execution.getVariable("servicename") return res } String getFirstSnssaiFromSliceProfile(String sliceProfileStr) { String snssaiListStr = jsonUtil.getJsonValue(sliceProfileStr, "snssaiList") String snssai = jsonUtil.StringArrayToList(snssaiListStr).get(0) return snssai } String getFirstPlmnIdFromSliceProfile(String sliceProfileStr) { String plmnListStr = jsonUtil.getJsonValue(sliceProfileStr, "pLMNIdList") String res = jsonUtil.StringArrayToList(plmnListStr).get(0) return res } void createRelationShipInAAI(DelegateExecution execution, AAIResourceUri uri, Relationship relationship) { logger.debug("createRelationShipInAAI Start") String msg AAIResourcesClient client = new AAIResourcesClient() try { if (!client.exists(uri)) { logger.info("ERROR: createRelationShipInAAI: not exist: uri={}", uri) return } AAIResourceUri from = ((AAIResourceUri) (uri.clone())).relationshipAPI() client.create(from, relationship) } catch (BpmnError e) { throw e } catch (Exception ex) { msg = "Exception in createRelationShipInAAI. " + ex.getMessage() logger.info(msg) exceptionUtil.buildAndThrowWorkflowException(execution, 7000, msg) } logger.debug("createRelationShipInAAI Exit") } void attachLogicalLinkToAllottedResource(DelegateExecution execution, String aaiVersion, AAIResourceUri arUri, String logicalLinkId) { String toLink = "aai/${aaiVersion}/network/logical-links/logical-link/${logicalLinkId}" Relationship relationship = new Relationship() relationship.setRelatedLink(toLink) relationship.setRelatedTo("logical-link") relationship.setRelationshipLabel("org.onap.relationships.inventory.ComposedOf") createRelationShipInAAI(execution, arUri, relationship) } void attachNetworkPolicyToAllottedResource(DelegateExecution execution, String aaiVersion, AAIResourceUri aaiResourceUri, String networkPolicyId) { String toLink = "aai/${aaiVersion}/network/network-policies/network-policy/${networkPolicyId}" Relationship relationship = new Relationship() relationship.setRelatedLink(toLink) relationship.setRelatedTo("network-policy") relationship.setRelationshipLabel("org.onap.relationships.inventory.Uses") createRelationShipInAAI(execution, aaiResourceUri, relationship) } ResourceOperationStatus buildRoStatus(String nsstId, String nssiId, String jobId, String nsiId, String action, String status, String progress, String statusDescription) { ResourceOperationStatus roStatus = new ResourceOperationStatus() roStatus.setResourceTemplateUUID(nsstId) roStatus.setResourceInstanceID(nssiId) roStatus.setServiceId(nsiId) roStatus.setOperationId(jobId) roStatus.setOperType(action) roStatus.setProgress(progress) roStatus.setStatus(status) roStatus.setStatusDescription(statusDescription) return roStatus } void setEnableSdncConfig(DelegateExecution execution) { String enableSdnc = UrnPropertiesReader.getVariable( "mso.workflow.TnNssmf.enableSDNCNetworkConfig") if (isBlank(enableSdnc)) { logger.debug("mso.workflow.TnNssmf.enableSDNCNetworkConfig is undefined, so use default value (true)") enableSdnc = "true" } logger.debug("setEnableSdncConfig: enableSdnc=" + enableSdnc) execution.setVariable("enableSdnc", enableSdnc) } String setExecVarFromJsonIfExists(DelegateExecution execution, String jsonStr, String jsonKey, String varName) { return setExecVarFromJsonStr(execution, jsonStr, jsonKey, varName, false) } String setExecVarFromJsonStr(DelegateExecution execution, String jsonStr, String jsonKey, String varName, boolean exceptionOnErr) { String msg = "" String valueStr = jsonUtil.getJsonValue(jsonStr, jsonKey) if (isBlank(valueStr)) { if (exceptionOnErr) { msg = "cannot find " + jsonKey + " in " + jsonStr logger.debug(msg) exceptionUtil.buildAndThrowWorkflowException(execution, 500, msg) } } else { execution.setVariable(varName, valueStr) } return valueStr } ServiceInstance getServiceInstanceFromAai(String serviceInstanceId) { if (isBlank(serviceInstanceId)) { logger.error("ERROR: getServiceInstanceFromAai: serviceInstanceId is blank") return null } ServiceInstance nssi = null AAIResourcesClient client = new AAIResourcesClient() AAIResourceUri uri = AAIUriFactory.createResourceUri(AAIFluentTypeBuilder.Types.SERVICE_INSTANCE .getFragment(serviceInstanceId)) Optional nssiOpt = client.get(ServiceInstance.class, uri) if (nssiOpt.isPresent()) { nssi = nssiOpt.get() return nssi } else { String msg = String.format("ERROR: getServiceInstanceFromAai: NSSI %s not found in AAI", serviceInstanceId) logger.error(msg) } return nssi; } String getModelUuidFromServiceInstance(String serviceInstanceId) { ServiceInstance si = getServiceInstanceFromAai(serviceInstanceId) if (si == null) { String msg = String.format("ERROR: getModelUuidFromServiceInstance: getServiceInstanceFromAai() failed. " + "serviceInstanceId=%s", serviceInstanceId) logger.error(msg) return null } return si.getModelVersionId() } AAIResourceUri buildNetworkPolicyUri(String networkPolicyId) { AAIResourceUri networkPolicyUri = AAIUriFactory.createResourceUri(AAIFluentTypeBuilder.network().networkPolicy(networkPolicyId)) return networkPolicyUri } AAIResourceUri buildAllottedResourceUri(DelegateExecution execution, String serviceInstanceId, String allottedResourceId) { AAIResourceUri allottedResourceUri = AAIUriFactory.createResourceUri(AAIFluentTypeBuilder.business() .customer(execution.getVariable("globalSubscriberId")) .serviceSubscription(execution.getVariable("subscriptionServiceType")) .serviceInstance(serviceInstanceId) .allottedResource(allottedResourceId)) return allottedResourceUri } AAIPluralResourceUri buildAllottedResourcesUri(DelegateExecution execution, String serviceInstanceId) { AAIPluralResourceUri arsUri = AAIUriFactory.createResourceUri(AAIFluentTypeBuilder.business() .customer(execution.getVariable("globalSubscriberId")) .serviceSubscription(execution.getVariable("subscriptionServiceType")) .serviceInstance(serviceInstanceId) .allottedResources()) return arsUri } AllottedResources getAllottedResourcesFromAai(DelegateExecution execution, String serviceInstanceId, boolean exceptionOnErr) { AllottedResources res try { AAIResourcesClient client = new AAIResourcesClient() AAIPluralResourceUri arsUri = buildAllottedResourcesUri(execution, serviceInstanceId) //AAIResultWrapper wrapperAllotted = client.get(arsUri, NotFoundException.class) //Optional allAllotted = wrapperAllotted.asBean(AllottedResources.class) //AllottedResources allottedResources = allAllotted.get() Optional arsOpt = client.get(AllottedResources.class, arsUri) if (arsOpt.isPresent()) { res = arsOpt.get() return res } else { String msg = String.format("ERROR: getAllottedResourcesFromAai: ars not found. nssiId=%s", serviceInstanceId) logger.error(msg) exceptionUtil.buildAndThrowWorkflowException(execution, 2500, msg) } } catch (BpmnError e) { if (exceptionOnErr) { throw e; } } catch (Exception ex) { if (exceptionOnErr) { String msg = String.format("ERROR: getAllottedResourcesFromAai: %s", ex.getMessage()) logger.error(msg) exceptionUtil.buildAndThrowWorkflowException(execution, 2500, msg) } } return res } String getPolicyIdFromAr(DelegateExecution execution, String serviceInstanceId, String arId, boolean exceptionOnErr) { String res try { AAIResourcesClient client = new AAIResourcesClient() AAIResourceUri arUri = buildAllottedResourceUri(execution, serviceInstanceId, arId) List policyUriList = getRelationshipUriListInAai(execution, arUri, AAIFluentTypeBuilder.Types.NETWORK_POLICY, exceptionOnErr) for (AAIResourceUri policyUri : policyUriList) { Optional policyOpt = client.get(NetworkPolicy.class, policyUri) if (policyOpt.isPresent()) { NetworkPolicy policy = policyOpt.get() return policy.getNetworkPolicyId() } else { String msg = String.format("ERROR: getPolicyIdFromAr: arUri=%s", policyUri) logger.error(msg) exceptionUtil.buildAndThrowWorkflowException(execution, 2500, msg) } } } catch (BpmnError e) { if (exceptionOnErr) { throw e; } } catch (Exception ex) { if (exceptionOnErr) { String msg = String.format("ERROR: getPolicyIdFromAr: %s", ex.getMessage()) logger.error(msg) exceptionUtil.buildAndThrowWorkflowException(execution, 2500, msg) } } return res } List getRelationshipUriListInAai(DelegateExecution execution, AAIResourceUri uri, Object info, boolean exceptionOnErr) { AAIResourcesClient client = new AAIResourcesClient() AAIResultWrapper wrapper = client.get(uri); Optional relationships = wrapper.getRelationships() if (relationships.isPresent()) { return relationships.get().getRelatedUris(info) } else { if (exceptionOnErr) { String msg = "ERROR: getRelationshipUriListInAai: No relationship found" logger.error(msg) exceptionUtil.buildAndThrowWorkflowException(execution, 2500, msg) } } return null } List getLogicalLinkNamesFromAr(DelegateExecution execution, String serviceInstanceId, String arId, boolean exceptionOnErr) { List res = new ArrayList<>() try { AAIResourcesClient client = new AAIResourcesClient() AAIResourceUri arUri = buildAllottedResourceUri(execution, serviceInstanceId, arId) List logicalLinkUriList = getRelationshipUriListInAai(execution, arUri, AAIFluentTypeBuilder.Types.LOGICAL_LINK, exceptionOnErr) for (AAIResourceUri logicalLinkUri : logicalLinkUriList) { Optional logicalLinkOpt = client.get(LogicalLink.class, logicalLinkUri) if (logicalLinkOpt.isPresent()) { LogicalLink logicalLink = logicalLinkOpt.get() res.add(logicalLink.getLinkName()) } else { String msg = String.format("ERROR: getLogicalLinkNamesFromAr: logicalLinkUri=%s", logicalLinkUri) logger.error(msg) exceptionUtil.buildAndThrowWorkflowException(execution, 2500, msg) } } } catch (BpmnError e) { if (exceptionOnErr) { throw e; } } catch (Exception ex) { if (exceptionOnErr) { String msg = String.format("ERROR: getLogicalLinkNamesFromAr: %s", ex.getMessage()) logger.error(msg) exceptionUtil.buildAndThrowWorkflowException(execution, 2500, msg) } } return res } }