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 org.apache.commons.lang3.*
24 import org.camunda.bpm.engine.delegate.BpmnError
25 import org.camunda.bpm.engine.delegate.DelegateExecution;
26 import org.onap.so.bpmn.common.scripts.AaiUtil;
27 import org.onap.so.bpmn.common.scripts.AbstractServiceTaskProcessor;
28 import org.onap.so.bpmn.common.scripts.ExceptionUtil;
29 import org.onap.so.bpmn.common.scripts.MsoUtils
30 import org.onap.so.bpmn.core.WorkflowException
31 import org.onap.so.logger.MessageEnum
32 import org.onap.so.logger.MsoLogger
33 import org.onap.so.rest.APIResponse
35 import groovy.json.JsonOutput
36 import groovy.json.JsonSlurper
38 class CreateVfModuleVolumeInfraV1 extends AbstractServiceTaskProcessor {
40 private static final MsoLogger msoLogger = MsoLogger.getMsoLogger(MsoLogger.Catalog.BPEL, CreateVfModuleVolumeInfraV1.class);
41 public static final String prefix='CVMVINFRAV1_'
44 * Perform initial processing, such as request validation, initialization of variables, etc.
47 public void preProcessRequest (DelegateExecution execution) {
48 def isDebugEnabled=execution.getVariable("isDebugLogEnabled")
49 setBasicDBAuthHeader(execution, isDebugEnabled)
50 preProcessRequest(execution, isDebugEnabled)
55 * Perform initial processing, such as request validation, initialization of variables, etc.
57 * @param isDebugEnabled
59 public void preProcessRequest (DelegateExecution execution, isDebugEnabled) {
61 execution.setVariable("prefix",prefix)
62 setSuccessIndicator(execution, false)
63 execution.setVariable(prefix+'syncResponseSent', false)
65 String createVolumeIncoming = validateRequest(execution, 'vnfId')
66 msoLogger.debug(createVolumeIncoming)
69 def jsonSlurper = new JsonSlurper()
70 Map reqMap = jsonSlurper.parseText(createVolumeIncoming)
71 setupVariables(execution, reqMap, isDebugEnabled)
72 msoLogger.debug("XML request:\n" + createVolumeIncoming)
74 catch(groovy.json.JsonException je) {
75 (new ExceptionUtil()).buildAndThrowWorkflowException(execution, 2500, 'Request is not a valid JSON document')
78 // For rollback in this flow
79 setBasicDBAuthHeader(execution, isDebugEnabled)
80 setRollbackEnabled(execution, isDebugEnabled)
85 * Set up variables that will be passed to the BB DoCreatevfModuleVolume flow
88 * @param serviceInstanceId
89 * @param isDebugLogEnabled
91 public void setupVariables(DelegateExecution execution, Map requestMap, isDebugLogEnabled) {
93 def jsonOutput = new JsonOutput()
95 // volumeGroupId - is generated
96 String volumeGroupId = UUID.randomUUID()
97 execution.setVariable('volumeGroupId', volumeGroupId)
98 msoLogger.debug("Generated volumeGroupId: " + volumeGroupId)
101 def volGrpName = requestMap.requestDetails.requestInfo?.instanceName ?: ''
102 execution.setVariable('volumeGroupName', volGrpName)
105 def vfModuleModelInfo = jsonOutput.toJson(requestMap.requestDetails?.modelInfo)
106 execution.setVariable('vfModuleModelInfo', vfModuleModelInfo)
109 def lcpCloudRegionId = requestMap.requestDetails.cloudConfiguration.lcpCloudRegionId
110 execution.setVariable('lcpCloudRegionId', lcpCloudRegionId)
113 def cloudOwner = requestMap.requestDetails.cloudConfiguration.cloudOwner
114 execution.setVariable('cloudOwner', cloudOwner)
117 def tenantId = requestMap.requestDetails.cloudConfiguration.tenantId
118 execution.setVariable('tenantId', tenantId)
121 def source = requestMap.requestDetails.requestInfo.source
122 execution.setVariable(prefix+'source', source)
124 // vnfType and asdcServiceModelVersion
127 def asdcServiceModelVersion = ''
128 def modelCustomizationName = ''
130 def relatedInstanceList = requestMap.requestDetails.relatedInstanceList
131 relatedInstanceList.each {
132 if (it.relatedInstance.modelInfo?.modelType == 'service') {
133 serviceName = it.relatedInstance.modelInfo?.modelName
134 asdcServiceModelVersion = it.relatedInstance.modelInfo?.modelVersion
136 if (it.relatedInstance.modelInfo?.modelType == 'vnf') {
137 modelCustomizationName = it.relatedInstance.modelInfo?.modelCustomizationName
141 def vnfType = serviceName + '/' + modelCustomizationName
142 execution.setVariable('vnfType', vnfType)
143 execution.setVariable('asdcServiceModelVersion', asdcServiceModelVersion)
145 // vfModuleInputParams
146 def userParams = requestMap.requestDetails?.requestParameters?.userParams
147 Map<String, String> vfModuleInputMap = [:]
149 userParams.each { userParam ->
150 vfModuleInputMap.put(userParam.name, userParam.value.toString())
152 execution.setVariable('vfModuleInputParams', vfModuleInputMap)
154 // disableRollback (true or false)
155 def disableRollback = requestMap.requestDetails.requestInfo.suppressRollback
156 execution.setVariable('disableRollback', disableRollback)
157 msoLogger.debug('disableRollback (suppressRollback) from request: ' + disableRollback)
163 public void sendSyncResponse (DelegateExecution execution, isDebugEnabled) {
164 def volumeGroupId = execution.getVariable('volumeGroupId')
165 def requestId = execution.getVariable("mso-request-id")
166 def serviceInstanceId = execution.getVariable("serviceInstanceId")
168 String syncResponse = """{"requestReferences":{"instanceId":"${volumeGroupId}","requestId":"${requestId}"}}""".trim()
170 msoLogger.debug("Sync Response: " + "\n" + syncResponse)
171 sendWorkflowResponse(execution, 200, syncResponse)
173 execution.setVariable(prefix+'syncResponseSent', true)
177 public void sendSyncError (DelegateExecution execution, isDebugEnabled) {
178 WorkflowException we = execution.getVariable('WorkflowException')
179 def errorCode = we?.getErrorCode()
180 def errorMessage = we?.getErrorMessage()
181 //default to 400 since only invalid request will trigger this method
182 sendWorkflowResponse(execution, 400, errorMessage)
187 * Create a WorkflowException
189 * @param isDebugEnabled
191 public void buildWorkflowException(DelegateExecution execution, int errorCode, errorMessage, isDebugEnabled) {
192 msoLogger.debug(errorMessage)
193 (new ExceptionUtil()).buildWorkflowException(execution, 2500, errorMessage)
198 * Build Infra DB Request
200 * @param isDebugEnabled
202 public void prepareDbInfraSuccessRequest(DelegateExecution execution, isDebugEnabled) {
203 def dbVnfOutputs = execution.getVariable(prefix+'volumeOutputs')
204 def requestId = execution.getVariable('mso-request-id')
205 def statusMessage = "VolumeGroup successfully created."
206 def requestStatus = "COMPLETED"
210 from: $gVolumeGroup/aai:volume-group-id/text()
211 to: vnfreq:volume-outputs/vnfreq:volume-group-id
213 // for now assume, generated volumeGroupId is accepted
214 def volumeGroupId = execution.getVariable(prefix+'volumeGroupId')
217 """<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
220 <ns:updateInfraRequest xmlns:ns="http://org.onap.so/requestsdb">
221 <requestId>${MsoUtils.xmlEscape(requestId)}</requestId>
222 <lastModifiedBy>BPMN</lastModifiedBy>
223 <statusMessage>${MsoUtils.xmlEscape(statusMessage)}</statusMessage>
224 <responseBody></responseBody>
225 <requestStatus>${MsoUtils.xmlEscape(requestStatus)}</requestStatus>
226 <progress>${MsoUtils.xmlEscape(progress)}</progress>
227 <vnfOutputs>${MsoUtils.xmlEscape(dbVnfOutputs)}</vnfOutputs>
228 <volumeGroupId>${MsoUtils.xmlEscape(volumeGroupId)}</volumeGroupId>
229 </ns:updateInfraRequest>
231 </soapenv:Envelope>"""
233 String buildDBRequestAsString = utils.formatXml(dbRequest)
234 execution.setVariable(prefix+"createDBRequest", buildDBRequestAsString)
235 msoLogger.debug("DB Infra Request: " + buildDBRequestAsString)
240 * Build CommpleteMsoProcess request
242 * @param isDebugEnabled
244 public void postProcessResponse (DelegateExecution execution, isDebugEnabled) {
246 def dbReturnCode = execution.getVariable(prefix+'dbReturnCode')
247 def createDBResponse = execution.getVariable(prefix+'createDBResponse')
249 msoLogger.debug('DB return code: ' + dbReturnCode)
250 msoLogger.debug('DB response: ' + createDBResponse)
252 def requestId = execution.getVariable("mso-request-id")
253 def source = execution.getVariable(prefix+'source')
255 String msoCompletionRequest =
256 """<aetgt:MsoCompletionRequest xmlns:aetgt="http://org.onap/so/workflow/schema/v1"
257 xmlns:ns="http://org.onap/so/request/types/v1">
258 <request-info xmlns="http://org.onap/so/infra/vnf-request/v1">
259 <request-id>${MsoUtils.xmlEscape(requestId)}</request-id>
260 <action>CREATE</action>
261 <source>${MsoUtils.xmlEscape(source)}</source>
263 <aetgt:status-message>Volume Group has been created successfully.</aetgt:status-message>
264 <aetgt:mso-bpel-name>BPMN VF Module Volume action: CREATE</aetgt:mso-bpel-name>
265 </aetgt:MsoCompletionRequest>"""
267 String xmlMsoCompletionRequest = utils.formatXml(msoCompletionRequest)
269 execution.setVariable(prefix+'Success', true)
270 execution.setVariable(prefix+'CompleteMsoProcessRequest', xmlMsoCompletionRequest)
271 msoLogger.debug(" Overall SUCCESS Response going to CompleteMsoProcess - " + "\n" + xmlMsoCompletionRequest)
275 public void prepareFalloutHandlerRequest(DelegateExecution execution, isDebugEnabled) {
277 WorkflowException we = execution.getVariable('WorkflowException')
278 def errorCode = we?.getErrorCode()
279 def errorMessage = we?.getErrorMessage()
281 def requestId = execution.getVariable("mso-request-id")
282 def source = execution.getVariable(prefix+'source')
284 String falloutHandlerRequest =
285 """<aetgt:FalloutHandlerRequest xmlns:aetgt="http://org.onap/so/workflow/schema/v1"
286 xmlns:ns="http://org.onap/so/request/types/v1"
287 xmlns:wfsch="http://org.onap/so/workflow/schema/v1">
288 <request-info xmlns="http://org.onap/so/infra/vnf-request/v1">
289 <request-id>${MsoUtils.xmlEscape(requestId)}</request-id>
290 <action>CREATE</action>
291 <source>${MsoUtils.xmlEscape(source)}</source>
293 <aetgt:WorkflowException>
294 <aetgt:ErrorMessage>${MsoUtils.xmlEscape(errorMessage)}</aetgt:ErrorMessage>
295 <aetgt:ErrorCode>${MsoUtils.xmlEscape(errorCode)}</aetgt:ErrorCode>
296 </aetgt:WorkflowException>
298 </aetgt:FalloutHandlerRequest>"""
301 String xmlHandlerRequest = utils.formatXml(falloutHandlerRequest)
303 execution.setVariable(prefix+'FalloutHandlerRequest', xmlHandlerRequest)
304 msoLogger.error(MessageEnum.BPMN_GENERAL_EXCEPTION_ARG, "Overall Error Response going to FalloutHandler", "BPMN", MsoLogger.getServiceName(), MsoLogger.ErrorCode.UnknownError, "\n" + xmlHandlerRequest);
309 * Query AAI service instance
311 * @param isDebugEnabled
313 public void callRESTQueryAAIServiceInstance(DelegateExecution execution, isDebugEnabled) {
315 def request = execution.getVariable(prefix+"Request")
316 def serviceInstanceId = utils.getNodeText(request, "service-instance-id")
318 AaiUtil aaiUtil = new AaiUtil(this)
319 String aaiEndpoint = aaiUtil.getSearchNodesQueryEndpoint(execution)
321 def String queryAAIRequest = aaiEndpoint + "?search-node-type=service-instance&filter=service-instance-id:EQUALS:" + serviceInstanceId
322 msoLogger.debug("AAI query service instance request: " + queryAAIRequest)
324 APIResponse response = aaiUtil.executeAAIGetCall(execution, queryAAIRequest)
326 String returnCode = response.getStatusCode()
327 String aaiResponseAsString = response.getResponseBodyAsString()
329 msoLogger.debug("AAI query service instance return code: " + returnCode)
330 msoLogger.debug("AAI query service instance response: " + aaiResponseAsString)
332 ExceptionUtil exceptionUtil = new ExceptionUtil()
334 if (returnCode=='200') {
335 msoLogger.debug('Service instance ' + serviceInstanceId + ' found in AAI.')
337 if (returnCode=='404') {
338 def message = 'Service instance ' + serviceInstanceId + ' was not found in AAI. Return code: 404.'
339 msoLogger.debug(message)
340 exceptionUtil.buildAndThrowWorkflowException(execution, 2500, message)
342 WorkflowException aWorkflowException = exceptionUtil.MapAAIExceptionToWorkflowException(aaiResponseAsString, execution)
343 throw new BpmnError("MSOWorkflowException")
348 public void logAndSaveOriginalException(DelegateExecution execution, isDebugLogEnabled) {
349 logWorkflowException(execution, 'CreateVfModuleVolumeInfraV1 caught an event')
350 saveWorkflowException(execution, 'CVMVINFRAV1_originalWorkflowException')
353 public void validateRollbackResponse(DelegateExecution execution, isDebugLogEnabled) {
355 def originalException = execution.getVariable("CVMVINFRAV1_originalWorkflowException")
356 execution.setVariable("WorkflowException", originalException)
357 execution.setVariable("RollbackCompleted", true)