Code changes in BPMN infra for RAN Slice Use case
[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 buildSelectNSSTRequest(String requestId,String messageType, Map<String, Object> profileInfo) {
551         def transactionId = requestId
552         logger.debug( "transactionId is: " + transactionId)
553         String correlator = requestId
554         String callbackUrl = UrnPropertiesReader.getVariable("mso.adapters.oof.callback.endpoint") + "/" + messageType + "/" + correlator
555         ObjectMapper objectMapper = new ObjectMapper()
556         String json = objectMapper.writeValueAsString(profileInfo)
557         StringBuilder response = new StringBuilder()
558         response.append(
559                 "{\n" +
560                         "  \"requestInfo\": {\n" +
561                         "    \"transactionId\": \"${transactionId}\",\n" +
562                         "    \"requestId\": \"${requestId}\",\n" +
563                         "    \"sourceId\": \"so\",\n" +
564                         "    \"timeout\": 600,\n" +
565                         "    \"callbackUrl\": \"${callbackUrl}\"\n" +
566                         "    },\n")
567         response.append(" \"SliceProfile\":")
568         response.append(json)
569         response.append("\n}\n")
570         return response.toString()
571     }
572
573
574     public String buildSelectNSIRequest(String requestId, String nstInfo,String messageType, Map<String, Object> profileInfo){
575
576         def transactionId = requestId
577         logger.debug( "transactionId is: " + transactionId)
578                 String correlator = requestId
579         String callbackUrl = UrnPropertiesReader.getVariable("mso.adapters.oof.callback.endpoint") + "/" + messageType + "/" + correlator
580         ObjectMapper objectMapper = new ObjectMapper();
581         String json = objectMapper.writeValueAsString(profileInfo);
582         StringBuilder response = new StringBuilder();
583         response.append(
584                 "{\n" +
585                         "  \"requestInfo\": {\n" +
586                         "    \"transactionId\": \"${transactionId}\",\n" +
587                         "    \"requestId\": \"${requestId}\",\n" +
588                         "    \"sourceId\": \"so\",\n" +
589                         "    \"timeout\": 600,\n" +
590                         "    \"callbackUrl\": \"${callbackUrl}\"\n" +
591                         "    },\n" +
592                         "  \"serviceInfo\": {\n" +
593                         "    \"serviceInstanceId\": \"\",\n" +
594                         "    \"serviceName\": \"\"\n" +
595                         "    },\n" +
596                         "  \"NSTInfoList\": [\n")
597         response.append(nstInfo);
598         response.append("\n  ],\n")
599         response.append("\n \"serviceProfile\": \n")
600         response.append(json);
601         response.append("\n  }\n")
602         return response.toString()
603     }
604 /**
605 * Method to create select NSSI request
606 * @param requestId - mso-request-id
607 * @param messageType - Message type for callback correlation
608 * @param UUID - UUID of NSST
609 * @param invariantUUID - Invariant UUID of NSST
610 * @param name - name of the NSST model
611 * @param profileInfo - A JSON object containing slice profile parameters
612 * @return
613 */
614 public String buildSelectNSSIRequest(String requestId, String messageType, String UUID,String invariantUUID,
615 String name, Map<String, Object> profileInfo){
616
617 def transactionId = requestId
618 logger.debug( "transactionId is: " + transactionId)
619 String correlator = requestId
620 String callbackUrl = UrnPropertiesReader.getVariable("mso.adapters.oof.callback.endpoint") + "/" + messageType + "/" + correlator
621 ObjectMapper objectMapper = new ObjectMapper();
622 String profileJson = objectMapper.writeValueAsString(profileInfo);
623 JsonParser parser = new JsonParser()
624
625 //Prepare requestInfo object
626 JsonObject requestInfo = new JsonObject()
627 requestInfo.addProperty("transactionId", transactionId)
628 requestInfo.addProperty("requestId", requestId)
629 requestInfo.addProperty("callbackUrl", callbackUrl)
630 requestInfo.addProperty("sourceId","SO" )
631 requestInfo.addProperty("timeout", 600)
632 requestInfo.addProperty("numSolutions", 1)
633
634 //Prepare serviceInfo object
635 JsonObject nsstInfo = new JsonObject()
636 nsstInfo.addProperty("UUID", UUID)
637 nsstInfo.addProperty("invariantUUID", invariantUUID)
638 nsstInfo.addProperty("name", name)
639
640 JsonObject json = new JsonObject()
641 json.add("requestInfo", requestInfo)
642 json.add("NSSTInfo", nsstInfo)
643 json.add("sliceProfile", (JsonObject) parser.parse(profileJson))
644
645 return json.toString()
646 }
647
648 /**
649 * Method to create NSI/NSSI termination request
650 * (OOF response will be synchronous in G-Release)
651 * @param requestId - mso-request-id
652 * @param nxlId        - NSI/NSSI Id to be terminated
653 * @param messageType - Message type for callback correlation
654 * @param serviceInstanceId - NSI/NSSI Id related to nxlId
655 * @return
656 */
657 public String buildTerminateNxiRequest(String requestId,String nxlId, String nxlType, String messageType, String serviceInstanceId) {
658 def transactionId = requestId
659 logger.debug( "transactionId is: " + transactionId)
660 String correlator = requestId
661 String callbackUrl = UrnPropertiesReader.getVariable("mso.adapters.oof.callback.endpoint") + "/" + messageType + "/" + correlator
662 //Prepare Terminate Nxl Json
663 JsonObject json = new JsonObject()
664 json.addProperty("type", nxlType)
665 json.addProperty("NxIId", nxlId)
666  
667 //Prepare requestInfo object
668 JsonObject requestInfo = new JsonObject()
669 requestInfo.addProperty("transactionId", transactionId)
670 requestInfo.addProperty("requestId", requestId)
671 requestInfo.addProperty("callbackUrl", callbackUrl)
672 requestInfo.addProperty("sourceId","SO" )
673 requestInfo.addProperty("timeout", 600)
674  
675 //Prepare addtnlArgs object
676 JsonObject addtnlArgs = new JsonObject()
677 addtnlArgs.addProperty("serviceInstanceId", serviceInstanceId)
678  
679 requestInfo.add("addtnlArgs", addtnlArgs)
680 json.add("requestInfo", requestInfo)
681  
682 return json.toString()
683  
684 }
685
686     public String buildSelectNSIRequest(String requestId, TemplateInfo nstInfo, List<TemplateInfo> nsstInfo,
687                                         String messageType, Map<String, Object> serviceProfile,
688                                         List<SubnetCapability> subnetCapabilities, Integer timeOut, boolean preferReuse){
689
690         def transactionId = requestId
691         String correlator = requestId
692         logger.debug( "transactionId is: " + transactionId)
693
694         String callbackUrl = UrnPropertiesReader.getVariable("mso.adapters.oof.callback.endpoint") + "/" + messageType + "/" + correlator
695
696         NsiReqBody nsiReqBody = new NsiReqBody()
697
698         RequestInfo requestInfo = new RequestInfo()
699         requestInfo.setRequestId(requestId)
700         requestInfo.setTransactionId(transactionId)
701         requestInfo.setCallbackUrl(callbackUrl)
702         requestInfo.setSourceId("so")
703         requestInfo.setTimeout(timeOut)
704         requestInfo.setNumSolutions(1)
705
706         nsiReqBody.setRequestInfo(requestInfo)
707         nsiReqBody.setNSTInfo(nstInfo)
708         nsiReqBody.setServiceProfile(serviceProfile)
709         nsiReqBody.setSubnetCapabilities(subnetCapabilities)
710         nsiReqBody.setNSSTInfo(nsstInfo)
711         nsiReqBody.setPreferReuse(preferReuse)
712
713         return bean2JsonStr(nsiReqBody)
714     }
715
716     public <T> String buildSelectNSSIRequest(String requestId, TemplateInfo nsstInfo, String messageType,
717                                              T sliceProfile, Integer timeOut){
718
719         def transactionId = requestId
720         String correlator = requestId
721         logger.debug( "transactionId is: " + transactionId)
722
723         String callbackUrl = UrnPropertiesReader.getVariable("mso.adapters.oof.callback.endpoint") + "/" + messageType + "/" + correlator
724
725         NssiReqBody nssiReqBody = new NssiReqBody()
726
727         RequestInfo requestInfo = new RequestInfo()
728         requestInfo.setRequestId(requestId)
729         requestInfo.setTransactionId(transactionId)
730         requestInfo.setCallbackUrl(callbackUrl)
731         requestInfo.setSourceId("so")
732         requestInfo.setTimeout(timeOut)
733         requestInfo.setNumSolutions(100)
734
735         nssiReqBody.setRequestInfo(requestInfo)
736         nssiReqBody.setSliceProfile(sliceProfile)
737         nssiReqBody.setNSSTInfo(nsstInfo)
738
739         return bean2JsonStr(nssiReqBody)
740     }
741
742     private static <T> String bean2JsonStr(T t) {
743         return new GsonBuilder().setPrettyPrinting().create().toJson(t)
744     }
745 }