1 package org.onap.so.apihandlerinfra;
3 import java.security.GeneralSecurityException;
4 import java.util.ArrayList;
5 import java.util.Collections;
6 import java.util.HashMap;
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;
34 public class CamundaRequestHandler {
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";
43 private Environment env;
45 public ResponseEntity<List<HistoricProcessInstanceEntity>> getCamundaProcessInstanceHistory(String requestId,
47 String path = env.getProperty("mso.camunda.rest.history.uri") + requestId;
48 String targetUrl = env.getProperty("mso.camundaURL") + path;
50 setCamundaHeaders(env.getRequiredProperty("mso.camundaAuth"), env.getRequiredProperty("mso.msoKey"));
52 HttpEntity<?> requestEntity = new HttpEntity<>(headers);
55 RestTemplate restTemplate = getRestTemplate(retry);
56 RetryTemplate retryTemplate = getRetryTemplate();
57 return retryTemplate.execute(context -> {
58 if (context.getLastThrowable() != null) {
59 logger.error("Retrying: Last call resulted in exception: ", context.getLastThrowable());
61 if (context.getRetryCount() == 0) {
62 logger.info("Querying Camunda for process-instance history for requestId: {}", requestId);
65 "Retry: Querying Camunda for process-instance history for retryCount: {} and requestId: {}",
66 context.getRetryCount(), requestId);
68 return restTemplate.exchange(targetUrl, HttpMethod.GET, requestEntity,
69 new ParameterizedTypeReference<List<HistoricProcessInstanceEntity>>() {});
72 RestTemplate restTemplate = getRestTemplate(retry);
73 return restTemplate.exchange(targetUrl, HttpMethod.GET, requestEntity,
74 new ParameterizedTypeReference<List<HistoricProcessInstanceEntity>>() {});
78 protected ResponseEntity<List<HistoricActivityInstanceEntity>> getCamundaActivityHistory(String processInstanceId) {
79 RestTemplate restTemplate = getRestTemplate(false);
80 String path = env.getProperty("mso.camunda.rest.activity.uri") + processInstanceId;
81 String targetUrl = env.getProperty("mso.camundaURL") + path;
83 setCamundaHeaders(env.getRequiredProperty("mso.camundaAuth"), env.getRequiredProperty("mso.msoKey"));
84 HttpEntity<?> requestEntity = new HttpEntity<>(headers);
86 return restTemplate.exchange(targetUrl, HttpMethod.GET, requestEntity,
87 new ParameterizedTypeReference<List<HistoricActivityInstanceEntity>>() {});
90 protected String getTaskName(String requestId) {
91 ResponseEntity<List<HistoricProcessInstanceEntity>> response = null;
93 String taskInformation = null;
95 response = getCamundaProcessInstanceHistory(requestId, false);
96 } catch (RestClientException e) {
97 logger.warn("Error querying Camunda for process-instance history for requestId: {}, exception: {}",
98 requestId, e.getMessage());
101 if (response != null) {
102 taskInformation = getTaskInformation(response, requestId);
104 return taskInformation;
107 protected String getTaskInformation(ResponseEntity<List<HistoricProcessInstanceEntity>> response,
109 List<HistoricProcessInstanceEntity> historicProcessInstanceList = response.getBody();
110 ResponseEntity<List<HistoricActivityInstanceEntity>> activityResponse = null;
111 String processInstanceId = null;
112 String taskInformation = null;
114 if (historicProcessInstanceList != null && !historicProcessInstanceList.isEmpty()) {
115 Collections.reverse(historicProcessInstanceList);
116 processInstanceId = historicProcessInstanceList.get(0).getId();
118 logger.warn("No processInstances returned for requestId: {} to get TaskInformation", requestId);
121 if (processInstanceId != null) {
123 activityResponse = getCamundaActivityHistory(processInstanceId);
124 } catch (RestClientException e) {
126 "Error querying Camunda for activity-instance history for processInstanceId: {}, for requestId: {}, exception: {}",
127 processInstanceId, requestId, e.getMessage());
130 logger.warn("No processInstanceId returned for requestId: {} to get TaskInformation", requestId);
133 if (activityResponse != null) {
134 taskInformation = getActivityName(activityResponse.getBody());
136 logger.warn("No activity history information returned for requestId: {} to get TaskInformation", requestId);
138 return taskInformation;
141 protected String getActivityName(List<HistoricActivityInstanceEntity> activityInstanceList) {
142 String activityName = null;
143 HistoricActivityInstanceEntity activityInstance = null;
144 String result = null;
146 if (activityInstanceList == null || activityInstanceList.isEmpty()) {
147 result = "No results returned on activityInstance history lookup.";
149 activityInstance = activityInstanceList.get(0);
150 activityName = activityInstance.getActivityName();
152 if (activityName == null) {
153 result = "Task name is null.";
155 result = "Last task executed: " + activityName;
162 protected HttpHeaders setCamundaHeaders(String auth, String msoKey) {
163 HttpHeaders headers = new HttpHeaders();
164 List<org.springframework.http.MediaType> acceptableMediaTypes = new ArrayList<>();
165 acceptableMediaTypes.add(org.springframework.http.MediaType.APPLICATION_JSON);
166 headers.setAccept(acceptableMediaTypes);
168 String userCredentials = CryptoUtils.decrypt(auth, msoKey);
169 if (userCredentials != null) {
170 headers.add(HttpHeaders.AUTHORIZATION,
171 "Basic " + DatatypeConverter.printBase64Binary(userCredentials.getBytes()));
173 } catch (GeneralSecurityException e) {
174 logger.error("Security exception", e);
179 protected RetryTemplate getRetryTemplate() {
180 RetryTemplate retryTemplate = new RetryTemplate();
181 Map<Class<? extends Throwable>, Boolean> retryableExceptions = new HashMap<>();
182 retryableExceptions.put(ResourceAccessException.class, true);
183 SimpleRetryPolicy policy = new SimpleRetryPolicy(2, retryableExceptions);
184 retryTemplate.setRetryPolicy(policy);
185 return retryTemplate;
188 protected RestTemplate getRestTemplate(boolean retry) {
191 timeout = Integer.parseInt(env.getProperty(RETRY_TIMEOUT_PROPERTY, RETRY_TIMEOUT));
193 timeout = Integer.parseInt(env.getProperty(TIMEOUT_PROPERTY, TIMEOUT));
196 RestTemplate restTemplate = new RestTemplate();
197 HttpComponentsClientHttpRequestFactory factory = new HttpComponentsClientHttpRequestFactory();
198 factory.setConnectionRequestTimeout(timeout);
199 factory.setReadTimeout(timeout);
200 factory.setConnectTimeout(timeout);
201 restTemplate.setRequestFactory(new BufferingClientHttpRequestFactory(factory));
202 restTemplate.getInterceptors().add(new SOSpringClientFilter());
203 restTemplate.getInterceptors().add((new SpringClientPayloadFilter()));