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 com.fasterxml.jackson.databind.ObjectMapper
24 import groovy.json.JsonSlurper
25 import org.camunda.bpm.engine.delegate.BpmnError
26 import org.camunda.bpm.engine.delegate.DelegateExecution
27 import org.onap.aai.domain.yang.AllottedResource
28 import org.onap.aai.domain.yang.AllottedResources
29 import org.onap.aai.domain.yang.NetworkPolicy
30 import org.onap.aai.domain.yang.ServiceInstance
31 import org.onap.aai.domain.yang.SliceProfile
32 import org.onap.aaiclient.client.aai.AAIResourcesClient
33 import org.onap.aaiclient.client.aai.entities.uri.AAIResourceUri
34 import org.onap.aaiclient.client.aai.entities.uri.AAIUriFactory
35 import org.onap.aaiclient.client.generated.fluentbuilders.AAIFluentTypeBuilder
36 import org.onap.aaiclient.client.generated.fluentbuilders.AAIFluentTypeBuilder.Types
37 import org.onap.so.bpmn.common.scripts.AbstractServiceTaskProcessor
38 import org.onap.so.bpmn.common.scripts.ExceptionUtil
39 import org.onap.so.bpmn.common.scripts.RequestDBUtil
40 import org.onap.so.bpmn.core.json.JsonUtils
41 import org.onap.so.db.request.beans.ResourceOperationStatus
42 import org.slf4j.Logger
43 import org.slf4j.LoggerFactory
45 import static org.apache.commons.lang3.StringUtils.isBlank
46 import static org.apache.commons.lang3.StringUtils.isEmpty
47 import static org.apache.commons.lang3.StringUtils.isNotBlank
49 public class DoModifyTnNssi extends AbstractServiceTaskProcessor {
50 String Prefix = "TNMOD_"
52 ExceptionUtil exceptionUtil = new ExceptionUtil()
53 JsonUtils jsonUtil = new JsonUtils()
54 RequestDBUtil requestDBUtil = new RequestDBUtil()
55 TnNssmfUtils tnNssmfUtils = new TnNssmfUtils()
56 JsonSlurper jsonSlurper = new JsonSlurper()
57 ObjectMapper objectMapper = new ObjectMapper()
58 private static final Logger logger = LoggerFactory.getLogger(DoModifyTnNssi.class)
61 void preProcessRequest(DelegateExecution execution) {
62 logger.debug("Start preProcessRequest")
63 execution.setVariable("prefix", Prefix)
67 execution.setVariable("startTime", System.currentTimeMillis())
68 msg = tnNssmfUtils.getExecutionInputParams(execution)
69 logger.debug("Modify TN NSSI input parameters: " + msg)
71 execution.setVariable("prefix", Prefix)
73 tnNssmfUtils.setSdncCallbackUrl(execution, true)
74 logger.debug("SDNC Callback URL: " + execution.getVariable("sdncCallbackUrl"))
76 String additionalPropJsonStr = execution.getVariable("sliceParams")
77 if (isBlank(additionalPropJsonStr)) {
78 msg = "ERROR: additionalPropJsonStr is null"
80 exceptionUtil.buildAndThrowWorkflowException(execution, 500, msg)
83 String sliceServiceInstanceId = execution.getVariable("serviceInstanceID")
84 if (isBlank(sliceServiceInstanceId)) {
85 msg = "ERROR: sliceServiceInstanceId is null"
87 exceptionUtil.buildAndThrowWorkflowException(execution, 500, msg)
89 execution.setVariable("sliceServiceInstanceId", sliceServiceInstanceId)
91 String sliceServiceInstanceName = execution.getVariable("servicename")
92 execution.setVariable("sliceServiceInstanceName", sliceServiceInstanceName)
94 String operationId = UUID.randomUUID().toString()
95 execution.setVariable("operationId", operationId)
97 String modelInvariantUuid = execution.getVariable("modelInvariantUuid")
98 String modelUuid = execution.getVariable("modelUuid")
99 if (isEmpty(modelUuid)) {
100 modelUuid = tnNssmfUtils.getModelUuidFromServiceInstance(execution.getVariable("serviceInstanceID"))
103 def isDebugLogEnabled = true
104 execution.setVariable("isDebugLogEnabled", isDebugLogEnabled)
105 String serviceModelInfo = """{
106 "modelInvariantUuid":"${modelInvariantUuid}",
107 "modelUuid":"${modelUuid}",
110 execution.setVariable("serviceModelInfo", serviceModelInfo)
112 tnNssmfUtils.setExecVarFromJsonStr(execution, additionalPropJsonStr,
113 "sliceProfile", "sliceProfile", true)
115 tnNssmfUtils.setExecVarFromJsonStr(execution, additionalPropJsonStr,
116 "transportSliceNetworks", "transportSliceNetworks", true)
117 logger.debug("transportSliceNetworks: " + execution.getVariable("transportSliceNetworks"))
119 tnNssmfUtils.setExecVarFromJsonStr(execution, additionalPropJsonStr,
120 "nsiInfo", "nsiInfo", true)
122 if (isBlank(tnNssmfUtils.setExecVarFromJsonIfExists(execution, additionalPropJsonStr,
123 "enableSdnc", "enableSdnc"))) {
124 tnNssmfUtils.setEnableSdncConfig(execution)
126 } catch (BpmnError e) {
128 } catch (Exception ex) {
129 msg = "Exception in preProcessRequest " + ex.getMessage()
131 exceptionUtil.buildAndThrowWorkflowException(execution, 7000, msg)
133 logger.debug("Finish preProcessRequest")
137 void deleteServiceInstance(DelegateExecution execution) {
139 AAIResourcesClient client = getAAIClient()
140 AAIResourceUri uri = AAIUriFactory.createResourceUri(AAIFluentTypeBuilder.business().customer(execution.getVariable("globalSubscriberId")).serviceSubscription(execution.getVariable("subscriptionServiceType")).serviceInstance(execution.getVariable("serviceInstanceID")))
142 } catch (BpmnError e) {
144 } catch (Exception ex) {
145 String msg = "Exception in DoDeallocateTnNssi.deleteServiceInstance. " + ex.getMessage()
147 exceptionUtil.buildAndThrowWorkflowException(execution, 7000, msg)
152 void getExistingServiceInstance(DelegateExecution execution) {
153 String serviceInstanceId = execution.getVariable("sliceServiceInstanceId")
155 AAIResourcesClient resourceClient = getAAIClient()
156 AAIResourceUri ssServiceuri = AAIUriFactory.createResourceUri(Types.SERVICE_INSTANCE.getFragment(serviceInstanceId))
159 Optional<ServiceInstance> ssOpt = resourceClient.get(ServiceInstance.class, ssServiceuri)
160 if (ssOpt.isPresent()) {
161 ServiceInstance ss = ssOpt.get()
162 AllottedResources ars = tnNssmfUtils.getAllottedResourcesFromAai(execution, serviceInstanceId, true)
164 List<AllottedResource> arList = ars.getAllottedResource()
165 List<String> arIdList = new ArrayList<>()
166 Map<String, String> policyMap = new HashMap<>()
167 Map<String, List<String>> logicalLinksMap = new HashMap<>()
168 for (AllottedResource ar : arList) {
169 String arId = ar.getId()
171 String policyId = tnNssmfUtils.getPolicyIdFromAr(execution, serviceInstanceId, arId, true)
172 policyMap.put(arId, policyId)
173 List<String> logicalLinkList = tnNssmfUtils.getLogicalLinkNamesFromAr(execution,
174 serviceInstanceId, arId, true)
175 logicalLinksMap.put(arId, logicalLinkList)
177 execution.setVariable("arIdList", arIdList)
178 execution.setVariable("arPolicyMap", policyMap)
179 execution.setVariable("arLogicalLinkMap", logicalLinksMap)
181 logger.error("ERROR: getExistingServiceInstance: getAllottedResources() returned null. ss=" + ss
185 exceptionUtil.buildAndThrowWorkflowException(execution, 2500, "Service instance was not found in aai to " +
186 "associate allotted resource for service :" + serviceInstanceId)
188 } catch (BpmnError e) {
190 } catch (Exception ex) {
191 String msg = "Exception in getExistingServiceInstance. " + ex.getMessage()
193 exceptionUtil.buildAndThrowWorkflowException(execution, 7000, msg)
197 void updateTnNssiInAAI(DelegateExecution execution) {
198 getExistingServiceInstance(execution)
199 updateTsciNetworks(execution)
202 void updateServiceInstance(DelegateExecution execution) {
203 String ssInstanceId = execution.getVariable("sliceServiceInstanceId")
205 ServiceInstance ss = new ServiceInstance()
206 //ss.setServiceInstanceId(ssInstanceId)
207 String serviceStatus = "modified"
208 ss.setOrchestrationStatus(serviceStatus)
209 ss.setEnvironmentContext("tn")
210 AAIResourcesClient client = getAAIClient()
211 AAIResourceUri uri = AAIUriFactory.createResourceUri(
212 AAIFluentTypeBuilder.business()
213 .customer(execution.getVariable("globalSubscriberId"))
214 .serviceSubscription(execution.getVariable("subscriptionServiceType"))
215 .serviceInstance(ssInstanceId))
216 client.update(uri, ss)
217 } catch (BpmnError e) {
219 } catch (Exception ex) {
220 String msg = "Exception in DoCreateTnNssiInstance.createServiceInstance. " + ex.getMessage()
222 exceptionUtil.buildAndThrowWorkflowException(execution, 7000, msg)
226 void updateSliceProfile(DelegateExecution execution) {
228 String sliceserviceInstanceId = execution.getVariable("sliceServiceInstanceId")
229 String sliceProfileStr = execution.getVariable("sliceProfile")
230 String sliceProfileId = execution.getVariable("sliceProfileId")
231 SliceProfile sliceProfile = new SliceProfile();
232 sliceProfile.setProfileId(sliceProfileId)
233 sliceProfile.setLatency(Integer.parseInt(jsonUtil.getJsonValue(sliceProfileStr, "latency")))
234 sliceProfile.setResourceSharingLevel(jsonUtil.getJsonValue(sliceProfileStr, "resourceSharingLevel"))
235 sliceProfile.setSNssai(tnNssmfUtils.getFirstSnssaiFromSliceProfile(sliceProfileStr)) //TODO: should be list
237 sliceProfile.setE2ELatency(Integer.parseInt(jsonUtil.getJsonValue(sliceProfileStr, "latency")))
238 sliceProfile.setMaxBandwidth(Integer.parseInt(jsonUtil.getJsonValue(sliceProfileStr, "maxBandwidth")))
241 sliceProfile.setReliability(new Object())
243 AAIResourcesClient client = getAAIClient()
244 AAIResourceUri uri = AAIUriFactory.createResourceUri(AAIFluentTypeBuilder.business().customer(execution.getVariable("globalSubscriberId")).serviceSubscription(execution.getVariable("subscriptionServiceType")).serviceInstance(sliceserviceInstanceId).sliceProfile(sliceProfileId))
245 client.update(uri, sliceProfile)
247 } catch (BpmnError e) {
249 } catch (Exception ex) {
250 String msg = "Exception in updateSliceProfile. " + ex.getMessage()
252 exceptionUtil.buildAndThrowWorkflowException(execution, 7000, msg)
256 String getValidArId(DelegateExecution execution, String arIdStr) {
257 List<String> arIdList = execution.getVariable("arIdList")
259 * If arId is not specified by the caller, then we assume the caller
260 * wants to modify the first network (i.e., allotted resource) in the TSCi tree.
262 String arId = isBlank(arIdStr) ? arIdList.get(0) : arIdStr
267 void updateLogicalLinksInAr(DelegateExecution execution, String arId, String linkArrayJsonStr) {
269 String serviceInstanceId = execution.getVariable('sliceServiceInstanceId')
272 * Each TSCi connection-link in linkArrayJsonStr is considered as an "ADD" new
273 * link to allotted-resource. So, if the link already exists under AR, then do
274 * nothing. Otherwise, create logical-link.
276 List<String> linkStrList = jsonUtil.StringArrayToList(linkArrayJsonStr)
277 for (String linkStr : linkStrList) {
278 if (logicalLinkExists(execution, arId, linkStr)) {
282 createLogicalLinkForAllocatedResource(execution, linkStr, serviceInstanceId, arId)
284 } catch (BpmnError e) {
286 } catch (Exception ex) {
287 exceptionUtil.buildAndThrowWorkflowException(execution, 7000,
288 "Exception in updateLogicalLinksInAr" + ex.getMessage())
292 void updateLogicalLinksInNetwork(DelegateExecution execution, String networkJsonStr) {
294 String arId = getValidArId(execution, jsonUtil.getJsonValue(networkJsonStr, "id"))
295 String linkArrayStr = jsonUtil.getJsonValue(networkJsonStr, "connectionLinks")
296 updateLogicalLinksInAr(execution, arId, linkArrayStr)
297 } catch (BpmnError e) {
299 } catch (Exception ex) {
300 String msg = String.format("ERROR: updateLogicalLinksInNetwork: exception: %s", ex.getMessage())
302 exceptionUtil.buildAndThrowWorkflowException(execution, 7000, msg);
306 void updateTsciNetworks(DelegateExecution execution) {
308 List<String> networkStrList = jsonUtil.StringArrayToList(execution.getVariable("transportSliceNetworks"))
309 for (String networkStr : networkStrList) {
310 updateLogicalLinksInNetwork(execution, networkStr)
311 updateNetworkPolicy(execution, networkStr)
314 } catch (BpmnError e) {
316 } catch (Exception ex) {
317 exceptionUtil.buildAndThrowWorkflowException(execution, 7000,
318 "Exception in updateTsciNetworks" + ex.getMessage())
322 int getMaxBw(DelegateExecution execution) {
325 String sliceProfileStr = execution.getVariable("sliceProfile")
326 if (isBlank(sliceProfileStr)) {
327 String msg = "ERROR: getMaxBw: sliceProfile is null"
329 exceptionUtil.buildAndThrowWorkflowException(execution, 7000, msg)
331 String bwStr = jsonUtil.getJsonValue(sliceProfileStr, "maxBandwidth")
332 if (isNotBlank(bwStr)) {
333 maxBw = Integer.parseInt(bwStr)
335 logger.error("ERROR: getMaxBw: maxBandwidth is null")
337 } catch (BpmnError e) {
339 } catch (Exception ex) {
340 exceptionUtil.buildAndThrowWorkflowException(execution, 7000,
341 "Exception in getMaxBw" + ex.getMessage())
347 void updatePolicyMaxBandwidthInAAI(DelegateExecution execution, String policyId, int maxBw) {
349 NetworkPolicy networkPolicy = new NetworkPolicy()
350 networkPolicy.setMaxBandwidth(maxBw)
351 AAIResourceUri networkPolicyUri =
352 AAIUriFactory.createResourceUri(AAIFluentTypeBuilder.network().networkPolicy(policyId))
353 getAAIClient().update(networkPolicyUri, networkPolicy)
354 } catch (BpmnError e) {
356 } catch (Exception ex) {
357 String msg = "Exception in DoCreateTnNssiInstance.createServiceInstance. " + ex.getMessage()
359 exceptionUtil.buildAndThrowWorkflowException(execution, 7000, msg)
363 void updateNetworkPolicy(DelegateExecution execution, String networkJsonStr) {
365 int maxBw = getMaxBw(execution)
367 String arId = getValidArId(execution, jsonUtil.getJsonValue(networkJsonStr, "id"))
368 Map<String, String> policyMap = execution.getVariable("arPolicyMap")
369 String policyId = policyMap.get(arId)
370 if (isBlank(policyId)) {
371 String msg = String.format("ERROR: updateNetworkPolicy: policyId not found. arId=%s", arId)
373 exceptionUtil.buildAndThrowWorkflowException(execution, 7000, msg)
376 updatePolicyMaxBandwidthInAAI(execution, policyId, maxBw)
378 } catch (BpmnError e) {
380 } catch (Exception ex) {
381 String msg = String.format("ERROR: updateNetworkPolicy: exception: %s", ex.getMessage())
383 exceptionUtil.buildAndThrowWorkflowException(execution, 7000, msg);
388 void createLogicalLinkForAllocatedResource(DelegateExecution execution,
389 String linkJsonStr, String ssInstanceId,
390 String allottedResourceId) {
392 AAIResourceUri allottedResourceUri = tnNssmfUtils.buildAllottedResourceUri(execution,
393 ssInstanceId, allottedResourceId)
395 if (!getAAIClient().exists(allottedResourceUri)) {
396 logger.info("ERROR: createLogicalLinksForAllocatedResource: allottedResource not exist: uri={}",
401 String linkId = jsonUtil.getJsonValue(linkJsonStr, "id")
402 if (isBlank(linkId)) {
403 linkId = "tn-nssmf-" + UUID.randomUUID().toString()
405 logger.debug("createLogicalLinkForAllocatedResource: linkId=" + linkId)
407 String epA = jsonUtil.getJsonValue(linkJsonStr, "transportEndpointA")
408 String epB = jsonUtil.getJsonValue(linkJsonStr, "transportEndpointB")
409 String modelInvariantId = execution.getVariable("modelInvariantUuid")
410 String modelVersionId = execution.getVariable("modelUuid")
412 org.onap.aai.domain.yang.LogicalLink resource = new org.onap.aai.domain.yang.LogicalLink()
413 resource.setLinkId(linkId)
414 resource.setLinkName(epA)
415 resource.setLinkName2(epB)
416 resource.setLinkType("TsciConnectionLink")
417 resource.setInMaint(false)
420 AAIResourceUri logicalLinkUri =
421 AAIUriFactory.createResourceUri(AAIFluentTypeBuilder.network().logicalLink(epA))
422 getAAIClient().create(logicalLinkUri, resource)
424 tnNssmfUtils.attachLogicalLinkToAllottedResource(execution, tnNssmfUtils.AAI_VERSION,
425 allottedResourceUri, epA);
426 } catch (BpmnError e) {
428 } catch (Exception ex) {
429 String msg = "Exception in DoCreateTnNssiInstance.createLogicalLinksForAllocatedResource: " + ex.getMessage()
431 exceptionUtil.buildAndThrowWorkflowException(execution, 7000, msg)
436 void preprocessSdncModifyTnNssiRequest(DelegateExecution execution) {
437 def method = getClass().getSimpleName() + '.preprocessSdncModifyTnNssiRequest(' +
438 'execution=' + execution.getId() + ')'
439 def isDebugLogEnabled = execution.getVariable('isDebugLogEnabled')
440 logger.trace('Entered ' + method)
443 String serviceInstanceId = execution.getVariable("sliceServiceInstanceId")
445 String sdncRequest = tnNssmfUtils.buildSDNCRequest(execution, serviceInstanceId, "update")
447 execution.setVariable("TNNSSMF_SDNCRequest", sdncRequest)
448 logger.debug("Outgoing SDNCRequest is: \n" + sdncRequest)
450 } catch (BpmnError e) {
452 } catch (Exception e) {
453 logger.debug("Exception Occured Processing preprocessSdncModifyTnNssiRequest. Exception is:\n" + e)
454 exceptionUtil.buildAndThrowWorkflowException(execution, 1002, "Error Occured during preProcessSDNCActivateRequest Method:\n" + e.getMessage())
456 logger.trace("COMPLETED preprocessSdncModifyTnNssiRequest Process")
460 void validateSDNCResponse(DelegateExecution execution, String response, String method) {
461 tnNssmfUtils.validateSDNCResponse(execution, response, method)
465 void updateAAIOrchStatus(DelegateExecution execution) {
466 logger.debug("Start updateAAIOrchStatus")
467 String sliceServiceInstanceId = execution.getVariable("sliceServiceInstanceId")
468 String orchStatus = execution.getVariable("orchestrationStatus")
471 ServiceInstance si = new ServiceInstance()
472 si.setOrchestrationStatus(orchStatus)
473 AAIResourcesClient client = getAAIClient()
474 AAIResourceUri uri = AAIUriFactory.createResourceUri(Types.SERVICE_INSTANCE.getFragment(sliceServiceInstanceId))
475 client.update(uri, si)
476 } catch (BpmnError e) {
478 } catch (Exception ex) {
479 String msg = "Exception in CreateSliceService.updateAAIOrchStatus " + ex.getMessage()
481 exceptionUtil.buildAndThrowWorkflowException(execution, 7000, msg)
484 logger.debug("Finish updateAAIOrchStatus")
487 void prepareUpdateJobStatus(DelegateExecution execution,
490 String statusDescription) {
491 String ssInstanceId = execution.getVariable("sliceServiceInstanceId")
492 String modelUuid = execution.getVariable("modelUuid")
493 String jobId = execution.getVariable("jobId")
494 String nsiId = execution.getVariable("nsiId")
495 String operType = "MODIFY"
497 ResourceOperationStatus roStatus = tnNssmfUtils.buildRoStatus(modelUuid, ssInstanceId,
498 jobId, nsiId, operType, status, progress, statusDescription)
500 logger.debug("prepareUpdateJobStatus: roStatus={}", roStatus)
501 requestDBUtil.prepareUpdateResourceOperationStatus(execution, roStatus)
504 boolean logicalLinkExists(DelegateExecution execution, String arIdStr, String linkJsonStr) {
505 if (isBlank(arIdStr)) {
506 logger.error("ERROR: logicalLinkExists: arIdStr is empty")
509 if (isBlank(linkJsonStr)) {
510 logger.error("ERROR: logicalLinkExists: linkJsonStr is empty")
514 Map<String, List<String>> logicalLinksMap = execution.getVariable("arLogicalLinkMap")
515 if (logicalLinksMap == null) {
516 logger.error("ERROR: logicalLinkExists: logicalLinksMap is null")
520 List<String> logicalLinkNameList = logicalLinksMap.get(arIdStr)
521 if (logicalLinksMap == null) {
522 logger.error("ERROR: logicalLinkExists: logicalLinkNameList is null. arIdStr=" + arIdStr)
526 String linkName = jsonUtil.getJsonValue(linkJsonStr, "transportEndpointA")
527 if (isBlank(linkName)) {
528 logger.error("ERROR: logicalLinkExists: epA is empty")
532 return logicalLinkNameList.contains(linkName)