Containerization feature of SO
[so.git] / bpmn / MSOCommonBPMN / src / main / java / org / onap / so / bpmn / common / workflow / context / WorkflowContextHolder.java
1 package org.onap.so.bpmn.common.workflow.context;
2 /*-
3  * ============LICENSE_START=======================================================
4  * ONAP - SO
5  * ================================================================================
6  * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
7  * ================================================================================
8  * Licensed under the Apache License, Version 2.0 (the "License");
9  * you may not use this file except in compliance with the License.
10  * You may obtain a copy of the License at
11  * 
12  *      http://www.apache.org/licenses/LICENSE-2.0
13  * 
14  * Unless required by applicable law or agreed to in writing, software
15  * distributed under the License is distributed on an "AS IS" BASIS,
16  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17  * See the License for the specific language governing permissions and
18  * limitations under the License.
19  * ============LICENSE_END=========================================================
20  */
21
22
23
24 import java.util.concurrent.DelayQueue;
25 import java.util.concurrent.TimeUnit;
26
27 import org.onap.so.logger.MessageEnum;
28 import org.onap.so.logger.MsoLogger;
29 import org.springframework.stereotype.Component;
30
31 /**
32  * Workflow Context Holder instance which can be accessed elsewhere either in groovy scripts or Java
33  * @version 1.0
34  *
35  */
36
37 @Component
38 public class WorkflowContextHolder {
39
40         private static MsoLogger msoLogger = MsoLogger.getMsoLogger(MsoLogger.Catalog.BPEL,WorkflowContextHolder.class);
41         private static final String logMarker = "[WORKFLOW-CONTEXT-HOLDER]";
42         private static WorkflowContextHolder instance = null;
43         
44         
45         private long defaultContextTimeout=60000;
46
47         /**
48          * Delay Queue which holds workflow context holder objects
49          */
50         private final DelayQueue<WorkflowContext> responseQueue = new DelayQueue<>();
51         private final TimeoutThread timeoutThread = new TimeoutThread();
52
53         private WorkflowContextHolder() {
54                 timeoutThread.start();
55         }
56
57         /**
58          * Singleton holder which eliminates hot lock
59          * Since the JVM synchronizes static method there is no synchronization needed for this method
60          * @return
61          */
62         public static synchronized WorkflowContextHolder getInstance() {
63                 if (instance == null) {
64                         instance = new WorkflowContextHolder();
65                 }
66                 return instance;
67         }
68         
69         public void put(WorkflowContext context) {
70                 msoLogger.debug(logMarker + " Adding context to the queue: "
71                         + context.getRequestId());
72                 responseQueue.put(context);
73         }
74         
75         public void remove(WorkflowContext context) {
76                 msoLogger.debug(logMarker + " Removing context from the queue: "
77                         + context.getRequestId());
78                 responseQueue.remove(context);
79         }
80         
81         public WorkflowContext getWorkflowContext(String requestId) {
82                 // Note: DelayQueue interator is threadsafe
83                 for (WorkflowContext context : responseQueue) {
84                         if (requestId.equals(context.getRequestId())) {
85                                 msoLogger.debug("Found context for request id: " + requestId);
86                                 return context;
87                         }
88                 }
89
90                 msoLogger.debug("Unable to find context for request id: " + requestId);
91                 return null;
92         }
93         
94         /**
95          * Builds the callback response object to respond to client
96          * @param processKey
97          * @param processInstanceId
98          * @param requestId
99          * @param callbackResponse
100          * @return
101          */
102         public void processCallback(String processKey, String processInstanceId,
103                         String requestId, WorkflowCallbackResponse callbackResponse) {          
104                 WorkflowResponse workflowResponse = new WorkflowResponse();
105                 workflowResponse.setResponse(callbackResponse.getResponse());
106                 workflowResponse.setProcessInstanceID(processInstanceId);
107                 workflowResponse.setMessageCode(callbackResponse.getStatusCode());
108                 workflowResponse.setMessage(callbackResponse.getMessage());
109                 WorkflowContext context = new WorkflowContext(processKey, requestId, defaultContextTimeout,workflowResponse);
110                 put(context);
111         }
112
113
114         /**
115          * Timeout thread which monitors the delay queue for expired context and send timeout response
116          * to client
117          *
118          * */
119         private class TimeoutThread extends Thread {
120                 @Override
121                 public void run() {
122                         while (!isInterrupted()) {
123                                 try {
124                                         WorkflowContext requestObject = responseQueue.take();
125                                         MsoLogger.setLogContext(requestObject.getRequestId(), null);
126                                         msoLogger.debug("Time remaining for request id: " + requestObject.getRequestId() + ":" + requestObject.getDelay(TimeUnit.MILLISECONDS));
127                                         msoLogger.debug("Preparing timeout response for " + requestObject.getProcessKey() + ":" + ":" + requestObject.getRequestId());
128                                 } catch (InterruptedException e) {
129                                         Thread.currentThread().interrupt();
130                                 } catch (Exception e) {
131                                         msoLogger.debug("WorkflowContextHolder timeout thread caught exception: " + e);
132                                 msoLogger.error(MessageEnum.BPMN_GENERAL_EXCEPTION, "BPMN", MsoLogger.getServiceName(), 
133                                                 MsoLogger.ErrorCode.UnknownError, "Error in WorkflowContextHolder timeout thread");
134                                 
135                                 }
136                         }
137                         msoLogger.debug("WorkflowContextHolder timeout thread interrupted, quitting");
138                 }
139         }
140 }