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.so.bpmn.core.UrnPropertiesReader;
30 import org.onap.so.client.aai.AAIVersion
31 import org.onap.so.client.aai.entities.uri.AAIUri
32 import org.onap.so.logger.MessageEnum
33 import org.onap.so.logger.MsoLogger
34 import org.onap.so.openpojo.rules.HasToStringRule
35 import org.onap.so.rest.APIResponse;
36 import org.onap.so.rest.RESTClient
37 import org.onap.so.rest.RESTConfig
41 private static final MsoLogger msoLogger = MsoLogger.getMsoLogger(MsoLogger.Catalog.BPEL, AaiUtil.class);
44 public MsoUtils utils = new MsoUtils()
45 public static final String AAI_NAMESPACE_STRING_KEY = 'mso.workflow.global.default.aai.namespace'
46 public static final String DEFAULT_VERSION_KEY = 'mso.workflow.global.default.aai.version'
48 private String aaiNamespace = null;
50 private AbstractServiceTaskProcessor taskProcessor
52 public AaiUtil(AbstractServiceTaskProcessor taskProcessor) {
53 this.taskProcessor = taskProcessor
56 public String getBusinessSPPartnerUri(DelegateExecution execution) {
57 def uri = getUri(execution, 'sp-partner')
58 msoLogger.debug('AaiUtil.getBusinessSPPartnerUri() - AAI URI: ' + uri)
62 public String getVersion(DelegateExecution execution, resourceName, processKey) {
63 def versionWithResourceKey = "mso.workflow.default.aai.${resourceName}.version"
64 def versionWithProcessKey = "mso.workflow.custom.${processKey}.aai.version"
66 def version = UrnPropertiesReader.getVariable(versionWithProcessKey, execution)
68 msoLogger.debug("AaiUtil.getVersion() - using flow specific ${versionWithProcessKey}=${version}")
72 version = UrnPropertiesReader.getVariable(versionWithResourceKey, execution)
74 msoLogger.debug("AaiUtil.getVersion() - using resource specific ${versionWithResourceKey}=${version}")
78 version = UrnPropertiesReader.getVariable(DEFAULT_VERSION_KEY, execution)
80 msoLogger.debug("AaiUtil.getVersion() - using default version ${DEFAULT_VERSION_KEY}=${version}")
84 (new ExceptionUtil()).buildAndThrowWorkflowException(execution, 9999, "Internal Error: One of the following should be defined in MSO URN properties file: ${versionWithResourceKey}, ${versionWithProcessKey}, ${DEFAULT_VERSION_KEY}")
87 public String createAaiUri(AAIUri uri) {
88 return createAaiUri(AAIVersion.valueOf('V' + UrnPropertiesReader.getVariable(DEFAULT_VERSION_KEY)), uri)
90 public String createAaiUri(AAIVersion version, AAIUri uri) {
91 String endpoint = UrnPropertiesReader.getVariable("aai.endpoint")
92 String result = UriBuilder.fromUri(endpoint).path('aai').path(version.toString()).build().toString()
93 return UriBuilder.fromUri(result + uri.build().toString()).build().toString()
96 public String setNamespace(DelegateExecution execution) {
97 def key = AAI_NAMESPACE_STRING_KEY
98 aaiNamespace = UrnPropertiesReader.getVariable(key, execution)
99 if (aaiNamespace == null ) {
100 (new ExceptionUtil()).buildAndThrowWorkflowException(execution, 9999, 'Internal Error: AAI URI entry for ' + key + ' not defined in the MSO URN properties file')
104 public String getNamespace() {
105 return getNamespace(AAIVersion.valueOf('V' + UrnPropertiesReader.getVariable(DEFAULT_VERSION_KEY)))
108 public String getNamespace(AAIVersion version) {
109 String namespace = UrnPropertiesReader.getVariable(AAI_NAMESPACE_STRING_KEY)
110 if (namespace == null) {
111 throw new Exception('Internal Error: AAI Namespace has not been set yet. A getUri() method needs to be invoked first.')
114 return namespace + version
117 * This method can be used for getting the building namespace out of uri.
118 * NOTE: A getUri() method needs to be invoked first.
119 * Alternative method is the getNamespaceFromUri(DelegateExecution execution, String uri)
120 * return namespace (plus version from uri)
126 public String getNamespaceFromUri(String uri) {
127 String namespace = UrnPropertiesReader.getVariable(AAI_NAMESPACE_STRING_KEY)
128 if (namespace == null) {
129 throw new Exception('Internal Error: AAI Namespace has not been set yet. A getUri() method needs to be invoked first.')
132 String version = getVersionFromUri(uri)
133 return namespace + "v"+version
140 * This method can be used for building namespace with aai version out of uri.
141 * NOTE: 2 arguments: DelegateExecution execution & String uri
147 public String getNamespaceFromUri(DelegateExecution execution, String uri) {
148 String namespace = UrnPropertiesReader.getVariable(AAI_NAMESPACE_STRING_KEY, execution)
149 if (namespace == null ) {
150 (new ExceptionUtil()).buildAndThrowWorkflowException(execution, 9999, 'Internal Error: AAI URI entry for ' + AAI_NAMESPACE_STRING_KEY + ' not defined in the MSO URN properties file')
153 String version = getVersionFromUri(uri)
154 return namespace + "v"+version
161 * This is used to extract the version from uri.
167 private String getVersionFromUri(String uri) {
169 Matcher versionRegEx = Pattern.compile("/v(\\d+)").matcher(uri)
170 if (versionRegEx.find()) {
171 return versionRegEx.group(1);
179 * This reusable method can be used for making AAI Get Calls. The url should
180 * be passed as a parameter along with the execution. The method will
181 * return an APIResponse.
186 * @return APIResponse
189 public APIResponse executeAAIGetCall(DelegateExecution execution, String url){
190 msoLogger.trace("STARTED Execute AAI Get Process ")
191 APIResponse apiResponse = null
193 String uuid = utils.getRequestID()
194 msoLogger.debug("Generated uuid is: " + uuid)
195 msoLogger.debug("URL to be used is: " + url)
197 String basicAuthCred = utils.getBasicAuth(UrnPropertiesReader.getVariable("aai.auth", execution),UrnPropertiesReader.getVariable("mso.msoKey", execution))
199 RESTConfig config = new RESTConfig(url);
200 RESTClient client = new RESTClient(config).addHeader("X-FromAppId", "MSO").addHeader("X-TransactionId", uuid).addHeader("Accept","application/xml");
202 if (basicAuthCred != null && !"".equals(basicAuthCred)) {
203 client.addAuthorizationHeader(basicAuthCred)
205 apiResponse = client.httpGet()
207 msoLogger.trace("COMPLETED Execute AAI Get Process ")
209 msoLogger.debug("Exception occured while executing AAI Get Call. Exception is: \n" + e)
210 (new ExceptionUtil()).buildAndThrowWorkflowException(execution, 9999, e.getMessage())
217 * This reusable method can be used for making AAI httpPut Calls. The url should
218 * be passed as a parameter along with the execution and payload. The method will
219 * return an APIResponse.
225 * @return APIResponse
228 public APIResponse executeAAIPutCall(DelegateExecution execution, String url, String payload){
229 msoLogger.trace("Started Execute AAI Put Process ")
230 APIResponse apiResponse = null
232 String uuid = utils.getRequestID()
233 msoLogger.debug("Generated uuid is: " + uuid)
234 msoLogger.debug("URL to be used is: " + url)
236 String basicAuthCred = utils.getBasicAuth(UrnPropertiesReader.getVariable("aai.auth", execution),UrnPropertiesReader.getVariable("mso.msoKey", execution))
238 RESTConfig config = new RESTConfig(url);
239 RESTClient client = new RESTClient(config).addHeader("X-FromAppId", "MSO").addHeader("X-TransactionId", uuid).addHeader("Content-Type", "application/xml").addHeader("Accept","application/xml");
240 if (basicAuthCred != null && !"".equals(basicAuthCred)) {
241 client.addAuthorizationHeader(basicAuthCred)
243 apiResponse = client.httpPut(payload)
245 msoLogger.trace("Completed Execute AAI Put Process ")
247 msoLogger.error(MessageEnum.BPMN_GENERAL_EXCEPTION_ARG, "Exception occured while executing AAI Put Call.", "BPMN", MsoLogger.getServiceName(), MsoLogger.ErrorCode.UnknownError, e);
248 (new ExceptionUtil()).buildAndThrowWorkflowException(execution, 9999, e.getMessage())
254 * This reusable method can be used for making AAI httpPatch Calls. The url should
255 * be passed as a parameter along with the execution and payload. The method will
256 * return an APIResponse.
262 * @return APIResponse
265 public APIResponse executeAAIPatchCall(DelegateExecution execution, String url, String payload){
266 msoLogger.trace("Started Execute AAI Patch Process ")
267 APIResponse apiResponse = null
269 String uuid = utils.getRequestID()
270 msoLogger.debug("Generated uuid is: " + uuid)
272 msoLogger.debug("URL to be used is: " + url)
274 String basicAuthCred = utils.getBasicAuth(UrnPropertiesReader.getVariable("aai.auth", execution),UrnPropertiesReader.getVariable("mso.msoKey", execution))
276 RESTConfig config = new RESTConfig(url);
277 RESTClient client = new RESTClient(config).addHeader("X-FromAppId", "MSO").addHeader("X-TransactionId", uuid).addHeader("Content-Type", "application/merge-patch+json").addHeader("Accept","application/json");
278 if (basicAuthCred != null && !"".equals(basicAuthCred)) {
279 client.addAuthorizationHeader(basicAuthCred)
281 apiResponse = client.httpPatch(payload)
283 msoLogger.trace("Completed Execute AAI Patch Process ")
285 msoLogger.error(MessageEnum.BPMN_GENERAL_EXCEPTION_ARG, "Exception occured while executing AAI Patch Call.", "BPMN", MsoLogger.getServiceName(), MsoLogger.ErrorCode.UnknownError, e);
286 (new ExceptionUtil()).buildAndThrowWorkflowException(execution, 9999, e.getMessage())
293 * This reusable method can be used for making AAI Delete Calls. The url should
294 * be passed as a parameter along with the execution. The method will
295 * return an APIResponse.
300 * @return APIResponse
303 public APIResponse executeAAIDeleteCall(DelegateExecution execution, String url){
304 msoLogger.trace("Started Execute AAI Delete Process ")
305 APIResponse apiResponse = null
307 String uuid = utils.getRequestID()
308 msoLogger.debug("Generated uuid is: " + uuid)
309 msoLogger.debug("URL to be used is: " + url)
311 String basicAuthCred = utils.getBasicAuth(UrnPropertiesReader.getVariable("aai.auth", execution),UrnPropertiesReader.getVariable("mso.msoKey", execution))
313 RESTConfig config = new RESTConfig(url);
314 RESTClient client = new RESTClient(config).addHeader("X-FromAppId", "MSO").addHeader("X-TransactionId", uuid).addHeader("Accept","application/xml");
315 if (basicAuthCred != null && !"".equals(basicAuthCred)) {
316 client.addAuthorizationHeader(basicAuthCred)
318 apiResponse = client.delete()
320 msoLogger.trace("Completed Execute AAI Delete Process ")
322 msoLogger.error(MessageEnum.BPMN_GENERAL_EXCEPTION_ARG, "Exception occured while executing AAI Delete Call.", "BPMN", MsoLogger.getServiceName(), MsoLogger.ErrorCode.UnknownError, e);
323 (new ExceptionUtil()).buildAndThrowWorkflowException(execution, 9999, e.getMessage())
329 * This reusable method can be used for making AAI Delete Calls. The url should
330 * be passed as a parameter along with the execution. The method will
331 * return an APIResponse.
337 * @return APIResponse
340 public APIResponse executeAAIDeleteCall(DelegateExecution execution, String url, String payload, String authHeader){
341 msoLogger.trace("Started Execute AAI Delete Process ")
342 APIResponse apiResponse = null
344 String uuid = utils.getRequestID()
345 msoLogger.debug("Generated uuid is: " + uuid)
347 msoLogger.debug("URL to be used is: " + url)
349 String basicAuthCred = utils.getBasicAuth(UrnPropertiesReader.getVariable("aai.auth", execution),UrnPropertiesReader.getVariable("mso.msoKey", execution))
350 RESTConfig config = new RESTConfig(url);
351 RESTClient client = new RESTClient(config).addHeader("X-FromAppId", "MSO").addHeader("X-TransactionId", uuid).addHeader("Accept","application/xml").addAuthorizationHeader(authHeader);
352 if (basicAuthCred != null && !"".equals(basicAuthCred)) {
353 client.addAuthorizationHeader(basicAuthCred)
355 apiResponse = client.httpDelete(payload)
357 msoLogger.trace("Completed Execute AAI Delete Process ")
359 msoLogger.error(MessageEnum.BPMN_GENERAL_EXCEPTION_ARG, "Exception occured while executing AAI Delete Call.", "BPMN", MsoLogger.getServiceName(), MsoLogger.ErrorCode.UnknownError, e);
360 (new ExceptionUtil()).buildAndThrowWorkflowException(execution, 9999, e.getMessage())
366 * This reusable method can be used for making AAI Post Calls. The url
367 * and payload should be passed as a parameters along with the execution.
368 * The method will return an APIResponse.
374 * @return APIResponse
377 public APIResponse executeAAIPostCall(DelegateExecution execution, String url, String payload){
378 msoLogger.trace("Started Execute AAI Post Process ")
379 APIResponse apiResponse = null
381 String uuid = utils.getRequestID()
382 msoLogger.debug("Generated uuid is: " + uuid)
383 msoLogger.debug("URL to be used is: " + url)
385 String basicAuthCred = utils.getBasicAuth(UrnPropertiesReader.getVariable("aai.auth", execution),UrnPropertiesReader.getVariable("mso.msoKey", execution))
386 RESTConfig config = new RESTConfig(url);
387 RESTClient client = new RESTClient(config).addHeader("X-FromAppId", "MSO").addHeader("X-TransactionId", uuid).addHeader("Accept","application/xml");
389 if (basicAuthCred != null && !"".equals(basicAuthCred)) {
390 client.addAuthorizationHeader(basicAuthCred)
392 apiResponse = client.httpPost(payload)
394 msoLogger.trace("Completed Execute AAI Post Process ")
396 msoLogger.error(MessageEnum.BPMN_GENERAL_EXCEPTION_ARG, "Exception occured while executing AAI Post Call.", "BPMN", MsoLogger.getServiceName(), MsoLogger.ErrorCode.UnknownError, e);
397 (new ExceptionUtil()).buildAndThrowWorkflowException(execution, 9999, e.getMessage())
403 * This reusable method can be used for making AAI Post Calls. The url
404 * and payload should be passed as a parameters along with the execution.
405 * The method will return an APIResponse.
410 * @param authenticationHeader - addAuthenticationHeader value
411 * @param headerName - name of header you want to add, i.e. addHeader(headerName, headerValue)
412 * @param headerValue - the header's value, i.e. addHeader(headerName, headerValue)
414 * @return APIResponse
417 public APIResponse executeAAIPostCall(DelegateExecution execution, String url, String payload, String authenticationHeaderValue, String headerName, String headerValue){
418 msoLogger.trace("Started Execute AAI Post Process ")
419 APIResponse apiResponse = null
421 msoLogger.debug("URL to be used is: " + url)
423 String basicAuthCred = utils.getBasicAuth(UrnPropertiesReader.getVariable("aai.auth", execution),UrnPropertiesReader.getVariable("mso.msoKey", execution))
425 RESTConfig config = new RESTConfig(url);
426 RESTClient client = new RESTClient(config).addAuthorizationHeader(authenticationHeaderValue).addHeader(headerName, headerValue)
427 if (basicAuthCred != null && !"".equals(basicAuthCred)) {
428 client.addAuthorizationHeader(basicAuthCred)
430 apiResponse = client.httpPost(payload)
432 msoLogger.trace("Completed Execute AAI Post Process ")
434 msoLogger.error(MessageEnum.BPMN_GENERAL_EXCEPTION_ARG, "Exception occured while executing AAI Post Call.", "BPMN", MsoLogger.getServiceName(), MsoLogger.ErrorCode.UnknownError, e);
435 (new ExceptionUtil()).buildAndThrowWorkflowException(execution, 9999, e.getMessage())
441 /* Utility to get the Cloud Region from AAI
442 * Returns String cloud region id, (ie, cloud-region-id)
444 * @param url - url for AAI get cloud region
445 * @param backend - "PO" - real region, or "SDNC" - v2.5 (fake region).
448 public String getAAICloudReqion(DelegateExecution execution, String url, String backend, inputCloudRegion){
451 APIResponse apiResponse = executeAAIGetCall(execution, url)
452 String returnCode = apiResponse.getStatusCode()
453 String aaiResponseAsString = apiResponse.getResponseBodyAsString()
454 msoLogger.debug("Call AAI Cloud Region Return code: " + returnCode)
455 execution.setVariable(execution.getVariable("prefix")+"queryCloudRegionReturnCode", returnCode)
457 if(returnCode == "200"){
458 msoLogger.debug("Call AAI Cloud Region is Successful.")
460 String regionVersion = taskProcessor.utils.getNodeText(aaiResponseAsString, "cloud-region-version")
461 msoLogger.debug("Cloud Region Version from AAI for " + backend + " is: " + regionVersion)
462 if (backend == "PO") {
463 regionId = taskProcessor.utils.getNodeText(aaiResponseAsString, "cloud-region-id")
464 } else { // backend not "PO"
465 if (regionVersion == "2.5" ) {
466 regionId = "AAIAIC25"
468 regionId = taskProcessor.utils.getNodeText(aaiResponseAsString, "cloud-region-id")
471 if(regionId == null){
472 throw new BpmnError("MSOWorkflowException")
474 msoLogger.debug("Cloud Region Id from AAI " + backend + " is: " + regionId)
475 }else if (returnCode == "404"){ // not 200
476 if (backend == "PO") {
477 regionId = inputCloudRegion
478 }else{ // backend not "PO"
479 regionId = "AAIAIC25"
481 msoLogger.debug("Cloud Region value for code='404' of " + backend + " is: " + regionId)
483 msoLogger.error(MessageEnum.BPMN_GENERAL_EXCEPTION_ARG, "Call AAI Cloud Region is NOT Successful.", "BPMN", MsoLogger.getServiceName(), MsoLogger.ErrorCode.UnknownError, "");
484 throw new BpmnError("MSOWorkflowException")
486 }catch(Exception e) {
487 msoLogger.error(MessageEnum.BPMN_GENERAL_EXCEPTION_ARG, "Exception occured while getting the Cloud Reqion.", "BPMN", MsoLogger.getServiceName(), MsoLogger.ErrorCode.UnknownError, e.getMessage());
488 (new ExceptionUtil()).buildAndThrowWorkflowException(execution, 9999, e.getMessage())
493 /* returns xml Node with service-type of searchValue */
494 def searchServiceType(xmlInput, searchValue){
495 def fxml= new XmlSlurper().parseText(xmlInput)
496 def ret = fxml.'**'.find {it.'service-type' == searchValue}
500 /* returns xml Node with service-instance-id of searchValue */
501 def searchServiceInstanceId(xmlInput, searchValue){
502 def ret = xmlInput.'**'.find {it.'service-instance-id' == searchValue}
507 * Get the lowest unused VF Module index from AAI response for a given module type. The criteria for
508 * determining module type is specified by "key" parameter (for example, "persona-model-id"),
509 * the value for filtering is specified in "value" parameter
512 * @param aaiVnfResponse
516 * @return moduleIndex
519 public int getLowestUnusedVfModuleIndexFromAAIVnfResponse(DelegateExecution execution, String aaiVnfResponse, String key, String value) {
520 if (aaiVnfResponse != null) {
521 String vfModulesText = taskProcessor.utils.getNodeXml(aaiVnfResponse, "vf-modules")
522 if (vfModulesText == null || vfModulesText.isEmpty()) {
523 msoLogger.debug("There are no VF modules in this VNF yet")
527 def xmlVfModules= new XmlSlurper().parseText(vfModulesText)
528 def vfModules = xmlVfModules.'**'.findAll {it.name() == "vf-module"}
529 int vfModulesSize = 0
530 if (vfModules != null) {
531 vfModulesSize = vfModules.size()
533 String matchingVfModules = "<vfModules>"
534 for (i in 0..vfModulesSize-1) {
535 def vfModuleXml = groovy.xml.XmlUtil.serialize(vfModules[i])
536 def keyFromAAI = taskProcessor.utils.getNodeText(vfModuleXml, key)
537 if (keyFromAAI != null && keyFromAAI.equals(value)) {
538 matchingVfModules = matchingVfModules + taskProcessor.utils.removeXmlPreamble(vfModuleXml)
541 matchingVfModules = matchingVfModules + "</vfModules>"
542 msoLogger.debug("Matching VF Modules: " + matchingVfModules)
543 String lowestUnusedIndex = taskProcessor.utils.getLowestUnusedIndex(matchingVfModules)
544 return Integer.parseInt(lowestUnusedIndex)