2 * ============LICENSE_START=======================================================
4 * ================================================================================
5 * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
6 * ================================================================================
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
11 * http://www.apache.org/licenses/LICENSE-2.0
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
18 * ============LICENSE_END=========================================================
21 package org.onap.so.bpmn.common.scripts
22 import java.util.regex.Matcher
23 import java.util.regex.Pattern
25 import javax.ws.rs.core.UriBuilder
27 import org.camunda.bpm.engine.delegate.BpmnError
28 import org.camunda.bpm.engine.delegate.DelegateExecution
29 import org.onap.aai.domain.yang.GenericVnf
30 import org.onap.so.bpmn.core.UrnPropertiesReader;
31 import org.onap.so.client.aai.AAIVersion
32 import org.onap.so.client.aai.entities.uri.AAIUri
33 import org.onap.so.logger.MessageEnum
34 import org.onap.so.logger.MsoLogger
35 import org.onap.so.openpojo.rules.HasToStringRule
36 import org.onap.so.rest.APIResponse;
37 import org.onap.so.rest.RESTClient
38 import org.onap.so.rest.RESTConfig
42 private static final MsoLogger msoLogger = MsoLogger.getMsoLogger(MsoLogger.Catalog.BPEL, AaiUtil.class);
45 public MsoUtils utils = new MsoUtils()
46 public static final String AAI_NAMESPACE_STRING_KEY = 'mso.workflow.global.default.aai.namespace'
47 public static final String DEFAULT_VERSION_KEY = 'mso.workflow.global.default.aai.version'
49 private String aaiNamespace = null;
51 private AbstractServiceTaskProcessor taskProcessor
53 public AaiUtil(AbstractServiceTaskProcessor taskProcessor) {
54 this.taskProcessor = taskProcessor
57 public String getBusinessSPPartnerUri(DelegateExecution execution) {
58 def uri = getUri(execution, 'sp-partner')
59 msoLogger.debug('AaiUtil.getBusinessSPPartnerUri() - AAI URI: ' + uri)
63 public String getVersion(DelegateExecution execution, resourceName, processKey) {
64 def versionWithResourceKey = "mso.workflow.default.aai.${resourceName}.version"
65 def versionWithProcessKey = "mso.workflow.custom.${processKey}.aai.version"
67 def version = UrnPropertiesReader.getVariable(versionWithProcessKey, execution)
69 msoLogger.debug("AaiUtil.getVersion() - using flow specific ${versionWithProcessKey}=${version}")
73 version = UrnPropertiesReader.getVariable(versionWithResourceKey, execution)
75 msoLogger.debug("AaiUtil.getVersion() - using resource specific ${versionWithResourceKey}=${version}")
79 version = UrnPropertiesReader.getVariable(DEFAULT_VERSION_KEY, execution)
81 msoLogger.debug("AaiUtil.getVersion() - using default version ${DEFAULT_VERSION_KEY}=${version}")
85 (new ExceptionUtil()).buildAndThrowWorkflowException(execution, 9999, "Internal Error: One of the following should be defined in MSO URN properties file: ${versionWithResourceKey}, ${versionWithProcessKey}, ${DEFAULT_VERSION_KEY}")
88 public String createAaiUri(AAIUri uri) {
89 return createAaiUri(AAIVersion.valueOf('V' + UrnPropertiesReader.getVariable(DEFAULT_VERSION_KEY)), uri)
91 public String createAaiUri(AAIVersion version, AAIUri uri) {
92 String endpoint = UrnPropertiesReader.getVariable("aai.endpoint")
93 String result = UriBuilder.fromUri(endpoint).path('aai').path(version.toString()).build().toString()
94 return UriBuilder.fromUri(result + uri.build().toString()).build().toString()
97 public String setNamespace(DelegateExecution execution) {
98 def key = AAI_NAMESPACE_STRING_KEY
99 aaiNamespace = UrnPropertiesReader.getVariable(key, execution)
100 if (aaiNamespace == null ) {
101 (new ExceptionUtil()).buildAndThrowWorkflowException(execution, 9999, 'Internal Error: AAI URI entry for ' + key + ' not defined in the MSO URN properties file')
105 public String getNamespace() {
106 return getNamespace(AAIVersion.valueOf('V' + UrnPropertiesReader.getVariable(DEFAULT_VERSION_KEY)))
109 public String getNamespace(AAIVersion version) {
110 String namespace = UrnPropertiesReader.getVariable(AAI_NAMESPACE_STRING_KEY)
111 if (namespace == null) {
112 throw new Exception('Internal Error: AAI Namespace has not been set yet. A getUri() method needs to be invoked first.')
115 return namespace + version
118 * This method can be used for getting the building namespace out of uri.
119 * NOTE: A getUri() method needs to be invoked first.
120 * Alternative method is the getNamespaceFromUri(DelegateExecution execution, String uri)
121 * return namespace (plus version from uri)
127 public String getNamespaceFromUri(String uri) {
128 String namespace = UrnPropertiesReader.getVariable(AAI_NAMESPACE_STRING_KEY)
129 if (namespace == null) {
130 throw new Exception('Internal Error: AAI Namespace has not been set yet. A getUri() method needs to be invoked first.')
133 String version = getVersionFromUri(uri)
134 return namespace + "v"+version
141 * This method can be used for building namespace with aai version out of uri.
142 * NOTE: 2 arguments: DelegateExecution execution & String uri
148 public String getNamespaceFromUri(DelegateExecution execution, String uri) {
149 String namespace = UrnPropertiesReader.getVariable(AAI_NAMESPACE_STRING_KEY, execution)
150 if (namespace == null ) {
151 (new ExceptionUtil()).buildAndThrowWorkflowException(execution, 9999, 'Internal Error: AAI URI entry for ' + AAI_NAMESPACE_STRING_KEY + ' not defined in the MSO URN properties file')
154 String version = getVersionFromUri(uri)
155 return namespace + "v"+version
162 * This is used to extract the version from uri.
168 private String getVersionFromUri(String uri) {
170 Matcher versionRegEx = Pattern.compile("/v(\\d+)").matcher(uri)
171 if (versionRegEx.find()) {
172 return versionRegEx.group(1);
180 * This reusable method can be used for making AAI Get Calls. The url should
181 * be passed as a parameter along with the execution. The method will
182 * return an APIResponse.
187 * @return APIResponse
190 public APIResponse executeAAIGetCall(DelegateExecution execution, String url){
191 msoLogger.trace("STARTED Execute AAI Get Process ")
192 APIResponse apiResponse = null
194 String uuid = utils.getRequestID()
195 msoLogger.debug("Generated uuid is: " + uuid)
196 msoLogger.debug("URL to be used is: " + url)
198 String basicAuthCred = utils.getBasicAuth(UrnPropertiesReader.getVariable("aai.auth", execution),UrnPropertiesReader.getVariable("mso.msoKey", execution))
200 RESTConfig config = new RESTConfig(url);
201 RESTClient client = new RESTClient(config).addHeader("X-FromAppId", "MSO").addHeader("X-TransactionId", uuid).addHeader("Accept","application/xml");
203 if (basicAuthCred != null && !"".equals(basicAuthCred)) {
204 client.addAuthorizationHeader(basicAuthCred)
206 apiResponse = client.httpGet()
208 msoLogger.trace("COMPLETED Execute AAI Get Process ")
210 msoLogger.debug("Exception occured while executing AAI Get Call. Exception is: \n" + e)
211 (new ExceptionUtil()).buildAndThrowWorkflowException(execution, 9999, e.getMessage())
218 * This reusable method can be used for making AAI httpPut Calls. The url should
219 * be passed as a parameter along with the execution and payload. The method will
220 * return an APIResponse.
226 * @return APIResponse
229 public APIResponse executeAAIPutCall(DelegateExecution execution, String url, String payload){
230 msoLogger.trace("Started Execute AAI Put Process ")
231 APIResponse apiResponse = null
233 String uuid = utils.getRequestID()
234 msoLogger.debug("Generated uuid is: " + uuid)
235 msoLogger.debug("URL to be used is: " + url)
237 String basicAuthCred = utils.getBasicAuth(UrnPropertiesReader.getVariable("aai.auth", execution),UrnPropertiesReader.getVariable("mso.msoKey", execution))
239 RESTConfig config = new RESTConfig(url);
240 RESTClient client = new RESTClient(config).addHeader("X-FromAppId", "MSO").addHeader("X-TransactionId", uuid).addHeader("Content-Type", "application/xml").addHeader("Accept","application/xml");
241 if (basicAuthCred != null && !"".equals(basicAuthCred)) {
242 client.addAuthorizationHeader(basicAuthCred)
244 apiResponse = client.httpPut(payload)
246 msoLogger.trace("Completed Execute AAI Put Process ")
248 msoLogger.error(MessageEnum.BPMN_GENERAL_EXCEPTION_ARG, "Exception occured while executing AAI Put Call.", "BPMN", MsoLogger.getServiceName(), MsoLogger.ErrorCode.UnknownError, e);
249 (new ExceptionUtil()).buildAndThrowWorkflowException(execution, 9999, e.getMessage())
255 * This reusable method can be used for making AAI httpPatch Calls. The url should
256 * be passed as a parameter along with the execution and payload. The method will
257 * return an APIResponse.
263 * @return APIResponse
266 public APIResponse executeAAIPatchCall(DelegateExecution execution, String url, String payload){
267 msoLogger.trace("Started Execute AAI Patch Process ")
268 APIResponse apiResponse = null
270 String uuid = utils.getRequestID()
271 msoLogger.debug("Generated uuid is: " + uuid)
273 msoLogger.debug("URL to be used is: " + url)
275 String basicAuthCred = utils.getBasicAuth(UrnPropertiesReader.getVariable("aai.auth", execution),UrnPropertiesReader.getVariable("mso.msoKey", execution))
277 RESTConfig config = new RESTConfig(url);
278 RESTClient client = new RESTClient(config).addHeader("X-FromAppId", "MSO").addHeader("X-TransactionId", uuid).addHeader("Content-Type", "application/merge-patch+json").addHeader("Accept","application/json");
279 if (basicAuthCred != null && !"".equals(basicAuthCred)) {
280 client.addAuthorizationHeader(basicAuthCred)
282 apiResponse = client.httpPatch(payload)
284 msoLogger.trace("Completed Execute AAI Patch Process ")
286 msoLogger.error(MessageEnum.BPMN_GENERAL_EXCEPTION_ARG, "Exception occured while executing AAI Patch Call.", "BPMN", MsoLogger.getServiceName(), MsoLogger.ErrorCode.UnknownError, e);
287 (new ExceptionUtil()).buildAndThrowWorkflowException(execution, 9999, e.getMessage())
294 * This reusable method can be used for making AAI Delete Calls. The url should
295 * be passed as a parameter along with the execution. The method will
296 * return an APIResponse.
301 * @return APIResponse
304 public APIResponse executeAAIDeleteCall(DelegateExecution execution, String url){
305 msoLogger.trace("Started Execute AAI Delete Process ")
306 APIResponse apiResponse = null
308 String uuid = utils.getRequestID()
309 msoLogger.debug("Generated uuid is: " + uuid)
310 msoLogger.debug("URL to be used is: " + url)
312 String basicAuthCred = utils.getBasicAuth(UrnPropertiesReader.getVariable("aai.auth", execution),UrnPropertiesReader.getVariable("mso.msoKey", execution))
314 RESTConfig config = new RESTConfig(url);
315 RESTClient client = new RESTClient(config).addHeader("X-FromAppId", "MSO").addHeader("X-TransactionId", uuid).addHeader("Accept","application/xml");
316 if (basicAuthCred != null && !"".equals(basicAuthCred)) {
317 client.addAuthorizationHeader(basicAuthCred)
319 apiResponse = client.delete()
321 msoLogger.trace("Completed Execute AAI Delete Process ")
323 msoLogger.error(MessageEnum.BPMN_GENERAL_EXCEPTION_ARG, "Exception occured while executing AAI Delete Call.", "BPMN", MsoLogger.getServiceName(), MsoLogger.ErrorCode.UnknownError, e);
324 (new ExceptionUtil()).buildAndThrowWorkflowException(execution, 9999, e.getMessage())
330 * This reusable method can be used for making AAI Delete Calls. The url should
331 * be passed as a parameter along with the execution. The method will
332 * return an APIResponse.
338 * @return APIResponse
341 public APIResponse executeAAIDeleteCall(DelegateExecution execution, String url, String payload, String authHeader){
342 msoLogger.trace("Started Execute AAI Delete Process ")
343 APIResponse apiResponse = null
345 String uuid = utils.getRequestID()
346 msoLogger.debug("Generated uuid is: " + uuid)
348 msoLogger.debug("URL to be used is: " + url)
350 String basicAuthCred = utils.getBasicAuth(UrnPropertiesReader.getVariable("aai.auth", execution),UrnPropertiesReader.getVariable("mso.msoKey", execution))
351 RESTConfig config = new RESTConfig(url);
352 RESTClient client = new RESTClient(config).addHeader("X-FromAppId", "MSO").addHeader("X-TransactionId", uuid).addHeader("Accept","application/xml").addAuthorizationHeader(authHeader);
353 if (basicAuthCred != null && !"".equals(basicAuthCred)) {
354 client.addAuthorizationHeader(basicAuthCred)
356 apiResponse = client.httpDelete(payload)
358 msoLogger.trace("Completed Execute AAI Delete Process ")
360 msoLogger.error(MessageEnum.BPMN_GENERAL_EXCEPTION_ARG, "Exception occured while executing AAI Delete Call.", "BPMN", MsoLogger.getServiceName(), MsoLogger.ErrorCode.UnknownError, e);
361 (new ExceptionUtil()).buildAndThrowWorkflowException(execution, 9999, e.getMessage())
367 * This reusable method can be used for making AAI Post Calls. The url
368 * and payload should be passed as a parameters along with the execution.
369 * The method will return an APIResponse.
375 * @return APIResponse
378 public APIResponse executeAAIPostCall(DelegateExecution execution, String url, String payload){
379 msoLogger.trace("Started Execute AAI Post Process ")
380 APIResponse apiResponse = null
382 String uuid = utils.getRequestID()
383 msoLogger.debug("Generated uuid is: " + uuid)
384 msoLogger.debug("URL to be used is: " + url)
386 String basicAuthCred = utils.getBasicAuth(UrnPropertiesReader.getVariable("aai.auth", execution),UrnPropertiesReader.getVariable("mso.msoKey", execution))
387 RESTConfig config = new RESTConfig(url);
388 RESTClient client = new RESTClient(config).addHeader("X-FromAppId", "MSO").addHeader("X-TransactionId", uuid).addHeader("Accept","application/xml");
390 if (basicAuthCred != null && !"".equals(basicAuthCred)) {
391 client.addAuthorizationHeader(basicAuthCred)
393 apiResponse = client.httpPost(payload)
395 msoLogger.trace("Completed Execute AAI Post Process ")
397 msoLogger.error(MessageEnum.BPMN_GENERAL_EXCEPTION_ARG, "Exception occured while executing AAI Post Call.", "BPMN", MsoLogger.getServiceName(), MsoLogger.ErrorCode.UnknownError, e);
398 (new ExceptionUtil()).buildAndThrowWorkflowException(execution, 9999, e.getMessage())
404 * This reusable method can be used for making AAI Post Calls. The url
405 * and payload should be passed as a parameters along with the execution.
406 * The method will return an APIResponse.
411 * @param authenticationHeader - addAuthenticationHeader value
412 * @param headerName - name of header you want to add, i.e. addHeader(headerName, headerValue)
413 * @param headerValue - the header's value, i.e. addHeader(headerName, headerValue)
415 * @return APIResponse
418 public APIResponse executeAAIPostCall(DelegateExecution execution, String url, String payload, String authenticationHeaderValue, String headerName, String headerValue){
419 msoLogger.trace("Started Execute AAI Post Process ")
420 APIResponse apiResponse = null
422 msoLogger.debug("URL to be used is: " + url)
424 String basicAuthCred = utils.getBasicAuth(UrnPropertiesReader.getVariable("aai.auth", execution),UrnPropertiesReader.getVariable("mso.msoKey", execution))
426 RESTConfig config = new RESTConfig(url);
427 RESTClient client = new RESTClient(config).addAuthorizationHeader(authenticationHeaderValue).addHeader(headerName, headerValue)
428 if (basicAuthCred != null && !"".equals(basicAuthCred)) {
429 client.addAuthorizationHeader(basicAuthCred)
431 apiResponse = client.httpPost(payload)
433 msoLogger.trace("Completed Execute AAI Post Process ")
435 msoLogger.error(MessageEnum.BPMN_GENERAL_EXCEPTION_ARG, "Exception occured while executing AAI Post Call.", "BPMN", MsoLogger.getServiceName(), MsoLogger.ErrorCode.UnknownError, e);
436 (new ExceptionUtil()).buildAndThrowWorkflowException(execution, 9999, e.getMessage())
442 /* Utility to get the Cloud Region from AAI
443 * Returns String cloud region id, (ie, cloud-region-id)
445 * @param url - url for AAI get cloud region
446 * @param backend - "PO" - real region, or "SDNC" - v2.5 (fake region).
449 public String getAAICloudReqion(DelegateExecution execution, String url, String backend, inputCloudRegion){
452 APIResponse apiResponse = executeAAIGetCall(execution, url)
453 String returnCode = apiResponse.getStatusCode()
454 String aaiResponseAsString = apiResponse.getResponseBodyAsString()
455 msoLogger.debug("Call AAI Cloud Region Return code: " + returnCode)
456 execution.setVariable(execution.getVariable("prefix")+"queryCloudRegionReturnCode", returnCode)
458 if(returnCode == "200"){
459 msoLogger.debug("Call AAI Cloud Region is Successful.")
461 String regionVersion = taskProcessor.utils.getNodeText(aaiResponseAsString, "cloud-region-version")
462 msoLogger.debug("Cloud Region Version from AAI for " + backend + " is: " + regionVersion)
463 if (backend == "PO") {
464 regionId = taskProcessor.utils.getNodeText(aaiResponseAsString, "cloud-region-id")
465 } else { // backend not "PO"
466 if (regionVersion == "2.5" ) {
467 regionId = "AAIAIC25"
469 regionId = taskProcessor.utils.getNodeText(aaiResponseAsString, "cloud-region-id")
472 if(regionId == null){
473 throw new BpmnError("MSOWorkflowException")
475 msoLogger.debug("Cloud Region Id from AAI " + backend + " is: " + regionId)
476 }else if (returnCode == "404"){ // not 200
477 if (backend == "PO") {
478 regionId = inputCloudRegion
479 }else{ // backend not "PO"
480 regionId = "AAIAIC25"
482 msoLogger.debug("Cloud Region value for code='404' of " + backend + " is: " + regionId)
484 msoLogger.error(MessageEnum.BPMN_GENERAL_EXCEPTION_ARG, "Call AAI Cloud Region is NOT Successful.", "BPMN", MsoLogger.getServiceName(), MsoLogger.ErrorCode.UnknownError, "");
485 throw new BpmnError("MSOWorkflowException")
487 }catch(Exception e) {
488 msoLogger.error(MessageEnum.BPMN_GENERAL_EXCEPTION_ARG, "Exception occured while getting the Cloud Reqion.", "BPMN", MsoLogger.getServiceName(), MsoLogger.ErrorCode.UnknownError, e.getMessage());
489 (new ExceptionUtil()).buildAndThrowWorkflowException(execution, 9999, e.getMessage())
494 /* returns xml Node with service-type of searchValue */
495 def searchServiceType(xmlInput, searchValue){
496 def fxml= new XmlSlurper().parseText(xmlInput)
497 def ret = fxml.'**'.find {it.'service-type' == searchValue}
501 /* returns xml Node with service-instance-id of searchValue */
502 def searchServiceInstanceId(xmlInput, searchValue){
503 def ret = xmlInput.'**'.find {it.'service-instance-id' == searchValue}
508 * Get the lowest unused VF Module index from AAI response for a given module type. The criteria for
509 * determining module type is specified by "key" parameter (for example, "persona-model-id"),
510 * the value for filtering is specified in "value" parameter
513 * @param aaiVnfResponse
517 * @return moduleIndex
520 public int getLowestUnusedVfModuleIndexFromAAIVnfResponse(DelegateExecution execution, GenericVnf aaiVnfResponse, String key, String value) {
521 if (aaiVnfResponse != null) {
522 String vfModulesText = taskProcessor.utils.getNodeXml(aaiVnfResponse, "vf-modules")
523 if (aaiVnfResponse.getVfModules() == null || aaiVnfResponse.getVfModules().getVfModule().isEmpty()) {
524 msoLogger.debug("There are no VF modules in this VNF yet")
528 def xmlVfModules= new XmlSlurper().parseText(vfModulesText)
529 def vfModules = xmlVfModules.'**'.findAll {it.name() == "vf-module"}
530 int vfModulesSize = 0
531 if (vfModules != null) {
532 vfModulesSize = vfModules.size()
534 String matchingVfModules = "<vfModules>"
535 for (i in 0..vfModulesSize-1) {
536 def vfModuleXml = groovy.xml.XmlUtil.serialize(vfModules[i])
537 def keyFromAAI = taskProcessor.utils.getNodeText(vfModuleXml, key)
538 if (keyFromAAI != null && keyFromAAI.equals(value)) {
539 matchingVfModules = matchingVfModules + taskProcessor.utils.removeXmlPreamble(vfModuleXml)
542 matchingVfModules = matchingVfModules + "</vfModules>"
543 msoLogger.debug("Matching VF Modules: " + matchingVfModules)
544 String lowestUnusedIndex = taskProcessor.utils.getLowestUnusedIndex(matchingVfModules)
545 return Integer.parseInt(lowestUnusedIndex)