Merge "Enable DeleteChildService functionality" into recursive-orch
[so.git] / bpmn / so-bpmn-infrastructure-common / src / main / groovy / org / onap / so / bpmn / infrastructure / scripts / DoCloudLeasedLineModify.groovy
1 /*-
2  * ============LICENSE_START=======================================================
3  * ONAP - SO
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
10  *
11  *      http://www.apache.org/licenses/LICENSE-2.0
12  *
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=========================================================
19  */
20
21 package org.onap.so.bpmn.infrastructure.scripts
22
23 import org.camunda.bpm.engine.delegate.BpmnError
24 import org.camunda.bpm.engine.delegate.DelegateExecution
25 import org.onap.aai.domain.yang.AllottedResource
26 import org.onap.aai.domain.yang.AllottedResources
27 import org.onap.aai.domain.yang.NetworkPolicy
28 import org.onap.aai.domain.yang.ServiceInstance
29 import org.onap.aaiclient.client.aai.AAIResourcesClient
30 import org.onap.aaiclient.client.aai.entities.uri.AAIResourceUri
31 import org.onap.aaiclient.client.aai.entities.uri.AAIUriFactory
32 import org.onap.aaiclient.client.generated.fluentbuilders.AAIFluentTypeBuilder
33 import org.onap.aaiclient.client.generated.fluentbuilders.AAIFluentTypeBuilder.Types
34 import org.onap.so.bpmn.common.scripts.AbstractServiceTaskProcessor
35 import org.onap.so.bpmn.common.scripts.ExceptionUtil
36 import org.onap.so.bpmn.common.scripts.RequestDBUtil
37 import org.onap.so.bpmn.core.json.JsonUtils
38 import org.onap.so.db.request.beans.ResourceOperationStatus
39 import org.slf4j.Logger
40 import org.slf4j.LoggerFactory
41
42 import static org.apache.commons.lang3.StringUtils.isBlank
43 import static org.apache.commons.lang3.StringUtils.isEmpty
44 import static org.apache.commons.lang3.StringUtils.isNotBlank
45
46 public class DoCloudLeasedLineModify extends AbstractServiceTaskProcessor {
47     String Prefix = "MCLL_"
48
49     ExceptionUtil exceptionUtil = new ExceptionUtil()
50     JsonUtils jsonUtil = new JsonUtils()
51     RequestDBUtil requestDBUtil = new RequestDBUtil()
52     ServiceIntentUtils serviceIntentUtils = new ServiceIntentUtils()
53     private static final Logger logger = LoggerFactory.getLogger(DoCloudLeasedLineModify.class)
54
55
56     void preProcessRequest(DelegateExecution execution) {
57         logger.debug("Start preProcessRequest")
58         execution.setVariable("prefix", Prefix)
59         String msg = ""
60
61         try {
62             execution.setVariable("startTime", System.currentTimeMillis())
63             msg = serviceIntentUtils.getExecutionInputParams(execution)
64             logger.debug("Modify CLL input parameters: " + msg)
65
66             execution.setVariable("prefix", Prefix)
67
68             serviceIntentUtils.setSdncCallbackUrl(execution, true)
69             logger.debug("SDNC Callback URL: " + execution.getVariable("sdncCallbackUrl"))
70
71             String additionalPropJsonStr = execution.getVariable("serviceIntentParams")
72             if (isBlank(additionalPropJsonStr)) {
73                 msg = "ERROR: preProcessRequest: additionalPropJsonStr is null"
74                 logger.error(msg)
75                 exceptionUtil.buildAndThrowWorkflowException(execution, 500, msg)
76             }
77
78             String cllId = execution.getVariable("serviceInstanceID")
79             if (isBlank(cllId)) {
80                 msg = "ERROR: cllId is null"
81                 logger.debug(msg)
82                 exceptionUtil.buildAndThrowWorkflowException(execution, 500, msg)
83             }
84             execution.setVariable("cllId", cllId)
85
86             String cllName = execution.getVariable("servicename")
87             execution.setVariable("cllName", cllName)
88
89             String operationId = UUID.randomUUID().toString()
90             execution.setVariable("operationId", operationId)
91
92             String modelInvariantUuid = execution.getVariable("modelInvariantUuid")
93             String modelUuid = execution.getVariable("modelUuid")
94             if (isEmpty(modelUuid)) {
95                 modelUuid = serviceIntentUtils.getModelUuidFromServiceInstance(execution.getVariable("serviceInstanceID"))
96             }
97
98             def isDebugLogEnabled = true
99             execution.setVariable("isDebugLogEnabled", isDebugLogEnabled)
100             String serviceModelInfo = """{
101             "modelInvariantUuid":"${modelInvariantUuid}",
102             "modelUuid":"${modelUuid}",
103             "modelVersion":""
104              }"""
105             execution.setVariable("serviceModelInfo", serviceModelInfo)
106
107
108             serviceIntentUtils.setExecVarFromJsonStr(execution, additionalPropJsonStr,
109                     "transportNetworks", "transportNetworks", true)
110             logger.debug("transportNetworks: " + execution.getVariable("transportNetworks"))
111
112             if (isBlank(serviceIntentUtils.setExecVarFromJsonIfExists(execution, additionalPropJsonStr,
113                     "enableSdnc", "enableSdnc"))) {
114                 serviceIntentUtils.setEnableSdncConfig(execution)
115             }
116         } catch (BpmnError e) {
117             throw e
118         } catch (Exception ex) {
119             msg = "Exception in preProcessRequest " + ex.getMessage()
120             logger.debug(msg)
121             exceptionUtil.buildAndThrowWorkflowException(execution, 7000, msg)
122         }
123         logger.debug("Finish preProcessRequest")
124     }
125
126
127     void deleteServiceInstance(DelegateExecution execution) {
128         try {
129             AAIResourcesClient client = getAAIClient()
130             AAIResourceUri uri = AAIUriFactory.createResourceUri(AAIFluentTypeBuilder.business().customer(execution.getVariable("globalSubscriberId")).serviceSubscription(execution.getVariable("subscriptionServiceType")).serviceInstance(execution.getVariable("serviceInstanceID")))
131             client.delete(uri)
132         } catch (BpmnError e) {
133             throw e
134         } catch (Exception ex) {
135             String msg = "Exception in DoDeallocateTnNssi.deleteServiceInstance. " + ex.getMessage()
136             logger.info(msg)
137             exceptionUtil.buildAndThrowWorkflowException(execution, 7000, msg)
138         }
139     }
140
141
142     void getExistingServiceInstance(DelegateExecution execution) {
143         String serviceInstanceId = execution.getVariable("cllId")
144
145         AAIResourcesClient resourceClient = getAAIClient()
146         AAIResourceUri ssServiceuri = AAIUriFactory.createResourceUri(Types.SERVICE_INSTANCE.getFragment(serviceInstanceId))
147
148         try {
149             Optional<ServiceInstance> ssOpt = resourceClient.get(ServiceInstance.class, ssServiceuri)
150             if (ssOpt.isPresent()) {
151                 ServiceInstance ss = ssOpt.get()
152                 AllottedResources ars = serviceIntentUtils.getAllottedResourcesFromAai(execution, serviceInstanceId, true)
153                 if (ars != null) {
154                     List<AllottedResource> arList = ars.getAllottedResource()
155                     List<String> arIdList = new ArrayList<>()
156                     Map<String, String> policyMap = new HashMap<>()
157                     Map<String, List<String>> logicalLinksMap = new HashMap<>()
158                     for (AllottedResource ar : arList) {
159                         String arId = ar.getId()
160                         arIdList.add(arId)
161                         String policyId = serviceIntentUtils.getPolicyIdFromAr(execution, serviceInstanceId, arId, true)
162                         policyMap.put(arId, policyId)
163                         List<String> logicalLinkList = serviceIntentUtils.getLogicalLinkNamesFromAr(execution,
164                                 serviceInstanceId, arId, true)
165                         logicalLinksMap.put(arId, logicalLinkList)
166                     }
167                     execution.setVariable("arIdList", arIdList)
168                     execution.setVariable("arPolicyMap", policyMap)
169                     execution.setVariable("arLogicalLinkMap", logicalLinksMap)
170                 } else {
171                     logger.error("ERROR: getExistingServiceInstance: getAllottedResources() returned null. ss=" + ss
172                             .toString())
173                 }
174             } else {
175                 exceptionUtil.buildAndThrowWorkflowException(execution, 2500, "Service instance was not found in aai to " +
176                         "associate allotted resource for service :" + serviceInstanceId)
177             }
178         } catch (BpmnError e) {
179             throw e;
180         } catch (Exception ex) {
181             String msg = "Exception in getExistingServiceInstance. " + ex.getMessage()
182             logger.debug(msg)
183             exceptionUtil.buildAndThrowWorkflowException(execution, 7000, msg)
184         }
185     }
186
187     void updateServiceInstanceInAAI(DelegateExecution execution) {
188         getExistingServiceInstance(execution)
189         updateTsciNetworks(execution)
190     }
191
192     void updateServiceInstance(DelegateExecution execution) {
193         String cllId = execution.getVariable("cllId")
194         try {
195             ServiceInstance ss = new ServiceInstance()
196             //ss.setServiceInstanceId(cllId)
197             String serviceStatus = "modified"
198             ss.setOrchestrationStatus(serviceStatus)
199             ss.setEnvironmentContext("tn")
200             AAIResourcesClient client = getAAIClient()
201             AAIResourceUri uri = AAIUriFactory.createResourceUri(
202                     AAIFluentTypeBuilder.business()
203                             .customer(execution.getVariable("globalSubscriberId"))
204                             .serviceSubscription(execution.getVariable("subscriptionServiceType"))
205                             .serviceInstance(cllId))
206             client.update(uri, ss)
207         } catch (BpmnError e) {
208             throw e
209         } catch (Exception ex) {
210             String msg = "Exception in DoModifyCllInstance.updateServiceInstance. " + ex.getMessage()
211             logger.info(msg)
212             exceptionUtil.buildAndThrowWorkflowException(execution, 7000, msg)
213         }
214     }
215
216
217     String getValidArId(DelegateExecution execution, String arIdStr) {
218         List<String> arIdList = execution.getVariable("arIdList")
219         /*
220          * If arId is not specified by the caller, then we assume the caller
221          * wants to modify the first network (i.e., allotted resource) in the TSCi tree.
222          */
223         String arId = isBlank(arIdStr) ? arIdList.get(0) : arIdStr
224
225         return arId
226     }
227
228     void updateLogicalLinksInAr(DelegateExecution execution, String arId, String linkArrayJsonStr) {
229         try {
230             String serviceInstanceId = execution.getVariable('cllId')
231
232             /*
233              * Each TSCi connection-link in linkArrayJsonStr is considered as an "ADD" new
234              * link to allotted-resource. So, if the link already exists under AR, then do
235              * nothing. Otherwise, create logical-link.
236              */
237             List<String> linkStrList = jsonUtil.StringArrayToList(linkArrayJsonStr)
238             for (String linkStr : linkStrList) {
239                 if (logicalLinkExists(execution, arId, linkStr)) {
240                     continue
241                 }
242
243                 createLogicalLinkForAllocatedResource(execution, linkStr, serviceInstanceId, arId)
244             }
245         } catch (BpmnError e) {
246             throw e
247         } catch (Exception ex) {
248             exceptionUtil.buildAndThrowWorkflowException(execution, 7000,
249                     "Exception in updateLogicalLinksInAr" + ex.getMessage())
250         }
251     }
252
253     void updateLogicalLinksInNetwork(DelegateExecution execution, String networkJsonStr) {
254         try {
255             String arId = getValidArId(execution, jsonUtil.getJsonValue(networkJsonStr, "id"))
256             String linkArrayStr = jsonUtil.getJsonValue(networkJsonStr, "connectionLinks")
257             updateLogicalLinksInAr(execution, arId, linkArrayStr)
258         } catch (BpmnError e) {
259             throw e
260         } catch (Exception ex) {
261             String msg = String.format("ERROR: updateLogicalLinksInNetwork: exception: %s", ex.getMessage())
262             logger.error(msg)
263             exceptionUtil.buildAndThrowWorkflowException(execution, 7000, msg);
264         }
265     }
266
267     void updateTsciNetworks(DelegateExecution execution) {
268         try {
269             List<String> networkStrList = jsonUtil.StringArrayToList(execution.getVariable("transportNetworks"))
270             for (String networkStr : networkStrList) {
271                 updateLogicalLinksInNetwork(execution, networkStr)
272                 updateNetworkPolicy(execution, networkStr)
273             }
274
275         } catch (BpmnError e) {
276             throw e
277         } catch (Exception ex) {
278             exceptionUtil.buildAndThrowWorkflowException(execution, 7000,
279                     "Exception in updateTsciNetworks" + ex.getMessage())
280         }
281     }
282
283     int getMaxBwFromNetworkJsonStr(DelegateExecution execution, String networkJsonStr) {
284         int maxBw = 0
285         try {
286             if (isBlank(networkJsonStr)) {
287                 String msg = "ERROR: getMaxBw: networkJsonStr is null"
288                 logger.error(msg)
289                 exceptionUtil.buildAndThrowWorkflowException(execution, 7000, msg)
290             }
291             String slaStr = jsonUtil.getJsonValue(networkJsonStr, "sla")
292             if (isBlank(slaStr)) {
293                 String msg = "ERROR: getMaxBw: slaStr is null"
294                 logger.error(msg)
295                 exceptionUtil.buildAndThrowWorkflowException(execution, 7000, msg)
296             }
297
298             String bwStr = jsonUtil.getJsonValue(slaStr, "maxBandwidth")
299             if (isNotBlank(bwStr)) {
300                 maxBw = Integer.parseInt(bwStr)
301             } else {
302                 logger.error("ERROR: getMaxBw: maxBandwidth is null")
303             }
304         } catch (BpmnError e) {
305             throw e
306         } catch (Exception ex) {
307             exceptionUtil.buildAndThrowWorkflowException(execution, 7000,
308                     "Exception in getMaxBw" + ex.getMessage())
309         }
310
311         return maxBw
312     }
313
314     void updatePolicyMaxBandwidthInAAI(DelegateExecution execution, String policyId, int maxBw) {
315         try {
316             NetworkPolicy networkPolicy = new NetworkPolicy()
317             networkPolicy.setMaxBandwidth(maxBw)
318             AAIResourceUri networkPolicyUri =
319                     AAIUriFactory.createResourceUri(AAIFluentTypeBuilder.network().networkPolicy(policyId))
320             getAAIClient().update(networkPolicyUri, networkPolicy)
321         } catch (BpmnError e) {
322             throw e
323         } catch (Exception ex) {
324             String msg = "Exception in DoModifyCllInstance.updatePolicyMaxBandwidthInAAI. " + ex.getMessage()
325             logger.info(msg)
326             exceptionUtil.buildAndThrowWorkflowException(execution, 7000, msg)
327         }
328     }
329
330     void updateNetworkPolicy(DelegateExecution execution, String networkJsonStr) {
331         try {
332             int maxBw = getMaxBwFromNetworkJsonStr(execution, networkJsonStr)
333
334             String arId = getValidArId(execution, jsonUtil.getJsonValue(networkJsonStr, "id"))
335             Map<String, String> policyMap = execution.getVariable("arPolicyMap")
336             String policyId = policyMap.get(arId)
337             if (isBlank(policyId)) {
338                 String msg = String.format("ERROR: updateNetworkPolicy: policyId not found. arId=%s", arId)
339                 logger.error(msg)
340                 exceptionUtil.buildAndThrowWorkflowException(execution, 7000, msg)
341             }
342
343             updatePolicyMaxBandwidthInAAI(execution, policyId, maxBw)
344
345         } catch (BpmnError e) {
346             throw e
347         } catch (Exception ex) {
348             String msg = String.format("ERROR: updateNetworkPolicy: exception: %s", ex.getMessage())
349             logger.error(msg)
350             exceptionUtil.buildAndThrowWorkflowException(execution, 7000, msg);
351         }
352     }
353
354
355     void createLogicalLinkForAllocatedResource(DelegateExecution execution,
356                                                String linkJsonStr, String cllId,
357                                                String allottedResourceId) {
358         try {
359             AAIResourceUri allottedResourceUri = serviceIntentUtils.buildAllottedResourceUri(execution,
360                     cllId, allottedResourceId)
361
362             if (!getAAIClient().exists(allottedResourceUri)) {
363                 logger.info("ERROR: createLogicalLinksForAllocatedResource: allottedResource not exist: uri={}",
364                         allottedResourceUri)
365                 return
366             }
367
368             String linkId = jsonUtil.getJsonValue(linkJsonStr, "id")
369             if (isBlank(linkId)) {
370                 linkId = "cll-" + UUID.randomUUID().toString()
371             }
372             logger.debug("createLogicalLinkForAllocatedResource: linkId=" + linkId)
373
374             String epA = jsonUtil.getJsonValue(linkJsonStr, "transportEndpointA")
375             String epB = jsonUtil.getJsonValue(linkJsonStr, "transportEndpointB")
376             String modelInvariantId = execution.getVariable("modelInvariantUuid")
377             String modelVersionId = execution.getVariable("modelUuid")
378
379             org.onap.aai.domain.yang.LogicalLink resource = new org.onap.aai.domain.yang.LogicalLink()
380             resource.setLinkId(linkId)
381             resource.setLinkName(epA)
382             resource.setLinkName2(epB)
383             resource.setLinkType("TsciConnectionLink")
384             resource.setInMaint(false)
385
386             //epA is link-name
387             AAIResourceUri logicalLinkUri =
388                     AAIUriFactory.createResourceUri(AAIFluentTypeBuilder.network().logicalLink(epA))
389             getAAIClient().create(logicalLinkUri, resource)
390
391             serviceIntentUtils.attachLogicalLinkToAllottedResource(execution, serviceIntentUtils.AAI_VERSION,
392                     allottedResourceUri, epA);
393         } catch (BpmnError e) {
394             throw e
395         } catch (Exception ex) {
396             String msg = "Exception in DoModifyCllInstance.createLogicalLinksForAllocatedResource: " + ex.getMessage()
397             logger.error(msg)
398             exceptionUtil.buildAndThrowWorkflowException(execution, 7000, msg)
399         }
400     }
401
402
403     void preprocessSdncModifyCllRequest(DelegateExecution execution) {
404         def method = getClass().getSimpleName() + '.preprocessSdncModifyCllRequest(' +
405                 'execution=' + execution.getId() + ')'
406         def isDebugLogEnabled = execution.getVariable('isDebugLogEnabled')
407         logger.trace('Entered ' + method)
408
409         try {
410             String serviceInstanceId = execution.getVariable("cllId")
411
412             String sdncRequest = serviceIntentUtils.buildSDNCRequest(execution, serviceInstanceId, "update")
413
414             execution.setVariable("CLL_SDNCRequest", sdncRequest)
415             logger.debug("Outgoing SDNCRequest is: \n" + sdncRequest)
416
417         } catch (BpmnError e) {
418             throw e
419         } catch (Exception e) {
420             logger.debug("Exception Occurred Processing preprocessSdncModifyCllRequest. Exception is:\n" + e)
421             exceptionUtil.buildAndThrowWorkflowException(execution, 1002, "Error Occurred during  preProcessSDNCActivateRequest Method:\n" + e.getMessage())
422         }
423         logger.trace("COMPLETED preprocessSdncModifyCllRequest Process")
424     }
425
426
427     void validateSDNCResponse(DelegateExecution execution, String response, String method) {
428         serviceIntentUtils.validateSDNCResponse(execution, response, method)
429     }
430
431
432     void updateAAIOrchStatus(DelegateExecution execution) {
433         logger.debug("Start updateAAIOrchStatus")
434         String cllId = execution.getVariable("cllId")
435         String orchStatus = execution.getVariable("orchestrationStatus")
436
437         try {
438             ServiceInstance si = new ServiceInstance()
439             si.setOrchestrationStatus(orchStatus)
440             AAIResourcesClient client = getAAIClient()
441             AAIResourceUri uri = AAIUriFactory.createResourceUri(Types.SERVICE_INSTANCE.getFragment(cllId))
442             client.update(uri, si)
443         } catch (BpmnError e) {
444             throw e
445         } catch (Exception ex) {
446             String msg = "Exception in CreateSliceService.updateAAIOrchStatus " + ex.getMessage()
447             logger.info(msg)
448             exceptionUtil.buildAndThrowWorkflowException(execution, 7000, msg)
449         }
450
451         logger.debug("Finish updateAAIOrchStatus")
452     }
453
454     void prepareUpdateJobStatus(DelegateExecution execution,
455                                 String status,
456                                 String progress,
457                                 String statusDescription) {
458         String cllId = execution.getVariable("cllId")
459         String modelUuid = execution.getVariable("modelUuid")
460         String jobId = execution.getVariable("jobId")
461         String nsiId = cllId
462         String operType = "MODIFY"
463
464         ResourceOperationStatus roStatus = serviceIntentUtils.buildRoStatus(modelUuid, cllId,
465                 jobId, nsiId, operType, status, progress, statusDescription)
466
467         logger.debug("prepareUpdateJobStatus: roStatus={}", roStatus)
468         requestDBUtil.prepareUpdateResourceOperationStatus(execution, roStatus)
469     }
470
471     boolean logicalLinkExists(DelegateExecution execution, String arIdStr, String linkJsonStr) {
472         if (isBlank(arIdStr)) {
473             logger.error("ERROR: logicalLinkExists: arIdStr is empty")
474             return false
475         }
476         if (isBlank(linkJsonStr)) {
477             logger.error("ERROR: logicalLinkExists: linkJsonStr is empty")
478             return false
479         }
480
481         Map<String, List<String>> logicalLinksMap = execution.getVariable("arLogicalLinkMap")
482         if (logicalLinksMap == null) {
483             logger.error("ERROR: logicalLinkExists: logicalLinksMap is null")
484             return false
485         }
486
487         List<String> logicalLinkNameList = logicalLinksMap.get(arIdStr)
488         if (logicalLinksMap == null) {
489             logger.error("ERROR: logicalLinkExists: logicalLinkNameList is null. arIdStr=" + arIdStr)
490             return false
491         }
492
493         String linkName = jsonUtil.getJsonValue(linkJsonStr, "transportEndpointA")
494         if (isBlank(linkName)) {
495             logger.error("ERROR: logicalLinkExists: epA is empty")
496             return false
497         }
498
499         return logicalLinkNameList.contains(linkName)
500     }
501 }
502