e9f17c42d09413c02b7ce565c91394fef9b04cf0
[so.git] /
1 package org.onap.so.apihandlerinfra;
2
3 import java.security.GeneralSecurityException;
4 import java.util.ArrayList;
5 import java.util.Collections;
6 import java.util.HashMap;
7 import java.util.List;
8 import java.util.Map;
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     public ResponseEntity<List<HistoricProcessInstanceEntity>> getCamundaProcessInstanceHistory(String requestId,
46             boolean retry) {
47         String path = env.getProperty("mso.camunda.rest.history.uri") + requestId;
48         String targetUrl = env.getProperty("mso.camundaURL") + path;
49         HttpHeaders headers =
50                 setCamundaHeaders(env.getRequiredProperty("mso.camundaAuth"), env.getRequiredProperty("mso.msoKey"));
51
52         HttpEntity<?> requestEntity = new HttpEntity<>(headers);
53
54         if (retry) {
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());
60                 }
61                 if (context.getRetryCount() == 0) {
62                     logger.info("Querying Camunda for process-instance history for requestId: {}", requestId);
63                 } else {
64                     logger.info(
65                             "Retry: Querying Camunda for process-instance history for retryCount: {} and requestId: {}",
66                             context.getRetryCount(), requestId);
67                 }
68                 return restTemplate.exchange(targetUrl, HttpMethod.GET, requestEntity,
69                         new ParameterizedTypeReference<List<HistoricProcessInstanceEntity>>() {});
70             });
71         } else {
72             RestTemplate restTemplate = getRestTemplate(retry);
73             return restTemplate.exchange(targetUrl, HttpMethod.GET, requestEntity,
74                     new ParameterizedTypeReference<List<HistoricProcessInstanceEntity>>() {});
75         }
76     }
77
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;
82         HttpHeaders headers =
83                 setCamundaHeaders(env.getRequiredProperty("mso.camundaAuth"), env.getRequiredProperty("mso.msoKey"));
84         HttpEntity<?> requestEntity = new HttpEntity<>(headers);
85
86         return restTemplate.exchange(targetUrl, HttpMethod.GET, requestEntity,
87                 new ParameterizedTypeReference<List<HistoricActivityInstanceEntity>>() {});
88     }
89
90     protected String getTaskName(String requestId) {
91         ResponseEntity<List<HistoricProcessInstanceEntity>> response = null;
92
93         String taskInformation = null;
94         try {
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());
99         }
100
101         if (response != null) {
102             taskInformation = getTaskInformation(response, requestId);
103         }
104         return taskInformation;
105     }
106
107     protected String getTaskInformation(ResponseEntity<List<HistoricProcessInstanceEntity>> response,
108             String requestId) {
109         List<HistoricProcessInstanceEntity> historicProcessInstanceList = response.getBody();
110         ResponseEntity<List<HistoricActivityInstanceEntity>> activityResponse = null;
111         String processInstanceId = null;
112         String taskInformation = null;
113
114         if (historicProcessInstanceList != null && !historicProcessInstanceList.isEmpty()) {
115             Collections.reverse(historicProcessInstanceList);
116             processInstanceId = historicProcessInstanceList.get(0).getId();
117         } else {
118             logger.warn("No processInstances returned for requestId: {} to get TaskInformation", requestId);
119         }
120
121         if (processInstanceId != null) {
122             try {
123                 activityResponse = getCamundaActivityHistory(processInstanceId);
124             } catch (RestClientException e) {
125                 logger.warn(
126                         "Error querying Camunda for activity-instance history for processInstanceId: {}, for requestId: {}, exception: {}",
127                         processInstanceId, requestId, e.getMessage());
128             }
129         } else {
130             logger.warn("No processInstanceId returned for requestId: {} to get TaskInformation", requestId);
131         }
132
133         if (activityResponse != null) {
134             taskInformation = getActivityName(activityResponse.getBody());
135         } else {
136             logger.warn("No activity history information returned for requestId: {} to get TaskInformation", requestId);
137         }
138         return taskInformation;
139     }
140
141     protected String getActivityName(List<HistoricActivityInstanceEntity> activityInstanceList) {
142         String activityName = null;
143         HistoricActivityInstanceEntity activityInstance = null;
144         String result = null;
145
146         if (activityInstanceList == null || activityInstanceList.isEmpty()) {
147             result = "No results returned on activityInstance history lookup.";
148         } else {
149             activityInstance = activityInstanceList.get(0);
150             activityName = activityInstance.getActivityName();
151
152             if (activityName == null) {
153                 result = "Task name is null.";
154             } else {
155                 result = "Last task executed: " + activityName;
156             }
157         }
158
159         return result;
160     }
161
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);
167         try {
168             String userCredentials = CryptoUtils.decrypt(auth, msoKey);
169             if (userCredentials != null) {
170                 headers.add(HttpHeaders.AUTHORIZATION,
171                         "Basic " + DatatypeConverter.printBase64Binary(userCredentials.getBytes()));
172             }
173         } catch (GeneralSecurityException e) {
174             logger.error("Security exception", e);
175         }
176         return headers;
177     }
178
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;
186     }
187
188     protected RestTemplate getRestTemplate(boolean retry) {
189         int timeout;
190         if (retry) {
191             timeout = Integer.parseInt(env.getProperty(RETRY_TIMEOUT_PROPERTY, RETRY_TIMEOUT));
192         } else {
193             timeout = Integer.parseInt(env.getProperty(TIMEOUT_PROPERTY, TIMEOUT));
194         }
195
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()));
204         return restTemplate;
205     }
206 }