2 * ============LICENSE_START=======================================================
4 * ================================================================================
5 * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
6 * ================================================================================
7 * Modifications Copyright (c) 2019 Samsung
8 * ================================================================================
9 * Licensed under the Apache License, Version 2.0 (the "License");
10 * you may not use this file except in compliance with the License.
11 * You may obtain a copy of the License at
13 * http://www.apache.org/licenses/LICENSE-2.0
15 * Unless required by applicable law or agreed to in writing, software
16 * distributed under the License is distributed on an "AS IS" BASIS,
17 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18 * See the License for the specific language governing permissions and
19 * limitations under the License.
20 * ============LICENSE_END=========================================================
23 package org.onap.so.bpmn.common.scripts
25 import java.text.SimpleDateFormat
26 import java.net.URLEncoder
28 import org.apache.commons.codec.binary.Base64
29 import org.apache.commons.lang3.*
30 import org.camunda.bpm.engine.delegate.BpmnError
31 import org.camunda.bpm.engine.delegate.DelegateExecution
35 import org.json.JSONObject
37 import org.onap.so.bpmn.core.WorkflowException
38 import org.onap.so.bpmn.core.json.JsonUtils
39 import org.onap.so.bpmn.core.UrnPropertiesReader
40 import org.onap.so.logger.MessageEnum
41 import org.onap.so.logger.MsoLogger
42 import org.slf4j.Logger
43 import org.slf4j.LoggerFactory
48 * This version of SDNCAdapterRest allows for interim notifications to be sent for
49 * any non-final response received from SDNC.
51 class SDNCAdapterRestV2 extends SDNCAdapterRestV1 {
52 private static final Logger logger = LoggerFactory.getLogger( SDNCAdapterRestV2.class);
55 ExceptionUtil exceptionUtil = new ExceptionUtil()
56 JsonUtils jsonUtil = new JsonUtils()
59 * Processes the incoming request.
61 public void preProcessRequest (DelegateExecution execution) {
62 def method = getClass().getSimpleName() + '.preProcessRequest(' +
63 'execution=' + execution.getId() +
65 logger.trace('Entered ' + method)
67 def prefix="SDNCREST_"
68 execution.setVariable("prefix", prefix)
69 setSuccessIndicator(execution, false)
72 // Determine the request type and log the request
74 String request = validateRequest(execution, "mso-request-id")
75 String requestType = jsonUtil.getJsonRootProperty(request)
76 execution.setVariable(prefix + 'requestType', requestType)
77 logger.debug(getProcessKey(execution) + ': ' + prefix + 'requestType = ' + requestType)
78 logger.debug('SDNCAdapterRestV2, request: ' + request)
80 // Determine the SDNCAdapter endpoint
82 String sdncAdapterEndpoint = UrnPropertiesReader.getVariable("mso.adapters.sdnc.rest.endpoint",execution)
84 if (sdncAdapterEndpoint == null || sdncAdapterEndpoint.isEmpty()) {
85 String msg = getProcessKey(execution) + ': mso:adapters:sdnc:rest:endpoint URN mapping is not defined'
87 logger.error("{} {} {} {} {}", MessageEnum.BPMN_GENERAL_EXCEPTION_ARG.toString(), msg, "BPMN",
88 MsoLogger.getServiceName(), MsoLogger.ErrorCode.UnknownError.getValue());
89 exceptionUtil.buildAndThrowWorkflowException(execution, 2000, msg)
92 while (sdncAdapterEndpoint.endsWith('/')) {
93 sdncAdapterEndpoint = sdncAdapterEndpoint.substring(0, sdncAdapterEndpoint.length()-1)
96 String sdncAdapterMethod = null
97 String sdncAdapterUrl = null
98 String sdncAdapterRequest = request
100 if ('SDNCServiceRequest'.equals(requestType)) {
101 // Get the sdncRequestId from the request
103 String sdncRequestId = jsonUtil.getJsonValue(request, requestType + ".sdncRequestId")
105 if (sdncRequestId == null || sdncRequestId.isEmpty()) {
106 String msg = getProcessKey(execution) + ': no sdncRequestId in ' + requestType
108 logger.error("{} {} {} {} {}", MessageEnum.BPMN_GENERAL_EXCEPTION_ARG.toString(), msg, "BPMN",
109 MsoLogger.getServiceName(), MsoLogger.ErrorCode.UnknownError.getValue());
110 exceptionUtil.buildAndThrowWorkflowException(execution, 2000, msg)
113 execution.setVariable('SDNCAResponse_CORRELATOR', sdncRequestId)
114 logger.debug(getProcessKey(execution) + ': SDNCAResponse_CORRELATOR = ' + sdncRequestId)
116 // Get the bpNotificationUrl from the request (just to make sure it's there)
118 String bpNotificationUrl = jsonUtil.getJsonValue(request, requestType + ".bpNotificationUrl")
120 if (bpNotificationUrl == null || bpNotificationUrl.isEmpty()) {
121 String msg = getProcessKey(execution) + ': no bpNotificationUrl in ' + requestType
123 logger.error("{} {} {} {} {}", MessageEnum.BPMN_GENERAL_EXCEPTION_ARG.toString(), msg, "BPMN",
124 MsoLogger.getServiceName(), MsoLogger.ErrorCode.UnknownError.getValue());
125 exceptionUtil.buildAndThrowWorkflowException(execution, 2000, msg)
128 sdncAdapterMethod = 'POST'
129 sdncAdapterUrl = sdncAdapterEndpoint
132 String msg = getProcessKey(execution) + ': Unsupported request type: ' + requestType
134 logger.error("{} {} {} {} {}", MessageEnum.BPMN_GENERAL_EXCEPTION_ARG.toString(), msg, "BPMN",
135 MsoLogger.getServiceName(), MsoLogger.ErrorCode.UnknownError.getValue());
136 exceptionUtil.buildAndThrowWorkflowException(execution, 2000, msg)
139 execution.setVariable(prefix + 'sdncAdapterMethod', sdncAdapterMethod)
140 logger.debug(getProcessKey(execution) + ': ' + prefix + 'sdncAdapterMethod = ' + sdncAdapterMethod)
141 execution.setVariable(prefix + 'sdncAdapterUrl', sdncAdapterUrl)
142 logger.debug(getProcessKey(execution) + ': ' + prefix + 'sdncAdapterUrl = ' + sdncAdapterUrl)
143 execution.setVariable(prefix + 'sdncAdapterRequest', sdncAdapterRequest)
144 logger.debug(getProcessKey(execution) + ': ' + prefix + 'sdncAdapterRequest = \n' + sdncAdapterRequest)
146 // Get the Basic Auth credentials for the SDNCAdapter (yes... we ARE using the PO adapters credentials)
148 String basicAuthValue = UrnPropertiesReader.getVariable("mso.adapters.po.auth",execution)
150 if (basicAuthValue == null || basicAuthValue.isEmpty()) {
151 logger.debug(getProcessKey(execution) + ": mso:adapters:po:auth URN mapping is not defined")
152 logger.error("{} {} {} {} {}", MessageEnum.BPMN_GENERAL_EXCEPTION_ARG.toString(),
153 getProcessKey(execution) + ": mso:adapters:po:auth URN mapping is not defined", "BPMN",
154 MsoLogger.getServiceName(), MsoLogger.ErrorCode.UnknownError.getValue());
157 def encodedString = utils.getBasicAuth(basicAuthValue, UrnPropertiesReader.getVariable("mso.msoKey", execution))
158 execution.setVariable(prefix + 'basicAuthHeaderValue', encodedString)
159 } catch (IOException ex) {
160 logger.debug(getProcessKey(execution) + ": Unable to encode BasicAuth credentials for SDNCAdapter")
161 logger.error("{} {} {} {} {}", MessageEnum.BPMN_GENERAL_EXCEPTION_ARG.toString(),
162 getProcessKey(execution) + ": Unable to encode BasicAuth credentials for SDNCAdapter",
163 "BPMN", MsoLogger.getServiceName(), MsoLogger.ErrorCode.UnknownError.getValue());
167 // Set the timeout value, e.g. PT5M. It may be specified in the request as the
168 // bpTimeout value. If it's not in the request, use the URN mapping value.
170 String timeout = jsonUtil.getJsonValue(request, requestType + ".bpTimeout")
172 // in addition to null/empty, also need to verify that the timer value is a valid duration "P[n]T[n]H|M|S"
173 String timerRegex = "PT[0-9]+[HMS]";
174 if (timeout == null || timeout.isEmpty() || !timeout.matches(timerRegex)) {
175 logger.debug(getProcessKey(execution) + ': preProcessRequest(): null/empty/invalid bpTimeout value. Using "mso.adapters.sdnc.timeout"')
176 timeout = UrnPropertiesReader.getVariable("mso.adapters.sdnc.timeout", execution)
179 // the timeout could still be null at this point if the config parm is missing/undefined
180 // forced to log (so OPs can fix the config) and temporarily use a hard coded value of 10 seconds
181 if (timeout == null) {
182 logger.warn("Service Name: {} Error: {}", 'preProcessRequest()', 'property "mso.adapters.sdnc.timeout" is missing/undefined. Using "PT10S"')
186 execution.setVariable(prefix + 'timeout', timeout)
187 logger.debug(getProcessKey(execution) + ': ' + prefix + 'timeout = ' + timeout)
188 } catch (BpmnError e) {
190 } catch (Exception e) {
191 String msg = 'Caught exception in ' + method + ": " + e
193 logger.error("{} {} {} {} {}", MessageEnum.BPMN_GENERAL_EXCEPTION_ARG.toString(), msg, "BPMN",
194 MsoLogger.getServiceName(), MsoLogger.ErrorCode.UnknownError.getValue());
195 exceptionUtil.buildAndThrowWorkflowException(execution, 2000, msg)
200 * Processes a callback. Check for possible interim notification.
202 public void processCallback(DelegateExecution execution){
203 def method = getClass().getSimpleName() + '.processCallback(' +
204 'execution=' + execution.getId() +
206 logger.trace('Entered ' + method)
208 String prefix = execution.getVariable('prefix')
209 String callback = execution.getVariable('SDNCAResponse_MESSAGE')
210 logger.debug("Incoming SDNC Rest Callback is: " + callback)
213 logger.debug(getProcessKey(execution) + ": received callback:\n" + callback)
215 int callbackNumber = 1
216 while (execution.getVariable(prefix + 'callback' + callbackNumber) != null) {
220 execution.setVariable(prefix + 'callback' + callbackNumber, callback)
221 execution.removeVariable('SDNCAResponse_MESSAGE')
223 String responseType = jsonUtil.getJsonRootProperty(callback)
225 // Get the ackFinalIndicator and make sure it's either Y or N. Default to Y.
226 String ackFinalIndicator = jsonUtil.getJsonValue(callback, responseType + ".ackFinalIndicator")
228 if (!'N'.equals(ackFinalIndicator)) {
229 ackFinalIndicator = 'Y'
232 execution.setVariable(prefix + "ackFinalIndicator", ackFinalIndicator)
234 if (responseType.endsWith('Error')) {
235 sdncAdapterBuildWorkflowException(execution, callback)
238 // Check for possible interim notification
239 execution.setVariable(prefix + "interimNotification", null)
240 execution.setVariable(prefix + "doInterimNotification", false)
241 if ('N'.equals(ackFinalIndicator)) {
242 def interimNotification = execution.getVariable(prefix + "InterimNotification" + callbackNumber)
243 if (interimNotification != null) {
244 execution.setVariable(prefix + "interimNotification", interimNotification)
245 execution.setVariable(prefix + "doInterimNotification", true)
249 } catch (Exception e) {
250 callback = callback == null || String.valueOf(callback).isEmpty() ? "NONE" : callback
251 String msg = "Received error from SDNCAdapter: " + callback
252 logger.debug(getProcessKey(execution) + ': ' + msg)
253 exceptionUtil.buildWorkflowException(execution, 5300, msg)
258 * Prepare to send an interim notification by extracting the variable/value definitions
259 * in the interimNotification JSON object and placing them in the execution. These
260 * variable/value definitions will be passed to the notification service.
262 public void prepareInterimNotification(DelegateExecution execution) {
263 def method = getClass().getSimpleName() + '.prepareInterimNotification(' +
264 'execution=' + execution.getId() +
266 logger.trace('Entered ' + method)
268 String prefix = execution.getVariable('prefix')
269 logger.debug("Preparing Interim Notification")
272 def interimNotification = execution.getVariable(prefix + "interimNotification")
273 logger.debug("Preparing Interim Notification:\n" + JsonUtils.prettyJson(interimNotification))
275 for (int i = 0; ; i++) {
276 def variable = JsonUtils.getJsonParamValue(interimNotification, 'variableList', 'variable', i)
278 if (variable == null) {
282 def String variableName = JsonUtils.getJsonValue(variable, "name")
283 if ((variableName != null) && !variableName.isEmpty()) {
284 def variableValue = JsonUtils.getJsonValue(variable, "value")
285 execution.setVariable(variableName, variableValue)
286 logger.debug("Setting "+ variableName + "=" + variableValue)
290 } catch (Exception e) {
291 String msg = "Error preparing interim notification"
292 logger.debug(getProcessKey(execution) + ': ' + msg)
293 exceptionUtil.buildWorkflowException(execution, 5300, msg)