69c1c9f8ac195688ca9d4ca61b8b509a22176fad
[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 com.google.gson.GsonBuilder
26 import org.onap.so.beans.nsmf.oof.NsiReqBody
27 import org.onap.so.beans.nsmf.oof.NssiReqBody
28 import org.onap.so.beans.nsmf.oof.RequestInfo
29 import org.onap.so.beans.nsmf.oof.SubnetCapability
30 import org.onap.so.beans.nsmf.oof.TemplateInfo
31
32 import static org.onap.so.bpmn.common.scripts.GenericUtils.*
33
34 import javax.ws.rs.core.UriBuilder
35
36 import org.camunda.bpm.engine.delegate.DelegateExecution
37 import org.onap.so.bpmn.common.util.OofInfraUtils
38 import org.onap.so.bpmn.core.UrnPropertiesReader
39 import org.onap.so.bpmn.core.domain.AllottedResource
40 import org.onap.so.bpmn.core.domain.HomingSolution
41 import org.onap.so.bpmn.core.domain.ModelInfo
42 import org.onap.so.bpmn.core.domain.Resource
43 import org.onap.so.bpmn.core.domain.ServiceDecomposition
44 import org.onap.so.bpmn.core.domain.ServiceInstance
45 import org.onap.so.bpmn.core.domain.Subscriber
46 import org.onap.so.bpmn.core.domain.VnfResource
47 import org.onap.so.bpmn.core.json.JsonUtils
48 import org.onap.so.db.catalog.beans.CloudSite
49 import org.onap.so.db.catalog.beans.HomingInstance
50 import org.slf4j.Logger
51 import org.slf4j.LoggerFactory
52 import com.google.gson.JsonObject
53 import com.google.gson.JsonParser
54 import com.fasterxml.jackson.databind.ObjectMapper
55
56 class OofUtils {
57     private static final Logger logger = LoggerFactory.getLogger( OofUtils.class);
58
59     ExceptionUtil exceptionUtil = new ExceptionUtil()
60     JsonUtils jsonUtil = new JsonUtils()
61     OofInfraUtils oofInfraUtils = new OofInfraUtils()
62
63     private AbstractServiceTaskProcessor utils
64
65     OofUtils(AbstractServiceTaskProcessor taskProcessor) {
66         this.utils = taskProcessor
67     }
68
69     /**
70      * This method builds the service-agnostic
71      * OOF json request to get a homing solution
72      * and license solution
73      *
74      * @param execution
75      * @param requestId
76      * @param decomposition - ServiceDecomposition object
77      * @param customerLocation -
78      * @param existingCandidates -
79      * @param excludedCandidates -
80      * @param requiredCandidates -
81      *
82      * @return request - OOF v1 payload - https://wiki.onap.org/pages/viewpage.action?pageId=25435066
83      */
84     String buildRequest(DelegateExecution execution,
85                         String requestId,
86                         ServiceDecomposition decomposition,
87                         Subscriber subscriber = null,
88                         Map customerLocation,
89                         ArrayList existingCandidates = null,
90                         ArrayList excludedCandidates = null,
91                         ArrayList requiredCandidates = null) {
92         logger.debug( "Started Building OOF Request")
93         String callbackEndpoint = UrnPropertiesReader.getVariable("mso.oof.callbackEndpoint", execution)
94         logger.debug( "mso.oof.callbackEndpoint is: " + callbackEndpoint)
95         try {
96             def callbackUrl = utils.createHomingCallbackURL(callbackEndpoint, "oofResponse", requestId)
97             logger.debug( "callbackUrl is: " + callbackUrl)
98
99
100             def transactionId = requestId
101             logger.debug( "transactionId is: " + transactionId)
102             //ServiceInstance Info
103             ServiceInstance serviceInstance = decomposition.getServiceInstance()
104             def serviceInstanceId = ""
105             def serviceName = ""
106
107             serviceInstanceId = execution.getVariable("serviceInstanceId")
108             logger.debug( "serviceInstanceId is: " + serviceInstanceId)
109             serviceName = execution.getVariable("subscriptionServiceType")
110             logger.debug( "serviceName is: " + serviceName)
111
112             if (serviceInstanceId == null || serviceInstanceId == "null") {
113                 logger.debug( "Unable to obtain Service Instance Id")
114                 exceptionUtil.buildAndThrowWorkflowException(execution, 400, "Internal Error - Unable to " +
115                         "obtain Service Instance Id, execution.getVariable(\"serviceInstanceId\") is null")
116             }
117             if (serviceName == null || serviceName == "null") {
118                 logger.debug( "Unable to obtain Service Name")
119                 exceptionUtil.buildAndThrowWorkflowException(execution, 400, "Internal Error - Unable to " +
120                         "obtain Service Name, execution.getVariable(\"subscriptionServiceType\") is null")
121             }
122             //Model Info
123             ModelInfo model = decomposition.getModelInfo()
124             logger.debug( "ModelInfo: " + model.toString())
125             String modelType = model.getModelType()
126             String modelInvariantId = model.getModelInvariantUuid()
127             String modelVersionId = model.getModelUuid()
128             String modelName = model.getModelName()
129             String modelVersion = model.getModelVersion()
130             //Subscriber Info
131             String subscriberId = ""
132             String subscriberName = ""
133             String commonSiteId = ""
134             if (subscriber != null) {
135                 subscriberId = subscriber.getGlobalId()
136                 subscriberName = subscriber.getName()
137                 commonSiteId = subscriber.getCommonSiteId()
138             }
139
140             //Determine RequestType
141             //TODO Figure out better way to determine this
142             String requestType = "create"
143             List<Resource> resources = decomposition.getServiceResources()
144             for (Resource r : resources) {
145                 HomingSolution currentSolution = (HomingSolution) r.getCurrentHomingSolution()
146                 if (currentSolution != null) {
147                     requestType = "speed changed"
148                 }
149             }
150
151             //Demands
152             String placementDemands = ""
153             StringBuilder sb = new StringBuilder()
154             List<AllottedResource> allottedResourceList = decomposition.getAllottedResources()
155             List<VnfResource> vnfResourceList = decomposition.getVnfResources()
156
157             if (allottedResourceList == null || allottedResourceList.isEmpty()) {
158                 logger.debug( "Allotted Resources List is empty - will try to get service VNFs instead.")
159             } else {
160                 for (AllottedResource resource : allottedResourceList) {
161                     logger.debug( "Allotted Resource: " + resource.toString())
162                     def serviceResourceId = resource.getResourceId()
163                     def toscaNodeType = resource.getToscaNodeType()
164                     def resourceModuleName = toscaNodeType.substring(toscaNodeType.lastIndexOf(".") + 1)
165                     def resourceModelInvariantId = resource.getModelInfo().getModelInvariantUuid()
166                     def resourceModelVersionId = resource.getModelInfo().getModelUuid()
167                     def resourceModelName = resource.getModelInfo().getModelName()
168                     def resourceModelVersion = resource.getModelInfo().getModelVersion()
169                     def resourceModelType = resource.getModelInfo().getModelType()
170                     def tenantId = execution.getVariable("tenantId")
171                     def requiredCandidatesJson = ""
172
173                     requiredCandidatesJson = createCandidateJson(
174                             existingCandidates,
175                             excludedCandidates,
176                             requiredCandidates)
177
178                     String demand =
179                             "      {\n" +
180                                     "      \"resourceModuleName\": \"${resourceModuleName}\",\n" +
181                                     "      \"serviceResourceId\": \"${serviceResourceId}\",\n" +
182                                     "      \"tenantId\": \"${tenantId}\",\n" +
183                                     "      \"resourceModelInfo\": {\n" +
184                                     "        \"modelInvariantId\": \"${resourceModelInvariantId}\",\n" +
185                                     "        \"modelVersionId\": \"${resourceModelVersionId}\",\n" +
186                                     "        \"modelName\": \"${resourceModelName}\",\n" +
187                                     "        \"modelType\": \"${resourceModelType}\",\n" +
188                                     "        \"modelVersion\": \"${resourceModelVersion}\",\n" +
189                                     "        \"modelCustomizationName\": \"\"\n" +
190                                     "        }" + requiredCandidatesJson + "\n" +
191                                     "      },"
192
193                     placementDemands = sb.append(demand)
194                 }
195             }
196
197             if (vnfResourceList == null || vnfResourceList.isEmpty()) {
198                 logger.debug( "VNF Resources List is empty")
199             } else {
200
201                 for (VnfResource vnfResource : vnfResourceList) {
202                     logger.debug( "VNF Resource: " + vnfResource.toString())
203                     ModelInfo vnfResourceModelInfo = vnfResource.getModelInfo()
204                     def toscaNodeType = vnfResource.getToscaNodeType()
205                     def resourceModuleName = toscaNodeType.substring(toscaNodeType.lastIndexOf(".") + 1)
206                     def serviceResourceId = vnfResource.getResourceId()
207                     def resourceModelInvariantId = vnfResourceModelInfo.getModelInvariantUuid()
208                     def resourceModelName = vnfResourceModelInfo.getModelName()
209                     def resourceModelVersion = vnfResourceModelInfo.getModelVersion()
210                     def resourceModelVersionId = vnfResourceModelInfo.getModelUuid()
211                     def resourceModelType = vnfResourceModelInfo.getModelType()
212                     def tenantId = execution.getVariable("tenantId")
213                     def requiredCandidatesJson = ""
214
215
216                     String placementDemand =
217                             "      {\n" +
218                                     "      \"resourceModuleName\": \"${resourceModuleName}\",\n" +
219                                     "      \"serviceResourceId\": \"${serviceResourceId}\",\n" +
220                                     "      \"tenantId\": \"${tenantId}\",\n" +
221                                     "      \"resourceModelInfo\": {\n" +
222                                     "        \"modelInvariantId\": \"${resourceModelInvariantId}\",\n" +
223                                     "        \"modelVersionId\": \"${resourceModelVersionId}\",\n" +
224                                     "        \"modelName\": \"${resourceModelName}\",\n" +
225                                     "        \"modelType\": \"${resourceModelType}\",\n" +
226                                     "        \"modelVersion\": \"${resourceModelVersion}\",\n" +
227                                     "        \"modelCustomizationName\": \"\"\n" +
228                                     "        }" + requiredCandidatesJson + "\n" +
229                                     "      },"
230
231                     placementDemands = sb.append(placementDemand)
232                 }
233                 placementDemands = placementDemands.substring(0, placementDemands.length() - 1)
234             }
235
236             /* Commenting Out Licensing as OOF doesn't support for Beijing
237         String licenseDemands = ""
238         sb = new StringBuilder()
239         if (vnfResourceList.isEmpty() || vnfResourceList == null) {
240             logger.debug( "Vnf Resources List is Empty")
241         } else {
242             for (VnfResource vnfResource : vnfResourceList) {
243                 ModelInfo vnfResourceModelInfo = vnfResource.getModelInfo()
244                 def resourceInstanceType = vnfResource.getResourceType()
245                 def serviceResourceId = vnfResource.getResourceId()
246                 def resourceModuleName = vnfResource.getResourceType()
247                 def resouceModelInvariantId = vnfResourceModelInfo.getModelInvariantUuid()
248                 def resouceModelName = vnfResourceModelInfo.getModelName()
249                 def resouceModelVersion = vnfResourceModelInfo.getModelVersion()
250                 def resouceModelVersionId = vnfResourceModelInfo.getModelUuid()
251                 def resouceModelType = vnfResourceModelInfo.getModelType()
252
253                 // TODO Add Existing Licenses to demand
254                 //"existingLicenses": {
255                 //"entitlementPoolUUID": ["87257b49-9602-4ca1-9817-094e52bc873b",
256                 // "43257b49-9602-4fe5-9337-094e52bc9435"],
257                 //"licenseKeyGroupUUID": ["87257b49-9602-4ca1-9817-094e52bc873b",
258                 // "43257b49-9602-4fe5-9337-094e52bc9435"]
259                 //}
260
261                     String licenseDemand =
262                         "{\n" +
263                         "\"resourceModuleName\": \"${resourceModuleName}\",\n" +
264                         "\"serviceResourceId\": \"${serviceResourceId}\",\n" +
265                         "\"resourceInstanceType\": \"${resourceInstanceType}\",\n" +
266                         "\"resourceModelInfo\": {\n" +
267                         "  \"modelInvariantId\": \"${resouceModelInvariantId}\",\n" +
268                         "  \"modelVersionId\": \"${resouceModelVersionId}\",\n" +
269                         "  \"modelName\": \"${resouceModelName}\",\n" +
270                         "  \"modelType\": \"${resouceModelType}\",\n" +
271                         "  \"modelVersion\": \"${resouceModelVersion}\",\n" +
272                         "  \"modelCustomizationName\": \"\"\n" +
273                         "  }\n"
274                         "},"
275
276                 licenseDemands = sb.append(licenseDemand)
277             }
278             licenseDemands = licenseDemands.substring(0, licenseDemands.length() - 1)
279         }*/
280
281             String request =
282                     "{\n" +
283                             "  \"requestInfo\": {\n" +
284                             "    \"transactionId\": \"${transactionId}\",\n" +
285                             "    \"requestId\": \"${requestId}\",\n" +
286                             "    \"callbackUrl\": \"${callbackUrl}\",\n" +
287                             "    \"sourceId\": \"so\",\n" +
288                             "    \"requestType\": \"${requestType}\"," +
289                             "    \"numSolutions\": 1,\n" +
290                             "    \"optimizers\": [\"placement\"],\n" +
291                             "    \"timeout\": 600\n" +
292                             "    },\n" +
293                             "  \"placementInfo\": {\n" +
294                             "    \"requestParameters\": {\n" +
295                             "      \"customerLatitude\": \"${customerLocation.customerLatitude}\",\n" +
296                             "      \"customerLongitude\": \"${customerLocation.customerLongitude}\",\n" +
297                             "      \"customerName\": \"${customerLocation.customerName}\"\n" +
298                             "    }," +
299                             "    \"subscriberInfo\": { \n" +
300                             "      \"globalSubscriberId\": \"${subscriberId}\",\n" +
301                             "      \"subscriberName\": \"${subscriberName}\",\n" +
302                             "      \"subscriberCommonSiteId\": \"${commonSiteId}\"\n" +
303                             "    },\n" +
304                             "    \"placementDemands\": [\n" +
305                             "      ${placementDemands}\n" +
306                             "      ]\n" +
307                             "    },\n" +
308                             "  \"serviceInfo\": {\n" +
309                             "    \"serviceInstanceId\": \"${serviceInstanceId}\",\n" +
310                             "    \"serviceName\": \"${serviceName}\",\n" +
311                             "    \"modelInfo\": {\n" +
312                             "      \"modelType\": \"${modelType}\",\n" +
313                             "      \"modelInvariantId\": \"${modelInvariantId}\",\n" +
314                             "      \"modelVersionId\": \"${modelVersionId}\",\n" +
315                             "      \"modelName\": \"${modelName}\",\n" +
316                             "      \"modelVersion\": \"${modelVersion}\",\n" +
317                             "      \"modelCustomizationName\": \"\"\n" +
318                             "    }\n" +
319                             "  }\n" +
320                             "}"
321
322
323             logger.debug( "Completed Building OOF Request")
324             return request
325         } catch (Exception ex) {
326              logger.debug( "buildRequest Exception: " + ex)
327         }
328     }
329
330     /**
331      * This method validates the callback response
332      * from OOF. If the response contains an
333      * exception the method will build and throw
334      * a workflow exception.
335      *
336      * @param execution
337      * @param response - the async callback response from oof
338      */
339     Void validateCallbackResponse(DelegateExecution execution, String response) {
340         String placements = ""
341         if (isBlank(response)) {
342             exceptionUtil.buildAndThrowWorkflowException(execution, 5000, "OOF Async Callback Response is Empty")
343         } else {
344             if (JsonUtils.jsonElementExist(response, "solutions.placementSolutions")) {
345                 placements = jsonUtil.getJsonValue(response, "solutions.placementSolutions")
346                 if (isBlank(placements) || placements.equalsIgnoreCase("[]")) {
347                     String statusMessage = jsonUtil.getJsonValue(response, "statusMessage")
348                     if (isBlank(statusMessage)) {
349                         logger.debug( "Error Occurred in Homing: OOF Async Callback Response does " +
350                                 "not contain placement solution.")
351                         exceptionUtil.buildAndThrowWorkflowException(execution, 400,
352                                 "OOF Async Callback Response does not contain placement solution.")
353                     } else {
354                         logger.debug( "Error Occurred in Homing: " + statusMessage)
355                         exceptionUtil.buildAndThrowWorkflowException(execution, 400, statusMessage)
356                     }
357                 } else {
358                     return
359                 }
360             } else if (response.contains("error") || response.contains("Error") ) {
361                 String errorMessage = ""
362                 if (response.contains("policyException")) {
363                     String text = jsonUtil.getJsonValue(response, "requestError.policyException.text")
364                     errorMessage = "OOF Async Callback Response contains a Request Error Policy Exception: " + text
365                 } else if (response.contains("Unable to find any candidate for demand")) {
366                     errorMessage = "OOF Async Callback Response contains error: Unable to find any candidate for " +
367                             "demand *** Response: " + response.toString()
368                 } else if (response.contains("serviceException")) {
369                     String text = jsonUtil.getJsonValue(response, "requestError.serviceException.text")
370                     errorMessage = "OOF Async Callback Response contains a Request Error Service Exception: " + text
371                 } else {
372                     errorMessage = "OOF Async Callback Response contains a Request Error. Unable to determine the Request Error Exception."
373                 }
374                 logger.debug( "Error Occurred in Homing: " + errorMessage)
375                 exceptionUtil.buildAndThrowWorkflowException(execution, 400, errorMessage)
376
377             } else {
378                 logger.debug( "Error Occurred in Homing: Received an Unknown Async Callback Response from OOF.")
379                 exceptionUtil.buildAndThrowWorkflowException(execution, 2500, "Received an Unknown Async Callback Response from OOF.")
380             }
381         }
382
383     }
384
385     /**
386      * This method creates candidates json for placement Demands.
387      *
388      * @param execution
389      * @param existingCandidates -
390      * @param excludedCandidates -
391      * @param requiredCandidates -
392      *
393      * @return candidatesJson - a JSON string with candidates
394      */
395     String createCandidateJson(ArrayList existingCandidates = null,
396                                ArrayList excludedCandidates = null,
397                                ArrayList requiredCandidates = null) {
398         def candidatesJson = ""
399         def type = ""
400         if (existingCandidates != null && existingCandidates != {}) {
401             sb = new StringBuilder()
402             sb.append(",\n" +
403                     "  \"existingCandidates\": [\n")
404             def existingCandidateJson = ""
405             existingCandidates.each { existingCandidate ->
406                 type = existingCandidate.get('identifierType')
407                 if (type == 'vimId') {
408                     def cloudOwner = existingCandidate.get('cloudOwner')
409                     def cloudRegionId = existingCandidate.get('identifiers')
410                     existingCandidateJson = "{\n" +
411                             "    \"identifierType\": \"vimId\",\n" +
412                             "    \"cloudOwner\": \"${cloudOwner}\",\n" +
413                             "    \"identifiers\": [\"${cloudRegionId}\"]\n" +
414                             "    },"
415                     sb.append(existingCandidateJson)
416                 }
417                 if (type == 'serviceInstanceId') {
418                     def serviceInstanceId = existingCandidate.get('identifiers')
419                     existingCandidateJson += "{\n" +
420                             "    \"identifierType\": \"serviceInstanceId\",\n" +
421                             "    \"identifiers\": [\"${serviceInstanceId}\"]\n" +
422                             "    },"
423                     sb.append(existingCandidateJson)
424                 }
425             }
426             if (existingCandidateJson != "") {
427                 sb.setLength(sb.length() - 1)
428                 candidatesJson = sb.append(",\n],")
429             }
430         }
431         if (excludedCandidates != null && excludedCandidates != {}) {
432             sb = new StringBuilder()
433             sb.append(",\n" +
434                     "  \"excludedCandidates\": [\n")
435             def excludedCandidateJson = ""
436             excludedCandidates.each { excludedCandidate ->
437                 type = excludedCandidate.get('identifierType')
438                 if (type == 'vimId') {
439                     def cloudOwner = excludedCandidate.get('cloudOwner')
440                     def cloudRegionId = excludedCandidate.get('identifiers')
441                     excludedCandidateJson = "{\n" +
442                             "    \"identifierType\": \"vimId\",\n" +
443                             "    \"cloudOwner\": \"${cloudOwner}\",\n" +
444                             "    \"identifiers\": [\"${cloudRegionId}\"]\n" +
445                             "    },"
446                     sb.append(excludedCandidateJson)
447                 }
448                 if (type == 'serviceInstanceId') {
449                     def serviceInstanceId = excludedCandidate.get('identifiers')
450                     excludedCandidateJson += "{\n" +
451                             "    \"identifierType\": \"serviceInstanceId\",\n" +
452                             "    \"identifiers\": [\"${serviceInstanceId}\"]\n" +
453                             "    },"
454                     sb.append(excludedCandidateJson)
455                 }
456             }
457             if (excludedCandidateJson != "") {
458                 sb.setLength(sb.length() - 1)
459                 candidatesJson = sb.append(",\n],")
460             }
461         }
462         if (requiredCandidates != null && requiredCandidates != {}) {
463             sb = new StringBuilder()
464             sb.append(",\n" +
465                     "  \"requiredCandidates\": [\n")
466             def requiredCandidatesJson = ""
467             requiredCandidates.each { requiredCandidate ->
468                 type = requiredCandidate.get('identifierType')
469                 if (type == 'vimId') {
470                     def cloudOwner = requiredCandidate.get('cloudOwner')
471                     def cloudRegionId = requiredCandidate.get('identifiers')
472                     requiredCandidatesJson = "{\n" +
473                             "    \"identifierType\": \"vimId\",\n" +
474                             "    \"cloudOwner\": \"${cloudOwner}\",\n" +
475                             "    \"identifiers\": [\"${cloudRegionId}\"]\n" +
476                             "    },"
477                     sb.append(requiredCandidatesJson)
478                 }
479                 if (type == 'serviceInstanceId') {
480                     def serviceInstanceId = requiredCandidate.get('identifiers')
481                     requiredCandidatesJson += "{\n" +
482                             "    \"identifierType\": \"serviceInstanceId\",\n" +
483                             "    \"identifiers\": [\"${serviceInstanceId}\"]\n" +
484                             "    },"
485                     sb.append(requiredCandidatesJson)
486                 }
487             }
488             if (requiredCandidatesJson != "") {
489                 sb.setLength(sb.length() - 1)
490                 candidatesJson = sb.append(",\n],")
491             }
492         }
493         if (candidatesJson != "") {candidatesJson = candidatesJson.substring(0, candidatesJson.length() - 1)}
494         return candidatesJson
495     }
496
497     /**
498      * This method creates a cloudsite in catalog database.
499      *
500      * @param CloudSite cloudSite
501      *
502      * @return void
503      */
504     Void createCloudSite(CloudSite cloudSite, DelegateExecution execution) {
505         oofInfraUtils.createCloudSite(cloudSite, execution)
506     }
507
508     /**
509      * This method creates a HomingInstance in catalog database.
510      *
511      * @param HomingInstance homingInstance
512      *
513      * @return void
514      */
515     Void createHomingInstance(HomingInstance homingInstance, DelegateExecution execution) {
516         oofInfraUtils.createHomingInstance(homingInstance, execution)
517     }
518
519     String getMsbHost(DelegateExecution execution) {
520         String msbHost = UrnPropertiesReader.getVariable("mso.msb.host", execution, "msb-iag.onap")
521
522         Integer msbPort = UrnPropertiesReader.getVariable("mso.msb.port", execution, "80").toInteger()
523
524         return UriBuilder.fromPath("").host(msbHost).port(msbPort).scheme("http").build().toString()
525     }
526
527     public String buildSelectNSTRequest(String requestId,String messageType, Map<String, Object> profileInfo) {
528         def transactionId = requestId
529         logger.debug( "transactionId is: " + transactionId)
530                 String correlator = requestId
531         String callbackUrl = UrnPropertiesReader.getVariable("mso.adapters.oof.callback.endpoint") + "/" + messageType + "/" + correlator
532         ObjectMapper objectMapper = new ObjectMapper()
533         String json = objectMapper.writeValueAsString(profileInfo)
534         StringBuilder response = new StringBuilder()
535         response.append(
536                 "{\n" +
537                         "  \"requestInfo\": {\n" +
538                         "    \"transactionId\": \"${transactionId}\",\n" +
539                         "    \"requestId\": \"${requestId}\",\n" +
540                         "    \"sourceId\": \"so\",\n" +
541                         "    \"timeout\": 600,\n" +
542                         "    \"callbackUrl\": \"${callbackUrl}\"\n" +
543                         "    },\n")
544         response.append(" \"serviceProfile\":")
545         response.append(json)
546         response.append("\n}\n")
547         return response.toString()
548     }
549
550     public String buildSelectNSIRequest(String requestId, String nstInfo,String messageType, Map<String, Object> profileInfo){
551
552         def transactionId = requestId
553         logger.debug( "transactionId is: " + transactionId)
554                 String correlator = requestId
555         String callbackUrl = UrnPropertiesReader.getVariable("mso.adapters.oof.callback.endpoint") + "/" + messageType + "/" + correlator
556         ObjectMapper objectMapper = new ObjectMapper();
557         String json = objectMapper.writeValueAsString(profileInfo);
558         StringBuilder response = new StringBuilder();
559         response.append(
560                 "{\n" +
561                         "  \"requestInfo\": {\n" +
562                         "    \"transactionId\": \"${transactionId}\",\n" +
563                         "    \"requestId\": \"${requestId}\",\n" +
564                         "    \"sourceId\": \"so\",\n" +
565                         "    \"timeout\": 600,\n" +
566                         "    \"callbackUrl\": \"${callbackUrl}\"\n" +
567                         "    },\n" +
568                         "  \"serviceInfo\": {\n" +
569                         "    \"serviceInstanceId\": \"\",\n" +
570                         "    \"serviceName\": \"\"\n" +
571                         "    },\n" +
572                         "  \"NSTInfoList\": [\n")
573         response.append(nstInfo);
574         response.append("\n  ],\n")
575         response.append("\n \"serviceProfile\": \n")
576         response.append(json);
577         response.append("\n  }\n")
578         return response.toString()
579     }
580 /**
581 * Method to create select NSSI request
582 * @param requestId - mso-request-id
583 * @param messageType - Message type for callback correlation
584 * @param UUID - UUID of NSST
585 * @param invariantUUID - Invariant UUID of NSST
586 * @param name - name of the NSST model
587 * @param profileInfo - A JSON object containing slice profile parameters
588 * @return
589 */
590 public String buildSelectNSSIRequest(String requestId, String messageType, String UUID,String invariantUUID,
591 String name, Map<String, Object> profileInfo){
592
593 def transactionId = requestId
594 logger.debug( "transactionId is: " + transactionId)
595 String correlator = requestId
596 String callbackUrl = UrnPropertiesReader.getVariable("mso.adapters.oof.callback.endpoint") + "/" + messageType + "/" + correlator
597 ObjectMapper objectMapper = new ObjectMapper();
598 String profileJson = objectMapper.writeValueAsString(profileInfo);
599 JsonParser parser = new JsonParser()
600
601 //Prepare requestInfo object
602 JsonObject requestInfo = new JsonObject()
603 requestInfo.addProperty("transactionId", transactionId)
604 requestInfo.addProperty("requestId", requestId)
605 requestInfo.addProperty("callbackUrl", callbackUrl)
606 requestInfo.addProperty("sourceId","SO" )
607 requestInfo.addProperty("timeout", 600)
608 requestInfo.addProperty("numSolutions", 1)
609
610 //Prepare serviceInfo object
611 JsonObject nsstInfo = new JsonObject()
612 nsstInfo.addProperty("UUID", UUID)
613 nsstInfo.addProperty("invariantUUID", invariantUUID)
614 nsstInfo.addProperty("name", name)
615
616 JsonObject json = new JsonObject()
617 json.add("requestInfo", requestInfo)
618 json.add("NSSTInfo", nsstInfo)
619 json.add("sliceProfile", (JsonObject) parser.parse(profileJson))
620
621 return json.toString()
622 }
623
624 /**
625 * Method to create NSI/NSSI termination request
626 * (OOF response will be synchronous in G-Release)
627 * @param requestId - mso-request-id
628 * @param nxlId        - NSI/NSSI Id to be terminated
629 * @param messageType - Message type for callback correlation
630 * @param serviceInstanceId - NSI/NSSI Id related to nxlId
631 * @return
632 */
633 public String buildTerminateNxiRequest(String requestId,String nxlId, String nxlType, String messageType, String serviceInstanceId) {
634 def transactionId = requestId
635 logger.debug( "transactionId is: " + transactionId)
636 String correlator = requestId
637 String callbackUrl = UrnPropertiesReader.getVariable("mso.adapters.oof.callback.endpoint") + "/" + messageType + "/" + correlator
638 //Prepare Terminate Nxl Json
639 JsonObject json = new JsonObject()
640 json.addProperty("type", nxlType)
641 json.addProperty("NxIId", nxlId)
642  
643 //Prepare requestInfo object
644 JsonObject requestInfo = new JsonObject()
645 requestInfo.addProperty("transactionId", transactionId)
646 requestInfo.addProperty("requestId", requestId)
647 requestInfo.addProperty("callbackUrl", callbackUrl)
648 requestInfo.addProperty("sourceId","SO" )
649 requestInfo.addProperty("timeout", 600)
650  
651 //Prepare addtnlArgs object
652 JsonObject addtnlArgs = new JsonObject()
653 addtnlArgs.addProperty("serviceInstanceId", serviceInstanceId)
654  
655 requestInfo.add("addtnlArgs", addtnlArgs)
656 json.add("requestInfo", requestInfo)
657  
658 return json.toString()
659  
660 }
661
662     public String buildSelectNSIRequest(String requestId, TemplateInfo nstInfo, List<TemplateInfo> nsstInfo,
663                                         String messageType, Map<String, Object> serviceProfile,
664                                         List<SubnetCapability> subnetCapabilities, Integer timeOut, boolean preferReuse){
665
666         def transactionId = requestId
667         String correlator = requestId
668         logger.debug( "transactionId is: " + transactionId)
669
670         String callbackUrl = UrnPropertiesReader.getVariable("mso.adapters.oof.callback.endpoint") + "/" + messageType + "/" + correlator
671
672         NsiReqBody nsiReqBody = new NsiReqBody()
673
674         RequestInfo requestInfo = new RequestInfo()
675         requestInfo.setRequestId(requestId)
676         requestInfo.setTransactionId(transactionId)
677         requestInfo.setCallbackUrl(callbackUrl)
678         requestInfo.setSourceId("so")
679         requestInfo.setTimeout(timeOut)
680         requestInfo.setNumSolutions(1)
681
682         nsiReqBody.setRequestInfo(requestInfo)
683         nsiReqBody.setNSTInfo(nstInfo)
684         nsiReqBody.setServiceProfile(serviceProfile)
685         nsiReqBody.setSubnetCapabilities(subnetCapabilities)
686         nsiReqBody.setNSSTInfo(nsstInfo)
687         nsiReqBody.setPreferReuse(preferReuse)
688
689         return bean2JsonStr(nsiReqBody)
690     }
691
692     public <T> String buildSelectNSSIRequest(String requestId, TemplateInfo nsstInfo, String messageType,
693                                              T sliceProfile, Integer timeOut){
694
695         def transactionId = requestId
696         String correlator = requestId
697         logger.debug( "transactionId is: " + transactionId)
698
699         String callbackUrl = UrnPropertiesReader.getVariable("mso.adapters.oof.callback.endpoint") + "/" + messageType + "/" + correlator
700
701         NssiReqBody nssiReqBody = new NssiReqBody()
702
703         RequestInfo requestInfo = new RequestInfo()
704         requestInfo.setRequestId(requestId)
705         requestInfo.setTransactionId(transactionId)
706         requestInfo.setCallbackUrl(callbackUrl)
707         requestInfo.setSourceId("so")
708         requestInfo.setTimeout(timeOut)
709         requestInfo.setNumSolutions(100)
710
711         nssiReqBody.setRequestInfo(requestInfo)
712         nssiReqBody.setSliceProfile(sliceProfile)
713         nssiReqBody.setNSSTInfo(nsstInfo)
714
715         return bean2JsonStr(nssiReqBody)
716     }
717
718     private static <T> String bean2JsonStr(T t) {
719         return new GsonBuilder().setPrettyPrinting().create().toJson(t)
720     }
721 }