Merge "save csar file path add directory version"
[so.git] / bpmn / MSOCommonBPMN / src / main / groovy / org / onap / so / bpmn / common / scripts / SniroUtils.groovy
1 /*-
2  * ============LICENSE_START=======================================================
3  * ONAP - SO
4  * ================================================================================
5  * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
6  * ================================================================================
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  *      http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  * ============LICENSE_END=========================================================
19  */
20
21 package org.onap.so.bpmn.common.scripts
22
23 import org.camunda.bpm.engine.delegate.BpmnError
24 import org.camunda.bpm.engine.delegate.DelegateExecution
25 import org.json.JSONArray
26 import org.onap.so.bpmn.common.scripts.AbstractServiceTaskProcessor
27 import org.onap.so.bpmn.common.scripts.ExceptionUtil
28 import org.onap.so.bpmn.common.scripts.MsoUtils
29 import org.onap.so.bpmn.core.domain.*
30 import org.onap.so.bpmn.core.json.JsonUtils
31 import org.apache.commons.lang3.StringUtils
32
33 import static  org.onap.so.bpmn.common.scripts.GenericUtils.*
34
35 import java.time.Duration
36
37 import org.onap.so.logger.MessageEnum
38 import org.onap.so.logger.MsoLogger
39
40
41
42 class SniroUtils{
43         private static final MsoLogger msoLogger = MsoLogger.getMsoLogger(MsoLogger.Catalog.BPEL, SniroUtils.class);
44
45
46         ExceptionUtil exceptionUtil = new ExceptionUtil()
47         JsonUtils jsonUtil = new JsonUtils()
48
49         private AbstractServiceTaskProcessor utils
50
51         public MsoUtils msoUtils = new MsoUtils()
52
53         public SniroUtils(AbstractServiceTaskProcessor taskProcessor) {
54                 this.utils = taskProcessor
55         }
56
57         /**
58          * This method builds the service-agnostic
59          * sniro json request to get a homing solution
60          * and license solution
61          *
62          * @param execution
63          * @param requestId
64          * @param decomposition - ServiceDecomposition object
65          * @param subscriber - Subscriber information
66          * @param homingParams - Homing/Request parameters
67          *
68          * @return request - sniro v2 payload
69          *
70          * @author cb645j
71          */
72         public String buildRequest(DelegateExecution execution, String requestId, ServiceDecomposition decomposition, Subscriber subscriber, String homingParams){
73                 msoLogger.debug("Started Building Sniro Request")
74                 def callbackUrl = utils.createWorkflowMessageAdapterCallbackURL(execution, "SNIROResponse", requestId)
75                 def transactionId = requestId
76                 //ServiceInstance Info
77                 ServiceInstance serviceInstance = decomposition.getServiceInstance()
78                 def serviceInstanceId
79                 if(serviceInstance == null){
80                         msoLogger.debug("Unable to obtain Service Instance Id, ServiceInstance Object is null" )
81                         exceptionUtil.buildAndThrowWorkflowException(execution, 400, "Internal Error - Unable to obtain Service Instance Id, ServiceInstance Object is null")
82                 }else{
83                         serviceInstanceId = serviceInstance.getInstanceId()
84                 }
85                 String type = decomposition.getServiceType()
86                 String serviceType = ""
87                 if(isNotBlank(type)){
88                         serviceType = """ "serviceType": "${type}", """
89                 }
90                 //Model Info
91                 ModelInfo model = decomposition.getModelInfo()
92                 String modelType = model.getModelType()
93                 String modelInvariantId = model.getModelInvariantUuid()
94                 String modelVersionId = model.getModelUuid()
95                 String modelName = model.getModelName()
96                 String modelVersion = model.getModelVersion()
97                 //Subscriber Info
98                 String subscriberId = subscriber.getGlobalId()
99                 String subscriberName = subscriber.getName()
100                 String commonSiteId = subscriber.getCommonSiteId()
101                 //OrderInfo
102                 String orderInfo
103                 if(!isBlank(homingParams)){
104                         orderInfo = homingParams.replaceAll("\"", "\\\\\"").replaceAll("\n", "").replaceAll("\r", "")
105                         orderInfo = StringUtils.normalizeSpace(orderInfo)
106                 }
107
108                 //Determine RequestType
109                 //TODO Implement better way to determine this
110                 String requestType = "initial"
111                 List<Resource> resources = decomposition.getServiceResources()
112                 for(Resource r:resources){
113                         HomingSolution currentSolution = r.getCurrentHomingSolution()
114                         if(currentSolution != null){
115                                 String indicator = currentSolution.getServiceInstanceId()
116                                 if(indicator != null){
117                                         requestType = "speed changed"
118                                 }
119                         }
120                 }
121
122                 String timeout = execution.getVariable("timeout")
123                 Duration d = Duration.parse(timeout);
124                 long timeoutSeconds = d.getSeconds();
125
126                 //Demands
127                 String placementDemands = ""
128                 StringBuilder sb = new StringBuilder()
129                 List<Resource> resourceList = decomposition.getAllottedResources()
130                 List<VnfResource> vnfResourceList = decomposition.getVnfResources()
131
132                 //TODO should be service agnostic so this is just a temp solution to all vnfs to be sent in placement container for adiod
133                 if(resourceList.isEmpty() || resourceList == null){
134                         search : {
135                                 for(VnfResource vnf : vnfResourceList){
136                                         if(StringUtils.containsIgnoreCase(vnf.getNfRole(), "vce") || StringUtils.containsIgnoreCase(vnf.getNfRole(), "vpe")){
137                                                 resourceList = decomposition.getVnfResources()
138                                                 break search
139                                         }
140                                 }
141                         }
142                 }
143
144                 if(resourceList.isEmpty() || resourceList == null){
145                         msoLogger.debug("Resources List is Empty")
146                 }else{
147                         for(Resource resource:resourceList){
148                                 ModelInfo resourceModelInfo = resource.getModelInfo()
149                                 ResourceInstance resourceInstance = resource.getResourceInstance()
150                                 def resourceInstanceType = resource.getResourceType()
151                                 def serviceResourceId = resource.getResourceId() //TODO - resourceId versus instanceId - should be what is put in AAI, whatever we put here will be what is in response, used to correlate
152                                 def resourceModuleName = resourceModelInfo.getModelInstanceName()
153                                 def resouceModelCustomizationId = resourceModelInfo.getModelCustomizationUuid()
154                                 def resouceModelInvariantId = resourceModelInfo.getModelInvariantUuid()
155                                 def resouceModelName = resourceModelInfo.getModelName()
156                                 def resouceModelVersion = resourceModelInfo.getModelVersion()
157                                 def resouceModelVersionId = resourceModelInfo.getModelUuid()
158                                 def resouceModelType = resourceModelInfo.getModelType()
159                                 def tenantId = "" //Optional
160                                 def tenantName = "" //Optional
161
162
163                                 String existingPlacement = ""
164                                 HomingSolution currentPlacement = resource.getCurrentHomingSolution()
165                                 if(currentPlacement != null){
166                                         String homedServiceInstanceId = currentPlacement.getServiceInstanceId()
167                                         existingPlacement =
168                                         ""","existingPlacement": {
169                            "serviceInstanceId": "${homedServiceInstanceId}"
170                     }"""
171                                 }
172
173
174                                 String demand =
175                                         """{
176                                                 "resourceInstanceType": "${resourceInstanceType}",
177                                                 "serviceResourceId": "${serviceResourceId}",
178                                                 "resourceModuleName": "${resourceModuleName}",
179                                                 "resourceModelInfo": {
180                                                         "modelCustomizationId": "${resouceModelCustomizationId}",
181                                                         "modelInvariantId": "${resouceModelInvariantId}",
182                                                         "modelName": "${resouceModelName}",
183                                                         "modelVersion": "${resouceModelVersion}",
184                                                         "modelVersionId": "${resouceModelVersionId}",
185                                                         "modelType": "${resouceModelType}"
186                                                 },
187                                                 "tenantId": "${tenantId}",
188                                                 "tenantName": "${tenantName}"
189                                                 ${existingPlacement}
190                                         },"""
191
192                                 placementDemands = sb.append(demand)
193                         }
194                         placementDemands = placementDemands.substring(0, placementDemands.length() - 1);
195                 }
196
197                 String licenseDemands = ""
198                 sb = new StringBuilder()
199                 if(vnfResourceList.isEmpty() || vnfResourceList == null){
200                         msoLogger.debug("Vnf Resources List is Empty")
201                 }else{
202                         for(VnfResource vnfResource:vnfResourceList){
203                                 ModelInfo vnfResourceModelInfo = vnfResource.getModelInfo()
204                                 ResourceInstance vnfResourceInstance = vnfResource.getResourceInstance()
205                                 def resourceInstanceType = vnfResource.getResourceType()
206                                 def serviceResourceId = vnfResource.getResourceId()
207                                 def resourceModuleName = vnfResourceModelInfo.getModelInstanceName()
208                                 def resouceModelCustomizationId = vnfResourceModelInfo.getModelCustomizationUuid()
209                                 def resouceModelInvariantId = vnfResourceModelInfo.getModelInvariantUuid()
210                                 def resouceModelName = vnfResourceModelInfo.getModelName()
211                                 def resouceModelVersion = vnfResourceModelInfo.getModelVersion()
212                                 def resouceModelVersionId = vnfResourceModelInfo.getModelUuid()
213                                 def resouceModelType = vnfResourceModelInfo.getModelType()
214
215                                 String curentLicenseJson = ""
216                                 HomingSolution currentSol = vnfResource.getCurrentHomingSolution()
217                                 if(currentSol != null){
218                                         JSONArray entitlementPoolList = currentSol.getLicense().getEntitlementPoolListAsString()
219                                         JSONArray licenseKeyGroupList = currentSol.getLicense().getLicenseKeyGroupListAsString()
220                                         curentLicenseJson =
221                                         """ ,"existingLicense": {
222                                  "entitlementPoolUUID":
223                                                                         ${entitlementPoolList},
224                                  "licenseKeyGroupUUID":
225                                                                         ${licenseKeyGroupList}
226
227                            }"""
228                                 }
229
230                                 String demand =
231                                 """{
232                                                 "resourceInstanceType": "${resourceInstanceType}",
233                                                 "serviceResourceId": "${serviceResourceId}",
234                                                 "resourceModuleName": "${resourceModuleName}",
235                                                 "resourceModelInfo": {
236                                                         "modelCustomizationId": "${resouceModelCustomizationId}",
237                                                         "modelInvariantId": "${resouceModelInvariantId}",
238                                                         "modelName": "${resouceModelName}",
239                                                         "modelVersion": "${resouceModelVersion}",
240                                                         "modelVersionId": "${resouceModelVersionId}",
241                                                         "modelType": "${resouceModelType}"
242                                                 }
243                                                 ${curentLicenseJson}
244                                         },"""
245
246                                         licenseDemands = sb.append(demand)
247                         }
248                         licenseDemands = licenseDemands.substring(0, licenseDemands.length() - 1);
249                 }
250
251                 String request =
252                                 """{
253                 "requestInfo": {
254                                 "transactionId": "${transactionId}",
255                                 "requestId": "${requestId}",
256                                 "callbackUrl": "${callbackUrl}",
257                                 "sourceId": "mso",
258                                 "requestType": "${requestType}",
259                                 "optimizer": [
260                                         "placement",
261                                         "license"
262                                 ],
263                                 "numSolutions": 1,
264                                 "timeout": ${timeoutSeconds}
265                                 },
266                 "placementInfo": {
267                         ${serviceType}
268                         "serviceModelInfo": {
269                                 "modelType": "${modelType}",
270                                 "modelInvariantId": "${modelInvariantId}",
271                                 "modelVersionId": "${modelVersionId}",
272                                 "modelName": "${modelName}",
273                                 "modelVersion": "${modelVersion}"
274                                 },
275                         "subscriberInfo": {
276                                 "globalSubscriberId": "${subscriberId}",
277                                 "subscriberName": "${subscriberName}",
278                                 "subscriberCommonSiteId": "${commonSiteId}"
279                                 },
280                         "demandInfo": {
281                                 "placementDemand": [
282                                         ${placementDemands}
283                                 ],
284                                 "licenseDemand": [
285                                         ${licenseDemands}
286                                 ]
287                         },
288                         "policyId": [],
289                         "serviceInstanceId": "${serviceInstanceId}",
290                         "orderInfo": "{\\\"requestParameters\\\": ${orderInfo}}"
291                 }
292           }"""
293
294                 msoLogger.debug("Completed Building Sniro Request")
295                 return request
296         }
297
298         /**
299          * This method validates the async callback response from Sniro.
300          * If the response contains an exception the method will build
301          * and throw a workflow exception.
302          *
303          * @param execution
304          * @param response - sniro async response
305          *
306          * @author cb645j
307          */
308         //TODO needs updating per sniro changes
309         public void validateCallbackResponse(DelegateExecution execution, String response){
310                 try{
311                         String placements = ""
312                         String licenses = ""
313                         if(isBlank(response)){
314                                 exceptionUtil.buildAndThrowWorkflowException(execution, 5000, "Sniro Async Callback Response is Empty")
315                         }else{
316                                 if(JsonUtils.jsonElementExist(response, "solutionInfo")){
317                                         if(JsonUtils.jsonElementExist(response, "solutionInfo.placementInfo")){
318                                                 placements = jsonUtil.getJsonValue(response, "solutionInfo.placementInfo")
319                                         }
320                                         if(JsonUtils.jsonElementExist(response, "solutionInfo.licenseInfo")){
321                                                 licenses = jsonUtil.getJsonValue(response, "solutionInfo.licenseInfo")
322                                         }
323                                         if((isBlank(placements) || placements.equalsIgnoreCase("[]")) && (isBlank(licenses) || licenses.equalsIgnoreCase("[]"))){
324                                                 msoLogger.debug("Sniro Async Response does not contain: licenses or placements")
325                                         }else{
326                                                 return
327                                         }
328                                 }else if(JsonUtils.jsonElementExist(response, "requestError") == true){
329                                         String errorMessage = ""
330                                         if(response.contains("policyException")){
331                                                 String text = jsonUtil.getJsonValue(response, "requestError.policyException.text")
332                                                 errorMessage = "Sniro Async Response contains a policy error: " + text
333                                         }else if(response.contains("serviceException")){
334                                                 String text = jsonUtil.getJsonValue(response, "requestError.serviceException.text")
335                                                 errorMessage = "Sniro Async Response contains a service error: " + text
336                                         }else{
337                                                 errorMessage = "Sniro Async Response contains an error: not provided"
338                                         }
339                                         msoLogger.debug("Sniro Async Response contains an error: " + errorMessage)
340                                         exceptionUtil.buildAndThrowWorkflowException(execution, 400, errorMessage)
341
342                                 }else{
343                                         msoLogger.debug("Sniro Async Response contains an error: not provided")
344                                         exceptionUtil.buildAndThrowWorkflowException(execution, 2500, "Sniro Async Response contains an error: not provided")
345                                 }
346                         }
347                 }catch(BpmnError b){
348                         throw b
349                 }catch(Exception e){
350                         msoLogger.debug("Error encountered within Homing validateCallbackResponse method: " + e)
351                         exceptionUtil.buildAndThrowWorkflowException(execution, 2500, "Internal Error - Occured in Sniro Homing Validate Async Response")
352                 }
353         }
354
355 }