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