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