Fix OOF Config Ingestion
[so.git] / bpmn / MSOCommonBPMN / src / main / groovy / org / onap / so / bpmn / common / scripts / OofHoming.groovy
1 /*
2  * ============LICENSE_START=======================================================
3  * ONAP - SO
4  * ================================================================================
5  * Copyright (C) 2018 Intel Corp. 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 package org.onap.so.bpmn.common.scripts
21 import org.onap.so.bpmn.core.UrnPropertiesReader
22 import org.camunda.bpm.engine.delegate.BpmnError
23 import org.camunda.bpm.engine.delegate.DelegateExecution
24
25 import org.onap.so.bpmn.common.scripts.AaiUtil
26 import org.onap.so.bpmn.common.scripts.ExceptionUtil
27
28 import org.onap.so.bpmn.core.domain.InventoryType
29 import org.onap.so.bpmn.core.domain.Resource
30 import org.onap.so.bpmn.core.domain.ResourceType
31 import org.onap.so.bpmn.core.domain.ServiceDecomposition
32 import org.onap.so.bpmn.core.domain.Subscriber
33 import org.onap.so.bpmn.core.domain.VnfResource
34 import org.onap.so.bpmn.core.json.JsonUtils
35 import org.onap.so.db.catalog.beans.CloudIdentity
36 import org.onap.so.db.catalog.beans.CloudSite
37 import org.onap.so.rest.APIResponse
38 import org.onap.so.rest.RESTClient
39 import org.onap.so.rest.RESTConfig
40 import org.onap.so.bpmn.common.scripts.AbstractServiceTaskProcessor
41
42 import org.json.JSONArray
43 import org.json.JSONObject
44
45 import static org.onap.so.bpmn.common.scripts.GenericUtils.*
46
47 /**
48  * This class contains the scripts used
49  * by the OOF Homing Subflow building block. The
50  * subflow attempts to home the provided
51  * resources by calling OOF.
52  */
53 class OofHoming extends AbstractServiceTaskProcessor {
54
55     ExceptionUtil exceptionUtil = new ExceptionUtil()
56     JsonUtils jsonUtil = new JsonUtils()
57     OofUtils oofUtils = new OofUtils(this)
58
59     /**
60      * This method validates the incoming variables.
61      * The method then prepares the OOF request
62      * and posts it to OOF's rest api.
63      *
64      * @param execution
65      */
66     public void callOof(DelegateExecution execution) {
67         def isDebugEnabled = execution.getVariable("isDebugLogEnabled")
68         execution.setVariable("prefix", "HOME_")
69         utils.log("DEBUG", "*** Started Homing Call OOF ***", isDebugEnabled)
70         try {
71             execution.setVariable("rollbackData", null)
72             execution.setVariable("rolledBack", false)
73
74             String requestId = execution.getVariable("msoRequestId")
75             utils.log("DEBUG", "Incoming Request Id is: " + requestId, isDebugEnabled)
76             String serviceInstanceId = execution.getVariable("serviceInstanceId")
77             utils.log("DEBUG", "Incoming Service Instance Id is: " + serviceInstanceId, isDebugEnabled)
78             String serviceInstanceName = execution.getVariable("serviceInstanceName")
79             utils.log("DEBUG", "Incoming Service Instance Name is: " + serviceInstanceName, isDebugEnabled)
80             ServiceDecomposition serviceDecomposition = execution.getVariable("serviceDecomposition")
81             utils.log("DEBUG", "Incoming Service Decomposition is: " + serviceDecomposition, isDebugEnabled)
82             String subscriberInfo = execution.getVariable("subscriberInfo")
83             utils.log("DEBUG", "Incoming Subscriber Information is: " + subscriberInfo, isDebugEnabled)
84             Map customerLocation = execution.getVariable("customerLocation")
85             utils.log("DEBUG", "Incoming Customer Location is: " + customerLocation.toString(), isDebugEnabled)
86             String cloudOwner = execution.getVariable("cloudOwner")
87             utils.log("DEBUG", "Incoming cloudOwner is: " + cloudOwner, isDebugEnabled)
88             String cloudRegionId = execution.getVariable("cloudRegionId")
89             utils.log("DEBUG", "Incoming cloudRegionId is: " + cloudRegionId, isDebugEnabled)
90
91             if (isBlank(requestId) ||
92                     isBlank(serviceInstanceId) ||
93                     isBlank(serviceInstanceName) ||
94                     isBlank(serviceDecomposition.toString()) ||
95                     isBlank(customerLocation.toString())) {
96                 exceptionUtil.buildAndThrowWorkflowException(execution, 4000,
97                         "A required input variable is missing or null")
98             } else {
99                 Subscriber subscriber = null
100                 if (isBlank(subscriberInfo)) {
101                     subscriber = new Subscriber("", "", "")
102                 } else {
103                 String subId = jsonUtil.getJsonValue(subscriberInfo, "globalSubscriberId")
104                 String subName = jsonUtil.getJsonValue(subscriberInfo, "subscriberName")
105                 String subCommonSiteId = ""
106                 if (jsonUtil.jsonElementExist(subscriberInfo, "subscriberCommonSiteId")) {
107                     subCommonSiteId = jsonUtil.getJsonValue(subscriberInfo, "subscriberCommonSiteId")
108                 }
109                     subscriber = new Subscriber(subId, subName, subCommonSiteId)
110                 }
111
112                 //Authentication
113                 def authHeader = ""
114                 String basicAuth = UrnPropertiesReader.getVariable("mso.oof.auth", execution)
115                 String msokey = UrnPropertiesReader.getVariable("mso.msoKey", execution)
116
117                 String basicAuthValue = utils.encrypt(basicAuth, msokey)
118                 if (basicAuthValue != null) {
119                     utils.log("DEBUG", "Obtained BasicAuth username and password for OOF Adapter: " + basicAuthValue,
120                             isDebugEnabled)
121                     try {
122                         authHeader = utils.getBasicAuth(basicAuthValue, msokey)
123                         execution.setVariable("BasicAuthHeaderValue", authHeader)
124                     } catch (Exception ex) {
125                         utils.log("DEBUG", "Unable to encode username and password string: " + ex, isDebugEnabled)
126                         exceptionUtil.buildAndThrowWorkflowException(execution, 401, "Internal Error - Unable to " +
127                                 "encode username and password string")
128                     }
129                 } else {
130                     utils.log("DEBUG", "Unable to obtain BasicAuth - BasicAuth value null", isDebugEnabled)
131                     exceptionUtil.buildAndThrowWorkflowException(execution, 401, "Internal Error - BasicAuth " +
132                             "value null")
133                 }
134
135                 //Prepare Callback
136                 String timeout = execution.getVariable("timeout")
137                 if (isBlank(timeout)) {                                 
138                     timeout = UrnPropertiesReader.getVariable("mso.oof.timeout", execution);
139                     if (isBlank(timeout)) {
140                         timeout = "PT30M"
141                     }
142                 }
143                 utils.log("DEBUG", "Async Callback Timeout will be: " + timeout, isDebugEnabled)
144
145                 execution.setVariable("timeout", timeout)
146                 execution.setVariable("correlator", requestId)
147                 execution.setVariable("messageType", "oofResponse")
148
149                 //Build Request & Call OOF
150                 String oofRequest = oofUtils.buildRequest(execution, requestId, serviceDecomposition,
151                         subscriber, customerLocation)
152                 execution.setVariable("oofRequest", oofRequest)
153                 utils.log("DEBUG", "OOF Request is: " + oofRequest, isDebugEnabled)
154
155                 String url = UrnPropertiesReader.getVariable("mso.oof.endpoint", execution)
156                 utils.log("DEBUG", "Posting to OOF Url: " + url, isDebugEnabled)
157
158                 logDebug("URL to be used is: " + url, isDebugEnabled)
159
160                 RESTConfig config = new RESTConfig(url)
161                 RESTClient client = new RESTClient(config).addAuthorizationHeader(authHeader).
162                         addHeader("Content-Type", "application/json")
163                 APIResponse response = client.httpPost(oofRequest)
164
165                 int responseCode = response.getStatusCode()
166                 logDebug("OOF sync response code is: " + responseCode, isDebugEnabled)
167                 String syncResponse = response.getResponseBodyAsString()
168                 execution.setVariable("syncResponse", syncResponse)
169                 logDebug("OOF sync response is: " + syncResponse, isDebugEnabled)
170
171                                 if(responseCode != 202){
172                                         exceptionUtil.buildAndThrowWorkflowException(execution, responseCode, "Received a Bad Sync Response from OOF.")
173                                 }
174
175                 utils.log("DEBUG", "*** Completed Homing Call OOF ***", isDebugEnabled)
176             }
177         } catch (BpmnError b) {
178             throw b
179         } catch (Exception e) {
180                         msoLogger.error(e);
181             exceptionUtil.buildAndThrowWorkflowException(execution, 2500,
182                     "Internal Error - Occured in Homing callOof: " + e.getMessage())
183         }
184     }
185
186     /**
187      * This method processes the callback response
188      * and the contained homing solution. It sets
189      * homing solution assignment and license
190      * information to the corresponding resources
191      *
192      * @param execution
193      */
194     public void processHomingSolution(DelegateExecution execution) {
195         def isDebugEnabled = execution.getVariable("isDebugLogEnabled")
196         utils.log("DEBUG", "*** Started Homing Process Homing Solution ***", isDebugEnabled)
197         try {
198             String response = execution.getVariable("asyncCallbackResponse")
199             utils.log("DEBUG", "OOF Async Callback Response is: " + response, isDebugEnabled)
200             utils.logAudit("OOF Async Callback Response is: " + response)
201
202             oofUtils.validateCallbackResponse(execution, response)
203             String placements = jsonUtil.getJsonValue(response, "solutions.placementSolutions")
204             utils.log("DEBUG", "****** Solution Placements: " + placements + " *****", isDebugEnabled)
205
206             ServiceDecomposition decomposition = execution.getVariable("serviceDecomposition")
207             utils.log("DEBUG", "Service Decomposition: " + decomposition, isDebugEnabled)
208
209             List<Resource> resourceList = decomposition.getServiceResources()
210             JSONArray arr = new JSONArray(placements)
211             for (int i = 0; i < arr.length(); i++) {
212                 JSONArray arrSol = arr.getJSONArray(i)
213                 for (int j = 0; j < arrSol.length(); j++) {
214                     JSONObject placement = arrSol.getJSONObject(j)
215                     utils.log("DEBUG", "****** Placement Solution is: " + placement + " *****", "true")
216                     String jsonServiceResourceId = placement.getString("serviceResourceId")
217                     String jsonResourceModuleName = placement.getString("resourceModuleName")
218                     for (Resource resource : resourceList) {
219                         String serviceResourceId = resource.getResourceId()
220                         String resourceModuleName = ""
221                         if (resource.getResourceType() == ResourceType.ALLOTTED_RESOURCE ||
222                             resource.getResourceType() == ResourceType.VNF) {
223                             resourceModuleName = resource.getNfFunction()
224                             }
225                         if (serviceResourceId.equalsIgnoreCase(jsonServiceResourceId) ||
226                             resourceModuleName.equalsIgnoreCase(jsonResourceModuleName)) {
227                             JSONObject solution = placement.getJSONObject("solution")
228                             String solutionType = solution.getString("identifierType")
229                             String inventoryType = ""
230                             if (solutionType.equalsIgnoreCase("serviceInstanceId")) {
231                                 inventoryType = "service"
232                             } else {
233                                 inventoryType = "cloud"
234                             }
235                             resource.getHomingSolution().setInventoryType(InventoryType.valueOf(inventoryType))
236
237                             JSONArray assignmentArr = placement.getJSONArray("assignmentInfo")
238                             String oofDirectives = null
239                             assignmentArr.each { element ->
240                                 JSONObject jsonObject = new JSONObject(element.toString())
241                                 if (jsonUtil.getJsonRawValue(jsonObject.toString(), "key") == "oof_directives") {
242                                     oofDirectives = jsonUtil.getJsonRawValue(jsonObject.toString(), "value")
243                                 }
244                             }
245                             Map<String, String> assignmentMap = jsonUtil.entryArrayToMap(execution,
246                                     assignmentArr.toString(), "key", "value")
247                             String cloudOwner = assignmentMap.get("cloudOwner")
248                             String cloudRegionId = assignmentMap.get("locationId")
249                             resource.getHomingSolution().setCloudOwner(cloudOwner)
250                             resource.getHomingSolution().setCloudRegionId(cloudRegionId)
251
252                             CloudSite cloudSite = new CloudSite();
253                             cloudSite.setId(cloudRegionId)
254                             cloudSite.setRegionId(cloudRegionId)
255                             String orchestrator = execution.getVariable("orchestrator")
256                             if ((orchestrator != null) || (orchestrator != "")) {
257                                 cloudSite.setOrchestrator(orchestrator)
258                             }
259
260                             CloudIdentity cloudIdentity = new CloudIdentity();
261                             cloudIdentity.setId(cloudRegionId);
262                             cloudIdentity.setIdentityUrl("/api/multicloud /v1/" + cloudOwner + "/" + cloudRegionId + "/infra_workload")
263                             cloudSite.setIdentityService(cloudIdentity);
264
265                             // Set cloudsite in catalog DB here
266                             oofUtils.createCloudSiteCatalogDb(cloudSite)
267
268                             if (oofDirectives != null && oofDirectives != "") {
269                                 resource.getHomingSolution().setOofDirectives(oofDirectives)
270                                 execution.setVariable("oofDirectives", oofDirectives)
271                                 utils.log("DEBUG", "***** OofDirectives is: " + oofDirectives +
272                                         " *****", "true")
273                             }
274
275                             if (inventoryType.equalsIgnoreCase("service")) {
276                                 resource.getHomingSolution().setRehome(assignmentMap.get("isRehome").toBoolean())
277                                 VnfResource vnf = new VnfResource()
278                                 vnf.setVnfHostname(assignmentMap.get("vnfHostName"))
279                                 resource.getHomingSolution().setVnf(vnf)
280                                 resource.getHomingSolution().setServiceInstanceId(solution.getJSONArray("identifiers")[0].toString())
281                             }
282                         }
283                     }
284                 }
285                 if (JsonUtils.jsonElementExist(response, "solutions.licenseSolutions")) {
286                     String licenseSolutions = jsonUtil.getJsonValue(response, "solutions.licenseSolutions")
287                     JSONArray licenseArr = new JSONArray(licenseSolutions)
288                     for (int l = 0; l < licenseArr.length(); l++) {
289                         JSONObject license = licenseArr.getJSONObject(l)
290                         String jsonServiceResourceId = license.getString("serviceResourceId")
291                         for (Resource resource : resourceList) {
292                             String serviceResourceId = resource.getResourceId()
293                             if (serviceResourceId.equalsIgnoreCase(jsonServiceResourceId)) {
294                                 String jsonEntitlementPoolList = jsonUtil.getJsonValue(license.toString(), "entitlementPoolUUID")
295                                 List<String> entitlementPoolList = jsonUtil.StringArrayToList(execution, jsonEntitlementPoolList)
296                                 resource.getHomingSolution().getLicense().setEntitlementPoolList(entitlementPoolList)
297
298                                 String jsonLicenseKeyGroupList = jsonUtil.getJsonValue(license.toString(), "licenseKeyGroupUUID")
299                                 List<String> licenseKeyGroupList = jsonUtil.StringArrayToList(execution, jsonLicenseKeyGroupList)
300                                 resource.getHomingSolution().getLicense().setLicenseKeyGroupList(licenseKeyGroupList)
301                             }
302                         }
303                     }
304                 }
305             }
306             execution.setVariable("serviceDecomposition", decomposition)
307             execution.setVariable("homingSolution", placements) //TODO - can be removed as output variable
308
309             utils.log("DEBUG", "*** Completed Homing Process Homing Solution ***", isDebugEnabled)
310         } catch (BpmnError b) {
311             throw b
312         } catch (Exception e) {
313                         msoLogger.error(e);
314             exceptionUtil.buildAndThrowWorkflowException(execution, 2500, "Internal Error - Occurred in Homing ProcessHomingSolution")
315         }
316     }
317
318     /**
319      * This method logs the start of DHVCreateService
320      * to make debugging easier.
321      *
322      * @param - execution
323      */
324     public String logStart(DelegateExecution execution) {
325         def isDebugEnabled = execution.getVariable("isDebugLogEnabled")
326         String requestId = execution.getVariable("testReqId")
327         if (isBlank(requestId)) {
328             requestId = execution.getVariable("msoRequestId")
329         }
330         execution.setVariable("DHVCS_requestId", requestId)
331         utils.log("DEBUG", "***** STARTED Homing Subflow for request: " + requestId + " *****", "true")
332         utils.log("DEBUG", "****** Homing Subflow Global Debug Enabled: " + isDebugEnabled + " *****", "true")
333         utils.logAudit("***** STARTED Homing Subflow for request: " + requestId + " *****")
334     }
335
336     /**
337      * Auto-generated method stub
338      */
339     public void preProcessRequest(DelegateExecution execution) {}
340         // Not Implemented Method
341 }