2 * ============LICENSE_START=======================================================
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
11 * http://www.apache.org/licenses/LICENSE-2.0
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=========================================================
20 package org.onap.so.bpmn.common.scripts
22 import org.onap.so.bpmn.core.UrnPropertiesReader
23 import org.camunda.bpm.engine.delegate.BpmnError
24 import org.camunda.bpm.engine.delegate.DelegateExecution
26 import org.onap.so.bpmn.core.domain.InventoryType
27 import org.onap.so.bpmn.core.domain.Resource
28 import org.onap.so.bpmn.core.domain.ResourceType
29 import org.onap.so.bpmn.core.domain.ServiceDecomposition
30 import org.onap.so.bpmn.core.domain.Subscriber
31 import org.onap.so.bpmn.core.domain.VnfResource
32 import org.onap.so.bpmn.core.json.JsonUtils
33 import org.onap.so.client.HttpClient
34 import org.onap.so.client.HttpClientFactory
35 import org.onap.so.logger.MsoLogger
36 import org.onap.so.db.catalog.beans.CloudIdentity
37 import org.onap.so.db.catalog.beans.CloudSite
38 import org.onap.so.db.catalog.beans.HomingInstance
39 import org.onap.so.bpmn.common.scripts.AbstractServiceTaskProcessor
40 import org.onap.so.utils.TargetEntity
42 import org.json.JSONArray
43 import org.json.JSONObject
44 import org.springframework.web.util.UriUtils
46 import static org.onap.so.bpmn.common.scripts.GenericUtils.*
48 import javax.ws.rs.core.Response
51 * This class contains the scripts used
52 * by the OOF Homing Subflow building block. The
53 * subflow attempts to home the provided
54 * resources by calling OOF.
56 class OofHoming extends AbstractServiceTaskProcessor {
58 ExceptionUtil exceptionUtil = new ExceptionUtil()
59 JsonUtils jsonUtil = new JsonUtils()
60 OofUtils oofUtils = new OofUtils(this)
63 * This method validates the incoming variables.
64 * The method then prepares the OOF request
65 * and posts it to OOF's rest api.
69 public void callOof(DelegateExecution execution) {
70 def isDebugEnabled = execution.getVariable("isDebugLogEnabled")
71 execution.setVariable("prefix", "HOME_")
72 utils.log("DEBUG", "*** Started Homing Call OOF ***", isDebugEnabled)
74 execution.setVariable("rollbackData", null)
75 execution.setVariable("rolledBack", false)
77 String requestId = execution.getVariable("msoRequestId")
78 utils.log("DEBUG", "Incoming Request Id is: " + requestId, isDebugEnabled)
79 String serviceInstanceId = execution.getVariable("serviceInstanceId")
80 utils.log("DEBUG", "Incoming Service Instance Id is: " + serviceInstanceId, isDebugEnabled)
81 String serviceInstanceName = execution.getVariable("serviceInstanceName")
82 utils.log("DEBUG", "Incoming Service Instance Name is: " + serviceInstanceName, isDebugEnabled)
83 ServiceDecomposition serviceDecomposition = execution.getVariable("serviceDecomposition")
84 utils.log("DEBUG", "Incoming Service Decomposition is: " + serviceDecomposition, isDebugEnabled)
85 String subscriberInfo = execution.getVariable("subscriberInfo")
86 utils.log("DEBUG", "Incoming Subscriber Information is: " + subscriberInfo, isDebugEnabled)
87 Map customerLocation = execution.getVariable("customerLocation")
88 utils.log("DEBUG", "Incoming Customer Location is: " + customerLocation.toString(), isDebugEnabled)
89 String cloudOwner = execution.getVariable("cloudOwner")
90 utils.log("DEBUG", "Incoming cloudOwner is: " + cloudOwner, isDebugEnabled)
91 String cloudRegionId = execution.getVariable("cloudRegionId")
92 utils.log("DEBUG", "Incoming cloudRegionId is: " + cloudRegionId, isDebugEnabled)
94 if (isBlank(requestId) ||
95 isBlank(serviceInstanceId) ||
96 isBlank(serviceInstanceName) ||
97 isBlank(serviceDecomposition.toString()) ||
98 isBlank(customerLocation.toString())) {
99 exceptionUtil.buildAndThrowWorkflowException(execution, 4000,
100 "A required input variable is missing or null")
102 Subscriber subscriber = null
103 if (isBlank(subscriberInfo)) {
104 subscriber = new Subscriber("", "", "")
106 String subId = jsonUtil.getJsonValue(subscriberInfo, "globalSubscriberId")
107 String subName = jsonUtil.getJsonValue(subscriberInfo, "subscriberName")
108 String subCommonSiteId = ""
109 if (jsonUtil.jsonElementExist(subscriberInfo, "subscriberCommonSiteId")) {
110 subCommonSiteId = jsonUtil.getJsonValue(subscriberInfo, "subscriberCommonSiteId")
112 subscriber = new Subscriber(subId, subName, subCommonSiteId)
117 String basicAuth = UrnPropertiesReader.getVariable("mso.oof.auth", execution)
118 String msokey = UrnPropertiesReader.getVariable("mso.msoKey", execution)
120 String basicAuthValue = utils.encrypt(basicAuth, msokey)
121 if (basicAuthValue != null) {
122 utils.log("DEBUG", "Obtained BasicAuth username and password for OOF Adapter: " + basicAuthValue,
125 authHeader = utils.getBasicAuth(basicAuthValue, msokey)
126 execution.setVariable("BasicAuthHeaderValue", authHeader)
127 } catch (Exception ex) {
128 utils.log("DEBUG", "Unable to encode username and password string: " + ex, isDebugEnabled)
129 exceptionUtil.buildAndThrowWorkflowException(execution, 401, "Internal Error - Unable to " +
130 "encode username and password string")
133 utils.log("DEBUG", "Unable to obtain BasicAuth - BasicAuth value null", isDebugEnabled)
134 exceptionUtil.buildAndThrowWorkflowException(execution, 401, "Internal Error - BasicAuth " +
139 String timeout = execution.getVariable("timeout")
140 if (isBlank(timeout)) {
141 timeout = UrnPropertiesReader.getVariable("mso.oof.timeout", execution);
142 if (isBlank(timeout)) {
146 utils.log("DEBUG", "Async Callback Timeout will be: " + timeout, isDebugEnabled)
148 execution.setVariable("timeout", timeout)
149 execution.setVariable("correlator", requestId)
150 execution.setVariable("messageType", "oofResponse")
152 //Build Request & Call OOF
153 String oofRequest = oofUtils.buildRequest(execution, requestId, serviceDecomposition,
154 subscriber, customerLocation)
155 execution.setVariable("oofRequest", oofRequest)
156 utils.log("DEBUG", "OOF Request is: " + oofRequest, isDebugEnabled)
158 String urlString = UrnPropertiesReader.getVariable("mso.oof.endpoint", execution)
159 utils.log("DEBUG", "Posting to OOF Url: " + urlString, isDebugEnabled)
162 URL url = new URL(urlString);
163 HttpClient httpClient = new HttpClientFactory().newJsonClient(url, TargetEntity.SNIRO)
164 httpClient.addAdditionalHeader("Authorization", authHeader)
165 Response httpResponse = httpClient.post(oofRequest)
167 int responseCode = httpResponse.getStatus()
168 logDebug("OOF sync response code is: " + responseCode, isDebugEnabled)
171 utils.log("DEBUG", "*** Completed Homing Call OOF ***", isDebugEnabled)
173 } catch (BpmnError b) {
175 } catch (Exception e) {
177 exceptionUtil.buildAndThrowWorkflowException(execution, 2500,
178 "Internal Error - Occured in Homing callOof: " + e.getMessage())
183 * This method processes the callback response
184 * and the contained homing solution. It sets
185 * homing solution assignment and license
186 * information to the corresponding resources
190 public void processHomingSolution(DelegateExecution execution) {
191 def isDebugEnabled = execution.getVariable("isDebugLogEnabled")
192 utils.log("DEBUG", "*** Started Homing Process Homing Solution ***", isDebugEnabled)
194 String response = execution.getVariable("asyncCallbackResponse")
195 utils.log("DEBUG", "OOF Async Callback Response is: " + response, isDebugEnabled)
196 utils.logAudit("OOF Async Callback Response is: " + response)
198 oofUtils.validateCallbackResponse(execution, response)
199 String placements = jsonUtil.getJsonValue(response, "solutions.placementSolutions")
200 utils.log("DEBUG", "****** Solution Placements: " + placements + " *****", isDebugEnabled)
202 ServiceDecomposition decomposition = execution.getVariable("serviceDecomposition")
203 utils.log("DEBUG", "Service Decomposition: " + decomposition, isDebugEnabled)
205 List<Resource> resourceList = decomposition.getServiceResources()
206 JSONArray arr = new JSONArray(placements)
207 for (int i = 0; i < arr.length(); i++) {
208 JSONArray arrSol = arr.getJSONArray(i)
209 for (int j = 0; j < arrSol.length(); j++) {
210 JSONObject placement = arrSol.getJSONObject(j)
211 utils.log("DEBUG", "****** Placement Solution is: " + placement + " *****", "true")
212 String jsonServiceResourceId = jsonUtil.getJsonValue( placement.toString(), "serviceResourceId")
213 utils.log("DEBUG", "****** homing serviceResourceId is: " + jsonServiceResourceId + " *****", "true")
214 for (Resource resource : resourceList) {
215 String serviceResourceId = resource.getResourceId()
216 utils.log("DEBUG", "****** decomp serviceResourceId is: " + serviceResourceId + " *****", "true")
217 if (serviceResourceId.equalsIgnoreCase(jsonServiceResourceId)) {
218 JSONObject solution = placement.getJSONObject("solution")
219 String solutionType = solution.getString("identifierType")
220 String inventoryType = ""
221 if (solutionType.equalsIgnoreCase("serviceInstanceId")) {
222 inventoryType = "service"
224 inventoryType = "cloud"
226 utils.log("DEBUG", "****** homing inventoryType is: " + inventoryType + " *****", "true")
227 resource.getHomingSolution().setInventoryType(InventoryType.valueOf(inventoryType))
229 JSONArray assignmentArr = placement.getJSONArray("assignmentInfo")
230 utils.log("DEBUG", "****** assignmentInfo is: " + assignmentArr.toString() + " *****", "true")
232 Map<String, String> assignmentMap = jsonUtil.entryArrayToMap(execution,
233 assignmentArr.toString(), "key", "value")
234 String oofDirectives = null
235 assignmentMap.each { key, value ->
236 utils.log("DEBUG", "****** element: " + key + " *****", "true")
237 if (key == "oof_directives") {
238 oofDirectives = value
239 utils.log("DEBUG", "****** homing oofDirectives: " + oofDirectives + " *****", "true")
242 String cloudOwner = assignmentMap.get("cloudOwner")
243 utils.log("DEBUG", "****** homing cloudOwner: " + cloudOwner + " *****", "true")
244 String cloudRegionId = assignmentMap.get("locationId")
245 utils.log("DEBUG", "****** homing cloudRegionId: " + cloudRegionId + " *****", "true")
246 resource.getHomingSolution().setCloudOwner(cloudOwner)
247 resource.getHomingSolution().setCloudRegionId(cloudRegionId)
249 CloudSite cloudSite = new CloudSite()
250 cloudSite.setId(cloudRegionId)
251 cloudSite.setRegionId(cloudRegionId)
252 String orchestrator = execution.getVariable("orchestrator")
253 if ((orchestrator != null) && (orchestrator != "")) {
254 cloudSite.setOrchestrator(orchestrator)
255 utils.log("DEBUG", "****** orchestrator: " + orchestrator + " *****", "true")
257 cloudSite.setOrchestrator("multicloud")
260 CloudIdentity cloudIdentity = new CloudIdentity()
261 cloudIdentity.setId(cloudRegionId)
262 cloudIdentity.setIdentityServerType(ServerType."KEYSTONE")
263 cloudIdentity.setAdminTenant("service")
264 cloudIdentity.setIdentityAuthenticationType(AuthenticationType.USERNAME_PASSWORD)
265 String msoMulticloudUserName = UrnPropertiesReader
266 .getVariable("mso.multicloud.api.username", execution,
268 String msoMulticloudPassword = UrnPropertiesReader
269 .getVariable("mso.multicloud.api.password", execution,
271 cloudIdentity.setMsoId(msoMulticloudUserName)
272 cloudIdentity.setMsoPass(msoMulticloudPassword)
274 String msbHost = oofUtils.getMsbHost(execution)
275 String multicloudApiEndpoint = UrnPropertiesReader
276 .getVariable("mso.multicloud.api.endpoint", execution,
277 "/api/multicloud-titaniumcloud/v1")
278 cloudIdentity.setIdentityUrl(msbHost + multicloudApiEndpoint
279 + "/" + cloudOwner + "/" +
280 cloudRegionId + "/infra_workload")
281 utils.log("DEBUG", "****** Cloud IdentityUrl: " + msbHost + multicloudApiEndpoint
282 + "/" + cloudOwner + "/" +
283 cloudRegionId + "/infra_workload"
285 utils.log("DEBUG", "****** CloudIdentity: " + cloudIdentity.toString()
287 cloudSite.setIdentityService(cloudIdentity)
288 utils.log("DEBUG", "****** CloudSite: " + cloudSite.toString()
291 // Set cloudsite in catalog DB here
292 oofUtils.createCloudSite(cloudSite, execution)
294 if (oofDirectives != null && oofDirectives != "") {
295 resource.getHomingSolution().setOofDirectives(oofDirectives)
296 execution.setVariable("oofDirectives", oofDirectives)
297 utils.log("DEBUG", "***** OofDirectives set to: " + oofDirectives +
301 // Set Homing Instance
302 String serviceInstanceId = decomposition.getServiceInstance().getInstanceId()
303 HomingInstance homingInstance = new HomingInstance()
304 homingInstance.setServiceInstanceId(serviceInstanceId)
305 homingInstance.setCloudOwner(cloudOwner)
306 homingInstance.setCloudRegionId(cloudRegionId)
307 if (oofDirectives != null && oofDirectives != "") {
308 homingInstance.setOofDirectives(oofDirectives)}
310 homingInstance.setOofDirectives("{}")
312 oofUtils.createHomingInstance(homingInstance, execution)
314 if (inventoryType.equalsIgnoreCase("service")) {
315 resource.getHomingSolution().setRehome(assignmentMap.get("isRehome").toBoolean())
316 VnfResource vnf = new VnfResource()
317 vnf.setVnfHostname(assignmentMap.get("vnfHostName"))
318 resource.getHomingSolution().setVnf(vnf)
319 resource.getHomingSolution().setServiceInstanceId(solution.getJSONArray("identifiers")[0].toString())
322 utils.log("DEBUG", "ProcessHomingSolution Exception: no matching serviceResourceIds returned in " +
323 "homing solution", isDebugEnabled)
324 exceptionUtil.buildAndThrowWorkflowException(execution, 2500, "Internal Error - " +
325 "Occurred in Homing ProcessHomingSolution: no matching serviceResourceIds returned")
330 if (JsonUtils.jsonElementExist(response, "solutions.licenseSolutions")) {
331 String licenseSolutions = jsonUtil.getJsonValue(response, "solutions.licenseSolutions")
332 JSONArray licenseArr = new JSONArray(licenseSolutions)
333 for (int l = 0; l < licenseArr.length(); l++) {
334 JSONObject license = licenseArr.getJSONObject(l)
335 String jsonServiceResourceId = license.getString("serviceResourceId")
336 for (Resource resource : resourceList) {
337 String serviceResourceId = resource.getResourceId()
338 if (serviceResourceId.equalsIgnoreCase(jsonServiceResourceId)) {
339 String jsonEntitlementPoolList = jsonUtil.getJsonValue(license.toString(), "entitlementPoolUUID")
340 List<String> entitlementPoolList = jsonUtil.StringArrayToList(execution, jsonEntitlementPoolList)
341 resource.getHomingSolution().getLicense().setEntitlementPoolList(entitlementPoolList)
343 String jsonLicenseKeyGroupList = jsonUtil.getJsonValue(license.toString(), "licenseKeyGroupUUID")
344 List<String> licenseKeyGroupList = jsonUtil.StringArrayToList(execution, jsonLicenseKeyGroupList)
345 resource.getHomingSolution().getLicense().setLicenseKeyGroupList(licenseKeyGroupList)
351 execution.setVariable("serviceDecomposition", decomposition)
352 execution.setVariable("homingSolution", placements) //TODO - can be removed as output variable
354 utils.log("DEBUG", "*** Completed Homing Process Homing Solution ***", isDebugEnabled)
355 } catch (BpmnError b) {
356 utils.log("DEBUG", "ProcessHomingSolution Error: " + b, isDebugEnabled)
358 } catch (Exception e) {
359 utils.log("DEBUG", "ProcessHomingSolution Exception: " + e, isDebugEnabled)
361 exceptionUtil.buildAndThrowWorkflowException(execution, 2500, "Internal Error - Occurred in Homing ProcessHomingSolution")
366 * This method logs the start of DHVCreateService
367 * to make debugging easier.
371 public String logStart(DelegateExecution execution) {
372 def isDebugEnabled = execution.getVariable("isDebugLogEnabled")
373 String requestId = execution.getVariable("testReqId")
374 if (isBlank(requestId)) {
375 requestId = execution.getVariable("msoRequestId")
377 execution.setVariable("DHVCS_requestId", requestId)
378 utils.log("DEBUG", "***** STARTED Homing Subflow for request: " + requestId + " *****", "true")
379 utils.log("DEBUG", "****** Homing Subflow Global Debug Enabled: " + isDebugEnabled + " *****", "true")
380 utils.logAudit("***** STARTED Homing Subflow for request: " + requestId + " *****")
384 * Auto-generated method stub
386 public void preProcessRequest(DelegateExecution execution) {}
387 // Not Implemented Method
390 * Constructs a workflow message callback URL for the specified message type and correlator.
391 * This type of callback URL is used when a workflow wants an MSO adapter (like the SDNC
392 * adapter) to call it back. In other words, this is for callbacks internal to the MSO
393 * complex. Use <code>createWorkflowMessageAdapterCallbackURL</code> if the callback
394 * will come from outside the MSO complex.
395 * @param endpoint endpoint address to contruct URL from
396 * @param messageType the message type (e.g. SDNCAResponse or VNFAResponse)
397 * @param correlator the correlator value (e.g. a request ID)
399 public String createHomingCallbackURL(String endpoint, String messageType, String correlator) {
401 if (endpoint == null || endpoint.isEmpty()) {
402 ExceptionUtil exceptionUtil = new ExceptionUtil()
403 exceptionUtil.buildAndThrowWorkflowException(execution, 2000,
404 'mso:workflow:message:endpoint was not passed in')
407 utils.log("DEBUG", "passed in endpoint: " + endpoint + " *****", "true")
409 while (endpoint.endsWith('/')) {
410 endpoint = endpoint.substring(0, endpoint.length() - 1)
412 utils.log("DEBUG", "processed endpoint: " + endpoint + " *****", "true")
415 '/' + UriUtils.encodePathSegment(messageType, 'UTF-8') +
416 '/' + UriUtils.encodePathSegment(correlator, 'UTF-8')
417 } catch (Exception ex) {
418 utils.log("DEBUG", "createCallbackURL Exception: " + ex + " *****", "true")