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