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 java.text.SimpleDateFormat
24 import java.net.URLEncoder
26 import org.apache.commons.codec.binary.Base64
27 import org.apache.commons.lang3.*
28 import org.camunda.bpm.engine.delegate.BpmnError
29 import org.camunda.bpm.engine.delegate.DelegateExecution
33 import org.json.JSONObject
35 import org.onap.so.bpmn.core.WorkflowException
36 import org.onap.so.bpmn.core.json.JsonUtils
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.core.UrnPropertiesReader
41 import org.onap.so.logger.MessageEnum
42 import org.onap.so.logger.MsoLogger
47 * This version of SDNCAdapterRest allows for interim notifications to be sent for
48 * any non-final response received from SDNC.
50 class SDNCAdapterRestV2 extends SDNCAdapterRestV1 {
51 private static final MsoLogger msoLogger = MsoLogger.getMsoLogger(MsoLogger.Catalog.BPEL, SDNCAdapterRestV2.class);
54 ExceptionUtil exceptionUtil = new ExceptionUtil()
55 JsonUtils jsonUtil = new JsonUtils()
58 * Processes the incoming request.
60 public void preProcessRequest (DelegateExecution execution) {
61 def method = getClass().getSimpleName() + '.preProcessRequest(' +
62 'execution=' + execution.getId() +
64 msoLogger.trace('Entered ' + method)
66 def prefix="SDNCREST_"
67 execution.setVariable("prefix", prefix)
68 setSuccessIndicator(execution, false)
71 // Determine the request type and log the request
73 String request = validateRequest(execution, "mso-request-id")
74 String requestType = jsonUtil.getJsonRootProperty(request)
75 execution.setVariable(prefix + 'requestType', requestType)
76 msoLogger.debug(getProcessKey(execution) + ': ' + prefix + 'requestType = ' + requestType)
77 msoLogger.debug('SDNCAdapterRestV2, request: ' + request)
79 // Determine the SDNCAdapter endpoint
81 String sdncAdapterEndpoint = UrnPropertiesReader.getVariable("mso.adapters.sdnc.rest.endpoint",execution)
83 if (sdncAdapterEndpoint == null || sdncAdapterEndpoint.isEmpty()) {
84 String msg = getProcessKey(execution) + ': mso:adapters:sdnc:rest:endpoint URN mapping is not defined'
86 msoLogger.error(MessageEnum.BPMN_GENERAL_EXCEPTION_ARG, msg, "BPMN", MsoLogger.getServiceName(), MsoLogger.ErrorCode.UnknownError, "");
87 exceptionUtil.buildAndThrowWorkflowException(execution, 2000, msg)
90 while (sdncAdapterEndpoint.endsWith('/')) {
91 sdncAdapterEndpoint = sdncAdapterEndpoint.substring(0, sdncAdapterEndpoint.length()-1)
94 String sdncAdapterMethod = null
95 String sdncAdapterUrl = null
96 String sdncAdapterRequest = request
98 if ('SDNCServiceRequest'.equals(requestType)) {
99 // Get the sdncRequestId from the request
101 String sdncRequestId = jsonUtil.getJsonValue(request, requestType + ".sdncRequestId")
103 if (sdncRequestId == null || sdncRequestId.isEmpty()) {
104 String msg = getProcessKey(execution) + ': no sdncRequestId in ' + requestType
106 msoLogger.error(MessageEnum.BPMN_GENERAL_EXCEPTION_ARG, msg, "BPMN", MsoLogger.getServiceName(), MsoLogger.ErrorCode.UnknownError, "");
107 exceptionUtil.buildAndThrowWorkflowException(execution, 2000, msg)
110 execution.setVariable('SDNCAResponse_CORRELATOR', sdncRequestId)
111 msoLogger.debug(getProcessKey(execution) + ': SDNCAResponse_CORRELATOR = ' + sdncRequestId)
113 // Get the bpNotificationUrl from the request (just to make sure it's there)
115 String bpNotificationUrl = jsonUtil.getJsonValue(request, requestType + ".bpNotificationUrl")
117 if (bpNotificationUrl == null || bpNotificationUrl.isEmpty()) {
118 String msg = getProcessKey(execution) + ': no bpNotificationUrl in ' + requestType
120 msoLogger.error(MessageEnum.BPMN_GENERAL_EXCEPTION_ARG, msg, "BPMN", MsoLogger.getServiceName(), MsoLogger.ErrorCode.UnknownError, "");
121 exceptionUtil.buildAndThrowWorkflowException(execution, 2000, msg)
124 sdncAdapterMethod = 'POST'
125 sdncAdapterUrl = sdncAdapterEndpoint
128 String msg = getProcessKey(execution) + ': Unsupported request type: ' + requestType
130 msoLogger.error(MessageEnum.BPMN_GENERAL_EXCEPTION_ARG, msg, "BPMN", MsoLogger.getServiceName(), MsoLogger.ErrorCode.UnknownError, "");
131 exceptionUtil.buildAndThrowWorkflowException(execution, 2000, msg)
134 execution.setVariable(prefix + 'sdncAdapterMethod', sdncAdapterMethod)
135 msoLogger.debug(getProcessKey(execution) + ': ' + prefix + 'sdncAdapterMethod = ' + sdncAdapterMethod)
136 execution.setVariable(prefix + 'sdncAdapterUrl', sdncAdapterUrl)
137 msoLogger.debug(getProcessKey(execution) + ': ' + prefix + 'sdncAdapterUrl = ' + sdncAdapterUrl)
138 execution.setVariable(prefix + 'sdncAdapterRequest', sdncAdapterRequest)
139 msoLogger.debug(getProcessKey(execution) + ': ' + prefix + 'sdncAdapterRequest = \n' + sdncAdapterRequest)
141 // Get the Basic Auth credentials for the SDNCAdapter (yes... we ARE using the PO adapters credentials)
143 String basicAuthValue = UrnPropertiesReader.getVariable("mso.adapters.po.auth",execution)
145 if (basicAuthValue == null || basicAuthValue.isEmpty()) {
146 msoLogger.debug(getProcessKey(execution) + ": mso:adapters:po:auth URN mapping is not defined")
147 msoLogger.error(MessageEnum.BPMN_GENERAL_EXCEPTION_ARG, getProcessKey(execution) + ": mso:adapters:po:auth URN mapping is not defined", "BPMN", MsoLogger.getServiceName(), MsoLogger.ErrorCode.UnknownError, "");
150 def encodedString = utils.getBasicAuth(basicAuthValue, UrnPropertiesReader.getVariable("mso.msoKey", execution))
151 execution.setVariable(prefix + 'basicAuthHeaderValue', encodedString)
152 } catch (IOException ex) {
153 msoLogger.debug(getProcessKey(execution) + ": Unable to encode BasicAuth credentials for SDNCAdapter")
154 msoLogger.error(MessageEnum.BPMN_GENERAL_EXCEPTION_ARG, getProcessKey(execution) + ": Unable to encode BasicAuth credentials for SDNCAdapter", "BPMN", MsoLogger.getServiceName(), MsoLogger.ErrorCode.UnknownError, "");
158 // Set the timeout value, e.g. PT5M. It may be specified in the request as the
159 // bpTimeout value. If it's not in the request, use the URN mapping value.
161 String timeout = jsonUtil.getJsonValue(request, requestType + ".bpTimeout")
163 // in addition to null/empty, also need to verify that the timer value is a valid duration "P[n]T[n]H|M|S"
164 String timerRegex = "PT[0-9]+[HMS]";
165 if (timeout == null || timeout.isEmpty() || !timeout.matches(timerRegex)) {
166 msoLogger.debug(getProcessKey(execution) + ': preProcessRequest(): null/empty/invalid bpTimeout value. Using "mso.adapters.sdnc.timeout"')
167 timeout = UrnPropertiesReader.getVariable("mso.adapters.sdnc.timeout", execution)
170 // the timeout could still be null at this point if the config parm is missing/undefined
171 // forced to log (so OPs can fix the config) and temporarily use a hard coded value of 10 seconds
172 if (timeout == null) {
173 msoLogger.warnSimple('preProcessRequest()', 'property "mso.adapters.sdnc.timeout" is missing/undefined. Using "PT10S"')
177 execution.setVariable(prefix + 'timeout', timeout)
178 msoLogger.debug(getProcessKey(execution) + ': ' + prefix + 'timeout = ' + timeout)
179 } catch (BpmnError e) {
181 } catch (Exception e) {
182 String msg = 'Caught exception in ' + method + ": " + e
184 msoLogger.error(MessageEnum.BPMN_GENERAL_EXCEPTION_ARG, msg, "BPMN", MsoLogger.getServiceName(), MsoLogger.ErrorCode.UnknownError, "");
185 exceptionUtil.buildAndThrowWorkflowException(execution, 2000, msg)
190 * Processes a callback. Check for possible interim notification.
192 public void processCallback(DelegateExecution execution){
193 def method = getClass().getSimpleName() + '.processCallback(' +
194 'execution=' + execution.getId() +
196 msoLogger.trace('Entered ' + method)
198 String prefix = execution.getVariable('prefix')
199 String callback = execution.getVariable('SDNCAResponse_MESSAGE')
200 msoLogger.debug("Incoming SDNC Rest Callback is: " + callback)
203 msoLogger.debug(getProcessKey(execution) + ": received callback:\n" + callback)
205 int callbackNumber = 1
206 while (execution.getVariable(prefix + 'callback' + callbackNumber) != null) {
210 execution.setVariable(prefix + 'callback' + callbackNumber, callback)
211 execution.removeVariable('SDNCAResponse_MESSAGE')
213 String responseType = jsonUtil.getJsonRootProperty(callback)
215 // Get the ackFinalIndicator and make sure it's either Y or N. Default to Y.
216 String ackFinalIndicator = jsonUtil.getJsonValue(callback, responseType + ".ackFinalIndicator")
218 if (!'N'.equals(ackFinalIndicator)) {
219 ackFinalIndicator = 'Y'
222 execution.setVariable(prefix + "ackFinalIndicator", ackFinalIndicator)
224 if (responseType.endsWith('Error')) {
225 sdncAdapterBuildWorkflowException(execution, callback)
228 // Check for possible interim notification
229 execution.setVariable(prefix + "interimNotification", null)
230 execution.setVariable(prefix + "doInterimNotification", false)
231 if ('N'.equals(ackFinalIndicator)) {
232 def interimNotification = execution.getVariable(prefix + "InterimNotification" + callbackNumber)
233 if (interimNotification != null) {
234 execution.setVariable(prefix + "interimNotification", interimNotification)
235 execution.setVariable(prefix + "doInterimNotification", true)
239 } catch (Exception e) {
240 callback = callback == null || String.valueOf(callback).isEmpty() ? "NONE" : callback
241 String msg = "Received error from SDNCAdapter: " + callback
242 msoLogger.debug(getProcessKey(execution) + ': ' + msg)
243 exceptionUtil.buildWorkflowException(execution, 5300, msg)
248 * Prepare to send an interim notification by extracting the variable/value definitions
249 * in the interimNotification JSON object and placing them in the execution. These
250 * variable/value definitions will be passed to the notification service.
252 public void prepareInterimNotification(DelegateExecution execution) {
253 def method = getClass().getSimpleName() + '.prepareInterimNotification(' +
254 'execution=' + execution.getId() +
256 msoLogger.trace('Entered ' + method)
258 String prefix = execution.getVariable('prefix')
259 msoLogger.debug("Preparing Interim Notification")
262 def interimNotification = execution.getVariable(prefix + "interimNotification")
263 msoLogger.debug("Preparing Interim Notification:\n" + JsonUtils.prettyJson(interimNotification))
265 for (int i = 0; ; i++) {
266 def variable = JsonUtils.getJsonParamValue(interimNotification, 'variableList', 'variable', i)
268 if (variable == null) {
272 def String variableName = JsonUtils.getJsonValue(variable, "name")
273 if ((variableName != null) && !variableName.isEmpty()) {
274 def variableValue = JsonUtils.getJsonValue(variable, "value")
275 execution.setVariable(variableName, variableValue)
276 msoLogger.debug("Setting "+ variableName + "=" + variableValue)
280 } catch (Exception e) {
281 String msg = "Error preparing interim notification"
282 msoLogger.debug(getProcessKey(execution) + ': ' + msg)
283 exceptionUtil.buildWorkflowException(execution, 5300, msg)