[MSO-8] Update the maven dependency
[so.git] / bpmn / MSOCommonBPMN / src / main / java / org / openecomp / mso / bpmn / common / workflow / service / SDNCAdapterCallbackServiceImpl.java
1 /*-
2  * ============LICENSE_START=======================================================
3  * OPENECOMP - MSO
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
10  * 
11  *      http://www.apache.org/licenses/LICENSE-2.0
12  * 
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=========================================================
19  */
20
21 package org.openecomp.mso.bpmn.common.workflow.service;
22
23 import java.util.HashMap;
24 import java.util.Map;
25
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;
32
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;
37 import org.openecomp.mso.bpmn.common.adapter.sdnc.SDNCAdapterCallbackRequest;
38 import org.openecomp.mso.bpmn.common.adapter.sdnc.SDNCAdapterResponse;
39 import org.openecomp.mso.bpmn.common.adapter.sdnc.SDNCCallbackAdapterPortType;
40 import org.openecomp.mso.bpmn.core.PropertyConfiguration;
41 import org.openecomp.mso.logger.MessageEnum;
42 import org.openecomp.mso.logger.MsoLogger;
43 /**
44  * @version 1.0
45  *  
46  */
47 @WebService(serviceName="SDNCAdapterCallbackService", targetNamespace="http://org.openecomp/workflow/sdnc/adapter/schema/v1")
48 public class SDNCAdapterCallbackServiceImpl implements SDNCCallbackAdapterPortType {
49
50         private static MsoLogger msoLogger = MsoLogger.getMsoLogger(MsoLogger.Catalog.BPEL);
51         private final int DEFAULT_RETRY_ATTEMPTS = 60;
52         private final int DEFAULT_SLEEP_TIME = 500;
53
54         private final String logMarker = "[SDNC-CALLBACK]";
55
56         @Context WebServiceContext wsContext;
57
58         private volatile ProcessEngineServices pes4junit = null;
59
60         @WebMethod(operationName = "SDNCAdapterCallback")
61     @WebResult(name = "SDNCAdapterResponse", targetNamespace = "http://org.openecomp/workflow/sdnc/adapter/schema/v1", partName = "SDNCAdapterCallbackResponse")
62     public SDNCAdapterResponse sdncAdapterCallback(
63             @WebParam(name = "SDNCAdapterCallbackRequest", targetNamespace = "http://org.openecomp/workflow/sdnc/adapter/schema/v1", partName = "SDNCAdapterCallbackRequest")
64             SDNCAdapterCallbackRequest sdncAdapterCallbackRequest) {
65
66                 //Callback URL to use http://localhost:28080/mso/SDNCAdapterCallbackService
67                 ProcessEngineServices pes = getProcessEngineServices();
68                 RuntimeService runtimeService = pes.getRuntimeService();
69                 String receivedRequestId = sdncAdapterCallbackRequest.getCallbackHeader().getRequestId();
70                 MsoLogger.setServiceName("MSO." + "sdncAdapter");
71                 MsoLogger.setLogContext(receivedRequestId, "N/A");
72                 msoLogger.debug(logMarker + "Received callback response:" + sdncAdapterCallbackRequest.toString());
73                 SDNCAdapterResponse sdncAdapterResponse;
74                 long startTime = System.currentTimeMillis();
75
76                 /* Check to make sure the process instance is reay for correlation*/
77                 isReadyforCorrelation(runtimeService, receivedRequestId);
78
79                 msoLogger.debug(logMarker + "*** Received MSO sdncAdapterCallbackService ******");
80                 
81                 msoLogger.recordAuditEvent (startTime, MsoLogger.StatusCode.COMPLETE, MsoLogger.ResponseCode.Suc, "Call to MSO sdncAdapterCallbackService");            
82                 
83                 msoLogger.debug(logMarker + "Callback response string:\n"  + sdncAdapterCallbackRequest.toString());
84
85                 String reqId = receivedRequestId;
86                 Map<String,Object> variables = new HashMap<String,Object>();
87                 variables.put("SDNCA_requestId", reqId );
88                 variables.put("sdncAdapterCallbackRequest", sdncAdapterCallbackRequest.toString());
89
90                 /*Correlating the response with the running instance*/
91
92                 // NOTE: the following loop is a workaround for problems we've had
93                 // with reliability of the runtime service.  It seems that queries
94                 // sometimes return results, and sometimes they don't.  This might
95                 // be a problem in mysql only.  We aren't sure if it affects camunda
96                 // on oracle or mariadb.  The workaround is to repeat the request
97                 // a number of times until it succeeds.  If it doesn't succeed after
98                 // 60 tries, then we give up.
99
100                 int maxAttempts = DEFAULT_RETRY_ATTEMPTS;
101                 int attempt = 1;
102                 int sleepTime = DEFAULT_SLEEP_TIME;
103
104                 Map<String,String> bpmnProperties = getMSOBPMNURNProperties();
105                 if (bpmnProperties != null) {
106                         try {
107                                 maxAttempts = Integer.parseInt(bpmnProperties.get("mso.callbackRetryAttempts"));
108                                 msoLogger.debug(logMarker + "mso.callbackRetryAttempts=" + maxAttempts);
109                                 sleepTime = Integer.parseInt(bpmnProperties.get("mso.callbackRetrySleepTime"));
110                                 msoLogger.debug(logMarker + "mso.callbackRetrySleepTime:" + sleepTime);
111                         } catch (Exception ex) {
112                                 
113                                 msoLogger.info (MessageEnum.BPMN_SDNC_CALLBACK_EXCEPTION, "BPMN", logMarker 
114                                                 + "Error parsing mso.callbackRetrySleepTime/mso.callbackRetryAttempts:" 
115                                                 + sleepTime + ":" 
116                                                 + maxAttempts);
117                                 
118                                 msoLogger.error (MessageEnum.BPMN_SDNC_CALLBACK_EXCEPTION, "BPMN", MsoLogger.getServiceName(), MsoLogger.ErrorCode.UnknownError, logMarker 
119                                                 + "Error parsing mso.callbackRetrySleepTime/mso.callbackRetryAttempts:" 
120                                                 + sleepTime + ":" 
121                                                 + maxAttempts);
122                                 
123                         }
124                 }
125
126                 while (true) {
127                         try {
128                                 // sdncAdapterCallbackRequest is the message event name (defined in the bpmn process)
129                                 runtimeService.createMessageCorrelation("sdncAdapterCallbackRequest")
130                                         .setVariables(variables)
131                                         .processInstanceVariableEquals("SDNCA_requestId", reqId).correlate();
132                                 sdncAdapterResponse = new SDNCAdapterResponse();
133                                 msoLogger.debug(logMarker + "***** Completed processing of MSO sdncAdapterCallbackService ******");
134                                 
135                                 msoLogger.recordAuditEvent (startTime, MsoLogger.StatusCode.COMPLETE, MsoLogger.ResponseCode.Suc, logMarker 
136                                                 + "Completed the execution of MSO SDNCAdapterCallbackService.");
137                                 
138                                 msoLogger.recordMetricEvent ( startTime, MsoLogger.StatusCode.COMPLETE, MsoLogger.ResponseCode.Suc, 
139                                                 logMarker + "Completed the execution of MSO SDNCAdapterCallbackService.", "BPMN", 
140                                                 MsoLogger.getServiceName(), "sdncAdapterCallback");
141                                 
142                                 return sdncAdapterResponse;
143                         } catch(MismatchingMessageCorrelationException e) {
144                                 msoLogger.debug(logMarker + "[CORM]correlation id mismatch (attempt " + attempt + "/" + maxAttempts + ")");
145                                 if (attempt == maxAttempts) {
146                                         // Couldn't correlate requestId to any active flow
147                                         //MsoLogger logger = MsoLogger.getMsoLogger("SDNCAdapterCallbackService");
148                                         String msg =
149                                                 "SDNC Adapter Callback Service received a SDNC Adapter Callback Request with RequestId '"
150                                                                 + receivedRequestId
151                                                                 + "' but that RequestId could not be correlated to any active process - ignoring the Request";
152                                         sdncAdapterResponse = new SDNCAdapterExceptionResponse(e);
153                                         
154                                         msoLogger.error (MessageEnum.BPMN_SDNC_CALLBACK_EXCEPTION, "BPMN", MsoLogger.getServiceName(), 
155                                                         MsoLogger.ErrorCode.UnknownError, logMarker + ":" + msg, e);
156                                         
157                                         msoLogger.recordAuditEvent (startTime, MsoLogger.StatusCode.COMPLETE, MsoLogger.ResponseCode.Suc, logMarker 
158                                                         + "Completed the execution of MSO SDNCAdapterCallbackService." );
159                                         
160                                         msoLogger.recordMetricEvent ( startTime, MsoLogger.StatusCode.COMPLETE, MsoLogger.ResponseCode.Suc, 
161                                                         logMarker + "Completed the execution of MSO SDNCAdapterCallbackService.", "BPMN", 
162                                                         MsoLogger.getServiceName(), "sdncAdapterCallback");
163                                         
164                                         return sdncAdapterResponse;
165                                 }
166
167                                 try {
168                                         Thread.sleep(sleepTime);
169                                 } catch (InterruptedException e2) {
170                                         String msg =
171                                                 "SDNC Adapter Callback Service received a SDNC Adapter Callback Request with RequestId '"
172                                                                 + receivedRequestId
173                                                                 + "' but correlation was interrupted";
174                                         sdncAdapterResponse = new SDNCAdapterExceptionResponse(e);
175                                         
176                                         msoLogger.error (MessageEnum.BPMN_SDNC_CALLBACK_EXCEPTION, "BPMN", MsoLogger.getServiceName(), 
177                                                         MsoLogger.ErrorCode.UnknownError, logMarker + ":" + msg, e);
178                                         
179                                         msoLogger.recordAuditEvent (startTime, MsoLogger.StatusCode.COMPLETE, MsoLogger.ResponseCode.Suc, logMarker 
180                                                         + "Completed the execution of MSO SDNCAdapterCallbackService.");
181                                         
182                                         msoLogger.recordMetricEvent ( startTime, MsoLogger.StatusCode.COMPLETE, MsoLogger.ResponseCode.Suc, 
183                                                         logMarker + "Completed the execution of MSO SDNCAdapterCallbackService.", "BPMN", 
184                                                         MsoLogger.getServiceName(), "sdncAdapterCallback");
185                                         
186                                         return sdncAdapterResponse;
187                                 }
188                         }
189
190                         attempt++;
191                 }
192         }
193
194
195         private Map<String,String> getMSOBPMNURNProperties() {
196                 PropertyConfiguration propertyConfiguration = PropertyConfiguration.getInstance();
197                 Map<String,String> props = propertyConfiguration.getProperties("mso.bpmn.urn.properties");
198                 return props;
199         }
200
201         private void isReadyforCorrelation(RuntimeService runtimeService,
202                         String receivedRequestId) {
203                 long waitingInstances = runtimeService.createExecutionQuery() //
204                                                                 .messageEventSubscriptionName("sdncAdapterCallbackRequest")
205                                                                 .processVariableValueEquals("SDNCA_requestId", receivedRequestId).count();
206                 //Workaround for performance testing, explicit wait for a second for the transactions to be committed
207                 try {
208                         Thread.sleep(1000);
209                 } catch (InterruptedException e1) {
210                 }
211
212                 int retries = 50;
213                 while (waitingInstances==0 && retries > 0) {
214                   try {
215                         Thread.sleep(100);
216                 } catch (InterruptedException e) {
217                         
218                         msoLogger.error (MessageEnum.BPMN_SDNC_CALLBACK_EXCEPTION, "BPMN", MsoLogger.getServiceName(), 
219                                         MsoLogger.ErrorCode.UnknownError, logMarker, e);
220                         
221                 } // you can still play with the numbers
222                   waitingInstances = runtimeService.createExecutionQuery() //
223                           .messageEventSubscriptionName("sdncAdapterCallbackRequest")
224                           .processVariableValueEquals("SDNCA_requestId", receivedRequestId).count();
225                   retries--;
226                 }
227         }
228
229         private ProcessEngineServices getProcessEngineServices() {
230                 if (pes4junit == null) {
231                         return BpmPlatform.getDefaultProcessEngine();
232                 } else {
233                         return pes4junit;
234                 }
235         }
236
237         @WebMethod(exclude=true)
238         public void setProcessEngineServices4junit(ProcessEngineServices pes) {
239                 pes4junit = pes;
240         }
241
242         public class SDNCAdapterExceptionResponse extends SDNCAdapterResponse {
243                 private Exception ex;
244
245                 public SDNCAdapterExceptionResponse(Exception ex) {
246                         super();
247                         this.ex = ex;
248                 }
249
250                 public Exception getException() {
251                         return ex;
252                 }
253         }
254 }