2 * ============LICENSE_START=======================================================
4 * ================================================================================
5 * Copyright (C) 2020 Huawei Technologies Co., Ltd. All rights reserved.
6 * ================================================================================
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
11 * http://www.apache.org/licenses/LICENSE-2.0
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
18 * ============LICENSE_END=========================================================
21 package org.onap.so.bpmn.infrastructure.scripts
23 import org.camunda.bpm.engine.delegate.BpmnError
24 import org.camunda.bpm.engine.delegate.DelegateExecution
25 import org.onap.aai.domain.yang.LogicalLink
26 import org.onap.aai.domain.yang.NetworkPolicy
27 import org.onap.aai.domain.yang.Relationship
28 import org.onap.aai.domain.yang.ServiceInstance
29 import org.onap.aaiclient.client.aai.AAIResourcesClient
30 import org.onap.aaiclient.client.aai.entities.AAIResultWrapper
31 import org.onap.aaiclient.client.aai.entities.Relationships
32 import org.onap.aaiclient.client.aai.entities.uri.AAIResourceUri
33 import org.onap.aaiclient.client.aai.entities.uri.AAIUriFactory
34 import org.onap.aaiclient.client.generated.fluentbuilders.AAIFluentTypeBuilder
35 import org.onap.aaiclient.client.generated.fluentbuilders.Activities
36 import org.onap.so.bpmn.common.scripts.ExceptionUtil
37 import org.onap.so.bpmn.common.scripts.MsoUtils
38 import org.onap.so.bpmn.common.scripts.SDNCAdapterUtils
39 import org.onap.so.bpmn.core.RollbackData
40 import org.onap.so.bpmn.core.UrnPropertiesReader
41 import org.onap.so.bpmn.core.WorkflowException
42 import org.onap.so.bpmn.core.json.JsonUtils
43 import org.onap.so.db.request.beans.ResourceOperationStatus
44 import org.slf4j.Logger
45 import org.slf4j.LoggerFactory
47 import static org.apache.commons.lang3.StringUtils.isBlank
50 static final String AAI_VERSION = "v23"
51 private static final Logger logger = LoggerFactory.getLogger(TnNssmfUtils.class);
54 ExceptionUtil exceptionUtil = new ExceptionUtil()
55 JsonUtils jsonUtil = new JsonUtils()
56 MsoUtils msoUtils = new MsoUtils()
57 SDNCAdapterUtils sdncAdapterUtils = new SDNCAdapterUtils()
63 void setSdncCallbackUrl(DelegateExecution execution, boolean exceptionOnErr) {
64 setSdncCallbackUrl(execution, "sdncCallbackUrl", exceptionOnErr)
67 void setSdncCallbackUrl(DelegateExecution execution, String variableName, boolean exceptionOnErr) {
68 String sdncCallbackUrl = UrnPropertiesReader.getVariable('mso.workflow.sdncadapter.callback', execution)
70 if (isBlank(sdncCallbackUrl) && exceptionOnErr) {
71 String msg = "mso.workflow.sdncadapter.callback is null"
73 exceptionUtil.buildAndThrowWorkflowException(execution, 500, msg)
75 execution.setVariable(variableName, sdncCallbackUrl)
79 String buildSDNCRequest(DelegateExecution execution, String svcInstId, String svcAction) {
83 reqAction = "AllocateTransportSliceInstance"
86 reqAction = "DeleteTransportSliceInstance"
89 reqAction = "ActivateTransportSliceInstance"
92 reqAction = "DeactivateTransportSliceInstance"
98 buildSDNCRequest(execution, svcInstId, svcAction, reqAction)
101 String buildSDNCRequest(DelegateExecution execution, String svcInstId, String svcAction, String reqAction) {
103 String uuid = execution.getVariable('testReqId') // for junits
105 uuid = execution.getVariable("msoRequestId") + "-" + System.currentTimeMillis()
108 def callbackURL = execution.getVariable("sdncCallbackUrl")
109 def requestId = execution.getVariable("msoRequestId")
110 def serviceId = execution.getVariable("sliceServiceInstanceId")
111 def subServiceType = execution.getVariable("subscriptionServiceType")
112 def vnfType = execution.getVariable("serviceType")
113 def vnfName = execution.getVariable("sliceServiceInstanceName")
114 def tenantId = execution.getVariable("sliceServiceInstanceId")
115 def source = execution.getVariable("sliceServiceInstanceId")
116 def vnfId = execution.getVariable("sliceServiceInstanceId")
117 def cloudSiteId = execution.getVariable("sliceServiceInstanceId")
118 def serviceModelInfo = execution.getVariable("serviceModelInfo")
119 def vnfModelInfo = execution.getVariable("serviceModelInfo")
120 def globalSubscriberId = execution.getVariable("globalSubscriberId")
122 String vnfNameString = """<vnf-name>${MsoUtils.xmlEscape(vnfName)}</vnf-name>"""
123 String serviceEcompModelInformation = sdncAdapterUtils.modelInfoToEcompModelInformation(serviceModelInfo)
124 String vnfEcompModelInformation = sdncAdapterUtils.modelInfoToEcompModelInformation(vnfModelInfo)
126 String sdncVNFParamsXml = ""
128 if (execution.getVariable("vnfParamsExistFlag") == true) {
129 sdncVNFParamsXml = buildSDNCParamsXml(execution)
131 sdncVNFParamsXml = buildDefaultVnfInputParams(vnfId)
135 """<sdncadapterworkflow:SDNCAdapterWorkflowRequest xmlns:ns5="http://org.onap/so/request/types/v1"
136 xmlns:sdncadapterworkflow="http://org.onap/so/workflow/schema/v1"
137 xmlns:sdncadapter="http://org.onap/workflow/sdnc/adapter/schema/v1">
138 <sdncadapter:RequestHeader>
139 <sdncadapter:RequestId>${MsoUtils.xmlEscape(uuid)}</sdncadapter:RequestId>
140 <sdncadapter:SvcInstanceId>${MsoUtils.xmlEscape(svcInstId)}</sdncadapter:SvcInstanceId>
141 <sdncadapter:SvcAction>${MsoUtils.xmlEscape(svcAction)}</sdncadapter:SvcAction>
142 <sdncadapter:SvcOperation>vnf-topology-operation</sdncadapter:SvcOperation>
143 <sdncadapter:CallbackUrl>${MsoUtils.xmlEscape(callbackURL)}</sdncadapter:CallbackUrl>
144 <sdncadapter:MsoAction>generic-resource</sdncadapter:MsoAction>
145 </sdncadapter:RequestHeader>
146 <sdncadapterworkflow:SDNCRequestData>
147 <request-information>
148 <request-id>${MsoUtils.xmlEscape(requestId)}</request-id>
149 <request-action>${MsoUtils.xmlEscape(reqAction)}</request-action>
150 <source>${MsoUtils.xmlEscape(source)}</source>
154 </request-information>
155 <service-information>
156 <service-id>${MsoUtils.xmlEscape(serviceId)}</service-id>
157 <subscription-service-type>${MsoUtils.xmlEscape(subServiceType)}</subscription-service-type>
158 ${serviceEcompModelInformation}
159 <service-instance-id>${MsoUtils.xmlEscape(svcInstId)}</service-instance-id>
160 <global-customer-id>${MsoUtils.xmlEscape(globalSubscriberId)}</global-customer-id>
161 </service-information>
163 <vnf-id>${MsoUtils.xmlEscape(vnfId)}</vnf-id>
164 <vnf-type>${MsoUtils.xmlEscape(vnfType)}</vnf-type>
165 ${vnfEcompModelInformation}
169 <tenant>${MsoUtils.xmlEscape(tenantId)}</tenant>
170 <aic-cloud-region>${MsoUtils.xmlEscape(cloudSiteId)}</aic-cloud-region>
173 </sdncadapterworkflow:SDNCRequestData>
174 </sdncadapterworkflow:SDNCAdapterWorkflowRequest>"""
176 logger.debug("sdncRequest: " + sdncRequest)
181 String buildDefaultVnfInputParams(String vnfName) {
183 """<vnf-input-parameters>
185 <name>${MsoUtils.xmlEscape(vnfName)}</name>
187 </vnf-input-parameters>"""
192 String buildSDNCParamsXml(DelegateExecution execution) {
194 StringBuilder sb = new StringBuilder()
195 Map<String, String> paramsMap = execution.getVariable("TNNSSMF_vnfParamsMap")
197 for (Map.Entry<String, String> entry : paramsMap.entrySet()) {
199 String key = entry.getKey();
200 String value = entry.getValue()
201 paramsXml = """<${key}>$value</$key>"""
202 params = sb.append(paramsXml)
207 void validateSDNCResponse(DelegateExecution execution, String response, String method) {
208 validateSDNCResponse(execution, response, method, true)
211 void validateSDNCResponse(DelegateExecution execution, String response, String method, boolean exceptionOnErr) {
212 logger.debug("STARTED ValidateSDNCResponse Process")
216 String prefix = execution.getVariable("prefix")
217 if (isBlank(prefix)) {
218 if (exceptionOnErr) {
219 msg = "validateSDNCResponse: prefix is null"
221 exceptionUtil.buildAndThrowWorkflowException(execution, 500, msg)
226 WorkflowException workflowException = execution.getVariable("WorkflowException")
227 boolean successIndicator = execution.getVariable("SDNCA_SuccessIndicator")
229 logger.debug("TnNssmfUtils.validateSDNCResponse: SDNCResponse: " + response)
230 logger.debug("TnNssmfUtils.validateSDNCResponse: workflowException: " + workflowException)
232 sdncAdapterUtils.validateSDNCResponse(execution, response, workflowException, successIndicator)
234 String sdncResponse = response
235 if (execution.getVariable(prefix + 'sdncResponseSuccess') == true) {
236 logger.debug("Received a Good Response from SDNC Adapter for " + method + " SDNC Call. Response is: \n" + sdncResponse)
237 RollbackData rollbackData = execution.getVariable("rollbackData")
238 if (rollbackData == null) {
239 rollbackData = new RollbackData()
242 if (method.equals("allocate")) {
243 rollbackData.put("VNFMODULE", "rollbackSDNCRequestAllocate", "true")
244 } else if (method.equals("deallocate")) {
245 rollbackData.put("VNFMODULE", "rollbackSDNCRequestDeallocate", "true")
246 } else if (method.equals("activate")) {
247 rollbackData.put("VNFMODULE", "rollbackSDNCRequestActivate", "true")
248 } else if (method.equals("deactivate")) {
249 rollbackData.put("VNFMODULE", "rollbackSDNCRequestDeactivate", "true")
250 } else if (method.equals("modify")) {
251 rollbackData.put("VNFMODULE", "rollbackSDNCRequestModify", "true")
253 execution.setVariable("rollbackData", rollbackData)
255 if (exceptionOnErr) {
256 msg = "TnNssmfUtils.validateSDNCResponse: bad Response from SDNC Adapter for " + method + " SDNC Call."
258 exceptionUtil.buildAndThrowWorkflowException(execution, 500, msg)
262 logger.debug("COMPLETED ValidateSDNCResponse Process")
265 String getExecutionInputParams(DelegateExecution execution) {
266 String res = "\n msoRequestId=" + execution.getVariable("msoRequestId") +
267 "\n modelInvariantUuid=" + execution.getVariable("modelInvariantUuid") +
268 "\n modelUuid=" + execution.getVariable("modelUuid") +
269 "\n serviceInstanceID=" + execution.getVariable("serviceInstanceID") +
270 "\n operationType=" + execution.getVariable("operationType") +
271 "\n globalSubscriberId=" + execution.getVariable("globalSubscriberId") +
272 "\n dummyServiceId=" + execution.getVariable("dummyServiceId") +
273 "\n nsiId=" + execution.getVariable("nsiId") +
274 "\n networkType=" + execution.getVariable("networkType") +
275 "\n subscriptionServiceType=" + execution.getVariable("subscriptionServiceType") +
276 "\n jobId=" + execution.getVariable("jobId") +
277 "\n sliceParams=" + execution.getVariable("sliceParams") +
278 "\n servicename=" + execution.getVariable("servicename")
283 String getFirstSnssaiFromSliceProfile(String sliceProfileStr) {
284 String snssaiListStr = jsonUtil.getJsonValue(sliceProfileStr, "snssaiList")
285 String snssai = jsonUtil.StringArrayToList(snssaiListStr).get(0)
290 String getFirstPlmnIdFromSliceProfile(String sliceProfileStr) {
291 String plmnListStr = jsonUtil.getJsonValue(sliceProfileStr, "plmnIdList")
292 String res = jsonUtil.StringArrayToList(plmnListStr).get(0)
297 void createRelationShipInAAI(DelegateExecution execution, AAIResourceUri uri, Relationship relationship) {
298 logger.debug("createRelationShipInAAI Start")
300 AAIResourcesClient client = new AAIResourcesClient()
302 if (!client.exists(uri)) {
303 logger.info("ERROR: createRelationShipInAAI: not exist: uri={}", uri)
306 AAIResourceUri from = ((AAIResourceUri) (uri.clone())).relationshipAPI()
307 client.create(from, relationship)
309 } catch (BpmnError e) {
311 } catch (Exception ex) {
312 msg = "Exception in createRelationShipInAAI. " + ex.getMessage()
314 exceptionUtil.buildAndThrowWorkflowException(execution, 7000, msg)
316 logger.debug("createRelationShipInAAI Exit")
319 void attachLogicalLinkToAllottedResource(DelegateExecution execution, String aaiVersion, AAIResourceUri arUri,
320 String logicalLinkId) {
322 String toLink = "aai/${aaiVersion}/network/logical-links/logical-link/${logicalLinkId}"
324 Relationship relationship = new Relationship()
325 relationship.setRelatedLink(toLink)
326 relationship.setRelatedTo("logical-link")
327 relationship.setRelationshipLabel("org.onap.relationships.inventory.ComposedOf")
329 createRelationShipInAAI(execution, arUri, relationship)
332 void attachNetworkPolicyToAllottedResource(DelegateExecution execution, String aaiVersion,
333 AAIResourceUri aaiResourceUri, String networkPolicyId) {
335 String toLink = "aai/${aaiVersion}/network/network-policies/network-policy/${networkPolicyId}"
337 Relationship relationship = new Relationship()
338 relationship.setRelatedLink(toLink)
339 relationship.setRelatedTo("network-policy")
340 relationship.setRelationshipLabel("org.onap.relationships.inventory.Uses")
342 createRelationShipInAAI(execution, aaiResourceUri, relationship)
346 ResourceOperationStatus buildRoStatus(String nsstId,
353 String statusDescription) {
354 ResourceOperationStatus roStatus = new ResourceOperationStatus()
355 roStatus.setResourceTemplateUUID(nsstId)
356 roStatus.setResourceInstanceID(nssiId)
357 roStatus.setServiceId(nsiId)
358 roStatus.setOperationId(jobId)
359 roStatus.setOperType(action)
360 roStatus.setProgress(progress)
361 roStatus.setStatus(status)
362 roStatus.setStatusDescription(statusDescription)
368 void setEnableSdncConfig(DelegateExecution execution) {
369 String enableSdnc = UrnPropertiesReader.getVariable(
370 "mso.workflow.TnNssmf.enableSDNCNetworkConfig")
371 if (isBlank(enableSdnc)) {
372 logger.debug("mso.workflow.TnNssmf.enableSDNCNetworkConfig is undefined, so use default value (true)")
376 logger.debug("setEnableSdncConfig: enableSdnc=" + enableSdnc)
378 execution.setVariable("enableSdnc", enableSdnc)
381 String setExecVarFromJsonIfExists(DelegateExecution execution,
382 String jsonStr, String jsonKey, String varName) {
383 return setExecVarFromJsonStr(execution, jsonStr, jsonKey, varName, false)
386 String setExecVarFromJsonStr(DelegateExecution execution,
387 String jsonStr, String jsonKey, String varName,
388 boolean exceptionOnErr) {
390 String valueStr = jsonUtil.getJsonValue(jsonStr, jsonKey)
391 if (isBlank(valueStr)) {
392 if (exceptionOnErr) {
393 msg = "cannot find " + jsonKey + " in " + jsonStr
395 exceptionUtil.buildAndThrowWorkflowException(execution, 500, msg)
398 execution.setVariable(varName, valueStr)
404 ServiceInstance getServiceInstanceFromAai(String serviceInstanceId) {
405 if (isBlank(serviceInstanceId)) {
406 logger.error("ERROR: getServiceInstanceFromAai: serviceInstanceId is blank")
410 ServiceInstance nssi = null
411 AAIResourcesClient client = new AAIResourcesClient()
412 AAIResourceUri uri = AAIUriFactory.createResourceUri(AAIFluentTypeBuilder.Types.SERVICE_INSTANCE
413 .getFragment(serviceInstanceId))
414 Optional<ServiceInstance> nssiOpt = client.get(ServiceInstance.class, uri)
416 if (nssiOpt.isPresent()) {
420 String msg = String.format("ERROR: getServiceInstanceFromAai: NSSI %s not found in AAI", serviceInstanceId)
427 String getModelUuidFromServiceInstance(String serviceInstanceId) {
428 ServiceInstance si = getServiceInstanceFromAai(serviceInstanceId)
430 String msg = String.format("ERROR: getModelUuidFromServiceInstance: getServiceInstanceFromAai() failed. " +
431 "serviceInstanceId=%s", serviceInstanceId)
436 return si.modelVersionId()
439 AAIResourceUri buildNetworkPolicyUri(String networkPolicyId) {
440 AAIResourceUri networkPolicyUri =
441 AAIUriFactory.createResourceUri(AAIFluentTypeBuilder.network().networkPolicy(networkPolicyId))
443 return networkPolicyUri
446 AAIResourceUri buildAllottedResourceUri(DelegateExecution execution, String serviceInstanceId,
447 String allottedResourceId) {
449 AAIResourceUri allottedResourceUri =
450 AAIUriFactory.createResourceUri(AAIFluentTypeBuilder.business()
451 .customer(execution.getVariable("globalSubscriberId"))
452 .serviceSubscription(execution.getVariable("subscriptionServiceType"))
453 .serviceInstance(serviceInstanceId)
454 .allottedResource(allottedResourceId))
456 return allottedResourceUri
460 String getPolicyIdFromAr(DelegateExecution execution, String serviceInstanceId,
461 String arId, boolean exceptionOnErr) {
464 AAIResourcesClient client = new AAIResourcesClient()
466 AAIResourceUri arUri = buildAllottedResourceUri(execution, serviceInstanceId, arId)
467 List<AAIResourceUri> logicalLinkUriList = getRelationshipUriListInAai(execution, arUri,
468 AAIFluentTypeBuilder.Types.NETWORK_POLICY, exceptionOnErr)
469 for (AAIResourceUri logicalLinkUri : logicalLinkUriList) {
470 Optional<NetworkPolicy> policyOpt = client.get(NetworkPolicy.class, logicalLinkUri)
471 if (policyOpt.isPresent()) {
472 NetworkPolicy policy = policyOpt.get()
473 return policy.getNetworkPolicyId()
475 String msg = String.format("ERROR: getLogicalLinkNamesFromAr: logicalLinkUri=%s", logicalLinkUri)
477 exceptionUtil.buildAndThrowWorkflowException(execution, 2500, msg)
480 } catch (BpmnError e) {
481 if (exceptionOnErr) {
484 } catch (Exception ex) {
485 if (exceptionOnErr) {
486 String msg = String.format("ERROR: getLogicalLinkNamesFromAr: %s", ex.getMessage())
488 exceptionUtil.buildAndThrowWorkflowException(execution, 2500, msg)
496 List<AAIResourceUri> getRelationshipUriListInAai(DelegateExecution execution,
497 AAIResourceUri uri, Activities.Info info,
498 boolean exceptionOnErr) {
499 AAIResourcesClient client = new AAIResourcesClient()
500 AAIResultWrapper wrapper = client.get(uri);
501 Optional<Relationships> relationships = wrapper.getRelationships()
502 if (relationships.isPresent()) {
503 return relationships.get().getRelatedUris(info)
505 if (exceptionOnErr) {
506 String msg = "ERROR: getRelationshipUriListInAai: No relationship found"
508 exceptionUtil.buildAndThrowWorkflowException(execution, 2500, msg)
515 List<String> getLogicalLinkNamesFromAr(DelegateExecution execution, String serviceInstanceId,
516 String arId, boolean exceptionOnErr) {
517 List<String> res = new ArrayList<>()
519 AAIResourcesClient client = new AAIResourcesClient()
521 AAIResourceUri arUri = buildAllottedResourceUri(execution, serviceInstanceId, arId)
522 List<AAIResourceUri> logicalLinkUriList = getRelationshipUriListInAai(execution, arUri,
523 AAIFluentTypeBuilder.Types.LOGICAL_LINK, exceptionOnErr)
524 for (AAIResourceUri logicalLinkUri : logicalLinkUriList) {
525 Optional<LogicalLink> logicalLinkOpt = client.get(LogicalLink.class, logicalLinkUri)
526 if (logicalLinkOpt.isPresent()) {
527 LogicalLink logicalLink = logicalLinkOpt.get()
528 res.add(logicalLink.getLinkName())
530 String msg = String.format("ERROR: getLogicalLinkNamesFromAr: logicalLinkUri=%s", logicalLinkUri)
532 exceptionUtil.buildAndThrowWorkflowException(execution, 2500, msg)
535 } catch (BpmnError e) {
536 if (exceptionOnErr) {
539 } catch (Exception ex) {
540 if (exceptionOnErr) {
541 String msg = String.format("ERROR: getLogicalLinkNamesFromAr: %s", ex.getMessage())
543 exceptionUtil.buildAndThrowWorkflowException(execution, 2500, msg)