2 * ============LICENSE_START=======================================================
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
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=========================================================
21 package org.onap.so.bpmn.common.scripts
23 import org.camunda.bpm.engine.delegate.BpmnError
24 import org.camunda.bpm.engine.delegate.DelegateExecution
25 import org.camunda.bpm.model.dmn.instance.OrganizationUnit
26 import org.hibernate.engine.jdbc.Size.LobMultiplier
27 import org.onap.so.bpmn.core.WorkflowException
28 import org.onap.aai.domain.yang.GenericVnf
29 import org.onap.so.bpmn.core.UrnPropertiesReader
30 import org.onap.so.client.aai.AAIObjectType
31 import org.onap.so.client.aai.AAIResourcesClient
32 import org.onap.so.client.aai.entities.AAIResultWrapper
33 import org.onap.so.client.aai.entities.uri.AAIResourceUri
34 import org.onap.so.client.aai.entities.uri.AAIUriFactory
35 import org.onap.so.client.graphinventory.entities.uri.Depth
36 import org.onap.so.rest.APIResponse
37 import org.onap.so.rest.RESTClient
38 import org.onap.so.rest.RESTConfig
39 import org.springframework.web.util.UriUtils
40 import org.onap.so.logger.MessageEnum
41 import org.onap.so.logger.MsoLogger
45 public class PrepareUpdateAAIVfModule extends VfModuleBase {
46 private static final MsoLogger msoLogger = MsoLogger.getMsoLogger(MsoLogger.Catalog.BPEL, PrepareUpdateAAIVfModule.class);
49 ExceptionUtil exceptionUtil = new ExceptionUtil()
50 private MsoUtils utils = new MsoUtils()
52 * Initialize the flow's variables.
54 * @param execution The flow's execution instance.
56 public void initProcessVariables(DelegateExecution execution) {
57 execution.setVariable('prefix', 'PUAAIVfMod_')
58 execution.setVariable('PUAAIVfMod_vnfId', null)
59 execution.setVariable('PUAAIVfMod_vfModuleId', null)
60 execution.setVariable('PUAAIVfMod_vnfName', null)
61 execution.setVariable('PUAAIVfMod_orchestrationStatus', null)
62 execution.setVariable('PUAAIVfMod_vfModule', null)
63 execution.setVariable('PUAAIVfMod_vfModuleOK', false)
64 execution.setVariable('PUAAIVfMod_vfModuleValidationError', null)
65 execution.setVariable('PUAAIVfMod_getVnfResponseCode' ,null)
66 execution.setVariable('PUAAIVfMod_getVnfResponse', '')
67 execution.setVariable('PUAAIVfMod_updateVfModuleResponseCode', null)
68 execution.setVariable('PUAAIVfMod_updateVfModuleResponse', '')
69 execution.setVariable('PUAAIVfMod_outVfModule', null)
73 * Check for missing elements in the received request.
75 * @param execution The flow's execution instance.
77 public void preProcessRequest(DelegateExecution execution) {
78 def method = getClass().getSimpleName() + '.preProcessRequest(' +
79 'execution=' + execution.getId() +
81 msoLogger.trace('Entered ' + method)
84 def xml = execution.getVariable('PrepareUpdateAAIVfModuleRequest')
85 msoLogger.debug('Received request xml:\n' + xml)
86 msoLogger.debug("PrepareUpdateAAIVfModule Request : " + xml)
88 initProcessVariables(execution)
90 def vnfId = getRequiredNodeText(execution, xml,'vnf-id')
91 execution.setVariable('PUAAIVfMod_vnfId', vnfId)
93 def vfModuleId = getRequiredNodeText(execution, xml,'vf-module-id')
94 execution.setVariable('PUAAIVfMod_vfModuleId', vfModuleId)
96 def orchestrationStatus = getRequiredNodeText(execution, xml,'orchestration-status')
97 execution.setVariable('PUAAIVfMod_orchestrationStatus', orchestrationStatus)
99 msoLogger.trace('Exited ' + method)
100 } catch (BpmnError e) {
102 } catch (Exception e) {
104 exceptionUtil.buildAndThrowWorkflowException(execution, 1002, 'Error in preProcessRequest(): ' + e.getMessage())
109 * Using the received vnfId, query AAI to get the corresponding Generic VNF.
110 * A 200 response is expected with the Generic VNF in the response body.
112 * @param execution The flow's execution instance.
114 public void getGenericVnf(DelegateExecution execution) {
115 def method = getClass().getSimpleName() + '.getGenericVnf(' +
116 'execution=' + execution.getId() +
118 msoLogger.trace('Entered ' + method)
121 def vnfId = execution.getVariable('PUAAIVfMod_vnfId')
125 AAIResourceUri uri = AAIUriFactory.createResourceUri(AAIObjectType.GENERIC_VNF, vnfId)
126 AAIResourcesClient resourceClient = new AAIResourcesClient()
127 AAIResultWrapper wrapper = resourceClient.get(uri.depth(Depth.ONE))
128 GenericVnf responseData = wrapper.asBean(GenericVnf.class).get()
130 execution.setVariable('PUAAIVfMod_getVnfResponse', responseData)
132 } catch (Exception ex) {
134 msoLogger.debug('Exception occurred while executing AAI GET:' + ex.getMessage())
135 execution.setVariable('PUAAIVfMod_getVnfResponseCode', 500)
136 execution.setVariable('PUAAIVfMod_getVnfResponse', 'AAI GET Failed:' + ex.getMessage())
138 msoLogger.trace('Exited ' + method)
139 } catch (BpmnError e) {
141 } catch (Exception e) {
143 exceptionUtil.buildAndThrowWorkflowException(execution, 1002, 'Error in getGenericVnf(): ' + e.getMessage())
148 * Validate the VF Module. That is, confirm that a VF Module with the input VF Module ID
149 * exists in the retrieved Generic VNF. Then, check to make sure that if that VF Module
150 * is the base VF Module and it's not the only VF Module for this Generic VNF, that we're not
151 * attempting to delete it.
153 * @param execution The flow's execution instance.
155 public void validateVfModule(DelegateExecution execution) {
156 def method = getClass().getSimpleName() + '.validateVfModule(' +
157 'execution=' + execution.getId() +
159 msoLogger.trace('Entered ' + method)
162 GenericVnf genericVnf = execution.getVariable('PUAAIVfMod_getVnfResponse')
163 def vnfId = execution.getVariable('PUAAIVfMod_vnfId')
164 def vfModuleId = execution.getVariable('PUAAIVfMod_vfModuleId')
165 def vnfName = genericVnf.getVnfName()
166 execution.setVariable('PUAAIVfMod_vnfName', vnfName)
168 AAIResourceUri uri = AAIUriFactory.createResourceUri(AAIObjectType.VF_MODULE, vnfId, vfModuleId)
169 AAIResourcesClient resourceClient = new AAIResourcesClient()
173 // def VfModule vfModule = findVfModule(genericVnf, vfModuleId)
174 if (!resourceClient.exists(uri)) {
175 def String msg = 'VF Module \'' + vfModuleId + '\' does not exist in Generic VNF \'' + vnfId + '\''
176 execution.setVariable('PUAAIVfMod_vfModuleValidationError', msg)
177 execution.setVariable('PUAAIVfMod_vfModuleOK', false)
179 AAIResultWrapper wrapper = resourceClient.get(uri)
180 org.onap.aai.domain.yang.VfModule vfModule = wrapper.asBean(org.onap.aai.domain.yang.VfModule.class)
182 def orchestrationStatus = execution.getVariable('PUAAIVfMod_orchestrationStatus')
183 if (vfModule.isBaseVfModule && genericVnf.getVfModules().getVfModule().size() > 1 && vfModule.getOrchestrationStatus().equals('pending-delete')) {
184 def String msg = 'Orchestration status for VF Module \'' + vfModuleId +
185 '\' cannot be set to \'pending-delete\' since it is the base VF Module and it\'s not the only VF Module in Generic VNF \'' + vnfId + '\''
186 execution.setVariable('PUAAIVfMod_vfModuleValidationError', msg)
187 execution.setVariable('PUAAIVfMod_vfModuleOK', false)
189 execution.setVariable('PUAAIVfMod_vfModule', vfModule)
190 execution.setVariable('PUAAIVfMod_vfModuleOK', true)
194 msoLogger.trace('Exited ' + method)
195 } catch (BpmnError e) {
197 } catch (Exception e) {
199 exceptionUtil.buildAndThrowWorkflowException(execution, 1002, 'Error in validateVfModule(): ' + e.getMessage())
204 * Construct and send a PATCH request to AAI to update the VF Module.
206 * @param execution The flow's execution instance.
208 public void updateVfModule(DelegateExecution execution) {
209 def method = getClass().getSimpleName() + '.updateVfModule(' +
210 'execution=' + execution.getId() +
212 msoLogger.trace('Entered ' + method)
216 org.onap.aai.domain.yang.VfModule vfModule = execution.getVariable('PUAAIVfMod_vfModule')
218 def orchestrationStatus = execution.getVariable('PUAAIVfMod_orchestrationStatus')
220 vfModule.setOrchestrationStatus(orchestrationStatus)
222 //def payload = utils.nodeToString(newVfModuleNode)
224 // Construct endpoint
225 def vnfId = execution.getVariable('PUAAIVfMod_vnfId')
226 def vfModuleId = execution.getVariable('PUAAIVfMod_vfModuleId')
229 "vf-module-id": "${vfModuleId}",
230 "orchestration-status": "${orchestrationStatus}"
233 msoLogger.debug("VfModule payload : " + payload)
235 AaiUtil aaiUtil = new AaiUtil(this)
236 AAIResourceUri uri = AAIUriFactory.createResourceUri(AAIObjectType.VF_MODULE, vnfId, vfModuleId)
238 String endPoint = aaiUtil.createAaiUri(uri)
240 msoLogger.debug("PrepareUpdateAAIVfModule: AAI endPoint : " + endPoint)
241 String basicAuthCred = utils.getBasicAuth(UrnPropertiesReader.getVariable("aai.auth", execution),UrnPropertiesReader.getVariable("mso.msoKey", execution))
243 RESTConfig config = new RESTConfig(endPoint);
244 def responseData = ''
245 def aaiRequestId = utils.getRequestID()
246 RESTClient client = new RESTClient(config).
247 addHeader('X-TransactionId', aaiRequestId).
248 addHeader('X-FromAppId', 'MSO').
249 addHeader('Content-Type', 'application/merge-patch+json').
250 addHeader('Accept','application/json');
251 if (basicAuthCred != null && !"".equals(basicAuthCred)) {
252 client.addAuthorizationHeader(basicAuthCred)
254 msoLogger.debug('sending PATCH to AAI endpoint \'' + endPoint + '\'' + 'with payload \n' + payload)
255 APIResponse response = client.httpPatch(payload)
256 msoLogger.debug("PrepareUpdateAAIVfModule: - invoking httpPatch to AAI")
258 responseData = response.getResponseBodyAsString()
259 execution.setVariable('PUAAIVfMod_updateVfModuleResponseCode', response.getStatusCode())
260 execution.setVariable('PUAAIVfMod_updateVfModuleResponse', responseData)
261 msoLogger.debug('Response code:' + response.getStatusCode())
262 msoLogger.debug('Response:' + System.lineSeparator() + responseData)
263 msoLogger.debug("PrepareUpdateAAIVfModule: AAI Response : " + responseData)
264 msoLogger.debug("PrepareUpdateAAIVfModule: AAI ResponseCode : " + response.getStatusCode())
266 // Set the output for this flow. The updated VfModule is an output, the generic VNF name, and for
267 // backward compatibilty, the heat-stack-id is an output
268 execution.setVariable('PUAAIVfMod_outVfModule', vfModule)
269 def vnfName = execution.getVariable('PUAAIVfMod_vnfName')
270 msoLogger.debug('Output PUAAIVfMod_vnfName set to ' + vnfName)
271 // TODO: Should deprecate use of processKey+Response variable for the response. Will use "WorkflowResponse" instead
272 execution.setVariable('WorkflowResponse', vfModule)
274 def heatStackId = vfModule.getHeatStackId()
275 execution.setVariable('PUAAIVfMod_heatStackId', heatStackId)
276 msoLogger.debug('Output PUAAIVfMod_heatStackId set to \'' + heatStackId + '\'')
277 } catch (Exception ex) {
279 msoLogger.debug('Exception occurred while executing AAI PUT:' + ex.getMessage())
280 execution.setVariable('PUAAIVfMod_updateVfModuleResponseCode', 500)
281 execution.setVariable('PUAAIVfMod_updateVfModuleResponse', 'AAI PATCH Failed:' + ex.getMessage())
283 msoLogger.trace('Exited ' + method)
284 } catch (BpmnError e) {
286 } catch (Exception e) {
288 exceptionUtil.buildAndThrowWorkflowException(execution, 1002, 'Error in updateVfModule(): ' + e.getMessage())
293 * Generates a WorkflowException if the AAI query returns a response code other than 200.
295 * @param execution The flow's execution instance.
297 public void handleVnfNotFound(DelegateExecution execution) {
298 def method = getClass().getSimpleName() + '.handleVnfNotFound(' +
299 'execution=' + execution.getId() +
301 msoLogger.trace('Entered ' + method)
303 msoLogger.error('Error occurred attempting to query AAI, Response Code ' + execution.getVariable('PUAAIVfMod_getVnfResponseCode'));
304 String processKey = getProcessKey(execution);
305 WorkflowException exception = new WorkflowException(processKey, 5000,
306 execution.getVariable('PUAAIVfMod_getVnfResponse'))
307 execution.setVariable('WorkflowException', exception)
309 msoLogger.trace('Exited ' + method)
313 * Generates a WorkflowException if the VF Module does not pass validation.
315 * @param execution The flow's execution instance.
317 public void handleVfModuleValidationError(DelegateExecution execution) {
318 def method = getClass().getSimpleName() + '.handleVfModuleValidationError(' +
319 'execution=' + execution.getId() +
321 msoLogger.trace('Entered ' + method)
323 def String errorMsg = 'VF Module validation error: ' + execution.getVariable('PUAAIVfMod_vfModuleValidationError')
324 msoLogger.error(errorMsg);
325 msoLogger.debug("PrepareUpdateAAIVfModule: Error Message : " + errorMsg)
327 String processKey = getProcessKey(execution);
328 WorkflowException exception = new WorkflowException(processKey, 5000, errorMsg)
329 execution.setVariable('WorkflowException', exception)
331 msoLogger.trace('Exited ' + method)
335 * Generates a WorkflowException if updating a VF Module in AAI returns a response code other than 200.
337 * @param execution The flow's execution instance.
339 public void handleUpdateVfModuleFailure(DelegateExecution execution) {
340 def method = getClass().getSimpleName() + '.handleUpdateVfModuleFailure(' +
341 'execution=' + execution.getId() +
343 msoLogger.trace('Entered ' + method)
345 msoLogger.error('Error occurred attempting to update VF Module in AAI, Response Code ' + execution.getVariable('PUAAIVfMod_updateVfModuleResponseCode'));
346 String processKey = getProcessKey(execution);
347 WorkflowException exception = new WorkflowException(processKey, 5000,
348 execution.getVariable('PUAAIVfMod_updateVfModuleResponse'))
349 execution.setVariable('WorkflowException', exception)
351 msoLogger.trace('Exited ' + method)