Transport Slicing Fixes
[so.git] / bpmn / so-bpmn-infrastructure-common / src / main / groovy / org / onap / so / bpmn / infrastructure / scripts / TnNssmfUtils.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.Relationship
26 import org.onap.aai.domain.yang.ServiceInstance
27 import org.onap.aaiclient.client.aai.AAIResourcesClient
28 import org.onap.aaiclient.client.aai.entities.uri.AAIResourceUri
29 import org.onap.aaiclient.client.aai.entities.uri.AAIUriFactory
30 import org.onap.aaiclient.client.generated.fluentbuilders.AAIFluentTypeBuilder
31 import org.onap.so.bpmn.common.scripts.ExceptionUtil
32 import org.onap.so.bpmn.common.scripts.MsoUtils
33 import org.onap.so.bpmn.common.scripts.SDNCAdapterUtils
34 import org.onap.so.bpmn.core.RollbackData
35 import org.onap.so.bpmn.core.UrnPropertiesReader
36 import org.onap.so.bpmn.core.WorkflowException
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
44 class TnNssmfUtils {
45     private static final Logger logger = LoggerFactory.getLogger(TnNssmfUtils.class);
46
47
48     ExceptionUtil exceptionUtil = new ExceptionUtil()
49     JsonUtils jsonUtil = new JsonUtils()
50     MsoUtils msoUtils = new MsoUtils()
51     SDNCAdapterUtils sdncAdapterUtils = new SDNCAdapterUtils()
52
53     TnNssmfUtils() {
54     }
55
56
57     void setSdncCallbackUrl(DelegateExecution execution, boolean exceptionOnErr) {
58         setSdncCallbackUrl(execution, "sdncCallbackUrl", exceptionOnErr)
59     }
60
61     void setSdncCallbackUrl(DelegateExecution execution, String variableName, boolean exceptionOnErr) {
62         String sdncCallbackUrl = UrnPropertiesReader.getVariable('mso.workflow.sdncadapter.callback', execution)
63
64         if (isBlank(sdncCallbackUrl) && exceptionOnErr) {
65             String msg = "mso.workflow.sdncadapter.callback is null"
66             logger.debug(msg)
67             exceptionUtil.buildAndThrowWorkflowException(execution, 500, msg)
68         } else {
69             execution.setVariable(variableName, sdncCallbackUrl)
70         }
71     }
72
73     String buildSDNCRequest(DelegateExecution execution, String svcInstId, String svcAction) {
74         String reqAction
75         switch (svcAction) {
76             case "create":
77                 reqAction = "AllocateTransportSliceInstance"
78                 break
79             case "delete":
80                 reqAction = "DeleteTransportSliceInstance"
81                 break
82             case "activate":
83                 reqAction = "ActivateTransportSliceInstance"
84                 break
85             case "deactivate":
86                 reqAction = "DeactivateTransportSliceInstance"
87                 break
88             default:
89                 reqAction = svcAction
90         }
91
92         buildSDNCRequest(execution, svcInstId, svcAction, reqAction)
93     }
94
95     String buildSDNCRequest(DelegateExecution execution, String svcInstId, String svcAction, String reqAction) {
96
97         String uuid = execution.getVariable('testReqId') // for junits
98         if (uuid == null) {
99             uuid = execution.getVariable("msoRequestId") + "-" + System.currentTimeMillis()
100         }
101
102         def callbackURL = execution.getVariable("sdncCallbackUrl")
103         def requestId = execution.getVariable("msoRequestId")
104         def serviceId = execution.getVariable("sliceServiceInstanceId")
105         def subServiceType = execution.getVariable("subscriptionServiceType")
106         def vnfType = execution.getVariable("serviceType")
107         def vnfName = execution.getVariable("sliceServiceInstanceName")
108         def tenantId = execution.getVariable("sliceServiceInstanceId")
109         def source = execution.getVariable("sliceServiceInstanceId")
110         def vnfId = execution.getVariable("sliceServiceInstanceId")
111         def cloudSiteId = execution.getVariable("sliceServiceInstanceId")
112         def serviceModelInfo = execution.getVariable("serviceModelInfo")
113         def vnfModelInfo = execution.getVariable("serviceModelInfo")
114         def globalSubscriberId = execution.getVariable("globalSubscriberId")
115
116         String vnfNameString = """<vnf-name>${MsoUtils.xmlEscape(vnfName)}</vnf-name>"""
117         String serviceEcompModelInformation = sdncAdapterUtils.modelInfoToEcompModelInformation(serviceModelInfo)
118         String vnfEcompModelInformation = sdncAdapterUtils.modelInfoToEcompModelInformation(vnfModelInfo)
119
120         String sdncVNFParamsXml = ""
121
122         if (execution.getVariable("vnfParamsExistFlag") == true) {
123             sdncVNFParamsXml = buildSDNCParamsXml(execution)
124         } else {
125             sdncVNFParamsXml = buildDefaultVnfInputParams(vnfId)
126         }
127
128         String sdncRequest =
129                 """<sdncadapterworkflow:SDNCAdapterWorkflowRequest xmlns:ns5="http://org.onap/so/request/types/v1"
130                                                     xmlns:sdncadapterworkflow="http://org.onap/so/workflow/schema/v1"
131                                                     xmlns:sdncadapter="http://org.onap/workflow/sdnc/adapter/schema/v1">
132          <sdncadapter:RequestHeader>
133             <sdncadapter:RequestId>${MsoUtils.xmlEscape(uuid)}</sdncadapter:RequestId>
134             <sdncadapter:SvcInstanceId>${MsoUtils.xmlEscape(svcInstId)}</sdncadapter:SvcInstanceId>
135             <sdncadapter:SvcAction>${MsoUtils.xmlEscape(svcAction)}</sdncadapter:SvcAction>
136             <sdncadapter:SvcOperation>vnf-topology-operation</sdncadapter:SvcOperation>
137             <sdncadapter:CallbackUrl>${MsoUtils.xmlEscape(callbackURL)}</sdncadapter:CallbackUrl>
138             <sdncadapter:MsoAction>generic-resource</sdncadapter:MsoAction>
139          </sdncadapter:RequestHeader>
140     <sdncadapterworkflow:SDNCRequestData>
141         <request-information>
142             <request-id>${MsoUtils.xmlEscape(requestId)}</request-id>
143             <request-action>${MsoUtils.xmlEscape(reqAction)}</request-action>
144             <source>${MsoUtils.xmlEscape(source)}</source>
145             <notification-url/>
146             <order-number/>
147             <order-version/>
148         </request-information>
149         <service-information>
150             <service-id>${MsoUtils.xmlEscape(serviceId)}</service-id>
151             <subscription-service-type>${MsoUtils.xmlEscape(subServiceType)}</subscription-service-type>
152             ${serviceEcompModelInformation}
153             <service-instance-id>${MsoUtils.xmlEscape(svcInstId)}</service-instance-id>
154             <global-customer-id>${MsoUtils.xmlEscape(globalSubscriberId)}</global-customer-id>
155         </service-information>
156         <vnf-information>
157             <vnf-id>${MsoUtils.xmlEscape(vnfId)}</vnf-id>
158             <vnf-type>${MsoUtils.xmlEscape(vnfType)}</vnf-type>
159             ${vnfEcompModelInformation}
160         </vnf-information>
161         <vnf-request-input>
162             ${vnfNameString}
163             <tenant>${MsoUtils.xmlEscape(tenantId)}</tenant>
164             <aic-cloud-region>${MsoUtils.xmlEscape(cloudSiteId)}</aic-cloud-region>
165             ${sdncVNFParamsXml}
166         </vnf-request-input>
167     </sdncadapterworkflow:SDNCRequestData>
168     </sdncadapterworkflow:SDNCAdapterWorkflowRequest>"""
169
170         logger.debug("sdncRequest:  " + sdncRequest)
171         return sdncRequest
172     }
173
174
175     String buildDefaultVnfInputParams(String vnfName) {
176         String res =
177                 """<vnf-input-parameters>
178                       <param>
179                           <name>${MsoUtils.xmlEscape(vnfName)}</name>
180                       </param>
181                    </vnf-input-parameters>"""
182
183         return res
184     }
185
186     String buildSDNCParamsXml(DelegateExecution execution) {
187         String params = ""
188         StringBuilder sb = new StringBuilder()
189         Map<String, String> paramsMap = execution.getVariable("TNNSSMF_vnfParamsMap")
190
191         for (Map.Entry<String, String> entry : paramsMap.entrySet()) {
192             String paramsXml
193             String key = entry.getKey();
194             String value = entry.getValue()
195             paramsXml = """<${key}>$value</$key>"""
196             params = sb.append(paramsXml)
197         }
198         return params
199     }
200
201     void validateSDNCResponse(DelegateExecution execution, String response, String method) {
202         validateSDNCResponse(execution, response, method, true)
203     }
204
205     void validateSDNCResponse(DelegateExecution execution, String response, String method, boolean exceptionOnErr) {
206         logger.debug("STARTED ValidateSDNCResponse Process")
207
208         String msg
209
210         String prefix = execution.getVariable("prefix")
211         if (isBlank(prefix)) {
212             if (exceptionOnErr) {
213                 msg = "validateSDNCResponse: prefix is null"
214                 logger.error(msg)
215                 exceptionUtil.buildAndThrowWorkflowException(execution, 500, msg)
216             }
217             return
218         }
219
220         WorkflowException workflowException = execution.getVariable("WorkflowException")
221         boolean successIndicator = execution.getVariable("SDNCA_SuccessIndicator")
222
223         logger.debug("TnNssmfUtils.validateSDNCResponse: SDNCResponse: " + response)
224         logger.debug("TnNssmfUtils.validateSDNCResponse: workflowException: " + workflowException)
225
226         sdncAdapterUtils.validateSDNCResponse(execution, response, workflowException, successIndicator)
227
228         String sdncResponse = response
229         if (execution.getVariable(prefix + 'sdncResponseSuccess') == true) {
230             logger.debug("Received a Good Response from SDNC Adapter for " + method + " SDNC Call.  Response is: \n" + sdncResponse)
231             RollbackData rollbackData = execution.getVariable("rollbackData")
232             if (rollbackData == null) {
233                 rollbackData = new RollbackData()
234             }
235
236             if (method.equals("allocate")) {
237                 rollbackData.put("VNFMODULE", "rollbackSDNCRequestAllocate", "true")
238             } else if (method.equals("deallocate")) {
239                 rollbackData.put("VNFMODULE", "rollbackSDNCRequestDeallocate", "true")
240             } else if (method.equals("activate")) {
241                 rollbackData.put("VNFMODULE", "rollbackSDNCRequestActivate", "true")
242             } else if (method.equals("deactivate")) {
243                 rollbackData.put("VNFMODULE", "rollbackSDNCRequestDeactivate", "true")
244             } else if (method.equals("modify")) {
245                 rollbackData.put("VNFMODULE", "rollbackSDNCRequestModify", "true")
246             }
247             execution.setVariable("rollbackData", rollbackData)
248         } else {
249             if (exceptionOnErr) {
250                 msg = "TnNssmfUtils.validateSDNCResponse: bad Response from SDNC Adapter for " + method + " SDNC Call."
251                 logger.error(msg)
252                 exceptionUtil.buildAndThrowWorkflowException(execution, 500, msg)
253             }
254         }
255
256         logger.debug("COMPLETED ValidateSDNCResponse Process")
257     }
258
259     String getExecutionInputParams(DelegateExecution execution) {
260         String res = "\n msoRequestId=" + execution.getVariable("msoRequestId") +
261                 "\n modelInvariantUuid=" + execution.getVariable("modelInvariantUuid") +
262                 "\n modelUuid=" + execution.getVariable("modelUuid") +
263                 "\n serviceInstanceID=" + execution.getVariable("serviceInstanceID") +
264                 "\n operationType=" + execution.getVariable("operationType") +
265                 "\n globalSubscriberId=" + execution.getVariable("globalSubscriberId") +
266                 "\n dummyServiceId=" + execution.getVariable("dummyServiceId") +
267                 "\n nsiId=" + execution.getVariable("nsiId") +
268                 "\n networkType=" + execution.getVariable("networkType") +
269                 "\n subscriptionServiceType=" + execution.getVariable("subscriptionServiceType") +
270                 "\n jobId=" + execution.getVariable("jobId") +
271                 "\n sliceParams=" + execution.getVariable("sliceParams") +
272                 "\n servicename=" + execution.getVariable("servicename")
273
274         return res
275     }
276
277     String getFirstSnssaiFromSliceProfile(String sliceProfileStr) {
278         String snssaiListStr = jsonUtil.getJsonValue(sliceProfileStr, "snssaiList")
279         String snssai = jsonUtil.StringArrayToList(snssaiListStr).get(0)
280
281         return snssai
282     }
283
284     String getFirstPlmnIdFromSliceProfile(String sliceProfileStr) {
285         String plmnListStr = jsonUtil.getJsonValue(sliceProfileStr, "plmnIdList")
286         String res = jsonUtil.StringArrayToList(plmnListStr).get(0)
287
288         return res
289     }
290
291     void createRelationShipInAAI(DelegateExecution execution, AAIResourceUri uri, Relationship relationship) {
292         logger.debug("createRelationShipInAAI Start")
293         String msg
294         AAIResourcesClient client = new AAIResourcesClient()
295         try {
296             if (!client.exists(uri)) {
297                 logger.info("ERROR: createRelationShipInAAI: not exist: uri={}", uri)
298                 return
299             }
300             AAIResourceUri from = ((AAIResourceUri) (uri.clone())).relationshipAPI()
301             client.create(from, relationship)
302
303         } catch (BpmnError e) {
304             throw e
305         } catch (Exception ex) {
306             msg = "Exception in createRelationShipInAAI. " + ex.getMessage()
307             logger.info(msg)
308             exceptionUtil.buildAndThrowWorkflowException(execution, 7000, msg)
309         }
310         logger.debug("createRelationShipInAAI Exit")
311     }
312
313     void attachLogicalLinkToAllottedResource(DelegateExecution execution, String aaiVersion, AAIResourceUri arUri,
314                                              String logicalLinkId) {
315
316         String toLink = "aai/${aaiVersion}/network/logical-links/logical-link/${logicalLinkId}"
317
318         Relationship relationship = new Relationship()
319         relationship.setRelatedLink(toLink)
320         relationship.setRelatedTo("logical-link")
321         relationship.setRelationshipLabel("org.onap.relationships.inventory.ComposedOf")
322
323         createRelationShipInAAI(execution, arUri, relationship)
324     }
325
326     void attachNetworkPolicyToAllottedResource(DelegateExecution execution, String aaiVersion,
327                                                AAIResourceUri aaiResourceUri, String networkPolicyId) {
328
329         String toLink = "aai/${aaiVersion}/network/network-policies/network-policy/${networkPolicyId}"
330
331         Relationship relationship = new Relationship()
332         relationship.setRelatedLink(toLink)
333         relationship.setRelatedTo("network-policy")
334         relationship.setRelationshipLabel("org.onap.relationships.inventory.Uses")
335
336         createRelationShipInAAI(execution, aaiResourceUri, relationship)
337
338     }
339
340     ResourceOperationStatus buildRoStatus(String nsstId,
341                                           String nssiId,
342                                           String jobId,
343                                           String nsiId,
344                                           String action,
345                                           String status,
346                                           String progress,
347                                           String statusDescription) {
348         ResourceOperationStatus roStatus = new ResourceOperationStatus()
349         roStatus.setResourceTemplateUUID(nsstId)
350         roStatus.setResourceInstanceID(nssiId)
351         roStatus.setServiceId(nsiId)
352         roStatus.setOperationId(jobId)
353         roStatus.setOperType(action)
354         roStatus.setProgress(progress)
355         roStatus.setStatus(status)
356         roStatus.setStatusDescription(statusDescription)
357
358         return roStatus
359     }
360
361
362     void setEnableSdncConfig(DelegateExecution execution) {
363         String enableSdnc = UrnPropertiesReader.getVariable(
364                 "mso.workflow.TnNssmf.enableSDNCNetworkConfig")
365         if (isBlank(enableSdnc)) {
366             logger.debug("mso.workflow.TnNssmf.enableSDNCNetworkConfig is undefined, so use default value (true)")
367             enableSdnc = "true"
368         }
369
370         logger.debug("setEnableSdncConfig: enableSdnc=" + enableSdnc)
371
372         execution.setVariable("enableSdnc", enableSdnc)
373     }
374
375     String setExecVarFromJsonIfExists(DelegateExecution execution,
376                                       String jsonStr, String jsonKey, String varName) {
377         return setExecVarFromJsonStr(execution, jsonStr, jsonKey, varName, false)
378     }
379
380     String setExecVarFromJsonStr(DelegateExecution execution,
381                                  String jsonStr, String jsonKey, String varName,
382                                  boolean exceptionOnErr) {
383         String msg = ""
384         String valueStr = jsonUtil.getJsonValue(jsonStr, jsonKey)
385         if (isBlank(valueStr)) {
386             if (exceptionOnErr) {
387                 msg = "cannot find " + jsonKey + " in " + jsonStr
388                 logger.debug(msg)
389                 exceptionUtil.buildAndThrowWorkflowException(execution, 500, msg)
390             }
391         } else {
392             execution.setVariable(varName, valueStr)
393         }
394
395         return valueStr
396     }
397
398     ServiceInstance getServiceInstanceFromAai(String serviceInstanceId) {
399         if (isBlank(serviceInstanceId)) {
400             logger.error("ERROR: getServiceInstanceFromAai: serviceInstanceId is blank")
401             return null
402         }
403
404         ServiceInstance nssi = null
405         AAIResourcesClient client = new AAIResourcesClient()
406         AAIResourceUri uri = AAIUriFactory.createResourceUri(AAIFluentTypeBuilder.Types.SERVICE_INSTANCE
407                 .getFragment(serviceInstanceId))
408         Optional<ServiceInstance> nssiOpt = client.get(ServiceInstance.class, uri)
409
410         if (nssiOpt.isPresent()) {
411             nssi = nssiOpt.get()
412             return nssi
413         } else {
414             String msg = String.format("ERROR: getServiceInstanceFromAai: NSSI %s not found in AAI", serviceInstanceId)
415             logger.error(msg)
416         }
417
418         return nssi;
419     }
420
421     String getModelUuidFromServiceInstance(String serviceInstanceId) {
422         ServiceInstance si = getServiceInstanceFromAai(serviceInstanceId)
423         if (si == null) {
424             String msg = String.format("ERROR: getModelUuidFromServiceInstance: getServiceInstanceFromAai() failed. " +
425                     "serviceInstanceId=%s", serviceInstanceId)
426             logger.error(msg)
427             return null
428         }
429
430         return si.modelVersionId()
431     }
432 }