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.openecomp.mso.bpmn.gamma.workflow.service;
23 import java.util.HashMap;
26 import javax.jws.WebMethod;
27 import javax.jws.WebParam;
28 import javax.jws.WebResult;
29 import javax.jws.WebService;
30 import javax.ws.rs.core.Context;
31 import javax.xml.ws.WebServiceContext;
33 import org.camunda.bpm.BpmPlatform;
34 import org.camunda.bpm.engine.MismatchingMessageCorrelationException;
35 import org.camunda.bpm.engine.ProcessEngineServices;
36 import org.camunda.bpm.engine.RuntimeService;
38 import com.att.domain2.workflow.sdnc.adapter.callback.wsdl.v1.SDNCCallbackAdapterPortType;
39 import com.att.domain2.workflow.sdnc.adapter.schema.v1.SDNCAdapterCallbackRequest;
40 import com.att.domain2.workflow.sdnc.adapter.schema.v1.SDNCAdapterResponse;
41 import org.openecomp.mso.bpmn.core.PropertyConfiguration;
42 import org.openecomp.mso.logger.MessageEnum;
43 import org.openecomp.mso.logger.MsoLogger;
48 @WebService(serviceName="SDNCAdapterCallbackService", targetNamespace="http://domain2.att.com/workflow/sdnc/adapter/schema/v1")
49 public class SDNCAdapterCallbackServiceImpl implements SDNCCallbackAdapterPortType {
51 private static MsoLogger msoLogger = MsoLogger.getMsoLogger(MsoLogger.Catalog.BPEL);
52 private final int DEFAULT_RETRY_ATTEMPTS = 60;
53 private final int DEFAULT_SLEEP_TIME = 500;
55 private final String logMarker = "[SDNC-CALLBACK]";
57 @Context WebServiceContext wsContext;
59 private volatile ProcessEngineServices pes4junit = null;
61 @WebMethod(operationName = "SDNCAdapterCallback")
62 @WebResult(name = "SDNCAdapterResponse", targetNamespace = "http://domain2.att.com/workflow/sdnc/adapter/schema/v1", partName = "SDNCAdapterCallbackResponse")
63 public SDNCAdapterResponse sdncAdapterCallback(
64 @WebParam(name = "SDNCAdapterCallbackRequest", targetNamespace = "http://domain2.att.com/workflow/sdnc/adapter/schema/v1", partName = "SDNCAdapterCallbackRequest")
65 SDNCAdapterCallbackRequest sdncAdapterCallbackRequest) {
67 //Callback URL to use http://localhost:8080/mso/SDNCAdapterCallbackService
68 ProcessEngineServices pes = getProcessEngineServices();
69 RuntimeService runtimeService = pes.getRuntimeService();
70 String receivedRequestId = sdncAdapterCallbackRequest.getCallbackHeader().getRequestId();
71 msoLogger.setServiceName("MSO." + "sdncAdapter");
72 msoLogger.setLogContext(receivedRequestId, "N/A");
73 msoLogger.debug(logMarker + "Received callback response:" + sdncAdapterCallbackRequest.toString());
74 SDNCAdapterResponse sdncAdapterResponse;
75 long startTime = System.currentTimeMillis();
77 /* Check to make sure the process instance is reay for correlation*/
78 isReadyforCorrelation(runtimeService, receivedRequestId);
80 msoLogger.debug(logMarker + "*** Received MSO sdncAdapterCallbackService ******");
82 msoLogger.recordAuditEvent (startTime, MsoLogger.StatusCode.COMPLETE, MsoLogger.ResponseCode.Suc, "Call to MSO sdncAdapterCallbackService");
84 msoLogger.debug(logMarker + "Callback response string:\n" + sdncAdapterCallbackRequest.toString());
86 String reqId = receivedRequestId;
87 Map<String,Object> variables = new HashMap<String,Object>();
88 variables.put("SDNCA_requestId", reqId );
89 variables.put("sdncAdapterCallbackRequest", sdncAdapterCallbackRequest.toString());
91 /*Correlating the response with the running instance*/
93 // NOTE: the following loop is a workaround for problems we've had
94 // with reliability of the runtime service. It seems that queries
95 // sometimes return results, and sometimes they don't. This might
96 // be a problem in mysql only. We aren't sure if it affects camunda
97 // on oracle or mariadb. The workaround is to repeat the request
98 // a number of times until it succeeds. If it doesn't succeed after
99 // 60 tries, then we give up.
101 int maxAttempts = DEFAULT_RETRY_ATTEMPTS;
103 int sleepTime = DEFAULT_SLEEP_TIME;
105 Map<String,String> bpmnProperties = getMSOBPMNURNProperties();
106 if (bpmnProperties != null) {
108 maxAttempts = Integer.parseInt(bpmnProperties.get("mso.callbackRetryAttempts"));
109 msoLogger.debug(logMarker + "mso.callbackRetryAttempts=" + maxAttempts);
110 sleepTime = Integer.parseInt(bpmnProperties.get("mso.callbackRetrySleepTime"));
111 msoLogger.debug(logMarker + "mso.callbackRetrySleepTime:" + sleepTime);
112 } catch (Exception ex) {
114 msoLogger.info (MessageEnum.BPMN_SDNC_CALLBACK_EXCEPTION, "BPMN", logMarker
115 + "Error parsing mso.callbackRetrySleepTime/mso.callbackRetryAttempts:"
119 msoLogger.error (MessageEnum.BPMN_SDNC_CALLBACK_EXCEPTION, "BPMN", MsoLogger.getServiceName(), MsoLogger.ErrorCode.UnknownError, logMarker
120 + "Error parsing mso.callbackRetrySleepTime/mso.callbackRetryAttempts:"
129 // sdncAdapterCallbackRequest is the message event name (defined in the bpmn process)
130 runtimeService.createMessageCorrelation("sdncAdapterCallbackRequest")
131 .setVariables(variables)
132 .processInstanceVariableEquals("SDNCA_requestId", reqId).correlate();
133 sdncAdapterResponse = new SDNCAdapterResponse();
134 msoLogger.debug(logMarker + "***** Completed processing of MSO sdncAdapterCallbackService ******");
136 msoLogger.recordAuditEvent (startTime, MsoLogger.StatusCode.COMPLETE, MsoLogger.ResponseCode.Suc, logMarker
137 + "Completed the execution of MSO SDNCAdapterCallbackService.");
139 msoLogger.recordMetricEvent ( startTime, MsoLogger.StatusCode.COMPLETE, MsoLogger.ResponseCode.Suc,
140 logMarker + "Completed the execution of MSO SDNCAdapterCallbackService.", "BPMN",
141 MsoLogger.getServiceName(), "sdncAdapterCallback");
143 return sdncAdapterResponse;
144 } catch(MismatchingMessageCorrelationException e) {
145 msoLogger.debug(logMarker + "[CORM]correlation id mismatch (attempt " + attempt + "/" + maxAttempts + ")");
146 if (attempt == maxAttempts) {
147 // Couldn't correlate requestId to any active flow
148 //MsoLogger logger = MsoLogger.getMsoLogger("SDNCAdapterCallbackService");
150 "SDNC Adapter Callback Service received a SDNC Adapter Callback Request with RequestId '"
152 + "' but that RequestId could not be correlated to any active process - ignoring the Request";
153 sdncAdapterResponse = new SDNCAdapterExceptionResponse(e);
155 msoLogger.error (MessageEnum.BPMN_SDNC_CALLBACK_EXCEPTION, "BPMN", MsoLogger.getServiceName(),
156 MsoLogger.ErrorCode.UnknownError, logMarker + ":" + msg, e);
158 msoLogger.recordAuditEvent (startTime, MsoLogger.StatusCode.COMPLETE, MsoLogger.ResponseCode.Suc, logMarker
159 + "Completed the execution of MSO SDNCAdapterCallbackService." );
161 msoLogger.recordMetricEvent ( startTime, MsoLogger.StatusCode.COMPLETE, MsoLogger.ResponseCode.Suc,
162 logMarker + "Completed the execution of MSO SDNCAdapterCallbackService.", "BPMN",
163 MsoLogger.getServiceName(), "sdncAdapterCallback");
165 return sdncAdapterResponse;
169 Thread.sleep(sleepTime);
170 } catch (InterruptedException e2) {
172 "SDNC Adapter Callback Service received a SDNC Adapter Callback Request with RequestId '"
174 + "' but correlation was interrupted";
175 sdncAdapterResponse = new SDNCAdapterExceptionResponse(e);
177 msoLogger.error (MessageEnum.BPMN_SDNC_CALLBACK_EXCEPTION, "BPMN", MsoLogger.getServiceName(),
178 MsoLogger.ErrorCode.UnknownError, logMarker + ":" + msg, e);
180 msoLogger.recordAuditEvent (startTime, MsoLogger.StatusCode.COMPLETE, MsoLogger.ResponseCode.Suc, logMarker
181 + "Completed the execution of MSO SDNCAdapterCallbackService.");
183 msoLogger.recordMetricEvent ( startTime, MsoLogger.StatusCode.COMPLETE, MsoLogger.ResponseCode.Suc,
184 logMarker + "Completed the execution of MSO SDNCAdapterCallbackService.", "BPMN",
185 MsoLogger.getServiceName(), "sdncAdapterCallback");
187 return sdncAdapterResponse;
196 private Map<String,String> getMSOBPMNURNProperties() {
197 PropertyConfiguration propertyConfiguration = PropertyConfiguration.getInstance();
198 Map<String,String> props = propertyConfiguration.getProperties("mso.bpmn.urn.properties");
202 private void isReadyforCorrelation(RuntimeService runtimeService,
203 String receivedRequestId) {
204 long waitingInstances = runtimeService.createExecutionQuery() //
205 .messageEventSubscriptionName("sdncAdapterCallbackRequest")
206 .processVariableValueEquals("SDNCA_requestId", receivedRequestId).count();
207 //Workaround for performance testing, explicit wait for a second for the transactions to be committed
210 } catch (InterruptedException e1) {
214 while (waitingInstances==0 && retries > 0) {
217 } catch (InterruptedException e) {
219 msoLogger.error (MessageEnum.BPMN_SDNC_CALLBACK_EXCEPTION, "BPMN", MsoLogger.getServiceName(),
220 MsoLogger.ErrorCode.UnknownError, logMarker, e);
222 } // you can still play with the numbers
223 waitingInstances = runtimeService.createExecutionQuery() //
224 .messageEventSubscriptionName("sdncAdapterCallbackRequest")
225 .processVariableValueEquals("SDNCA_requestId", receivedRequestId).count();
230 private ProcessEngineServices getProcessEngineServices() {
231 if (pes4junit == null) {
232 return BpmPlatform.getDefaultProcessEngine();
238 @WebMethod(exclude=true)
239 public void setProcessEngineServices4junit(ProcessEngineServices pes) {
243 public class SDNCAdapterExceptionResponse extends SDNCAdapterResponse {
244 private Exception ex;
246 public SDNCAdapterExceptionResponse(Exception ex) {
251 public Exception getException() {