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.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;
33 public class CamundaRequestHandler {
35 private static Logger logger = LoggerFactory.getLogger(CamundaRequestHandler.class);
38 private RestTemplate restTemplate;
41 private Environment env;
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;
48 setCamundaHeaders(env.getRequiredProperty("mso.camundaAuth"), env.getRequiredProperty("mso.msoKey"));
50 HttpEntity<?> requestEntity = new HttpEntity<>(headers);
52 return retryTemplate.execute(context -> {
53 if (context.getLastThrowable() != null) {
54 logger.error("Retrying: Last call resulted in exception: ", context.getLastThrowable());
56 if (context.getRetryCount() == 0) {
57 logger.info("Querying Camunda for process-instance history for requestId: {}", requestId);
59 logger.info("Retry: {} of 3. Querying Camunda for process-instance history for requestId: {}",
60 context.getRetryCount(), requestId);
62 return restTemplate.exchange(targetUrl, HttpMethod.GET, requestEntity,
63 new ParameterizedTypeReference<List<HistoricProcessInstanceEntity>>() {});
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;
73 setCamundaHeaders(env.getRequiredProperty("mso.camundaAuth"), env.getRequiredProperty("mso.msoKey"));
74 HttpEntity<?> requestEntity = new HttpEntity<>(headers);
76 return retryTemplate.execute(context -> {
77 if (context.getLastThrowable() != null) {
78 logger.error("Retrying: Last call resulted in exception: ", context.getLastThrowable());
80 if (context.getRetryCount() == 0) {
82 "Querying Camunda for activity-instance history for processInstanceId: {}, for requestId: {}",
83 processInstanceId, requestId);
86 "Retry: {} of 3. Querying Camunda for activity-instance history for processInstanceId: {}, for requestId: {}",
87 context.getRetryCount(), processInstanceId, requestId);
90 return restTemplate.exchange(targetUrl, HttpMethod.GET, requestEntity,
91 new ParameterizedTypeReference<List<HistoricActivityInstanceEntity>>() {});
94 } catch (RestClientException e) {
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();
103 protected String getTaskName(String requestId) throws ContactCamundaException {
104 ResponseEntity<List<HistoricProcessInstanceEntity>> response = null;
105 ResponseEntity<List<HistoricActivityInstanceEntity>> activityResponse = null;
106 String processInstanceId = null;
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();
116 List<HistoricProcessInstanceEntity> historicProcessInstanceList = response.getBody();
118 if (historicProcessInstanceList != null && !historicProcessInstanceList.isEmpty()) {
119 Collections.reverse(historicProcessInstanceList);
120 processInstanceId = historicProcessInstanceList.get(0).getId();
122 return "No processInstances returned for requestId: " + requestId;
125 if (processInstanceId != null) {
126 activityResponse = getCamundaActivityHistory(processInstanceId, requestId);
128 return "No processInstanceId returned for requestId: " + requestId;
131 return getActivityName(activityResponse.getBody());
134 protected String getActivityName(List<HistoricActivityInstanceEntity> activityInstanceList) {
135 String activityName = null;
136 HistoricActivityInstanceEntity activityInstance = null;
137 String result = null;
139 if (activityInstanceList == null || activityInstanceList.isEmpty()) {
140 result = "No results returned on activityInstance history lookup.";
142 activityInstance = activityInstanceList.get(0);
143 activityName = activityInstance.getActivityName();
145 if (activityName == null) {
146 result = "Task name is null.";
148 result = "Last task executed: " + activityName;
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);
161 String userCredentials = CryptoUtils.decrypt(auth, msoKey);
162 if (userCredentials != null) {
163 headers.add(HttpHeaders.AUTHORIZATION,
164 "Basic " + DatatypeConverter.printBase64Binary(userCredentials.getBytes()));
166 } catch (GeneralSecurityException e) {
167 logger.error("Security exception", e);
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;