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.infrastructure.scripts
23 import static org.apache.commons.lang3.StringUtils.*;
25 import org.camunda.bpm.engine.delegate.BpmnError
26 import org.camunda.bpm.engine.delegate.DelegateExecution;
27 import org.onap.so.bpmn.common.scripts.AaiUtil
28 import org.onap.so.bpmn.common.scripts.AbstractServiceTaskProcessor
29 import org.onap.so.bpmn.common.scripts.ExceptionUtil
30 import org.onap.so.bpmn.common.scripts.MsoUtils
31 import org.onap.so.bpmn.core.UrnPropertiesReader
32 import org.onap.so.bpmn.core.domain.ModelInfo
33 import org.onap.so.bpmn.core.domain.ModuleResource
34 import org.onap.so.bpmn.core.domain.VnfResource
35 import org.onap.so.bpmn.core.json.JsonUtils
36 import org.onap.so.logger.MessageEnum
37 import org.onap.so.logger.MsoLogger
38 import org.onap.so.rest.APIResponse
39 import org.onap.so.rest.RESTClient
40 import org.onap.so.rest.RESTConfig
41 import org.springframework.web.util.UriUtils;
44 * This class supports the VID Flow
45 * with the update of a generic vnf and related VF modules.
47 class DoUpdateVnfAndModules extends AbstractServiceTaskProcessor {
48 private static final MsoLogger msoLogger = MsoLogger.getMsoLogger(MsoLogger.Catalog.BPEL, DoUpdateVnfAndModules.class);
50 String Prefix="DUVAM_"
51 ExceptionUtil exceptionUtil = new ExceptionUtil()
52 JsonUtils jsonUtil = new JsonUtils()
55 * This method gets and validates the incoming
61 public void preProcessRequest(DelegateExecution execution) {
63 execution.setVariable("prefix",Prefix)
64 msoLogger.trace("STARTED DoUpdateVnfAndModules PreProcessRequest Process")
69 String requestId = execution.getVariable("msoRequestId")
70 execution.setVariable("requestId", requestId)
71 execution.setVariable("mso-request-id", requestId)
72 msoLogger.debug("Incoming Request Id is: " + requestId)
74 String serviceInstanceId = execution.getVariable("serviceInstanceId")
75 msoLogger.debug("Incoming Service Instance Id is: " + serviceInstanceId)
77 String vnfId = execution.getVariable("vnfId")
78 msoLogger.debug("Incoming Vnf Id is: " + vnfId)
81 execution.setVariable("DUVAM_source", source)
82 msoLogger.debug("Incoming Source is: " + source)
84 String sdncVersion = execution.getVariable("sdncVersion")
85 if (sdncVersion == null) {
88 execution.setVariable("DUVAM_sdncVersion", sdncVersion)
89 msoLogger.debug("Incoming Sdnc Version is: " + sdncVersion)
91 VnfResource vnfResource = (VnfResource) execution.getVariable("vnfResourceDecomposition")
93 String vnfModelInfo = execution.getVariable("vnfModelInfo")
94 String serviceModelInfo = execution.getVariable("serviceModelInfo")
96 String serviceId = execution.getVariable("productFamilyId")
97 execution.setVariable("DUVAM_serviceId", serviceId)
98 msoLogger.debug("Incoming Service Id is: " + serviceId)
100 String modelUuid = jsonUtil.getJsonValue(vnfModelInfo, "modelUuid")
101 execution.setVariable("DUVAM_modelUuid", modelUuid)
102 msoLogger.debug("Incoming modelUuid is: " + modelUuid)
104 String modelCustomizationUuid = jsonUtil.getJsonValue(vnfModelInfo, "modelCustomizationUuid")
105 execution.setVariable("DUVAM_modelCustomizationUuid", modelCustomizationUuid)
106 msoLogger.debug("Incoming Model Customization Uuid is: " + modelCustomizationUuid)
108 String cloudSiteId = execution.getVariable("lcpCloudRegionId")
109 execution.setVariable("DUVAM_cloudSiteId", cloudSiteId)
110 msoLogger.debug("Incoming Cloud Site Id is: " + cloudSiteId)
112 String tenantId = execution.getVariable("tenantId")
113 execution.setVariable("DUVAM_tenantId", tenantId)
114 msoLogger.debug("Incoming Tenant Id is: " + tenantId)
116 String globalSubscriberId = execution.getVariable("globalSubscriberId")
117 if (globalSubscriberId == null) {
118 globalSubscriberId = ""
120 execution.setVariable("DUVAM_globalSubscriberId", globalSubscriberId)
121 msoLogger.debug("Incoming Global Subscriber Id is: " + globalSubscriberId)
123 execution.setVariable("DUVAM_moduleCount", 0)
124 execution.setVariable("DUVAM_nextModule", 0)
128 msoLogger.debug("Rethrowing MSOWorkflowException")
131 msoLogger.debug(" Error Occured in DoUpdateVnfAndModules PreProcessRequest method!" + e.getMessage())
132 exceptionUtil.buildAndThrowWorkflowException(execution, 2500, "Internal Error - Occured in DoUpdateVnfAndModules PreProcessRequest")
135 msoLogger.trace("COMPLETED DoUpdateVnfAndModules PreProcessRequest Process ")
139 * Using the received vnfId and vfModuleId, query AAI to get the corresponding VNF info.
140 * A 200 response is expected with the VNF info in the response body. Will find out the base module info.
142 * @param execution The flow's execution instance.
144 public void queryAAIVfModule(DelegateExecution execution) {
146 def method = getClass().getSimpleName() + '.queryAAIVfModule(' +
147 'execution=' + execution.getId() +
149 msoLogger.trace('Entered ' + method)
152 def vnfId = execution.getVariable('vnfId')
154 AaiUtil aaiUriUtil = new AaiUtil(this)
155 String aai_uri = aaiUriUtil.getNetworkGenericVnfUri(execution)
156 msoLogger.debug('AAI URI is: ' + aai_uri)
158 String endPoint = UrnPropertiesReader.getVariable("aai.endpoint", execution) + "${aai_uri}/" + UriUtils.encode(vnfId, "UTF-8") + "?depth=1"
159 msoLogger.debug("AAI endPoint: " + endPoint)
162 RESTConfig config = new RESTConfig(endPoint);
163 def responseData = ''
164 def aaiRequestId = UUID.randomUUID().toString()
165 RESTClient client = new RESTClient(config).
166 addHeader('X-TransactionId', aaiRequestId).
167 addHeader('X-FromAppId', 'MSO').
168 addHeader('Content-Type', 'application/xml').
169 addHeader('Accept','application/xml');
170 msoLogger.debug('sending GET to AAI endpoint \'' + endPoint + '\'')
171 APIResponse response = client.httpGet()
172 msoLogger.debug("createVfModule - invoking httpGet() to AAI")
174 responseData = response.getResponseBodyAsString()
175 if (responseData != null) {
176 msoLogger.debug("Received generic VNF data: " + responseData)
180 msoLogger.debug("createVfModule - queryAAIVfModule Response: " + responseData)
181 msoLogger.debug("createVfModule - queryAAIVfModule ResponseCode: " + response.getStatusCode())
183 execution.setVariable('DUVAM_queryAAIVfModuleResponseCode', response.getStatusCode())
184 execution.setVariable('DUVAM_queryAAIVfModuleResponse', responseData)
185 msoLogger.debug('Response code:' + response.getStatusCode())
186 msoLogger.debug('Response:' + System.lineSeparator() + responseData)
187 //Map<String, String>[] vfModules = new HashMap<String,String>[]
188 def vfModulesList = new ArrayList<Map<String,String>>()
190 def vfModuleBaseEntry = null
191 if (response.getStatusCode() == 200) {
192 // Parse the VNF record from A&AI to find base module info
193 msoLogger.debug('Parsing the VNF data to find base module info')
194 if (responseData != null) {
195 def vfModulesText = utils.getNodeXml(responseData, "vf-modules")
196 msoLogger.debug("vModulesText: " + vfModulesText)
197 if (vfModulesText != null && !vfModulesText.trim().isEmpty()) {
198 def xmlVfModules= new XmlSlurper().parseText(vfModulesText)
199 vfModules = xmlVfModules.'**'.findAll {it.name() == "vf-module"}
200 execution.setVariable("DUVAM_moduleCount", vfModules.size())
201 int vfModulesSize = 0
202 for (i in 0..vfModules.size()-1) {
203 def vfModuleXml = groovy.xml.XmlUtil.serialize(vfModules[i])
205 Map<String, String> vfModuleEntry = new HashMap<String, String>()
206 def vfModuleId = utils.getNodeText(vfModuleXml, "vf-module-id")
207 vfModuleEntry.put("vfModuleId", vfModuleId)
208 def vfModuleName = utils.getNodeText(vfModuleXml, "vf-module-name")
209 vfModuleEntry.put("vfModuleName", vfModuleName)
210 def modelInvariantUuid = utils.getNodeText(vfModuleXml, "model-invariant-id")
211 vfModuleEntry.put("modelInvariantUuid", modelInvariantUuid)
212 def modelUuid = utils.getNodeText(vfModuleXml, "model-version-id")
213 vfModuleEntry.put("modelUuid", modelUuid)
214 def modelCustomizationUuid = utils.getNodeText(vfModuleXml, "model-customization-id")
215 vfModuleEntry.put("modelCustomizationUuid", modelCustomizationUuid)
217 def isBaseVfModule = utils.getNodeText(vfModuleXml, "is-base-vf-module")
218 vfModuleEntry.put("isBaseVfModule", isBaseVfModule)
220 String volumeGroupId = ''
222 msoLogger.debug("Next module!")
223 def vfModuleRelationships = vfModules[i].'**'.findAll {it.name() == 'relationship-data'}
224 if (vfModuleRelationships.size() > 0) {
225 for (j in 0..vfModuleRelationships.size()-1) {
226 if (vfModuleRelationships[j] != null) {
228 def relationshipKey = vfModuleRelationships[j].'**'.findAll {it.name() == 'relationship-key'}
230 if (relationshipKey[0] == 'volume-group.volume-group-id') {
231 def relationshipValue = vfModuleRelationships[j].'**'.findAll {it.name() == 'relationship-value'}
232 volumeGroupId = relationshipValue[0]
239 vfModuleEntry.put("volumeGroupId", volumeGroupId)
240 msoLogger.debug("volumeGroupId is: " + volumeGroupId)
242 // Save base vf module to add it to the start of the list later
243 if (isBaseVfModule == "true") {
244 vfModuleBaseEntry = vfModuleEntry
247 vfModulesList.add(vfModuleEntry)
250 // Start the list with the base module if any
251 if (vfModuleBaseEntry != null) {
252 vfModulesList.add(0, vfModuleBaseEntry)
259 msoLogger.debug('Response code from AAI GET is: ' + response.getStatusCode())
260 exceptionUtil.buildAndThrowWorkflowException(execution, 1002, 'Response code from AAI GET is: ' + response.getStatusCode())
262 execution.setVariable("DUVAM_vfModules", vfModulesList)
263 } catch (Exception ex) {
265 msoLogger.debug('Exception occurred while executing AAI GET:' + ex.getMessage())
266 exceptionUtil.buildAndThrowWorkflowException(execution, 1002, 'AAI GET Failed:' + ex.getMessage())
268 msoLogger.trace('Exited ' + method)
269 } catch (BpmnError e) {
271 } catch (Exception e) {
272 msoLogger.error(MessageEnum.BPMN_GENERAL_EXCEPTION_ARG, 'Caught exception in ' + method, "BPMN", MsoLogger.getServiceName(), MsoLogger.ErrorCode.UnknownError, "Exception is:\n" + e);
273 exceptionUtil.buildAndThrowWorkflowException(execution, 1002, 'Error in queryAAIVfModule(): ' + e.getMessage())
277 public void prepareNextModuleToUpdate(DelegateExecution execution){
279 execution.setVariable("prefix", Prefix)
280 msoLogger.trace("STARTED prepareNextModuleToUpdate ")
283 int i = execution.getVariable("DUVAM_nextModule")
284 def vfModules = execution.getVariable("DUVAM_vfModules")
285 def vfModule = vfModules[i]
287 def vfModuleId = vfModule.get("vfModuleId")
288 execution.setVariable("DUVAM_vfModuleId", vfModuleId)
290 def vfModuleName = vfModule.get("vfModuleName")
291 execution.setVariable("DUVAM_vfModuleName", vfModuleName)
293 def isBaseVfModule = vfModule.get("isBaseVfModule")
294 execution.setVariable("DUVAM_isBaseVfModule", isBaseVfModule)
296 String modelInvariantUuid = vfModule.get("modelInvariantUuid")
297 msoLogger.debug("ModelInvariantUuid: " + modelInvariantUuid)
299 def volumeGroupId = vfModule.get("volumeGroupId")
300 execution.setVariable("DUVAM_volumeGroupId", volumeGroupId)
302 execution.setVariable("DUVAM_volumeGroupName", "")
304 VnfResource vnfResource = (VnfResource) execution.getVariable("vnfResourceDecomposition")
305 List<ModuleResource> moduleResources = vnfResource.getVfModules()
307 if (moduleResources != null && !moduleResources.isEmpty()) {
309 for (j in 0..moduleResources.size()-1) {
310 ModelInfo modelInfo = moduleResources[j].getModelInfo()
311 String modelInvariantUuidFromDecomposition = modelInfo.getModelInvariantUuid()
312 msoLogger.debug("modelInvariantUuidFromDecomposition: " + modelInvariantUuidFromDecomposition)
314 if (modelInvariantUuid.equals(modelInvariantUuidFromDecomposition)) {
315 String vfModuleModelInfo = modelInfo.toJsonString()
316 String vfModuleModelInfoValue = jsonUtil.getJsonValue(vfModuleModelInfo, "modelInfo")
317 execution.setVariable("DUVAM_vfModuleModelInfo", vfModuleModelInfoValue)
318 msoLogger.debug("vfModuleModelInfo: " + vfModuleModelInfoValue)
326 msoLogger.error(MessageEnum.BPMN_GENERAL_EXCEPTION_ARG, "Exception Occured Processing preProcessAddOnModule. Exception is:\n" + e, "BPMN", MsoLogger.getServiceName(), MsoLogger.ErrorCode.UnknownError, "Exception is:\n" + e);
327 exceptionUtil.buildAndThrowWorkflowException(execution, 1002, "Error Occurred during prepareNextModuleToUpdate Method:\n" + e.getMessage())
329 msoLogger.trace("COMPLETED prepareNextModuleToUpdate ")
334 * Prepare a Request for invoking the UpdateAAIGenericVnf subflow.
336 * @param execution The flow's execution instance.
338 public void prepUpdateAAIGenericVnf(DelegateExecution execution) {
339 def method = getClass().getSimpleName() + '.prepUpdateAAIGenericVnf(' +
340 'execution=' + execution.getId() +
343 msoLogger.trace('Entered ' + method)
346 def vnfId = execution.getVariable('vnfId')
347 VnfResource vnfResource = (VnfResource) execution.getVariable("vnfResourceDecomposition")
348 ModelInfo vnfDecompModelInfo = vnfResource.getModelInfo()
349 String vnfModelInfo = execution.getVariable("vnfModelInfo")
350 String modelUuid = execution.getVariable("DUVAM_modelUuid")
351 if (modelUuid == null || modelUuid.isEmpty()) {
352 modelUuid = vnfDecompModelInfo.getModelUuid()
354 String modelCustomizationUuid = execution.getVariable("DUVAM_modelCustomizationUuid")
355 if (modelCustomizationUuid == null || modelCustomizationUuid.isEmpty()) {
356 modelCustomizationUuid = vnfDecompModelInfo.getModelCustomizationUuid()
358 String nfType = vnfResource.getNfType()
359 String nfTypeString = ''
360 if (nfType != null && !nfType.isEmpty()) {
361 nfTypeString = "<nf-type>" + nfType + "</nf-type>"
363 String nfRole = vnfResource.getNfRole()
364 String nfRoleString = ''
365 if (nfRole != null && !nfRole.isEmpty()) {
366 nfRoleString = "<nf-role>" + nfRole + "</nf-role>"
368 String nfFunction = vnfResource.getNfFunction()
369 String nfFunctionString = ''
370 if (nfFunction != null && !nfFunction.isEmpty()) {
371 nfFunctionString = "<nf-function>" + nfFunction + "</nf-function>"
373 String nfNamingCode = vnfResource.getNfNamingCode()
374 String nfNamingCodeString = ''
375 if (nfNamingCode != null && !nfNamingCode.isEmpty()) {
376 nfNamingCodeString = "<nf-naming-code>" + nfNamingCode + "</nf-naming-code>"
379 String updateAAIGenericVnfRequest = """
380 <UpdateAAIGenericVnfRequest>
381 <vnf-id>${MsoUtils.xmlEscape(vnfId)}</vnf-id>
382 <model-version-id>${MsoUtils.xmlEscape(modelUuid)}</model-version-id>
383 <model-customization-id>${MsoUtils.xmlEscape(modelCustomizationUuid)}</model-customization-id>
387 ${nfNamingCodeString}
388 </UpdateAAIGenericVnfRequest>
390 updateAAIGenericVnfRequest = utils.formatXml(updateAAIGenericVnfRequest)
391 execution.setVariable('DUVAM_updateAAIGenericVnfRequest', updateAAIGenericVnfRequest)
392 msoLogger.debug("updateAAIGenericVnfRequest : " + updateAAIGenericVnfRequest)
393 msoLogger.debug('Request for UpdateAAIGenericVnf:\n' + updateAAIGenericVnfRequest)
396 msoLogger.trace('Exited ' + method)
397 } catch (BpmnError e) {
399 } catch (Exception e) {
400 msoLogger.error(MessageEnum.BPMN_GENERAL_EXCEPTION_ARG, 'Caught exception in ' + method, "BPMN", MsoLogger.getServiceName(), MsoLogger.ErrorCode.UnknownError, "Exception is:\n" + e);
401 exceptionUtil.buildAndThrowWorkflowException(execution, 1002, 'Error in prepUpdateAAIGenericVnf(): ' + e.getMessage())
406 * APP-C Call - placeholder.
408 * @param execution The flow's execution instance.
410 public void callAppCf(DelegateExecution execution) {
411 def method = getClass().getSimpleName() + '.callAppC(' +
412 'execution=' + execution.getId() +
415 msoLogger.trace('Entered ' + method)