1 package org.onap.so.apihandlerinfra;
 
   3 import java.security.GeneralSecurityException;
 
   4 import java.util.ArrayList;
 
   5 import java.util.HashMap;
 
   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;
 
  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     private String buildCamundaUrlString(boolean historyLookup, boolean sort, boolean active, String lookupId) {
 
  46         UriBuilder uriBuilder = UriBuilder.fromUri(env.getProperty("mso.camundaURL"));
 
  48             uriBuilder.path(env.getProperty("mso.camunda.rest.history.uri"));
 
  49             uriBuilder.queryParam("processInstanceBusinessKey", lookupId);
 
  51                 uriBuilder.queryParam("active", true);
 
  54                 uriBuilder.queryParam("sortBy", "startTime");
 
  55                 uriBuilder.queryParam("sortOrder", "desc");
 
  58             uriBuilder.path(env.getProperty("mso.camunda.rest.activity.uri"));
 
  59             uriBuilder.queryParam("processInstanceId", lookupId);
 
  61         uriBuilder.queryParam("maxResults", 1);
 
  62         return uriBuilder.build().toString();
 
  65     public ResponseEntity<List<HistoricProcessInstanceEntity>> getCamundaProcessInstanceHistory(String requestId,
 
  66             boolean retry, boolean activeOnly, boolean sort) {
 
  67         String targetUrl = buildCamundaUrlString(true, sort, activeOnly, requestId);
 
  69                 setCamundaHeaders(env.getRequiredProperty("mso.camundaAuth"), env.getRequiredProperty("mso.msoKey"));
 
  71         HttpEntity<?> requestEntity = new HttpEntity<>(headers);
 
  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());
 
  80                 if (context.getRetryCount() == 0) {
 
  81                     logger.info("Querying Camunda for process-instance history for requestId: {}", requestId);
 
  84                             "Retry: Querying Camunda for process-instance history for retryCount: {} and requestId: {}",
 
  85                             context.getRetryCount(), requestId);
 
  87                 return restTemplate.exchange(targetUrl, HttpMethod.GET, requestEntity,
 
  88                         new ParameterizedTypeReference<List<HistoricProcessInstanceEntity>>() {});
 
  91             RestTemplate restTemplate = getRestTemplate(retry);
 
  92             return restTemplate.exchange(targetUrl, HttpMethod.GET, requestEntity,
 
  93                     new ParameterizedTypeReference<List<HistoricProcessInstanceEntity>>() {});
 
  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);
 
 104         return restTemplate.exchange(targetUrl, HttpMethod.GET, requestEntity,
 
 105                 new ParameterizedTypeReference<List<HistoricActivityInstanceEntity>>() {});
 
 108     protected String getTaskName(String requestId) {
 
 109         ResponseEntity<List<HistoricProcessInstanceEntity>> response = null;
 
 111         String taskInformation = null;
 
 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());
 
 119         if (response != null) {
 
 120             taskInformation = getTaskInformation(response, requestId);
 
 122         return taskInformation;
 
 125     protected String getTaskInformation(ResponseEntity<List<HistoricProcessInstanceEntity>> response,
 
 127         List<HistoricProcessInstanceEntity> historicProcessInstanceList = response.getBody();
 
 128         ResponseEntity<List<HistoricActivityInstanceEntity>> activityResponse = null;
 
 129         String processInstanceId = null;
 
 130         String taskInformation = null;
 
 132         if (historicProcessInstanceList != null && !historicProcessInstanceList.isEmpty()) {
 
 133             processInstanceId = historicProcessInstanceList.get(0).getId();
 
 135             logger.warn("No processInstances returned for requestId: {} to get TaskInformation", requestId);
 
 138         if (processInstanceId != null) {
 
 140                 activityResponse = getCamundaActivityHistory(processInstanceId);
 
 141             } catch (RestClientException e) {
 
 143                         "Error querying Camunda for activity-instance history for processInstanceId: {}, for requestId: {}, exception: {}",
 
 144                         processInstanceId, requestId, e.getMessage());
 
 147             logger.warn("No processInstanceId returned for requestId: {} to get TaskInformation", requestId);
 
 150         if (activityResponse != null) {
 
 151             taskInformation = getActivityName(activityResponse.getBody());
 
 153             logger.warn("No activity history information returned for requestId: {} to get TaskInformation", requestId);
 
 155         return taskInformation;
 
 158     protected String getActivityName(List<HistoricActivityInstanceEntity> activityInstanceList) {
 
 159         String activityName = null;
 
 160         HistoricActivityInstanceEntity activityInstance = null;
 
 161         String result = null;
 
 163         if (activityInstanceList == null || activityInstanceList.isEmpty()) {
 
 164             result = "No results returned on activityInstance history lookup.";
 
 166             activityInstance = activityInstanceList.get(0);
 
 167             activityName = activityInstance.getActivityName();
 
 169             if (activityName == null) {
 
 170                 result = "Task name is null.";
 
 172                 result = "Last task executed: " + activityName;
 
 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);
 
 185             String userCredentials = CryptoUtils.decrypt(auth, msoKey);
 
 186             if (userCredentials != null) {
 
 187                 headers.add(HttpHeaders.AUTHORIZATION,
 
 188                         "Basic " + DatatypeConverter.printBase64Binary(userCredentials.getBytes()));
 
 190         } catch (GeneralSecurityException e) {
 
 191             logger.error("Security exception", e);
 
 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;
 
 205     protected RestTemplate getRestTemplate(boolean retry) {
 
 208             timeout = Integer.parseInt(env.getProperty(RETRY_TIMEOUT_PROPERTY, RETRY_TIMEOUT));
 
 210             timeout = Integer.parseInt(env.getProperty(TIMEOUT_PROPERTY, TIMEOUT));
 
 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()));