Merge branch '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             serviceIntentUtils.setExecVarFromJsonIfExists(execution, additionalPropJsonStr,
113                     "modifyAction", "modifyAction");
114             if (isNotBlank(execution.getVariable("modifyAction"))) {
115                 logger.debug("modifyAction: " + execution.getVariable("modifyAction"))
116             } else {
117                 logger.debug("modifyAction is not set")
118             }
119
120             if (isBlank(serviceIntentUtils.setExecVarFromJsonIfExists(execution, additionalPropJsonStr,
121                     "enableSdnc", "enableSdnc"))) {
122                 serviceIntentUtils.setEnableSdncConfig(execution)
123             }
124         } catch (BpmnError e) {
125             throw e
126         } catch (Exception ex) {
127             msg = "Exception in preProcessRequest " + ex.getMessage()
128             logger.debug(msg)
129             exceptionUtil.buildAndThrowWorkflowException(execution, 7000, msg)
130         }
131         logger.debug("Finish preProcessRequest")
132     }
133
134
135     void deleteServiceInstance(DelegateExecution execution) {
136         try {
137             AAIResourcesClient client = getAAIClient()
138             AAIResourceUri uri = AAIUriFactory.createResourceUri(AAIFluentTypeBuilder.business().customer(execution.getVariable("globalSubscriberId")).serviceSubscription(execution.getVariable("subscriptionServiceType")).serviceInstance(execution.getVariable("serviceInstanceID")))
139             client.delete(uri)
140         } catch (BpmnError e) {
141             throw e
142         } catch (Exception ex) {
143             String msg = "Exception in DoDeallocateTnNssi.deleteServiceInstance. " + ex.getMessage()
144             logger.info(msg)
145             exceptionUtil.buildAndThrowWorkflowException(execution, 7000, msg)
146         }
147     }
148
149
150     void getExistingServiceInstance(DelegateExecution execution) {
151         String serviceInstanceId = execution.getVariable("cllId")
152
153         AAIResourcesClient resourceClient = getAAIClient()
154         AAIResourceUri ssServiceuri = AAIUriFactory.createResourceUri(Types.SERVICE_INSTANCE.getFragment(serviceInstanceId))
155
156         try {
157             Optional<ServiceInstance> ssOpt = resourceClient.get(ServiceInstance.class, ssServiceuri)
158             if (ssOpt.isPresent()) {
159                 ServiceInstance ss = ssOpt.get()
160                 AllottedResources ars = serviceIntentUtils.getAllottedResourcesFromAai(execution, serviceInstanceId, true)
161                 if (ars != null) {
162                     List<AllottedResource> arList = ars.getAllottedResource()
163                     List<String> arIdList = new ArrayList<>()
164                     Map<String, String> policyMap = new HashMap<>()
165                     Map<String, List<String>> logicalLinksMap = new HashMap<>()
166                     for (AllottedResource ar : arList) {
167                         String arId = ar.getId()
168                         arIdList.add(arId)
169                         String policyId = serviceIntentUtils.getPolicyIdFromAr(execution, serviceInstanceId, arId, true)
170                         policyMap.put(arId, policyId)
171                         List<String> logicalLinkList = serviceIntentUtils.getLogicalLinkNamesFromAr(execution,
172                                 serviceInstanceId, arId, true)
173                         logicalLinksMap.put(arId, logicalLinkList)
174                     }
175                     execution.setVariable("arIdList", arIdList)
176                     execution.setVariable("arPolicyMap", policyMap)
177                     execution.setVariable("arLogicalLinkMap", logicalLinksMap)
178                 } else {
179                     logger.error("ERROR: getExistingServiceInstance: getAllottedResources() returned null. ss=" + ss
180                             .toString())
181                 }
182             } else {
183                 exceptionUtil.buildAndThrowWorkflowException(execution, 2500, "Service instance was not found in aai to " +
184                         "associate allotted resource for service :" + serviceInstanceId)
185             }
186         } catch (BpmnError e) {
187             throw e;
188         } catch (Exception ex) {
189             String msg = "Exception in getExistingServiceInstance. " + ex.getMessage()
190             logger.debug(msg)
191             exceptionUtil.buildAndThrowWorkflowException(execution, 7000, msg)
192         }
193     }
194
195     void updateServiceInstanceInAAI(DelegateExecution execution) {
196         getExistingServiceInstance(execution)
197         updateTsciNetworks(execution)
198     }
199
200     void updateServiceInstance(DelegateExecution execution) {
201         String cllId = execution.getVariable("cllId")
202         try {
203             ServiceInstance ss = new ServiceInstance()
204             //ss.setServiceInstanceId(cllId)
205             String serviceStatus = "modified"
206             ss.setOrchestrationStatus(serviceStatus)
207             ss.setEnvironmentContext("tn")
208             AAIResourcesClient client = getAAIClient()
209             AAIResourceUri uri = AAIUriFactory.createResourceUri(
210                     AAIFluentTypeBuilder.business()
211                             .customer(execution.getVariable("globalSubscriberId"))
212                             .serviceSubscription(execution.getVariable("subscriptionServiceType"))
213                             .serviceInstance(cllId))
214             client.update(uri, ss)
215         } catch (BpmnError e) {
216             throw e
217         } catch (Exception ex) {
218             String msg = "Exception in DoModifyCllInstance.updateServiceInstance. " + ex.getMessage()
219             logger.info(msg)
220             exceptionUtil.buildAndThrowWorkflowException(execution, 7000, msg)
221         }
222     }
223
224
225     String getValidArId(DelegateExecution execution, String arIdStr) {
226         List<String> arIdList = execution.getVariable("arIdList")
227         /*
228          * If arId is not specified by the caller, then we assume the caller
229          * wants to modify the first network (i.e., allotted resource) in the TSCi tree.
230          */
231         String arId = isBlank(arIdStr) ? arIdList.get(0) : arIdStr
232
233         return arId
234     }
235
236     void updateLogicalLinksInAr(DelegateExecution execution, String arId, String linkArrayJsonStr) {
237         try {
238             String serviceInstanceId = execution.getVariable('cllId')
239
240             /*
241              * Each TSCi connection-link in linkArrayJsonStr is considered as an "ADD" new
242              * link to allotted-resource. So, if the link already exists under AR, then do
243              * nothing. Otherwise, create logical-link.
244              */
245             List<String> linkStrList = jsonUtil.StringArrayToList(linkArrayJsonStr)
246             for (String linkStr : linkStrList) {
247                 if (logicalLinkExists(execution, arId, linkStr)) {
248                     continue
249                 }
250
251                 createLogicalLinkForAllocatedResource(execution, linkStr, serviceInstanceId, arId)
252             }
253         } catch (BpmnError e) {
254             throw e
255         } catch (Exception ex) {
256             exceptionUtil.buildAndThrowWorkflowException(execution, 7000,
257                     "Exception in updateLogicalLinksInAr" + ex.getMessage())
258         }
259     }
260
261     void updateLogicalLinksInNetwork(DelegateExecution execution, String networkJsonStr) {
262         try {
263             String arId = getValidArId(execution, jsonUtil.getJsonValue(networkJsonStr, "id"))
264             String linkArrayStr = jsonUtil.getJsonValue(networkJsonStr, "connectionLinks")
265             updateLogicalLinksInAr(execution, arId, linkArrayStr)
266         } catch (BpmnError e) {
267             throw e
268         } catch (Exception ex) {
269             String msg = String.format("ERROR: updateLogicalLinksInNetwork: exception: %s", ex.getMessage())
270             logger.error(msg)
271             exceptionUtil.buildAndThrowWorkflowException(execution, 7000, msg);
272         }
273     }
274
275     void updateTsciNetworks(DelegateExecution execution) {
276         try {
277             if (modifyBandwidthGlobal(execution)) {
278                 String netStr = jsonUtil.StringArrayToList(execution.getVariable("transportNetworks")).get(0)
279                 int maxBw = getMaxBwFromNetworkJsonStr(execution, netStr)
280                 updateNetworkPolicyGlobal(execution, maxBw)
281                 return
282             }
283             List<String> networkStrList = jsonUtil.StringArrayToList(execution.getVariable("transportNetworks"))
284             for (String networkStr : networkStrList) {
285                 updateTsciNetwork(execution, networkStr)
286             }
287         } catch (BpmnError e) {
288             throw e
289         } catch (Exception ex) {
290             exceptionUtil.buildAndThrowWorkflowException(execution, 7000,
291                     "Exception in updateTsciNetworks" + ex.getMessage())
292         }
293     }
294
295     boolean modifyBandwidthGlobal(DelegateExecution execution) {
296         String modifyAction = execution.getVariable("modifyAction")
297         if (isNotBlank(modifyAction) && modifyAction.equals("bandwidth")) {
298             return true
299         }
300
301         return false
302     }
303
304     void updateTsciNetwork(DelegateExecution execution, String networkStr) {
305         updateLogicalLinksInNetwork(execution, networkStr)
306         updateNetworkPolicy(execution, networkStr)
307     }
308
309     int getMaxBwFromNetworkJsonStr(DelegateExecution execution, String networkJsonStr) {
310         int maxBw = 0
311         try {
312             if (isBlank(networkJsonStr)) {
313                 String msg = "ERROR: getMaxBw: networkJsonStr is null"
314                 logger.error(msg)
315                 exceptionUtil.buildAndThrowWorkflowException(execution, 7000, msg)
316             }
317             String slaStr = jsonUtil.getJsonValue(networkJsonStr, "sla")
318             if (isBlank(slaStr)) {
319                 String msg = "ERROR: getMaxBw: slaStr is null"
320                 logger.error(msg)
321                 exceptionUtil.buildAndThrowWorkflowException(execution, 7000, msg)
322             }
323
324             String bwStr = jsonUtil.getJsonValue(slaStr, "maxBandwidth")
325             if (isNotBlank(bwStr)) {
326                 maxBw = Integer.parseInt(bwStr)
327             } else {
328                 logger.error("ERROR: getMaxBw: maxBandwidth is null")
329             }
330         } catch (BpmnError e) {
331             throw e
332         } catch (Exception ex) {
333             exceptionUtil.buildAndThrowWorkflowException(execution, 7000,
334                     "Exception in getMaxBw" + ex.getMessage())
335         }
336
337         return maxBw
338     }
339
340     void updatePolicyMaxBandwidthInAAI(DelegateExecution execution, String policyId, int maxBw) {
341         try {
342             NetworkPolicy networkPolicy = new NetworkPolicy()
343             networkPolicy.setMaxBandwidth(maxBw)
344             AAIResourceUri networkPolicyUri =
345                     AAIUriFactory.createResourceUri(AAIFluentTypeBuilder.network().networkPolicy(policyId))
346             getAAIClient().update(networkPolicyUri, networkPolicy)
347         } catch (BpmnError e) {
348             throw e
349         } catch (Exception ex) {
350             String msg = "Exception in DoModifyCllInstance.updatePolicyMaxBandwidthInAAI. " + ex.getMessage()
351             logger.info(msg)
352             exceptionUtil.buildAndThrowWorkflowException(execution, 7000, msg)
353         }
354     }
355
356     void updateNetworkPolicyGlobal(DelegateExecution execution, int maxBw) {
357         try {
358             List<String> arIdList = execution.getVariable("arIdList")
359             for (String arId : arIdList) {
360                 Map<String, String> policyMap = execution.getVariable("arPolicyMap")
361                 String policyId = policyMap.get(arId)
362                 if (isBlank(policyId)) {
363                     String msg = String.format("ERROR: updateNetworkPolicy: policyId not found. arId=%s", arId)
364                     logger.error(msg)
365                     exceptionUtil.buildAndThrowWorkflowException(execution, 7000, msg)
366                 }
367                 updatePolicyMaxBandwidthInAAI(execution, policyId, maxBw)
368             }
369         } catch (BpmnError e) {
370             throw e
371         } catch (Exception ex) {
372             String msg = String.format("ERROR: updateNetworkPolicy: exception: %s", ex.getMessage())
373             logger.error(msg)
374             exceptionUtil.buildAndThrowWorkflowException(execution, 7000, msg);
375         }
376     }
377
378     void updateNetworkPolicy(DelegateExecution execution, String networkJsonStr) {
379         try {
380             int maxBw = getMaxBwFromNetworkJsonStr(execution, networkJsonStr)
381
382             String arId = getValidArId(execution, jsonUtil.getJsonValue(networkJsonStr, "id"))
383             Map<String, String> policyMap = execution.getVariable("arPolicyMap")
384             String policyId = policyMap.get(arId)
385             if (isBlank(policyId)) {
386                 String msg = String.format("ERROR: updateNetworkPolicy: policyId not found. arId=%s", arId)
387                 logger.error(msg)
388                 exceptionUtil.buildAndThrowWorkflowException(execution, 7000, msg)
389             }
390
391             updatePolicyMaxBandwidthInAAI(execution, policyId, maxBw)
392
393         } catch (BpmnError e) {
394             throw e
395         } catch (Exception ex) {
396             String msg = String.format("ERROR: updateNetworkPolicy: exception: %s", ex.getMessage())
397             logger.error(msg)
398             exceptionUtil.buildAndThrowWorkflowException(execution, 7000, msg);
399         }
400     }
401
402
403     void createLogicalLinkForAllocatedResource(DelegateExecution execution,
404                                                String linkJsonStr, String cllId,
405                                                String allottedResourceId) {
406         try {
407             AAIResourceUri allottedResourceUri = serviceIntentUtils.buildAllottedResourceUri(execution,
408                     cllId, allottedResourceId)
409
410             if (!getAAIClient().exists(allottedResourceUri)) {
411                 logger.info("ERROR: createLogicalLinksForAllocatedResource: allottedResource not exist: uri={}",
412                         allottedResourceUri)
413                 return
414             }
415
416             String linkId = jsonUtil.getJsonValue(linkJsonStr, "id")
417             if (isBlank(linkId)) {
418                 linkId = "cll-" + UUID.randomUUID().toString()
419             }
420             logger.debug("createLogicalLinkForAllocatedResource: linkId=" + linkId)
421
422             String epA = jsonUtil.getJsonValue(linkJsonStr, "transportEndpointA")
423             String epB = jsonUtil.getJsonValue(linkJsonStr, "transportEndpointB")
424             String modelInvariantId = execution.getVariable("modelInvariantUuid")
425             String modelVersionId = execution.getVariable("modelUuid")
426
427             org.onap.aai.domain.yang.LogicalLink resource = new org.onap.aai.domain.yang.LogicalLink()
428             resource.setLinkId(linkId)
429             resource.setLinkName(epA)
430             resource.setLinkName2(epB)
431             resource.setLinkType("TsciConnectionLink")
432             resource.setInMaint(false)
433
434             //epA is link-name
435             AAIResourceUri logicalLinkUri =
436                     AAIUriFactory.createResourceUri(AAIFluentTypeBuilder.network().logicalLink(epA))
437             getAAIClient().create(logicalLinkUri, resource)
438
439             serviceIntentUtils.attachLogicalLinkToAllottedResource(execution, serviceIntentUtils.AAI_VERSION,
440                     allottedResourceUri, epA);
441         } catch (BpmnError e) {
442             throw e
443         } catch (Exception ex) {
444             String msg = "Exception in DoModifyCllInstance.createLogicalLinksForAllocatedResource: " + ex.getMessage()
445             logger.error(msg)
446             exceptionUtil.buildAndThrowWorkflowException(execution, 7000, msg)
447         }
448     }
449
450
451     void preprocessSdncModifyCllRequest(DelegateExecution execution) {
452         def method = getClass().getSimpleName() + '.preprocessSdncModifyCllRequest(' +
453                 'execution=' + execution.getId() + ')'
454         def isDebugLogEnabled = execution.getVariable('isDebugLogEnabled')
455         logger.trace('Entered ' + method)
456
457         try {
458             String serviceInstanceId = execution.getVariable("cllId")
459
460             String sdncRequest = serviceIntentUtils.buildSDNCRequest(execution, serviceInstanceId, "update")
461
462             execution.setVariable("CLL_SDNCRequest", sdncRequest)
463             logger.debug("Outgoing SDNCRequest is: \n" + sdncRequest)
464
465         } catch (BpmnError e) {
466             throw e
467         } catch (Exception e) {
468             logger.debug("Exception Occurred Processing preprocessSdncModifyCllRequest. Exception is:\n" + e)
469             exceptionUtil.buildAndThrowWorkflowException(execution, 1002, "Error Occurred during  preProcessSDNCActivateRequest Method:\n" + e.getMessage())
470         }
471         logger.trace("COMPLETED preprocessSdncModifyCllRequest Process")
472     }
473
474
475     void validateSDNCResponse(DelegateExecution execution, String response, String method) {
476         serviceIntentUtils.validateSDNCResponse(execution, response, method)
477     }
478
479
480     void updateAAIOrchStatus(DelegateExecution execution) {
481         logger.debug("Start updateAAIOrchStatus")
482         String cllId = execution.getVariable("cllId")
483         String orchStatus = execution.getVariable("orchestrationStatus")
484
485         try {
486             ServiceInstance si = new ServiceInstance()
487             si.setOrchestrationStatus(orchStatus)
488             AAIResourcesClient client = getAAIClient()
489             AAIResourceUri uri = AAIUriFactory.createResourceUri(Types.SERVICE_INSTANCE.getFragment(cllId))
490             client.update(uri, si)
491         } catch (BpmnError e) {
492             throw e
493         } catch (Exception ex) {
494             String msg = "Exception in CreateSliceService.updateAAIOrchStatus " + ex.getMessage()
495             logger.info(msg)
496             exceptionUtil.buildAndThrowWorkflowException(execution, 7000, msg)
497         }
498
499         logger.debug("Finish updateAAIOrchStatus")
500     }
501
502     void prepareUpdateJobStatus(DelegateExecution execution,
503                                 String status,
504                                 String progress,
505                                 String statusDescription) {
506         String cllId = execution.getVariable("cllId")
507         String modelUuid = execution.getVariable("modelUuid")
508         String jobId = execution.getVariable("jobId")
509         String nsiId = cllId
510         String operType = "MODIFY"
511
512         ResourceOperationStatus roStatus = serviceIntentUtils.buildRoStatus(modelUuid, cllId,
513                 jobId, nsiId, operType, status, progress, statusDescription)
514
515         logger.debug("prepareUpdateJobStatus: roStatus={}", roStatus)
516         requestDBUtil.prepareUpdateResourceOperationStatus(execution, roStatus)
517     }
518
519     boolean logicalLinkExists(DelegateExecution execution, String arIdStr, String linkJsonStr) {
520         if (isBlank(arIdStr)) {
521             logger.error("ERROR: logicalLinkExists: arIdStr is empty")
522             return false
523         }
524         if (isBlank(linkJsonStr)) {
525             logger.error("ERROR: logicalLinkExists: linkJsonStr is empty")
526             return false
527         }
528
529         Map<String, List<String>> logicalLinksMap = execution.getVariable("arLogicalLinkMap")
530         if (logicalLinksMap == null) {
531             logger.error("ERROR: logicalLinkExists: logicalLinksMap is null")
532             return false
533         }
534
535         List<String> logicalLinkNameList = logicalLinksMap.get(arIdStr)
536         if (logicalLinksMap == null) {
537             logger.error("ERROR: logicalLinkExists: logicalLinkNameList is null. arIdStr=" + arIdStr)
538             return false
539         }
540
541         String linkName = jsonUtil.getJsonValue(linkJsonStr, "transportEndpointA")
542         if (isBlank(linkName)) {
543             logger.error("ERROR: logicalLinkExists: epA is empty")
544             return false
545         }
546
547         return logicalLinkNameList.contains(linkName)
548     }
549 }
550