Merge "Move Homing Building Block into ONAP"
[so.git] / bpmn / MSOCommonBPMN / src / main / groovy / org / openecomp / mso / bpmn / common / scripts / SNIROUtils.groovy
1 package org.openecomp.mso.bpmn.common.scripts\r
2 \r
3 import org.camunda.bpm.engine.runtime.Execution\r
4 import org.openecomp.mso.bpmn.common.scripts.AbstractServiceTaskProcessor\r
5 import org.openecomp.mso.bpmn.common.scripts.ExceptionUtil\r
6 import org.openecomp.mso.bpmn.common.scripts.MsoUtils\r
7 import org.openecomp.mso.bpmn.core.domain.*\r
8 import org.openecomp.mso.bpmn.core.json.JsonUtils\r
9 import org.apache.commons.lang3.StringUtils\r
10 \r
11 import static  org.openecomp.mso.bpmn.common.scripts.GenericUtils.*\r
12 \r
13 class SNIROUtils{\r
14 \r
15         ExceptionUtil exceptionUtil = new ExceptionUtil()\r
16         JsonUtils jsonUtil = new JsonUtils()\r
17 \r
18         private AbstractServiceTaskProcessor utils\r
19 \r
20         public MsoUtils msoUtils = new MsoUtils()\r
21 \r
22         public SNIROUtils(AbstractServiceTaskProcessor taskProcessor) {\r
23                 this.utils = taskProcessor\r
24         }\r
25 \r
26         /**\r
27          * This method builds the service-agnostic\r
28          * sniro json request to get a homing solution\r
29          * and license solution\r
30          *\r
31          * @param execution\r
32          * @param requestId\r
33          * @param decomposition - ServiceDecomposition object\r
34          * @param subscriber - Subscriber information\r
35          * @param homingParams - Homing/Request parameters\r
36          *\r
37          * @return request - sniro v2 payload\r
38          *\r
39          * @author cb645j\r
40          */\r
41         public String buildRequest(Execution execution, String requestId, ServiceDecomposition decomposition, Subscriber subscriber, String homingParams){\r
42                 def isDebugEnabled = execution.getVariable("isDebugLogEnabled")\r
43                 utils.log("DEBUG", "Started Building Sniro Request", isDebugEnabled)\r
44                 def callbackUrl = utils.createWorkflowMessageAdapterCallbackURL(execution, "SNIROResponse", requestId)\r
45                 def transactionId = requestId\r
46                 //ServiceInstance Info\r
47                 ServiceInstance serviceInstance = decomposition.getServiceInstance()\r
48                 def serviceInstanceId\r
49                 if(serviceInstance == null){\r
50                         utils.log("DEBUG", "Unable to obtain Service Instance Id, ServiceInstance Object is null" , isDebugEnabled)\r
51                         exceptionUtil.buildAndThrowWorkflowException(execution, 400, "Internal Error - Unable to obtain Service Instance Id, ServiceInstance Object is null")\r
52                 }else{\r
53                         serviceInstanceId = serviceInstance.getInstanceId()\r
54                 }\r
55                 //Model Info\r
56                 ModelInfo model = decomposition.getModelInfo()\r
57                 String modelType = model.getModelType()\r
58                 String modelInvariantId = model.getModelInvariantUuid()\r
59                 String modelVersionId = model.getModelUuid()\r
60                 String modelName = model.getModelName()\r
61                 String modelVersion = model.getModelVersion()\r
62                 //Subscriber Info\r
63                 String subscriberId = subscriber.getGlobalId()\r
64                 String subscriberName = subscriber.getName()\r
65                 String commonSiteId = subscriber.getCommonSiteId()\r
66                 //OrderInfo\r
67                 String orderInfo\r
68                 if(!isBlank(homingParams)){\r
69                         orderInfo = homingParams.replaceAll("\"", "\\\\\"").replaceAll("\n", "").replaceAll("\r", "")\r
70                         orderInfo = StringUtils.normalizeSpace(orderInfo)\r
71                 }\r
72 \r
73                 //Demands\r
74                 String placementDemands = ""\r
75                 StringBuilder sb = new StringBuilder()\r
76                 List<Resource> resourceList = decomposition.getServiceAllottedResources()\r
77                 List<VnfResource> vnfResourceList = decomposition.getServiceVnfs()\r
78 \r
79                 // TODO: We should include both alloted resources and service resources in the placementDeamnds- not one or the other.\r
80                 if(resourceList.isEmpty() || resourceList == null){\r
81                         utils.log("DEBUG", "Allotted Resources List is empty - will try to get service VNFs instead.", isDebugEnabled)\r
82                         resourceList = decomposition.getServiceVnfs()\r
83                 }\r
84                 \r
85                 if(resourceList.isEmpty() || resourceList == null){\r
86                         utils.log("DEBUG", "Resources List is Empty", isDebugEnabled)\r
87                 }else{\r
88                         for(Resource resource:resourceList){\r
89                                 ModelInfo resourceModelInfo = resource.getModelInfo()\r
90                                 ResourceInstance resourceInstance = resource.getResourceInstance()\r
91                                 def resourceInstanceType = resource.getResourceType()\r
92                                 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
93                                 def resourceModuleName = resourceModelInfo.getModelInstanceName()\r
94                                 def resouceModelCustomizationId = resourceModelInfo.getModelCustomizationUuid()\r
95                                 def resouceModelInvariantId = resourceModelInfo.getModelInvariantUuid()\r
96                                 def resouceModelName = resourceModelInfo.getModelName()\r
97                                 def resouceModelVersion = resourceModelInfo.getModelVersion()\r
98                                 def resouceModelVersionId = resourceModelInfo.getModelUuid()\r
99                                 def resouceModelType = resourceModelInfo.getModelType()\r
100                                 def tenantId = "" //Optional\r
101                                 def tenantName = "" //Optional\r
102         \r
103                                 String demand =\r
104                                         """{\r
105                                                 "resourceInstanceType": "${resourceInstanceType}",\r
106                                                 "serviceResourceId": "${serviceResourceId}",\r
107                                                 "resourceModuleName": "${resourceModuleName}",\r
108                                                 "resourceModelInfo": {\r
109                                                         "modelCustomizationId": "${resouceModelCustomizationId}",\r
110                                                         "modelInvariantId": "${resouceModelInvariantId}",\r
111                                                         "modelName": "${resouceModelName}",\r
112                                                         "modelVersion": "${resouceModelVersion}",\r
113                                                         "modelVersionId": "${resouceModelVersionId}",\r
114                                                         "modelType": "${resouceModelType}"\r
115                                                 },\r
116                                                 "tenantId": "${tenantId}",\r
117                                                 "tenantName": "${tenantName}"\r
118                                         },"""\r
119         \r
120                                 placementDemands = sb.append(demand)\r
121                         }\r
122                         placementDemands = placementDemands.substring(0, placementDemands.length() - 1);\r
123                 }\r
124 \r
125                 String licenseDemands = ""\r
126                 sb = new StringBuilder()\r
127                 if(vnfResourceList.isEmpty() || vnfResourceList == null){\r
128                         utils.log("DEBUG", "Vnf Resources List is Empty", isDebugEnabled)\r
129                 }else{  \r
130                         for(VnfResource vnfResource:vnfResourceList){\r
131                                 ModelInfo vnfResourceModelInfo = vnfResource.getModelInfo()\r
132                                 ResourceInstance vnfResourceInstance = vnfResource.getResourceInstance()\r
133                                 def resourceInstanceType = vnfResource.getResourceType()\r
134                                 def serviceResourceId = vnfResource.getResourceId()\r
135                                 def resourceModuleName = vnfResourceModelInfo.getModelInstanceName()\r
136                                 def resouceModelCustomizationId = vnfResourceModelInfo.getModelCustomizationUuid()\r
137                                 def resouceModelInvariantId = vnfResourceModelInfo.getModelInvariantUuid()\r
138                                 def resouceModelName = vnfResourceModelInfo.getModelName()\r
139                                 def resouceModelVersion = vnfResourceModelInfo.getModelVersion()\r
140                                 def resouceModelVersionId = vnfResourceModelInfo.getModelUuid()\r
141                                 def resouceModelType = vnfResourceModelInfo.getModelType()\r
142         \r
143                                 String demand =\r
144                                 """{\r
145                                                 "resourceInstanceType": "${resourceInstanceType}",\r
146                                                 "serviceResourceId": "${serviceResourceId}",\r
147                                                 "resourceModuleName": "${resourceModuleName}",\r
148                                                 "resourceModelInfo": {\r
149                                                         "modelCustomizationId": "${resouceModelCustomizationId}",\r
150                                                         "modelInvariantId": "${resouceModelInvariantId}",\r
151                                                         "modelName": "${resouceModelName}",\r
152                                                         "modelVersion": "${resouceModelVersion}",\r
153                                                         "modelVersionId": "${resouceModelVersionId}",\r
154                                                         "modelType": "${resouceModelType}"\r
155                                                 }\r
156                                         },"""\r
157         \r
158                                         licenseDemands = sb.append(demand)\r
159                         }\r
160                         licenseDemands = licenseDemands.substring(0, licenseDemands.length() - 1);\r
161                 }\r
162                         \r
163                 String request =\r
164                                 """{\r
165                 "requestInfo": {\r
166                                 "transactionId": "${transactionId}",\r
167                                 "requestId": "${requestId}",\r
168                                 "callbackUrl": "${callbackUrl}",\r
169                                 "sourceId": "mso",\r
170                                 "optimizer": [\r
171                                         "placement",\r
172                                         "license"\r
173                                 ],\r
174                                 "numSolutions": 1,\r
175                                 "timeout": 600\r
176                                 },\r
177                 "placementInfo": {\r
178                         "serviceModelInfo": {\r
179                                 "modelType": "${modelType}",\r
180                                 "modelInvariantId": "${modelInvariantId}",\r
181                                 "modelVersionId": "${modelVersionId}",\r
182                                 "modelName": "${modelName}",\r
183                                 "modelVersion": "${modelVersion}"\r
184                                 },\r
185                         "subscriberInfo": {\r
186                                 "globalSubscriberId": "${subscriberId}",\r
187                                 "subscriberName": "${subscriberName}",\r
188                                 "subscriberCommonSiteId": "${commonSiteId}"\r
189                                 },\r
190                         "demandInfo": {\r
191                                 "placementDemand": [\r
192                                         ${placementDemands}\r
193                                 ],\r
194                                 "licenseDemand": [\r
195                                         ${licenseDemands}\r
196                                 ]\r
197                         },\r
198                         "policyId": [],\r
199                         "serviceInstanceId": "${serviceInstanceId}",\r
200                         "orderInfo": "{\\\"requestParameters\\\": ${orderInfo}}"\r
201                 }\r
202           }"""\r
203 \r
204                 utils.log("DEBUG", "Completed Building Sniro Request", isDebugEnabled)\r
205                 return request\r
206         }\r
207 \r
208         /**\r
209          * This method validates the callback response\r
210          * from Sniro. If the response contains an\r
211          * exception the method will build and throw\r
212          * a workflow exception.\r
213          *\r
214          * @param execution\r
215          * @param response - the async callback response from sniro\r
216          *\r
217          * @author cb645j\r
218          */\r
219         public void validateCallbackResponse(Execution execution, String response){\r
220                 def isDebugEnabled = execution.getVariable("isDebugLogEnabled")\r
221                 String placements = ""\r
222                 if(isBlank(response)){\r
223                         exceptionUtil.buildAndThrowWorkflowException(execution, 5000, "Sniro Async Callback Response is Empty")\r
224                 }else{\r
225                         if(JsonUtils.jsonElementExist(response, "solutionInfo.placement")){\r
226                                 placements = jsonUtil.getJsonValue(response, "solutionInfo.placement")\r
227                                 if(isBlank(placements) || placements.equalsIgnoreCase("[]")){\r
228                                         String statusMessage = jsonUtil.getJsonValue(response, "statusMessage")\r
229                                         if(isBlank(statusMessage)){\r
230                                                 utils.log("DEBUG", "Error Occured in Homing: Sniro Async Callback Response does not contain placement solution.", isDebugEnabled)\r
231                                                 exceptionUtil.buildAndThrowWorkflowException(execution, 400, "Sniro Async Callback Response does not contain placement solution.")\r
232                                         }else{\r
233                                                 utils.log("DEBUG", "Error Occured in Homing: " + statusMessage, isDebugEnabled)\r
234                                                 exceptionUtil.buildAndThrowWorkflowException(execution, 400, statusMessage)\r
235                                         }\r
236                                 }else{\r
237                                         return\r
238                                 }\r
239                         }else if(JsonUtils.jsonElementExist(response, "requestError") == true){\r
240                                 String errorMessage = ""\r
241                                 if(response.contains("policyException")){\r
242                                         String text = jsonUtil.getJsonValue(response, "requestError.policyException.text")\r
243                                         errorMessage = "Sniro Async Callback Response contains a Request Error Policy Exception: " + text\r
244                                 }else if(response.contains("serviceException")){\r
245                                         String text = jsonUtil.getJsonValue(response, "requestError.serviceException.text")\r
246                                         errorMessage = "Sniro Async Callback Response contains a Request Error Service Exception: " + text\r
247                                 }else{\r
248                                         errorMessage = "Sniro Async Callback Response contains a Request Error. Unable to determine the Request Error Exception."\r
249                                 }\r
250                                 utils.log("DEBUG", "Error Occured in Homing: " + errorMessage, isDebugEnabled)\r
251                                 exceptionUtil.buildAndThrowWorkflowException(execution, 400, errorMessage)\r
252 \r
253                         }else{\r
254                                 utils.log("DEBUG", "Error Occured in Homing: Received an Unknown Async Callback Response from Sniro.", isDebugEnabled)\r
255                                 exceptionUtil.buildAndThrowWorkflowException(execution, 2500, "Received an Unknown Async Callback Response from Sniro.")\r
256                         }\r
257                 }\r
258 \r
259         }\r
260 \r
261 \r
262 }