17377d881a2fc89996c1aa54da2772a3631744a5
[so.git] /
1 package org.onap.so.apihandlerinfra;
2
3 import java.security.GeneralSecurityException;
4 import java.util.ArrayList;
5 import java.util.HashMap;
6 import java.util.List;
7 import java.util.Map;
8 import javax.ws.rs.core.UriBuilder;
9 import javax.xml.bind.DatatypeConverter;
10 import org.camunda.bpm.engine.impl.persistence.entity.HistoricActivityInstanceEntity;
11 import org.camunda.bpm.engine.impl.persistence.entity.HistoricProcessInstanceEntity;
12 import org.onap.logging.filter.spring.SpringClientPayloadFilter;
13 import org.onap.so.logging.jaxrs.filter.SOSpringClientFilter;
14 import org.onap.so.utils.CryptoUtils;
15 import org.slf4j.Logger;
16 import org.slf4j.LoggerFactory;
17 import org.springframework.beans.factory.annotation.Autowired;
18 import org.springframework.core.ParameterizedTypeReference;
19 import org.springframework.core.env.Environment;
20 import org.springframework.http.HttpEntity;
21 import org.springframework.http.HttpHeaders;
22 import org.springframework.http.HttpMethod;
23 import org.springframework.http.ResponseEntity;
24 import org.springframework.http.client.BufferingClientHttpRequestFactory;
25 import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
26 import org.springframework.retry.policy.SimpleRetryPolicy;
27 import org.springframework.retry.support.RetryTemplate;
28 import org.springframework.stereotype.Component;
29 import org.springframework.web.client.ResourceAccessException;
30 import org.springframework.web.client.RestClientException;
31 import org.springframework.web.client.RestTemplate;
32
33 @Component
34 public class CamundaRequestHandler {
35
36     private static Logger logger = LoggerFactory.getLogger(CamundaRequestHandler.class);
37     private static final String TIMEOUT = "30000";
38     private static final String RETRY_TIMEOUT = "15000";
39     private static final String TIMEOUT_PROPERTY = "mso.camunda.request.timeout";
40     private static final String RETRY_TIMEOUT_PROPERTY = "mso.camunda.request.timeout.retry";
41
42     @Autowired
43     private Environment env;
44
45     private String buildCamundaUrlString(boolean historyLookup, boolean sort, boolean active, String lookupId) {
46         UriBuilder uriBuilder = UriBuilder.fromUri(env.getProperty("mso.camundaURL"));
47         if (historyLookup) {
48             uriBuilder.path(env.getProperty("mso.camunda.rest.history.uri"));
49             uriBuilder.queryParam("processInstanceBusinessKey", lookupId);
50             if (active) {
51                 uriBuilder.queryParam("active", true);
52             }
53             if (sort) {
54                 uriBuilder.queryParam("sortBy", "startTime");
55                 uriBuilder.queryParam("sortOrder", "desc");
56             }
57         } else {
58             uriBuilder.path(env.getProperty("mso.camunda.rest.activity.uri"));
59             uriBuilder.queryParam("processInstanceId", lookupId);
60         }
61         uriBuilder.queryParam("maxResults", 1);
62         return uriBuilder.build().toString();
63     }
64
65     public ResponseEntity<List<HistoricProcessInstanceEntity>> getCamundaProcessInstanceHistory(String requestId,
66             boolean retry, boolean activeOnly, boolean sort) {
67         String targetUrl = buildCamundaUrlString(true, sort, activeOnly, requestId);
68         HttpHeaders headers =
69                 setCamundaHeaders(env.getRequiredProperty("mso.camundaAuth"), env.getRequiredProperty("mso.msoKey"));
70
71         HttpEntity<?> requestEntity = new HttpEntity<>(headers);
72
73         if (retry) {
74             RestTemplate restTemplate = getRestTemplate(retry);
75             RetryTemplate retryTemplate = getRetryTemplate();
76             return retryTemplate.execute(context -> {
77                 if (context.getLastThrowable() != null) {
78                     logger.error("Retrying: Last call resulted in exception: ", context.getLastThrowable());
79                 }
80                 if (context.getRetryCount() == 0) {
81                     logger.info("Querying Camunda for process-instance history for requestId: {}", requestId);
82                 } else {
83                     logger.info(
84                             "Retry: Querying Camunda for process-instance history for retryCount: {} and requestId: {}",
85                             context.getRetryCount(), requestId);
86                 }
87                 return restTemplate.exchange(targetUrl, HttpMethod.GET, requestEntity,
88                         new ParameterizedTypeReference<List<HistoricProcessInstanceEntity>>() {});
89             });
90         } else {
91             RestTemplate restTemplate = getRestTemplate(retry);
92             return restTemplate.exchange(targetUrl, HttpMethod.GET, requestEntity,
93                     new ParameterizedTypeReference<List<HistoricProcessInstanceEntity>>() {});
94         }
95     }
96
97     protected ResponseEntity<List<HistoricActivityInstanceEntity>> getCamundaActivityHistory(String processInstanceId) {
98         RestTemplate restTemplate = getRestTemplate(false);
99         String targetUrl = buildCamundaUrlString(false, false, false, processInstanceId);
100         HttpHeaders headers =
101                 setCamundaHeaders(env.getRequiredProperty("mso.camundaAuth"), env.getRequiredProperty("mso.msoKey"));
102         HttpEntity<?> requestEntity = new HttpEntity<>(headers);
103
104         return restTemplate.exchange(targetUrl, HttpMethod.GET, requestEntity,
105                 new ParameterizedTypeReference<List<HistoricActivityInstanceEntity>>() {});
106     }
107
108     protected String getTaskName(String requestId) {
109         ResponseEntity<List<HistoricProcessInstanceEntity>> response = null;
110
111         String taskInformation = null;
112         try {
113             response = getCamundaProcessInstanceHistory(requestId, false, false, true);
114         } catch (RestClientException e) {
115             logger.warn("Error querying Camunda for process-instance history for requestId: {}, exception: {}",
116                     requestId, e.getMessage());
117         }
118
119         if (response != null) {
120             taskInformation = getTaskInformation(response, requestId);
121         }
122         return taskInformation;
123     }
124
125     protected String getTaskInformation(ResponseEntity<List<HistoricProcessInstanceEntity>> response,
126             String requestId) {
127         List<HistoricProcessInstanceEntity> historicProcessInstanceList = response.getBody();
128         ResponseEntity<List<HistoricActivityInstanceEntity>> activityResponse = null;
129         String processInstanceId = null;
130         String taskInformation = null;
131
132         if (historicProcessInstanceList != null && !historicProcessInstanceList.isEmpty()) {
133             processInstanceId = historicProcessInstanceList.get(0).getId();
134         } else {
135             logger.warn("No processInstances returned for requestId: {} to get TaskInformation", requestId);
136         }
137
138         if (processInstanceId != null) {
139             try {
140                 activityResponse = getCamundaActivityHistory(processInstanceId);
141             } catch (RestClientException e) {
142                 logger.warn(
143                         "Error querying Camunda for activity-instance history for processInstanceId: {}, for requestId: {}, exception: {}",
144                         processInstanceId, requestId, e.getMessage());
145             }
146         } else {
147             logger.warn("No processInstanceId returned for requestId: {} to get TaskInformation", requestId);
148         }
149
150         if (activityResponse != null) {
151             taskInformation = getActivityName(activityResponse.getBody());
152         } else {
153             logger.warn("No activity history information returned for requestId: {} to get TaskInformation", requestId);
154         }
155         return taskInformation;
156     }
157
158     protected String getActivityName(List<HistoricActivityInstanceEntity> activityInstanceList) {
159         String activityName = null;
160         HistoricActivityInstanceEntity activityInstance = null;
161         String result = null;
162
163         if (activityInstanceList == null || activityInstanceList.isEmpty()) {
164             result = "No results returned on activityInstance history lookup.";
165         } else {
166             activityInstance = activityInstanceList.get(0);
167             activityName = activityInstance.getActivityName();
168
169             if (activityName == null) {
170                 result = "Task name is null.";
171             } else {
172                 result = "Last task executed: " + activityName;
173             }
174         }
175
176         return result;
177     }
178
179     protected HttpHeaders setCamundaHeaders(String auth, String msoKey) {
180         HttpHeaders headers = new HttpHeaders();
181         List<org.springframework.http.MediaType> acceptableMediaTypes = new ArrayList<>();
182         acceptableMediaTypes.add(org.springframework.http.MediaType.APPLICATION_JSON);
183         headers.setAccept(acceptableMediaTypes);
184         try {
185             String userCredentials = CryptoUtils.decrypt(auth, msoKey);
186             if (userCredentials != null) {
187                 headers.add(HttpHeaders.AUTHORIZATION,
188                         "Basic " + DatatypeConverter.printBase64Binary(userCredentials.getBytes()));
189             }
190         } catch (GeneralSecurityException e) {
191             logger.error("Security exception", e);
192         }
193         return headers;
194     }
195
196     protected RetryTemplate getRetryTemplate() {
197         RetryTemplate retryTemplate = new RetryTemplate();
198         Map<Class<? extends Throwable>, Boolean> retryableExceptions = new HashMap<>();
199         retryableExceptions.put(ResourceAccessException.class, true);
200         SimpleRetryPolicy policy = new SimpleRetryPolicy(2, retryableExceptions);
201         retryTemplate.setRetryPolicy(policy);
202         return retryTemplate;
203     }
204
205     protected RestTemplate getRestTemplate(boolean retry) {
206         int timeout;
207         if (retry) {
208             timeout = Integer.parseInt(env.getProperty(RETRY_TIMEOUT_PROPERTY, RETRY_TIMEOUT));
209         } else {
210             timeout = Integer.parseInt(env.getProperty(TIMEOUT_PROPERTY, TIMEOUT));
211         }
212
213         RestTemplate restTemplate = new RestTemplate();
214         HttpComponentsClientHttpRequestFactory factory = new HttpComponentsClientHttpRequestFactory();
215         factory.setConnectionRequestTimeout(timeout);
216         factory.setReadTimeout(timeout);
217         factory.setConnectTimeout(timeout);
218         restTemplate.setRequestFactory(new BufferingClientHttpRequestFactory(factory));
219         restTemplate.getInterceptors().add(new SOSpringClientFilter());
220         restTemplate.getInterceptors().add((new SpringClientPayloadFilter()));
221         return restTemplate;
222     }
223 }