Merge "ensure default flags are set on execution"
[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
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
600 //Prepare requestInfo object
601 JsonObject requestInfo = new JsonObject()
602 requestInfo.addProperty("transactionId", transactionId)
603 requestInfo.addProperty("requestId", requestId)
604 requestInfo.addProperty("callbackUrl", callbackUrl)
605 requestInfo.addProperty("sourceId","SO" )
606 requestInfo.addProperty("timeout", 600)
607 requestInfo.addProperty("numSolutions", 1)
608
609 //Prepare serviceInfo object
610 JsonObject nsstInfo = new JsonObject()
611 nsstInfo.addProperty("UUID", UUID)
612 nsstInfo.addProperty("invariantUUID", invariantUUID)
613 nsstInfo.addProperty("name", name)
614
615 JsonObject json = new JsonObject()
616 json.add("requestInfo", requestInfo)
617 json.add("NSSTInfo", nsstInfo)
618 json.addProperty("sliceProfile", profileJson)
619 return json.toString()
620 }
621 /**
622 * Method to create NSI/NSSI termination request
623 * (OOF response will be synchronous in G-Release)
624 * @param requestId - mso-request-id
625 * @param nxlId        - NSI/NSSI Id to be terminated
626 * @param messageType - Message type for callback correlation
627 * @param serviceInstanceId - NSI/NSSI Id related to nxlId
628 * @return
629 */
630 public String buildTerminateNxiRequest(String requestId,String nxlId, String nxlType, String messageType, String serviceInstanceId) {
631 def transactionId = requestId
632 logger.debug( "transactionId is: " + transactionId)
633 String correlator = requestId
634 String callbackUrl = UrnPropertiesReader.getVariable("mso.adapters.oof.callback.endpoint") + "/" + messageType + "/" + correlator
635 //Prepare Terminate Nxl Json
636 JsonObject json = new JsonObject()
637 json.addProperty("type", nxlType)
638 json.addProperty("NxIId", nxlId)
639  
640 //Prepare requestInfo object
641 JsonObject requestInfo = new JsonObject()
642 requestInfo.addProperty("transactionId", transactionId)
643 requestInfo.addProperty("requestId", requestId)
644 requestInfo.addProperty("callbackUrl", callbackUrl)
645 requestInfo.addProperty("sourceId","SO" )
646 requestInfo.addProperty("timeout", 600)
647  
648 //Prepare addtnlArgs object
649 JsonObject addtnlArgs = new JsonObject()
650 addtnlArgs.addProperty("serviceInstanceId", serviceInstanceId)
651  
652 requestInfo.add("addtnlArgs", addtnlArgs)
653 json.add("requestInfo", requestInfo)
654  
655 return json.toString()
656  
657 }
658
659     public String buildSelectNSIRequest(String requestId, TemplateInfo nstInfo, List<TemplateInfo> nsstInfo,
660                                         String messageType, Map<String, Object> serviceProfile,
661                                         List<SubnetCapability> subnetCapabilities, Integer timeOut, boolean preferReuse){
662
663         def transactionId = requestId
664         String correlator = requestId
665         logger.debug( "transactionId is: " + transactionId)
666
667         String callbackUrl = UrnPropertiesReader.getVariable("mso.adapters.oof.callback.endpoint") + "/" + messageType + "/" + correlator
668
669         NsiReqBody nsiReqBody = new NsiReqBody()
670
671         RequestInfo requestInfo = new RequestInfo()
672         requestInfo.setRequestId(requestId)
673         requestInfo.setTransactionId(transactionId)
674         requestInfo.setCallbackUrl(callbackUrl)
675         requestInfo.setSourceId("so")
676         requestInfo.setTimeout(timeOut)
677         requestInfo.setNumSolutions(100)
678
679         nsiReqBody.setRequestInfo(requestInfo)
680         nsiReqBody.setNSTInfo(nstInfo)
681         nsiReqBody.setServiceProfile(serviceProfile)
682         nsiReqBody.setSubnetCapabilities(subnetCapabilities)
683         nsiReqBody.setNSSTInfo(nsstInfo)
684         nsiReqBody.setPreferReuse(preferReuse)
685
686         return bean2JsonStr(nsiReqBody)
687     }
688
689     public <T> String buildSelectNSSIRequest(String requestId, TemplateInfo nsstInfo, String messageType,
690                                              T sliceProfile, Integer timeOut){
691
692         def transactionId = requestId
693         String correlator = requestId
694         logger.debug( "transactionId is: " + transactionId)
695
696         String callbackUrl = UrnPropertiesReader.getVariable("mso.adapters.oof.callback.endpoint") + "/" + messageType + "/" + correlator
697
698         NssiReqBody nssiReqBody = new NssiReqBody()
699
700         RequestInfo requestInfo = new RequestInfo()
701         requestInfo.setRequestId(requestId)
702         requestInfo.setTransactionId(transactionId)
703         requestInfo.setCallbackUrl(callbackUrl)
704         requestInfo.setSourceId("so")
705         requestInfo.setTimeout(timeOut)
706         requestInfo.setNumSolutions(100)
707
708         nssiReqBody.setRequestInfo(requestInfo)
709         nssiReqBody.setSliceProfile(sliceProfile)
710         nssiReqBody.setNSSTInfo(nsstInfo)
711
712         return bean2JsonStr(nssiReqBody)
713     }
714
715     private static <T> String bean2JsonStr(T t) {
716         return new GsonBuilder().setPrettyPrinting().create().toJson(t)
717     }
718 }