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