Fix OOF Directives processing
[so.git] / bpmn / MSOCommonBPMN / src / main / groovy / org / onap / so / bpmn / common / scripts / OofUtils.groovy
1 /*-
2  * ============LICENSE_START=======================================================
3  * ONAP - SO
4  * ================================================================================
5  * Copyright (C) 2018 Intel Corp. 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.common.scripts
22
23 import org.camunda.bpm.engine.delegate.DelegateExecution
24 import org.onap.so.bpmn.common.scripts.AbstractServiceTaskProcessor
25 import org.onap.so.bpmn.common.scripts.ExceptionUtil
26 import org.onap.so.bpmn.core.UrnPropertiesReader
27 import org.onap.so.bpmn.core.domain.HomingSolution
28 import org.onap.so.bpmn.core.domain.ModelInfo
29 import org.onap.so.bpmn.core.domain.Resource
30 import org.onap.so.bpmn.core.domain.AllottedResource
31 import org.onap.so.bpmn.core.domain.ServiceDecomposition
32 import org.onap.so.bpmn.core.domain.ServiceInstance
33 import org.onap.so.bpmn.core.domain.Subscriber
34 import org.onap.so.bpmn.core.domain.VnfResource
35 import org.onap.so.bpmn.core.json.JsonUtils
36 import org.onap.so.db.catalog.beans.CloudIdentity
37 import org.onap.so.db.catalog.beans.CloudSite
38 import org.onap.so.db.catalog.client.CatalogDbClient
39 import org.onap.so.rest.APIResponse
40 import org.onap.so.rest.RESTClient
41 import org.onap.so.rest.RESTConfig
42 import org.springframework.http.HttpEntity
43 import org.springframework.http.HttpHeaders
44 import org.springframework.web.util.UriComponentsBuilder
45
46 import javax.ws.rs.core.MediaType
47 import javax.ws.rs.core.UriBuilder
48
49 import static org.onap.so.bpmn.common.scripts.GenericUtils.*
50
51 class OofUtils {
52     ExceptionUtil exceptionUtil = new ExceptionUtil()
53     JsonUtils jsonUtil = new JsonUtils()
54
55     private AbstractServiceTaskProcessor utils
56
57     OofUtils(AbstractServiceTaskProcessor taskProcessor) {
58         this.utils = taskProcessor
59     }
60
61     /**
62      * This method builds the service-agnostic
63      * OOF json request to get a homing solution
64      * and license solution
65      *
66      * @param execution
67      * @param requestId
68      * @param decomposition - ServiceDecomposition object
69      * @param customerLocation -
70      * @param existingCandidates -
71      * @param excludedCandidates -
72      * @param requiredCandidates -
73      *
74      * @return request - OOF v1 payload - https://wiki.onap.org/pages/viewpage.action?pageId=25435066
75      */
76     String buildRequest(DelegateExecution execution,
77                         String requestId,
78                         ServiceDecomposition decomposition,
79                         Subscriber subscriber = null,
80                         Map customerLocation,
81                         ArrayList existingCandidates = null,
82                         ArrayList excludedCandidates = null,
83                         ArrayList requiredCandidates = null) {
84         def isDebugEnabled = execution.getVariable("isDebugLogEnabled")
85         utils.log("DEBUG", "Started Building OOF Request", isDebugEnabled)
86         String callbackEndpoint = UrnPropertiesReader.getVariable("mso.oof.callbackEndpoint", execution)
87         utils.log("DEBUG", "mso.oof.callbackEndpoint is: " + callbackEndpoint, isDebugEnabled)
88         try {
89             def callbackUrl = utils.createHomingCallbackURL(callbackEndpoint, "oofResponse", requestId)
90             utils.log("DEBUG", "callbackUrl is: " + callbackUrl, isDebugEnabled)
91
92
93             def transactionId = requestId
94             utils.log("DEBUG", "transactionId is: " + transactionId, isDebugEnabled)
95             //ServiceInstance Info
96             ServiceInstance serviceInstance = decomposition.getServiceInstance()
97             def serviceInstanceId = ""
98             def serviceName = ""
99
100             serviceInstanceId = execution.getVariable("serviceInstanceId")
101             utils.log("DEBUG", "serviceInstanceId is: " + serviceInstanceId, isDebugEnabled)
102             serviceName = execution.getVariable("subscriptionServiceType")
103             utils.log("DEBUG", "serviceName is: " + serviceName, isDebugEnabled)
104
105             if (serviceInstanceId == null || serviceInstanceId == "null") {
106                 utils.log("DEBUG", "Unable to obtain Service Instance Id", isDebugEnabled)
107                 exceptionUtil.buildAndThrowWorkflowException(execution, 400, "Internal Error - Unable to " +
108                         "obtain Service Instance Id, execution.getVariable(\"serviceInstanceId\") is null")
109             }
110             if (serviceName == null || serviceName == "null") {
111                 utils.log("DEBUG", "Unable to obtain Service Name", isDebugEnabled)
112                 exceptionUtil.buildAndThrowWorkflowException(execution, 400, "Internal Error - Unable to " +
113                         "obtain Service Name, execution.getVariable(\"subscriptionServiceType\") is null")
114             }
115             //Model Info
116             ModelInfo model = decomposition.getModelInfo()
117             utils.log("DEBUG", "ModelInfo: " + model.toString(), isDebugEnabled)
118             String modelType = model.getModelType()
119             String modelInvariantId = model.getModelInvariantUuid()
120             String modelVersionId = model.getModelUuid()
121             String modelName = model.getModelName()
122             String modelVersion = model.getModelVersion()
123             //Subscriber Info
124             String subscriberId = ""
125             String subscriberName = ""
126             String commonSiteId = ""
127             if (subscriber != null) {
128                 subscriberId = subscriber.getGlobalId()
129                 subscriberName = subscriber.getName()
130                 commonSiteId = subscriber.getCommonSiteId()
131             }
132
133             //Determine RequestType
134             //TODO Figure out better way to determine this
135             String requestType = "create"
136             List<Resource> resources = decomposition.getServiceResources()
137             for (Resource r : resources) {
138                 HomingSolution currentSolution = (HomingSolution) r.getCurrentHomingSolution()
139                 if (currentSolution != null) {
140                     requestType = "speed changed"
141                 }
142             }
143
144             //Demands
145             String placementDemands = ""
146             StringBuilder sb = new StringBuilder()
147             List<AllottedResource> allottedResourceList = decomposition.getAllottedResources()
148             List<VnfResource> vnfResourceList = decomposition.getVnfResources()
149
150             if (allottedResourceList == null || allottedResourceList.isEmpty()) {
151                 utils.log("DEBUG", "Allotted Resources List is empty - will try to get service VNFs instead.",
152                         isDebugEnabled)
153             } else {
154                 for (AllottedResource resource : allottedResourceList) {
155                     utils.log("DEBUG", "Allotted Resource: " + resource.toString(),
156                             isDebugEnabled)
157                     def serviceResourceId = resource.getResourceId()
158                     def toscaNodeType = resource.getToscaNodeType()
159                     def resourceModuleName = toscaNodeType.substring(toscaNodeType.lastIndexOf(".") + 1)
160                     def resourceModelInvariantId = resource.getModelInfo().getModelInvariantUuid()
161                     def resourceModelVersionId = resource.getModelInfo().getModelUuid()
162                     def resourceModelName = resource.getModelInfo().getModelName()
163                     def resourceModelVersion = resource.getModelInfo().getModelVersion()
164                     def resourceModelType = resource.getModelInfo().getModelType()
165                     def tenantId = execution.getVariable("tenantId")
166                     def requiredCandidatesJson = ""
167
168                     requiredCandidatesJson = createCandidateJson(
169                             existingCandidates,
170                             excludedCandidates,
171                             requiredCandidates)
172
173                     String demand =
174                             "      {\n" +
175                                     "      \"resourceModuleName\": \"${resourceModuleName}\",\n" +
176                                     "      \"serviceResourceId\": \"${serviceResourceId}\",\n" +
177                                     "      \"tenantId\": \"${tenantId}\",\n" +
178                                     "      \"resourceModelInfo\": {\n" +
179                                     "        \"modelInvariantId\": \"${resourceModelInvariantId}\",\n" +
180                                     "        \"modelVersionId\": \"${resourceModelVersionId}\",\n" +
181                                     "        \"modelName\": \"${resourceModelName}\",\n" +
182                                     "        \"modelType\": \"${resourceModelType}\",\n" +
183                                     "        \"modelVersion\": \"${resourceModelVersion}\",\n" +
184                                     "        \"modelCustomizationName\": \"\"\n" +
185                                     "        }" + requiredCandidatesJson + "\n" +
186                                     "      },"
187
188                     placementDemands = sb.append(demand)
189                 }
190             }
191
192             if (vnfResourceList == null || vnfResourceList.isEmpty()) {
193                 utils.log("DEBUG", "VNF Resources List is empty",
194                         isDebugEnabled)
195             } else {
196
197                 for (VnfResource vnfResource : vnfResourceList) {
198                     utils.log("DEBUG", "VNF Resource: " + vnfResource.toString(),
199                             isDebugEnabled)
200                     ModelInfo vnfResourceModelInfo = vnfResource.getModelInfo()
201                     def toscaNodeType = vnfResource.getToscaNodeType()
202                     def resourceModuleName = toscaNodeType.substring(toscaNodeType.lastIndexOf(".") + 1)
203                     def serviceResourceId = vnfResource.getResourceId()
204                     def resourceModelInvariantId = vnfResourceModelInfo.getModelInvariantUuid()
205                     def resourceModelName = vnfResourceModelInfo.getModelName()
206                     def resourceModelVersion = vnfResourceModelInfo.getModelVersion()
207                     def resourceModelVersionId = vnfResourceModelInfo.getModelUuid()
208                     def resourceModelType = vnfResourceModelInfo.getModelType()
209                     def tenantId = execution.getVariable("tenantId")
210                     def requiredCandidatesJson = ""
211
212
213                     String placementDemand =
214                             "      {\n" +
215                                     "      \"resourceModuleName\": \"${resourceModuleName}\",\n" +
216                                     "      \"serviceResourceId\": \"${serviceResourceId}\",\n" +
217                                     "      \"tenantId\": \"${tenantId}\",\n" +
218                                     "      \"resourceModelInfo\": {\n" +
219                                     "        \"modelInvariantId\": \"${resourceModelInvariantId}\",\n" +
220                                     "        \"modelVersionId\": \"${resourceModelVersionId}\",\n" +
221                                     "        \"modelName\": \"${resourceModelName}\",\n" +
222                                     "        \"modelType\": \"${resourceModelType}\",\n" +
223                                     "        \"modelVersion\": \"${resourceModelVersion}\",\n" +
224                                     "        \"modelCustomizationName\": \"\"\n" +
225                                     "        }" + requiredCandidatesJson + "\n" +
226                                     "      },"
227
228                     placementDemands = sb.append(placementDemand)
229                 }
230                 placementDemands = placementDemands.substring(0, placementDemands.length() - 1)
231             }
232
233             /* Commenting Out Licensing as OOF doesn't support for Beijing
234         String licenseDemands = ""
235         sb = new StringBuilder()
236         if (vnfResourceList.isEmpty() || vnfResourceList == null) {
237             utils.log("DEBUG", "Vnf Resources List is Empty", isDebugEnabled)
238         } else {
239             for (VnfResource vnfResource : vnfResourceList) {
240                 ModelInfo vnfResourceModelInfo = vnfResource.getModelInfo()
241                 def resourceInstanceType = vnfResource.getResourceType()
242                 def serviceResourceId = vnfResource.getResourceId()
243                 def resourceModuleName = vnfResource.getResourceType()
244                 def resouceModelInvariantId = vnfResourceModelInfo.getModelInvariantUuid()
245                 def resouceModelName = vnfResourceModelInfo.getModelName()
246                 def resouceModelVersion = vnfResourceModelInfo.getModelVersion()
247                 def resouceModelVersionId = vnfResourceModelInfo.getModelUuid()
248                 def resouceModelType = vnfResourceModelInfo.getModelType()
249
250                 // TODO Add Existing Licenses to demand
251                 //"existingLicenses": {
252                 //"entitlementPoolUUID": ["87257b49-9602-4ca1-9817-094e52bc873b",
253                 // "43257b49-9602-4fe5-9337-094e52bc9435"],
254                 //"licenseKeyGroupUUID": ["87257b49-9602-4ca1-9817-094e52bc873b",
255                 // "43257b49-9602-4fe5-9337-094e52bc9435"]
256                 //}
257
258                     String licenseDemand =
259                         "{\n" +
260                         "\"resourceModuleName\": \"${resourceModuleName}\",\n" +
261                         "\"serviceResourceId\": \"${serviceResourceId}\",\n" +
262                         "\"resourceInstanceType\": \"${resourceInstanceType}\",\n" +
263                         "\"resourceModelInfo\": {\n" +
264                         "  \"modelInvariantId\": \"${resouceModelInvariantId}\",\n" +
265                         "  \"modelVersionId\": \"${resouceModelVersionId}\",\n" +
266                         "  \"modelName\": \"${resouceModelName}\",\n" +
267                         "  \"modelType\": \"${resouceModelType}\",\n" +
268                         "  \"modelVersion\": \"${resouceModelVersion}\",\n" +
269                         "  \"modelCustomizationName\": \"\"\n" +
270                         "  }\n"
271                         "},"
272
273                 licenseDemands = sb.append(licenseDemand)
274             }
275             licenseDemands = licenseDemands.substring(0, licenseDemands.length() - 1)
276         }*/
277
278             String request =
279                     "{\n" +
280                             "  \"requestInfo\": {\n" +
281                             "    \"transactionId\": \"${transactionId}\",\n" +
282                             "    \"requestId\": \"${requestId}\",\n" +
283                             "    \"callbackUrl\": \"${callbackUrl}\",\n" +
284                             "    \"sourceId\": \"so\",\n" +
285                             "    \"requestType\": \"${requestType}\"," +
286                             "    \"numSolutions\": 1,\n" +
287                             "    \"optimizers\": [\"placement\"],\n" +
288                             "    \"timeout\": 600\n" +
289                             "    },\n" +
290                             "  \"placementInfo\": {\n" +
291                             "    \"requestParameters\": {\n" +
292                             "      \"customerLatitude\": \"${customerLocation.customerLatitude}\",\n" +
293                             "      \"customerLongitude\": \"${customerLocation.customerLongitude}\",\n" +
294                             "      \"customerName\": \"${customerLocation.customerName}\"\n" +
295                             "    }," +
296                             "    \"subscriberInfo\": { \n" +
297                             "      \"globalSubscriberId\": \"${subscriberId}\",\n" +
298                             "      \"subscriberName\": \"${subscriberName}\",\n" +
299                             "      \"subscriberCommonSiteId\": \"${commonSiteId}\"\n" +
300                             "    },\n" +
301                             "    \"placementDemands\": [\n" +
302                             "      ${placementDemands}\n" +
303                             "      ]\n" +
304                             "    },\n" +
305                             "  \"serviceInfo\": {\n" +
306                             "    \"serviceInstanceId\": \"${serviceInstanceId}\",\n" +
307                             "    \"serviceName\": \"${serviceName}\",\n" +
308                             "    \"modelInfo\": {\n" +
309                             "      \"modelType\": \"${modelType}\",\n" +
310                             "      \"modelInvariantId\": \"${modelInvariantId}\",\n" +
311                             "      \"modelVersionId\": \"${modelVersionId}\",\n" +
312                             "      \"modelName\": \"${modelName}\",\n" +
313                             "      \"modelVersion\": \"${modelVersion}\",\n" +
314                             "      \"modelCustomizationName\": \"\"\n" +
315                             "    }\n" +
316                             "  }\n" +
317                             "}"
318
319
320             utils.log("DEBUG", "Completed Building OOF Request", isDebugEnabled)
321             return request
322         } catch (Exception ex) {
323              utils.log("DEBUG", "buildRequest Exception: " + ex, isDebugEnabled)
324         }
325     }
326
327     /**
328      * This method validates the callback response
329      * from OOF. If the response contains an
330      * exception the method will build and throw
331      * a workflow exception.
332      *
333      * @param execution
334      * @param response - the async callback response from oof
335      */
336     Void validateCallbackResponse(DelegateExecution execution, String response) {
337         def isDebugEnabled = execution.getVariable("isDebugLogEnabled")
338         String placements = ""
339         if (isBlank(response)) {
340             exceptionUtil.buildAndThrowWorkflowException(execution, 5000, "OOF Async Callback Response is Empty")
341         } else {
342             if (JsonUtils.jsonElementExist(response, "solutions.placementSolutions")) {
343                 placements = jsonUtil.getJsonValue(response, "solutions.placementSolutions")
344                 if (isBlank(placements) || placements.equalsIgnoreCase("[]")) {
345                     String statusMessage = jsonUtil.getJsonValue(response, "statusMessage")
346                     if (isBlank(statusMessage)) {
347                         utils.log("DEBUG", "Error Occurred in Homing: OOF Async Callback Response does " +
348                                 "not contain placement solution.", isDebugEnabled)
349                         exceptionUtil.buildAndThrowWorkflowException(execution, 400,
350                                 "OOF Async Callback Response does not contain placement solution.")
351                     } else {
352                         utils.log("DEBUG", "Error Occurred in Homing: " + statusMessage, isDebugEnabled)
353                         exceptionUtil.buildAndThrowWorkflowException(execution, 400, statusMessage)
354                     }
355                 } else {
356                     return
357                 }
358             } else if (response.contains("error") || response.contains("Error") ) {
359                 String errorMessage = ""
360                 if (response.contains("policyException")) {
361                     String text = jsonUtil.getJsonValue(response, "requestError.policyException.text")
362                     errorMessage = "OOF Async Callback Response contains a Request Error Policy Exception: " + text
363                 } else if (response.contains("Unable to find any candidate for demand")) {
364                     errorMessage = "OOF Async Callback Response contains error: Unable to find any candidate for " +
365                             "demand *** Response: " + response.toString()
366                 } else if (response.contains("serviceException")) {
367                     String text = jsonUtil.getJsonValue(response, "requestError.serviceException.text")
368                     errorMessage = "OOF Async Callback Response contains a Request Error Service Exception: " + text
369                 } else {
370                     errorMessage = "OOF Async Callback Response contains a Request Error. Unable to determine the Request Error Exception."
371                 }
372                 utils.log("DEBUG", "Error Occurred in Homing: " + errorMessage, isDebugEnabled)
373                 exceptionUtil.buildAndThrowWorkflowException(execution, 400, errorMessage)
374
375             } else {
376                 utils.log("DEBUG", "Error Occurred in Homing: Received an Unknown Async Callback Response from OOF.", isDebugEnabled)
377                 exceptionUtil.buildAndThrowWorkflowException(execution, 2500, "Received an Unknown Async Callback Response from OOF.")
378             }
379         }
380
381     }
382
383     /**
384      * This method creates candidates json for placement Demands.
385      *
386      * @param execution
387      * @param existingCandidates -
388      * @param excludedCandidates -
389      * @param requiredCandidates -
390      *
391      * @return candidatesJson - a JSON string with candidates
392      */
393     String createCandidateJson(ArrayList existingCandidates = null,
394                                ArrayList excludedCandidates = null,
395                                ArrayList requiredCandidates = null) {
396         def candidatesJson = ""
397         def type = ""
398         if (existingCandidates != null && existingCandidates != {}) {
399             sb = new StringBuilder()
400             sb.append(",\n" +
401                     "  \"existingCandidates\": [\n")
402             def existingCandidateJson = ""
403             existingCandidates.each { existingCandidate ->
404                 type = existingCandidate.get('identifierType')
405                 if (type == 'vimId') {
406                     def cloudOwner = existingCandidate.get('cloudOwner')
407                     def cloudRegionId = existingCandidate.get('identifiers')
408                     existingCandidateJson = "{\n" +
409                             "    \"identifierType\": \"vimId\",\n" +
410                             "    \"cloudOwner\": \"${cloudOwner}\",\n" +
411                             "    \"identifiers\": [\"${cloudRegionId}\"]\n" +
412                             "    },"
413                     sb.append(existingCandidateJson)
414                 }
415                 if (type == 'serviceInstanceId') {
416                     def serviceInstanceId = existingCandidate.get('identifiers')
417                     existingCandidateJson += "{\n" +
418                             "    \"identifierType\": \"serviceInstanceId\",\n" +
419                             "    \"identifiers\": [\"${serviceInstanceId}\"]\n" +
420                             "    },"
421                     sb.append(existingCandidateJson)
422                 }
423             }
424             if (existingCandidateJson != "") {
425                 sb.setLength(sb.length() - 1)
426                 candidatesJson = sb.append(",\n],")
427             }
428         }
429         if (excludedCandidates != null && excludedCandidates != {}) {
430             sb = new StringBuilder()
431             sb.append(",\n" +
432                     "  \"excludedCandidates\": [\n")
433             def excludedCandidateJson = ""
434             excludedCandidates.each { excludedCandidate ->
435                 type = excludedCandidate.get('identifierType')
436                 if (type == 'vimId') {
437                     def cloudOwner = excludedCandidate.get('cloudOwner')
438                     def cloudRegionId = excludedCandidate.get('identifiers')
439                     excludedCandidateJson = "{\n" +
440                             "    \"identifierType\": \"vimId\",\n" +
441                             "    \"cloudOwner\": \"${cloudOwner}\",\n" +
442                             "    \"identifiers\": [\"${cloudRegionId}\"]\n" +
443                             "    },"
444                     sb.append(excludedCandidateJson)
445                 }
446                 if (type == 'serviceInstanceId') {
447                     def serviceInstanceId = excludedCandidate.get('identifiers')
448                     excludedCandidateJson += "{\n" +
449                             "    \"identifierType\": \"serviceInstanceId\",\n" +
450                             "    \"identifiers\": [\"${serviceInstanceId}\"]\n" +
451                             "    },"
452                     sb.append(excludedCandidateJson)
453                 }
454             }
455             if (excludedCandidateJson != "") {
456                 sb.setLength(sb.length() - 1)
457                 candidatesJson = sb.append(",\n],")
458             }
459         }
460         if (requiredCandidates != null && requiredCandidates != {}) {
461             sb = new StringBuilder()
462             sb.append(",\n" +
463                     "  \"requiredCandidates\": [\n")
464             def requiredCandidatesJson = ""
465             requiredCandidates.each { requiredCandidate ->
466                 type = requiredCandidate.get('identifierType')
467                 if (type == 'vimId') {
468                     def cloudOwner = requiredCandidate.get('cloudOwner')
469                     def cloudRegionId = requiredCandidate.get('identifiers')
470                     requiredCandidatesJson = "{\n" +
471                             "    \"identifierType\": \"vimId\",\n" +
472                             "    \"cloudOwner\": \"${cloudOwner}\",\n" +
473                             "    \"identifiers\": [\"${cloudRegionId}\"]\n" +
474                             "    },"
475                     sb.append(requiredCandidatesJson)
476                 }
477                 if (type == 'serviceInstanceId') {
478                     def serviceInstanceId = requiredCandidate.get('identifiers')
479                     requiredCandidatesJson += "{\n" +
480                             "    \"identifierType\": \"serviceInstanceId\",\n" +
481                             "    \"identifiers\": [\"${serviceInstanceId}\"]\n" +
482                             "    },"
483                     sb.append(requiredCandidatesJson)
484                 }
485             }
486             if (requiredCandidatesJson != "") {
487                 sb.setLength(sb.length() - 1)
488                 candidatesJson = sb.append(",\n],")
489             }
490         }
491         if (candidatesJson != "") {candidatesJson = candidatesJson.substring(0, candidatesJson.length() - 1)}
492         return candidatesJson
493     }
494     /**
495      * This method creates a cloudsite in catalog database.
496      *
497      * @param CloudSite cloudSite
498      *
499      * @return void
500      */
501     Void createCloudSiteCatalogDb(CloudSite cloudSite, DelegateExecution execution) {
502         def isDebugEnabled = execution.getVariable("isDebugLogEnabled")
503         String endpoint = UrnPropertiesReader.getVariable("mso.catalog.db.spring.endpoint", execution)
504         String auth = UrnPropertiesReader.getVariable("mso.db.auth", execution)
505         CloudSite getCloudsite = null
506
507         CatalogDbClient catalogDbClient = new CatalogDbClient(endpoint, auth)
508         try {
509             getCloudsite = catalogDbClient.getCloudSite(cloudSite.getId().toString())
510         } catch (Exception e) {
511             e = null
512             utils.log("DEBUG", "Could not find cloudsite : " + cloudSite.getId(), isDebugEnabled)
513             utils.log("DEBUG", "Creating cloudSite: " + cloudSite.toString(), isDebugEnabled)
514         }
515         if (getCloudsite?.getId() != cloudSite.getId()) {
516             catalogDbClient.postCloudSite(cloudSite)
517         }
518     }
519
520      String getMsbHost(DelegateExecution execution) {
521          String msbHost = UrnPropertiesReader.getVariable("mso.msb.host", execution, "msb-iag.onap")
522
523          Integer msbPort = UrnPropertiesReader.getVariable("mso.msb.port", execution, "80").toInteger()
524
525          return UriBuilder.fromPath("").host(msbHost).port(msbPort).scheme("http").build().toString()
526     }
527 }