4624cdafe9cfd85fef4a3a61ea3a701c3a7739e1
[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.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
46
47 import static org.apache.commons.lang3.StringUtils.isBlank
48
49 class TnNssmfUtils {
50     static final String AAI_VERSION = "v23"
51     private static final Logger logger = LoggerFactory.getLogger(TnNssmfUtils.class);
52
53
54     ExceptionUtil exceptionUtil = new ExceptionUtil()
55     JsonUtils jsonUtil = new JsonUtils()
56     MsoUtils msoUtils = new MsoUtils()
57     SDNCAdapterUtils sdncAdapterUtils = new SDNCAdapterUtils()
58
59     TnNssmfUtils() {
60     }
61
62
63     void setSdncCallbackUrl(DelegateExecution execution, boolean exceptionOnErr) {
64         setSdncCallbackUrl(execution, "sdncCallbackUrl", exceptionOnErr)
65     }
66
67     void setSdncCallbackUrl(DelegateExecution execution, String variableName, boolean exceptionOnErr) {
68         String sdncCallbackUrl = UrnPropertiesReader.getVariable('mso.workflow.sdncadapter.callback', execution)
69
70         if (isBlank(sdncCallbackUrl) && exceptionOnErr) {
71             String msg = "mso.workflow.sdncadapter.callback is null"
72             logger.debug(msg)
73             exceptionUtil.buildAndThrowWorkflowException(execution, 500, msg)
74         } else {
75             execution.setVariable(variableName, sdncCallbackUrl)
76         }
77     }
78
79     String buildSDNCRequest(DelegateExecution execution, String svcInstId, String svcAction) {
80         String reqAction
81         switch (svcAction) {
82             case "create":
83                 reqAction = "AllocateTransportSliceInstance"
84                 break
85             case "delete":
86                 reqAction = "DeleteTransportSliceInstance"
87                 break
88             case "activate":
89                 reqAction = "ActivateTransportSliceInstance"
90                 break
91             case "deactivate":
92                 reqAction = "DeactivateTransportSliceInstance"
93                 break
94             default:
95                 reqAction = svcAction
96         }
97
98         buildSDNCRequest(execution, svcInstId, svcAction, reqAction)
99     }
100
101     String buildSDNCRequest(DelegateExecution execution, String svcInstId, String svcAction, String reqAction) {
102
103         String uuid = execution.getVariable('testReqId') // for junits
104         if (uuid == null) {
105             uuid = execution.getVariable("msoRequestId") + "-" + System.currentTimeMillis()
106         }
107
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")
121
122         String vnfNameString = """<vnf-name>${MsoUtils.xmlEscape(vnfName)}</vnf-name>"""
123         String serviceEcompModelInformation = sdncAdapterUtils.modelInfoToEcompModelInformation(serviceModelInfo)
124         String vnfEcompModelInformation = sdncAdapterUtils.modelInfoToEcompModelInformation(vnfModelInfo)
125
126         String sdncVNFParamsXml = ""
127
128         if (execution.getVariable("vnfParamsExistFlag") == true) {
129             sdncVNFParamsXml = buildSDNCParamsXml(execution)
130         } else {
131             sdncVNFParamsXml = buildDefaultVnfInputParams(vnfId)
132         }
133
134         String sdncRequest =
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>
151             <notification-url/>
152             <order-number/>
153             <order-version/>
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>
162         <vnf-information>
163             <vnf-id>${MsoUtils.xmlEscape(vnfId)}</vnf-id>
164             <vnf-type>${MsoUtils.xmlEscape(vnfType)}</vnf-type>
165             ${vnfEcompModelInformation}
166         </vnf-information>
167         <vnf-request-input>
168             ${vnfNameString}
169             <tenant>${MsoUtils.xmlEscape(tenantId)}</tenant>
170             <aic-cloud-region>${MsoUtils.xmlEscape(cloudSiteId)}</aic-cloud-region>
171             ${sdncVNFParamsXml}
172         </vnf-request-input>
173     </sdncadapterworkflow:SDNCRequestData>
174     </sdncadapterworkflow:SDNCAdapterWorkflowRequest>"""
175
176         logger.debug("sdncRequest:  " + sdncRequest)
177         return sdncRequest
178     }
179
180
181     String buildDefaultVnfInputParams(String vnfName) {
182         String res =
183                 """<vnf-input-parameters>
184                       <param>
185                           <name>${MsoUtils.xmlEscape(vnfName)}</name>
186                       </param>
187                    </vnf-input-parameters>"""
188
189         return res
190     }
191
192     String buildSDNCParamsXml(DelegateExecution execution) {
193         String params = ""
194         StringBuilder sb = new StringBuilder()
195         Map<String, String> paramsMap = execution.getVariable("TNNSSMF_vnfParamsMap")
196
197         for (Map.Entry<String, String> entry : paramsMap.entrySet()) {
198             String paramsXml
199             String key = entry.getKey();
200             String value = entry.getValue()
201             paramsXml = """<${key}>$value</$key>"""
202             params = sb.append(paramsXml)
203         }
204         return params
205     }
206
207     void validateSDNCResponse(DelegateExecution execution, String response, String method) {
208         validateSDNCResponse(execution, response, method, true)
209     }
210
211     void validateSDNCResponse(DelegateExecution execution, String response, String method, boolean exceptionOnErr) {
212         logger.debug("STARTED ValidateSDNCResponse Process")
213
214         String msg
215
216         String prefix = execution.getVariable("prefix")
217         if (isBlank(prefix)) {
218             if (exceptionOnErr) {
219                 msg = "validateSDNCResponse: prefix is null"
220                 logger.error(msg)
221                 exceptionUtil.buildAndThrowWorkflowException(execution, 500, msg)
222             }
223             return
224         }
225
226         WorkflowException workflowException = execution.getVariable("WorkflowException")
227         boolean successIndicator = execution.getVariable("SDNCA_SuccessIndicator")
228
229         logger.debug("TnNssmfUtils.validateSDNCResponse: SDNCResponse: " + response)
230         logger.debug("TnNssmfUtils.validateSDNCResponse: workflowException: " + workflowException)
231
232         sdncAdapterUtils.validateSDNCResponse(execution, response, workflowException, successIndicator)
233
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()
240             }
241
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")
252             }
253             execution.setVariable("rollbackData", rollbackData)
254         } else {
255             if (exceptionOnErr) {
256                 msg = "TnNssmfUtils.validateSDNCResponse: bad Response from SDNC Adapter for " + method + " SDNC Call."
257                 logger.error(msg)
258                 exceptionUtil.buildAndThrowWorkflowException(execution, 500, msg)
259             }
260         }
261
262         logger.debug("COMPLETED ValidateSDNCResponse Process")
263     }
264
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")
279
280         return res
281     }
282
283     String getFirstSnssaiFromSliceProfile(String sliceProfileStr) {
284         String snssaiListStr = jsonUtil.getJsonValue(sliceProfileStr, "snssaiList")
285         String snssai = jsonUtil.StringArrayToList(snssaiListStr).get(0)
286
287         return snssai
288     }
289
290     String getFirstPlmnIdFromSliceProfile(String sliceProfileStr) {
291         String plmnListStr = jsonUtil.getJsonValue(sliceProfileStr, "plmnIdList")
292         String res = jsonUtil.StringArrayToList(plmnListStr).get(0)
293
294         return res
295     }
296
297     void createRelationShipInAAI(DelegateExecution execution, AAIResourceUri uri, Relationship relationship) {
298         logger.debug("createRelationShipInAAI Start")
299         String msg
300         AAIResourcesClient client = new AAIResourcesClient()
301         try {
302             if (!client.exists(uri)) {
303                 logger.info("ERROR: createRelationShipInAAI: not exist: uri={}", uri)
304                 return
305             }
306             AAIResourceUri from = ((AAIResourceUri) (uri.clone())).relationshipAPI()
307             client.create(from, relationship)
308
309         } catch (BpmnError e) {
310             throw e
311         } catch (Exception ex) {
312             msg = "Exception in createRelationShipInAAI. " + ex.getMessage()
313             logger.info(msg)
314             exceptionUtil.buildAndThrowWorkflowException(execution, 7000, msg)
315         }
316         logger.debug("createRelationShipInAAI Exit")
317     }
318
319     void attachLogicalLinkToAllottedResource(DelegateExecution execution, String aaiVersion, AAIResourceUri arUri,
320                                              String logicalLinkId) {
321
322         String toLink = "aai/${aaiVersion}/network/logical-links/logical-link/${logicalLinkId}"
323
324         Relationship relationship = new Relationship()
325         relationship.setRelatedLink(toLink)
326         relationship.setRelatedTo("logical-link")
327         relationship.setRelationshipLabel("org.onap.relationships.inventory.ComposedOf")
328
329         createRelationShipInAAI(execution, arUri, relationship)
330     }
331
332     void attachNetworkPolicyToAllottedResource(DelegateExecution execution, String aaiVersion,
333                                                AAIResourceUri aaiResourceUri, String networkPolicyId) {
334
335         String toLink = "aai/${aaiVersion}/network/network-policies/network-policy/${networkPolicyId}"
336
337         Relationship relationship = new Relationship()
338         relationship.setRelatedLink(toLink)
339         relationship.setRelatedTo("network-policy")
340         relationship.setRelationshipLabel("org.onap.relationships.inventory.Uses")
341
342         createRelationShipInAAI(execution, aaiResourceUri, relationship)
343
344     }
345
346     ResourceOperationStatus buildRoStatus(String nsstId,
347                                           String nssiId,
348                                           String jobId,
349                                           String nsiId,
350                                           String action,
351                                           String status,
352                                           String progress,
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)
363
364         return roStatus
365     }
366
367
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)")
373             enableSdnc = "true"
374         }
375
376         logger.debug("setEnableSdncConfig: enableSdnc=" + enableSdnc)
377
378         execution.setVariable("enableSdnc", enableSdnc)
379     }
380
381     String setExecVarFromJsonIfExists(DelegateExecution execution,
382                                       String jsonStr, String jsonKey, String varName) {
383         return setExecVarFromJsonStr(execution, jsonStr, jsonKey, varName, false)
384     }
385
386     String setExecVarFromJsonStr(DelegateExecution execution,
387                                  String jsonStr, String jsonKey, String varName,
388                                  boolean exceptionOnErr) {
389         String msg = ""
390         String valueStr = jsonUtil.getJsonValue(jsonStr, jsonKey)
391         if (isBlank(valueStr)) {
392             if (exceptionOnErr) {
393                 msg = "cannot find " + jsonKey + " in " + jsonStr
394                 logger.debug(msg)
395                 exceptionUtil.buildAndThrowWorkflowException(execution, 500, msg)
396             }
397         } else {
398             execution.setVariable(varName, valueStr)
399         }
400
401         return valueStr
402     }
403
404     ServiceInstance getServiceInstanceFromAai(String serviceInstanceId) {
405         if (isBlank(serviceInstanceId)) {
406             logger.error("ERROR: getServiceInstanceFromAai: serviceInstanceId is blank")
407             return null
408         }
409
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)
415
416         if (nssiOpt.isPresent()) {
417             nssi = nssiOpt.get()
418             return nssi
419         } else {
420             String msg = String.format("ERROR: getServiceInstanceFromAai: NSSI %s not found in AAI", serviceInstanceId)
421             logger.error(msg)
422         }
423
424         return nssi;
425     }
426
427     String getModelUuidFromServiceInstance(String serviceInstanceId) {
428         ServiceInstance si = getServiceInstanceFromAai(serviceInstanceId)
429         if (si == null) {
430             String msg = String.format("ERROR: getModelUuidFromServiceInstance: getServiceInstanceFromAai() failed. " +
431                     "serviceInstanceId=%s", serviceInstanceId)
432             logger.error(msg)
433             return null
434         }
435
436         return si.modelVersionId()
437     }
438
439     AAIResourceUri buildNetworkPolicyUri(String networkPolicyId) {
440         AAIResourceUri networkPolicyUri =
441                 AAIUriFactory.createResourceUri(AAIFluentTypeBuilder.network().networkPolicy(networkPolicyId))
442
443         return networkPolicyUri
444     }
445
446     AAIResourceUri buildAllottedResourceUri(DelegateExecution execution, String serviceInstanceId,
447                                             String allottedResourceId) {
448
449         AAIResourceUri allottedResourceUri =
450                 AAIUriFactory.createResourceUri(AAIFluentTypeBuilder.business()
451                         .customer(execution.getVariable("globalSubscriberId"))
452                         .serviceSubscription(execution.getVariable("subscriptionServiceType"))
453                         .serviceInstance(serviceInstanceId)
454                         .allottedResource(allottedResourceId))
455
456         return allottedResourceUri
457     }
458
459
460     String getPolicyIdFromAr(DelegateExecution execution, String serviceInstanceId,
461                              String arId, boolean exceptionOnErr) {
462         String res
463         try {
464             AAIResourcesClient client = new AAIResourcesClient()
465
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()
474                 } else {
475                     String msg = String.format("ERROR: getLogicalLinkNamesFromAr: logicalLinkUri=%s", logicalLinkUri)
476                     logger.error(msg)
477                     exceptionUtil.buildAndThrowWorkflowException(execution, 2500, msg)
478                 }
479             }
480         } catch (BpmnError e) {
481             if (exceptionOnErr) {
482                 throw e;
483             }
484         } catch (Exception ex) {
485             if (exceptionOnErr) {
486                 String msg = String.format("ERROR: getLogicalLinkNamesFromAr: %s", ex.getMessage())
487                 logger.error(msg)
488                 exceptionUtil.buildAndThrowWorkflowException(execution, 2500, msg)
489             }
490         }
491
492         return res
493     }
494
495
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)
504         } else {
505             if (exceptionOnErr) {
506                 String msg = "ERROR: getRelationshipUriListInAai: No relationship found"
507                 logger.error(msg)
508                 exceptionUtil.buildAndThrowWorkflowException(execution, 2500, msg)
509             }
510         }
511
512         return null
513     }
514
515     List<String> getLogicalLinkNamesFromAr(DelegateExecution execution, String serviceInstanceId,
516                                            String arId, boolean exceptionOnErr) {
517         List<String> res = new ArrayList<>()
518         try {
519             AAIResourcesClient client = new AAIResourcesClient()
520
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())
529                 } else {
530                     String msg = String.format("ERROR: getLogicalLinkNamesFromAr: logicalLinkUri=%s", logicalLinkUri)
531                     logger.error(msg)
532                     exceptionUtil.buildAndThrowWorkflowException(execution, 2500, msg)
533                 }
534             }
535         } catch (BpmnError e) {
536             if (exceptionOnErr) {
537                 throw e;
538             }
539         } catch (Exception ex) {
540             if (exceptionOnErr) {
541                 String msg = String.format("ERROR: getLogicalLinkNamesFromAr: %s", ex.getMessage())
542                 logger.error(msg)
543                 exceptionUtil.buildAndThrowWorkflowException(execution, 2500, msg)
544             }
545         }
546
547         return res
548     }
549 }