e56eb422d88b7d4f0e29fb064d79cbc1847eb0b0
[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.apache.http.HttpStatus;
11 import org.camunda.bpm.engine.impl.persistence.entity.HistoricActivityInstanceEntity;
12 import org.camunda.bpm.engine.impl.persistence.entity.HistoricProcessInstanceEntity;
13 import org.onap.so.apihandler.common.ErrorNumbers;
14 import org.onap.so.apihandlerinfra.exceptions.ContactCamundaException;
15 import org.onap.so.utils.CryptoUtils;
16 import org.slf4j.Logger;
17 import org.slf4j.LoggerFactory;
18 import org.springframework.beans.factory.annotation.Autowired;
19 import org.springframework.core.ParameterizedTypeReference;
20 import org.springframework.core.env.Environment;
21 import org.springframework.http.HttpEntity;
22 import org.springframework.http.HttpHeaders;
23 import org.springframework.http.HttpMethod;
24 import org.springframework.http.ResponseEntity;
25 import org.springframework.retry.policy.SimpleRetryPolicy;
26 import org.springframework.retry.support.RetryTemplate;
27 import org.springframework.stereotype.Component;
28 import org.springframework.web.client.ResourceAccessException;
29 import org.springframework.web.client.RestClientException;
30 import org.springframework.web.client.RestTemplate;
31
32 @Component
33 public class CamundaRequestHandler {
34
35     private static Logger logger = LoggerFactory.getLogger(CamundaRequestHandler.class);
36
37     @Autowired
38     private RestTemplate restTemplate;
39
40     @Autowired
41     private Environment env;
42
43     public ResponseEntity<List<HistoricProcessInstanceEntity>> getCamundaProcessInstanceHistory(String requestId) {
44         RetryTemplate retryTemplate = setRetryTemplate();
45         String path = env.getProperty("mso.camunda.rest.history.uri") + requestId;
46         String targetUrl = env.getProperty("mso.camundaURL") + path;
47         HttpHeaders headers =
48                 setCamundaHeaders(env.getRequiredProperty("mso.camundaAuth"), env.getRequiredProperty("mso.msoKey"));
49
50         HttpEntity<?> requestEntity = new HttpEntity<>(headers);
51
52         return retryTemplate.execute(context -> {
53             if (context.getLastThrowable() != null) {
54                 logger.error("Retrying: Last call resulted in exception: ", context.getLastThrowable());
55             }
56             if (context.getRetryCount() == 0) {
57                 logger.info("Querying Camunda for process-instance history for requestId: {}", requestId);
58             } else {
59                 logger.info("Retry: {} of 3. Querying Camunda for process-instance history for requestId: {}",
60                         context.getRetryCount(), requestId);
61             }
62             return restTemplate.exchange(targetUrl, HttpMethod.GET, requestEntity,
63                     new ParameterizedTypeReference<List<HistoricProcessInstanceEntity>>() {});
64         });
65     }
66
67     protected ResponseEntity<List<HistoricActivityInstanceEntity>> getCamundaActivityHistory(String processInstanceId,
68             String requestId) throws ContactCamundaException {
69         RetryTemplate retryTemplate = setRetryTemplate();
70         String path = env.getProperty("mso.camunda.rest.activity.uri") + processInstanceId;
71         String targetUrl = env.getProperty("mso.camundaURL") + path;
72         HttpHeaders headers =
73                 setCamundaHeaders(env.getRequiredProperty("mso.camundaAuth"), env.getRequiredProperty("mso.msoKey"));
74         HttpEntity<?> requestEntity = new HttpEntity<>(headers);
75         try {
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(
82                             "Querying Camunda for activity-instance history for processInstanceId: {}, for requestId: {}",
83                             processInstanceId, requestId);
84                 } else {
85                     logger.info(
86                             "Retry: {} of 3. Querying Camunda for activity-instance history for processInstanceId: {}, for requestId: {}",
87                             context.getRetryCount(), processInstanceId, requestId);
88                 }
89
90                 return restTemplate.exchange(targetUrl, HttpMethod.GET, requestEntity,
91                         new ParameterizedTypeReference<List<HistoricActivityInstanceEntity>>() {});
92             });
93
94         } catch (RestClientException e) {
95             logger.error(
96                     "Error querying Camunda for activity-instance history for processInstanceId: {}, for requestId: {}, exception: {}",
97                     processInstanceId, requestId, e.getMessage());
98             throw new ContactCamundaException.Builder("activity-instance", requestId, e.toString(),
99                     HttpStatus.SC_INTERNAL_SERVER_ERROR, ErrorNumbers.SVC_DETAILED_SERVICE_ERROR).cause(e).build();
100         }
101     }
102
103     protected String getTaskName(String requestId) throws ContactCamundaException {
104         ResponseEntity<List<HistoricProcessInstanceEntity>> response = null;
105         ResponseEntity<List<HistoricActivityInstanceEntity>> activityResponse = null;
106         String processInstanceId = null;
107         try {
108             response = getCamundaProcessInstanceHistory(requestId);
109         } catch (RestClientException e) {
110             logger.error("Error querying Camunda for process-instance history for requestId: {}, exception: {}",
111                     requestId, e.getMessage());
112             throw new ContactCamundaException.Builder("process-instance", requestId, e.toString(),
113                     HttpStatus.SC_INTERNAL_SERVER_ERROR, ErrorNumbers.SVC_DETAILED_SERVICE_ERROR).cause(e).build();
114         }
115
116         List<HistoricProcessInstanceEntity> historicProcessInstanceList = response.getBody();
117
118         if (historicProcessInstanceList != null && !historicProcessInstanceList.isEmpty()) {
119             Collections.reverse(historicProcessInstanceList);
120             processInstanceId = historicProcessInstanceList.get(0).getId();
121         } else {
122             return "No processInstances returned for requestId: " + requestId;
123         }
124
125         if (processInstanceId != null) {
126             activityResponse = getCamundaActivityHistory(processInstanceId, requestId);
127         } else {
128             return "No processInstanceId returned for requestId: " + requestId;
129         }
130
131         return getActivityName(activityResponse.getBody());
132     }
133
134     protected String getActivityName(List<HistoricActivityInstanceEntity> activityInstanceList) {
135         String activityName = null;
136         HistoricActivityInstanceEntity activityInstance = null;
137         String result = null;
138
139         if (activityInstanceList == null || activityInstanceList.isEmpty()) {
140             result = "No results returned on activityInstance history lookup.";
141         } else {
142             activityInstance = activityInstanceList.get(0);
143             activityName = activityInstance.getActivityName();
144
145             if (activityName == null) {
146                 result = "Task name is null.";
147             } else {
148                 result = "Last task executed: " + activityName;
149             }
150         }
151
152         return result;
153     }
154
155     protected HttpHeaders setCamundaHeaders(String auth, String msoKey) {
156         HttpHeaders headers = new HttpHeaders();
157         List<org.springframework.http.MediaType> acceptableMediaTypes = new ArrayList<>();
158         acceptableMediaTypes.add(org.springframework.http.MediaType.APPLICATION_JSON);
159         headers.setAccept(acceptableMediaTypes);
160         try {
161             String userCredentials = CryptoUtils.decrypt(auth, msoKey);
162             if (userCredentials != null) {
163                 headers.add(HttpHeaders.AUTHORIZATION,
164                         "Basic " + DatatypeConverter.printBase64Binary(userCredentials.getBytes()));
165             }
166         } catch (GeneralSecurityException e) {
167             logger.error("Security exception", e);
168         }
169         return headers;
170     }
171
172     protected RetryTemplate setRetryTemplate() {
173         RetryTemplate retryTemplate = new RetryTemplate();
174         Map<Class<? extends Throwable>, Boolean> retryableExceptions = new HashMap<>();
175         retryableExceptions.put(ResourceAccessException.class, true);
176         SimpleRetryPolicy policy = new SimpleRetryPolicy(4, retryableExceptions);
177         retryTemplate.setRetryPolicy(policy);
178         return retryTemplate;
179     }
180 }