aboutsummaryrefslogtreecommitdiffstats
path: root/mso-api-handlers
diff options
context:
space:
mode:
Diffstat (limited to 'mso-api-handlers')
-rw-r--r--mso-api-handlers/mso-api-handler-common/src/main/java/org/onap/so/apihandlerinfra/exceptions/ContactCamundaException.java8
-rw-r--r--mso-api-handlers/mso-api-handler-infra/pom.xml4
-rw-r--r--mso-api-handlers/mso-api-handler-infra/src/main/java/org/onap/so/apihandlerinfra/CamundaRequestHandler.java180
-rw-r--r--mso-api-handlers/mso-api-handler-infra/src/main/java/org/onap/so/apihandlerinfra/E2EServiceInstances.java33
-rw-r--r--mso-api-handlers/mso-api-handler-infra/src/main/java/org/onap/so/apihandlerinfra/OrchestrationRequests.java15
-rw-r--r--mso-api-handlers/mso-api-handler-infra/src/main/java/org/onap/so/apihandlerinfra/RequestHandlerUtils.java49
-rw-r--r--mso-api-handlers/mso-api-handler-infra/src/main/resources/application.yaml4
-rw-r--r--mso-api-handlers/mso-api-handler-infra/src/test/java/org/onap/so/apihandlerinfra/CamundaRequestHandlerTest.java327
-rw-r--r--mso-api-handlers/mso-api-handler-infra/src/test/java/org/onap/so/apihandlerinfra/OrchestrationRequestsTest.java17
-rw-r--r--mso-api-handlers/mso-api-handler-infra/src/test/java/org/onap/so/apihandlerinfra/OrchestrationRequestsUnitTest.java105
-rw-r--r--mso-api-handlers/mso-api-handler-infra/src/test/java/org/onap/so/apihandlerinfra/RequestHandlerUtilsTest.java5
-rw-r--r--mso-api-handlers/mso-api-handler-infra/src/test/java/org/onap/so/apihandlerinfra/ServiceInstancesTest.java13
-rw-r--r--mso-api-handlers/mso-api-handler-infra/src/test/resources/OrchestrationRequest/ActivityInstanceHistoryResponse.json48
-rw-r--r--mso-api-handlers/mso-api-handler-infra/src/test/resources/OrchestrationRequest/OrchestrationFilterResponse.json2
-rw-r--r--mso-api-handlers/mso-api-handler-infra/src/test/resources/OrchestrationRequest/OrchestrationList.json4
-rw-r--r--mso-api-handlers/mso-api-handler-infra/src/test/resources/OrchestrationRequest/ProcessInstanceHistoryResponse.json44
16 files changed, 768 insertions, 90 deletions
diff --git a/mso-api-handlers/mso-api-handler-common/src/main/java/org/onap/so/apihandlerinfra/exceptions/ContactCamundaException.java b/mso-api-handlers/mso-api-handler-common/src/main/java/org/onap/so/apihandlerinfra/exceptions/ContactCamundaException.java
index 6b38eec4ae..d5fc01781e 100644
--- a/mso-api-handlers/mso-api-handler-common/src/main/java/org/onap/so/apihandlerinfra/exceptions/ContactCamundaException.java
+++ b/mso-api-handlers/mso-api-handler-common/src/main/java/org/onap/so/apihandlerinfra/exceptions/ContactCamundaException.java
@@ -23,7 +23,7 @@ package org.onap.so.apihandlerinfra.exceptions;
public class ContactCamundaException extends ApiException {
private static final String contactCamundaErrorMessage =
- "Unable to get process-instance history from Camunda for requestId: %s due to error: %s";
+ "Unable to get %s history from Camunda for requestId: %s due to error: %s";
private ContactCamundaException(Builder builder) {
super(builder);
@@ -32,9 +32,9 @@ public class ContactCamundaException extends ApiException {
public static class Builder extends ApiException.Builder<Builder> {
- public Builder(String requestId, String error, int httpResponseCode, String messageID) {
- super(contactCamundaErrorMessage.format(contactCamundaErrorMessage, requestId, error), httpResponseCode,
- messageID);
+ public Builder(String query, String requestId, String error, int httpResponseCode, String messageID) {
+ super(contactCamundaErrorMessage.format(contactCamundaErrorMessage, query, requestId, error),
+ httpResponseCode, messageID);
}
public ContactCamundaException build() {
diff --git a/mso-api-handlers/mso-api-handler-infra/pom.xml b/mso-api-handlers/mso-api-handler-infra/pom.xml
index dc665a9446..a3b9827d9f 100644
--- a/mso-api-handlers/mso-api-handler-infra/pom.xml
+++ b/mso-api-handlers/mso-api-handler-infra/pom.xml
@@ -88,6 +88,10 @@
</exclusions>
</dependency>
<dependency>
+ <groupId>org.springframework.retry</groupId>
+ <artifactId>spring-retry</artifactId>
+ </dependency>
+ <dependency>
<groupId>commons-lang</groupId>
<artifactId>commons-lang</artifactId>
<version>2.6</version>
diff --git a/mso-api-handlers/mso-api-handler-infra/src/main/java/org/onap/so/apihandlerinfra/CamundaRequestHandler.java b/mso-api-handlers/mso-api-handler-infra/src/main/java/org/onap/so/apihandlerinfra/CamundaRequestHandler.java
new file mode 100644
index 0000000000..451fa64585
--- /dev/null
+++ b/mso-api-handlers/mso-api-handler-infra/src/main/java/org/onap/so/apihandlerinfra/CamundaRequestHandler.java
@@ -0,0 +1,180 @@
+package org.onap.so.apihandlerinfra;
+
+import java.security.GeneralSecurityException;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import javax.xml.bind.DatatypeConverter;
+import org.apache.http.HttpStatus;
+import org.camunda.bpm.engine.impl.persistence.entity.HistoricActivityInstanceEntity;
+import org.camunda.bpm.engine.impl.persistence.entity.HistoricProcessInstanceEntity;
+import org.onap.so.apihandler.common.ErrorNumbers;
+import org.onap.so.apihandlerinfra.exceptions.ContactCamundaException;
+import org.onap.so.utils.CryptoUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.core.ParameterizedTypeReference;
+import org.springframework.core.env.Environment;
+import org.springframework.http.HttpEntity;
+import org.springframework.http.HttpHeaders;
+import org.springframework.http.HttpMethod;
+import org.springframework.http.ResponseEntity;
+import org.springframework.retry.policy.SimpleRetryPolicy;
+import org.springframework.retry.support.RetryTemplate;
+import org.springframework.stereotype.Component;
+import org.springframework.web.client.ResourceAccessException;
+import org.springframework.web.client.RestClientException;
+import org.springframework.web.client.RestTemplate;
+
+@Component
+public class CamundaRequestHandler {
+
+ private static Logger logger = LoggerFactory.getLogger(CamundaRequestHandler.class);
+
+ @Autowired
+ private RestTemplate restTemplate;
+
+ @Autowired
+ private Environment env;
+
+ public ResponseEntity<List<HistoricProcessInstanceEntity>> getCamundaProcessInstanceHistory(String requestId) {
+ RetryTemplate retryTemplate = setRetryTemplate();
+ String path = env.getProperty("mso.camunda.rest.history.uri") + requestId;
+ String targetUrl = env.getProperty("mso.camundaURL") + path;
+ HttpHeaders headers =
+ setCamundaHeaders(env.getRequiredProperty("mso.camundaAuth"), env.getRequiredProperty("mso.msoKey"));
+
+ HttpEntity<?> requestEntity = new HttpEntity<>(headers);
+
+ return retryTemplate.execute(context -> {
+ if (context.getLastThrowable() != null) {
+ logger.error("Retrying: Last call resulted in exception: ", context.getLastThrowable());
+ }
+ if (context.getRetryCount() == 0) {
+ logger.info("Querying Camunda for process-instance history for requestId: {}", requestId);
+ } else {
+ logger.info("Retry: {} of 3. Querying Camunda for process-instance history for requestId: {}",
+ context.getRetryCount(), requestId);
+ }
+ return restTemplate.exchange(targetUrl, HttpMethod.GET, requestEntity,
+ new ParameterizedTypeReference<List<HistoricProcessInstanceEntity>>() {});
+ });
+ }
+
+ protected ResponseEntity<List<HistoricActivityInstanceEntity>> getCamundaActivityHistory(String processInstanceId,
+ String requestId) throws ContactCamundaException {
+ RetryTemplate retryTemplate = setRetryTemplate();
+ String path = env.getProperty("mso.camunda.rest.activity.uri") + processInstanceId;
+ String targetUrl = env.getProperty("mso.camundaURL") + path;
+ HttpHeaders headers =
+ setCamundaHeaders(env.getRequiredProperty("mso.camundaAuth"), env.getRequiredProperty("mso.msoKey"));
+ HttpEntity<?> requestEntity = new HttpEntity<>(headers);
+ try {
+ return retryTemplate.execute(context -> {
+ if (context.getLastThrowable() != null) {
+ logger.error("Retrying: Last call resulted in exception: ", context.getLastThrowable());
+ }
+ if (context.getRetryCount() == 0) {
+ logger.info(
+ "Querying Camunda for activity-instance history for processInstanceId: {}, for requestId: {}",
+ processInstanceId, requestId);
+ } else {
+ logger.info(
+ "Retry: {} of 3. Querying Camunda for activity-instance history for processInstanceId: {}, for requestId: {}",
+ context.getRetryCount(), processInstanceId, requestId);
+ }
+
+ return restTemplate.exchange(targetUrl, HttpMethod.GET, requestEntity,
+ new ParameterizedTypeReference<List<HistoricActivityInstanceEntity>>() {});
+ });
+
+ } catch (RestClientException e) {
+ logger.error(
+ "Error querying Camunda for activity-instance history for processInstanceId: {}, for requestId: {}, exception: {}",
+ processInstanceId, requestId, e.getMessage());
+ throw new ContactCamundaException.Builder("activity-instance", requestId, e.toString(),
+ HttpStatus.SC_INTERNAL_SERVER_ERROR, ErrorNumbers.SVC_DETAILED_SERVICE_ERROR).cause(e).build();
+ }
+ }
+
+ protected String getTaskName(String requestId) throws ContactCamundaException {
+ ResponseEntity<List<HistoricProcessInstanceEntity>> response = null;
+ ResponseEntity<List<HistoricActivityInstanceEntity>> activityResponse = null;
+ String processInstanceId = null;
+ try {
+ response = getCamundaProcessInstanceHistory(requestId);
+ } catch (RestClientException e) {
+ logger.error("Error querying Camunda for process-instance history for requestId: {}, exception: {}",
+ requestId, e.getMessage());
+ throw new ContactCamundaException.Builder("process-instance", requestId, e.toString(),
+ HttpStatus.SC_INTERNAL_SERVER_ERROR, ErrorNumbers.SVC_DETAILED_SERVICE_ERROR).cause(e).build();
+ }
+
+ List<HistoricProcessInstanceEntity> historicProcessInstanceList = response.getBody();
+
+ if (historicProcessInstanceList != null) {
+ Collections.reverse(historicProcessInstanceList);
+ processInstanceId = historicProcessInstanceList.get(0).getId();
+ } else {
+ return "No processInstances returned for requestId: " + requestId;
+ }
+
+ if (processInstanceId != null) {
+ activityResponse = getCamundaActivityHistory(processInstanceId, requestId);
+ } else {
+ return "No processInstanceId returned for requestId: " + requestId;
+ }
+
+ return getActivityName(activityResponse.getBody());
+ }
+
+ protected String getActivityName(List<HistoricActivityInstanceEntity> activityInstanceList) {
+ String activityName = null;
+ HistoricActivityInstanceEntity activityInstance = null;
+ String result = null;
+
+ if (activityInstanceList == null || activityInstanceList.isEmpty()) {
+ result = "No results returned on activityInstance history lookup.";
+ } else {
+ activityInstance = activityInstanceList.get(0);
+ activityName = activityInstance.getActivityName();
+
+ if (activityName == null) {
+ result = "Task name is null.";
+ } else {
+ result = "Last task executed: " + activityName;
+ }
+ }
+
+ return result;
+ }
+
+ protected HttpHeaders setCamundaHeaders(String auth, String msoKey) {
+ HttpHeaders headers = new HttpHeaders();
+ List<org.springframework.http.MediaType> acceptableMediaTypes = new ArrayList<>();
+ acceptableMediaTypes.add(org.springframework.http.MediaType.APPLICATION_JSON);
+ headers.setAccept(acceptableMediaTypes);
+ try {
+ String userCredentials = CryptoUtils.decrypt(auth, msoKey);
+ if (userCredentials != null) {
+ headers.add(HttpHeaders.AUTHORIZATION,
+ "Basic " + DatatypeConverter.printBase64Binary(userCredentials.getBytes()));
+ }
+ } catch (GeneralSecurityException e) {
+ logger.error("Security exception", e);
+ }
+ return headers;
+ }
+
+ protected RetryTemplate setRetryTemplate() {
+ RetryTemplate retryTemplate = new RetryTemplate();
+ Map<Class<? extends Throwable>, Boolean> retryableExceptions = new HashMap<>();
+ retryableExceptions.put(ResourceAccessException.class, true);
+ SimpleRetryPolicy policy = new SimpleRetryPolicy(4, retryableExceptions);
+ retryTemplate.setRetryPolicy(policy);
+ return retryTemplate;
+ }
+}
diff --git a/mso-api-handlers/mso-api-handler-infra/src/main/java/org/onap/so/apihandlerinfra/E2EServiceInstances.java b/mso-api-handlers/mso-api-handler-infra/src/main/java/org/onap/so/apihandlerinfra/E2EServiceInstances.java
index af7641705e..d3a279fd8e 100644
--- a/mso-api-handlers/mso-api-handler-infra/src/main/java/org/onap/so/apihandlerinfra/E2EServiceInstances.java
+++ b/mso-api-handlers/mso-api-handler-infra/src/main/java/org/onap/so/apihandlerinfra/E2EServiceInstances.java
@@ -92,6 +92,8 @@ public class E2EServiceInstances {
private static final String END_OF_THE_TRANSACTION = "End of the transaction, the final response is: ";
+ private static final String SERVICE_ID = "serviceId";
+
@Autowired
private MsoRequest msoRequest;
@@ -138,7 +140,7 @@ public class E2EServiceInstances {
public Response updateE2EServiceInstance(String request, @PathParam("version") String version,
@PathParam("serviceId") String serviceId) throws ApiException {
- instanceIdMap.put("serviceId", serviceId);
+ instanceIdMap.put(SERVICE_ID, serviceId);
return updateE2EserviceInstances(request, Action.updateInstance, version);
}
@@ -155,9 +157,9 @@ public class E2EServiceInstances {
@Produces(MediaType.APPLICATION_JSON)
@ApiOperation(value = "Delete E2E Service Instance on a specified version and serviceId", response = Response.class)
public Response deleteE2EServiceInstance(String request, @PathParam("version") String version,
- @PathParam("serviceId") String serviceId) throws ApiException {
+ @PathParam(SERVICE_ID) String serviceId) throws ApiException {
- instanceIdMap.put("serviceId", serviceId);
+ instanceIdMap.put(SERVICE_ID, serviceId);
return deleteE2EserviceInstances(request, Action.deleteInstance, instanceIdMap, version);
}
@@ -167,7 +169,7 @@ public class E2EServiceInstances {
@ApiOperation(value = "Find e2eServiceInstances Requests for a given serviceId and operationId",
response = Response.class)
@Produces(MediaType.APPLICATION_JSON)
- public Response getE2EServiceInstances(@PathParam("serviceId") String serviceId,
+ public Response getE2EServiceInstances(@PathParam(SERVICE_ID) String serviceId,
@PathParam("version") String version, @PathParam("operationId") String operationId) {
return getE2EServiceInstance(serviceId, operationId, version);
}
@@ -184,10 +186,10 @@ public class E2EServiceInstances {
@Produces(MediaType.APPLICATION_JSON)
@ApiOperation(value = "Scale E2E Service Instance on a specified version", response = Response.class)
public Response scaleE2EServiceInstance(String request, @PathParam("version") String version,
- @PathParam("serviceId") String serviceId) throws ApiException {
+ @PathParam(SERVICE_ID) String serviceId) throws ApiException {
logger.debug("------------------scale begin------------------");
- instanceIdMap.put("serviceId", serviceId);
+ instanceIdMap.put(SERVICE_ID, serviceId);
return scaleE2EserviceInstances(request, Action.scaleInstance, version);
}
@@ -207,7 +209,7 @@ public class E2EServiceInstances {
public Response compareModelwithTargetVersion(String request, @PathParam("serviceId") String serviceId,
@PathParam("version") String version) throws ApiException {
- instanceIdMap.put("serviceId", serviceId);
+ instanceIdMap.put(SERVICE_ID, serviceId);
return compareModelwithTargetVersion(request, Action.compareModel, instanceIdMap, version);
}
@@ -216,7 +218,6 @@ public class E2EServiceInstances {
HashMap<String, String> instanceIdMap, String version) throws ApiException {
String requestId = UUID.randomUUID().toString();
- long startTime = System.currentTimeMillis();
CompareModelsRequest e2eCompareModelReq;
@@ -237,12 +238,12 @@ public class E2EServiceInstances {
return response;
}
- return runCompareModelBPMWorkflow(e2eCompareModelReq, requestJSON, requestId, startTime, action, version);
+ return runCompareModelBPMWorkflow(e2eCompareModelReq, requestJSON, requestId, action, version);
}
private Response runCompareModelBPMWorkflow(CompareModelsRequest e2eCompareModelReq, String requestJSON,
- String requestId, long startTime, Action action, String version) throws ApiException {
+ String requestId, Action action, String version) throws ApiException {
// Define RecipeLookupResult info here instead of query DB for efficiency
String workflowUrl = "/mso/async/services/CompareModelofE2EServiceInstance";
@@ -259,7 +260,7 @@ public class E2EServiceInstances {
// Capture audit event
logger.debug("MSO API Handler Posting call to BPEL engine for url: " + requestClient.getUrl());
- String serviceId = instanceIdMap.get("serviceId");
+ String serviceId = instanceIdMap.get(SERVICE_ID);
String serviceType = e2eCompareModelReq.getServiceType();
RequestClientParameter postParam = new RequestClientParameter.Builder().setRequestId(requestId)
.setBaseVfModule(false).setRecipeTimeout(recipeTimeout).setRequestAction(action.name())
@@ -334,7 +335,6 @@ public class E2EServiceInstances {
private Response deleteE2EserviceInstances(String requestJSON, Action action, HashMap<String, String> instanceIdMap,
String version) throws ApiException {
// TODO should be a new one or the same service instance Id
- long startTime = System.currentTimeMillis();
E2EServiceInstanceDeleteRequest e2eDelReq;
ObjectMapper mapper = new ObjectMapper();
@@ -397,7 +397,7 @@ public class E2EServiceInstances {
// Capture audit event
logger.debug("MSO API Handler Posting call to BPEL engine for url: " + requestClient.getUrl());
- String serviceId = instanceIdMap.get("serviceId");
+ String serviceId = instanceIdMap.get(SERVICE_ID);
String serviceInstanceType = e2eDelReq.getServiceType();
RequestClientParameter clientParam = new RequestClientParameter.Builder().setRequestId(requestId)
.setBaseVfModule(false).setRecipeTimeout(recipeLookupResult.getRecipeTimeout())
@@ -436,9 +436,8 @@ public class E2EServiceInstances {
private Response updateE2EserviceInstances(String requestJSON, Action action, String version) throws ApiException {
String requestId = UUID.randomUUID().toString();
- long startTime = System.currentTimeMillis();
E2EServiceInstanceRequest e2eSir;
- String serviceId = instanceIdMap.get("serviceId");
+ String serviceId = instanceIdMap.get(SERVICE_ID);
ObjectMapper mapper = new ObjectMapper();
try {
@@ -552,7 +551,6 @@ public class E2EServiceInstances {
HashMap<String, String> instanceIdMap, String version) throws ApiException {
String requestId = UUID.randomUUID().toString();
- long startTime = System.currentTimeMillis();
E2EServiceInstanceRequest e2eSir;
MsoRequest msoRequest = new MsoRequest();
@@ -663,7 +661,6 @@ public class E2EServiceInstances {
private Response scaleE2EserviceInstances(String requestJSON, Action action, String version) throws ApiException {
String requestId = UUID.randomUUID().toString();
- long startTime = System.currentTimeMillis();
E2EServiceInstanceScaleRequest e2eScaleReq;
ObjectMapper mapper = new ObjectMapper();
@@ -725,7 +722,7 @@ public class E2EServiceInstances {
// Capture audit event
logger.debug("MSO API Handler Posting call to BPEL engine for url: " + requestClient.getUrl());
- String serviceId = instanceIdMap.get("serviceId");
+ String serviceId = instanceIdMap.get(SERVICE_ID);
String serviceInstanceType = e2eScaleReq.getService().getServiceType();
RequestClientParameter postParam = new RequestClientParameter.Builder().setRequestId(requestId)
.setBaseVfModule(false).setRecipeTimeout(recipeLookupResult.getRecipeTimeout())
diff --git a/mso-api-handlers/mso-api-handler-infra/src/main/java/org/onap/so/apihandlerinfra/OrchestrationRequests.java b/mso-api-handlers/mso-api-handler-infra/src/main/java/org/onap/so/apihandlerinfra/OrchestrationRequests.java
index 9e92c293bf..6f36fb2aff 100644
--- a/mso-api-handlers/mso-api-handler-infra/src/main/java/org/onap/so/apihandlerinfra/OrchestrationRequests.java
+++ b/mso-api-handlers/mso-api-handler-infra/src/main/java/org/onap/so/apihandlerinfra/OrchestrationRequests.java
@@ -46,6 +46,7 @@ import org.apache.http.HttpStatus;
import org.onap.so.apihandler.common.ErrorNumbers;
import org.onap.so.apihandler.common.ResponseBuilder;
import org.onap.so.apihandlerinfra.exceptions.ApiException;
+import org.onap.so.apihandlerinfra.exceptions.ContactCamundaException;
import org.onap.so.apihandlerinfra.exceptions.ValidateException;
import org.onap.so.apihandlerinfra.logging.ErrorLoggerInfo;
import org.onap.so.constants.OrchestrationRequestFormat;
@@ -91,6 +92,9 @@ public class OrchestrationRequests {
@Autowired
private ResponseBuilder builder;
+ @Autowired
+ private CamundaRequestHandler camundaRequestHandler;
+
@GET
@Path("/{version:[vV][4-7]}/{requestId}")
@ApiOperation(value = "Find Orchestrated Requests for a given requestId", response = Response.class)
@@ -424,10 +428,19 @@ public class OrchestrationRequests {
}
protected void mapRequestStatusAndExtSysErrSrcToRequest(InfraActiveRequests iar, RequestStatus status,
- String format) {
+ String format) throws ContactCamundaException {
String rollbackStatusMessage = iar.getRollbackStatusMessage();
String flowStatusMessage = iar.getFlowStatus();
String retryStatusMessage = iar.getRetryStatusMessage();
+ String taskName = null;
+
+ if (flowStatusMessage != null && !flowStatusMessage.equals("Successfully completed all Building Blocks")
+ && !flowStatusMessage.equals("All Rollback flows have completed successfully")) {
+ taskName = camundaRequestHandler.getTaskName(iar.getRequestId());
+ if (taskName != null) {
+ flowStatusMessage = flowStatusMessage + " TASK INFORMATION: " + taskName;
+ }
+ }
String statusMessages = null;
if (iar.getStatusMessage() != null) {
diff --git a/mso-api-handlers/mso-api-handler-infra/src/main/java/org/onap/so/apihandlerinfra/RequestHandlerUtils.java b/mso-api-handlers/mso-api-handler-infra/src/main/java/org/onap/so/apihandlerinfra/RequestHandlerUtils.java
index c3f323459c..9ab95a2319 100644
--- a/mso-api-handlers/mso-api-handler-infra/src/main/java/org/onap/so/apihandlerinfra/RequestHandlerUtils.java
+++ b/mso-api-handlers/mso-api-handler-infra/src/main/java/org/onap/so/apihandlerinfra/RequestHandlerUtils.java
@@ -27,7 +27,6 @@ package org.onap.so.apihandlerinfra;
import static org.onap.so.logger.HttpHeadersConstants.REQUESTOR_ID;
import java.io.IOException;
import java.net.URL;
-import java.security.GeneralSecurityException;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.HashMap;
@@ -37,7 +36,6 @@ import java.util.Optional;
import javax.ws.rs.container.ContainerRequestContext;
import javax.ws.rs.core.MultivaluedMap;
import javax.ws.rs.core.Response;
-import javax.xml.bind.DatatypeConverter;
import org.apache.commons.lang.StringUtils;
import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
@@ -78,21 +76,16 @@ import org.onap.so.serviceinstancebeans.RelatedInstanceList;
import org.onap.so.serviceinstancebeans.RequestParameters;
import org.onap.so.serviceinstancebeans.ServiceInstancesRequest;
import org.onap.so.serviceinstancebeans.ServiceInstancesResponse;
-import org.onap.so.utils.CryptoUtils;
import org.onap.so.utils.UUIDChecker;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.slf4j.MDC;
import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.core.ParameterizedTypeReference;
import org.springframework.core.env.Environment;
-import org.springframework.http.HttpEntity;
-import org.springframework.http.HttpHeaders;
-import org.springframework.http.HttpMethod;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Component;
import org.springframework.web.client.HttpStatusCodeException;
-import org.springframework.web.client.RestTemplate;
+import org.springframework.web.client.RestClientException;
import com.fasterxml.jackson.annotation.JsonInclude.Include;
import com.fasterxml.jackson.databind.ObjectMapper;
@@ -119,7 +112,7 @@ public class RequestHandlerUtils extends AbstractRestHandler {
private MsoRequest msoRequest;
@Autowired
- private RestTemplate restTemplate;
+ private CamundaRequestHandler camundaRequestHandler;
@Autowired
private CatalogDbClient catalogDbClient;
@@ -323,25 +316,20 @@ public class RequestHandlerUtils extends AbstractRestHandler {
public boolean camundaHistoryCheck(InfraActiveRequests duplicateRecord, InfraActiveRequests currentActiveReq)
throws RequestDbFailureException, ContactCamundaException {
String requestId = duplicateRecord.getRequestId();
- String path = env.getProperty("mso.camunda.rest.history.uri") + requestId;
- String targetUrl = env.getProperty("mso.camundaURL") + path;
- HttpHeaders headers =
- setCamundaHeaders(env.getRequiredProperty("mso.camundaAuth"), env.getRequiredProperty("mso.msoKey"));
- HttpEntity<?> requestEntity = new HttpEntity<>(headers);
ResponseEntity<List<HistoricProcessInstanceEntity>> response = null;
try {
- response = restTemplate.exchange(targetUrl, HttpMethod.GET, requestEntity,
- new ParameterizedTypeReference<List<HistoricProcessInstanceEntity>>() {});
- } catch (HttpStatusCodeException e) {
- ErrorLoggerInfo errorLoggerInfo =
- new ErrorLoggerInfo.Builder(MessageEnum.APIH_DUPLICATE_CHECK_EXC, ErrorCode.DataError)
- .errorSource(Constants.MSO_PROP_APIHANDLER_INFRA).build();
+ response = camundaRequestHandler.getCamundaProcessInstanceHistory(requestId);
+ } catch (RestClientException e) {
+ logger.error("Error querying Camunda for process-instance history for requestId: {}, exception: {}",
+ requestId, e.getMessage());
ContactCamundaException contactCamundaException =
- new ContactCamundaException.Builder(requestId, e.toString(), HttpStatus.SC_INTERNAL_SERVER_ERROR,
- ErrorNumbers.SVC_DETAILED_SERVICE_ERROR).cause(e).errorInfo(errorLoggerInfo).build();
+ new ContactCamundaException.Builder("process-instance", requestId, e.toString(),
+ HttpStatus.SC_INTERNAL_SERVER_ERROR, ErrorNumbers.SVC_DETAILED_SERVICE_ERROR).cause(e)
+ .build();
updateStatus(currentActiveReq, Status.FAILED, contactCamundaException.getMessage());
throw contactCamundaException;
}
+
if (response.getBody().isEmpty()) {
updateStatus(duplicateRecord, Status.COMPLETE, "Request Completed");
}
@@ -355,23 +343,6 @@ public class RequestHandlerUtils extends AbstractRestHandler {
return false;
}
- protected HttpHeaders setCamundaHeaders(String auth, String msoKey) {
- HttpHeaders headers = new HttpHeaders();
- List<org.springframework.http.MediaType> acceptableMediaTypes = new ArrayList<>();
- acceptableMediaTypes.add(org.springframework.http.MediaType.APPLICATION_JSON);
- headers.setAccept(acceptableMediaTypes);
- try {
- String userCredentials = CryptoUtils.decrypt(auth, msoKey);
- if (userCredentials != null) {
- headers.add(HttpHeaders.AUTHORIZATION,
- "Basic " + DatatypeConverter.printBase64Binary(userCredentials.getBytes()));
- }
- } catch (GeneralSecurityException e) {
- logger.error("Security exception", e);
- }
- return headers;
- }
-
public ServiceInstancesRequest convertJsonToServiceInstanceRequest(String requestJSON, Actions action,
String requestId, String requestUri) throws ApiException {
try {
diff --git a/mso-api-handlers/mso-api-handler-infra/src/main/resources/application.yaml b/mso-api-handlers/mso-api-handler-infra/src/main/resources/application.yaml
index 136acfb9e1..93a4ae9489 100644
--- a/mso-api-handlers/mso-api-handler-infra/src/main/resources/application.yaml
+++ b/mso-api-handlers/mso-api-handler-infra/src/main/resources/application.yaml
@@ -26,6 +26,10 @@ mso:
uri: /sobpmnengine/task
history:
uri: /sobpmnengine/history/process-instance?variables=mso-request-id_eq_
+ activity:
+ uri: /sobpmnengine/history/activity-instance?processInstanceId=
+ camundaURL: http://localhost:8089
+ camundaAuth: E8E19DD16CC90D2E458E8FF9A884CC0452F8F3EB8E321F96038DE38D5C1B0B02DFAE00B88E2CF6E2A4101AB2C011FC161212EE
spring:
datasource:
diff --git a/mso-api-handlers/mso-api-handler-infra/src/test/java/org/onap/so/apihandlerinfra/CamundaRequestHandlerTest.java b/mso-api-handlers/mso-api-handler-infra/src/test/java/org/onap/so/apihandlerinfra/CamundaRequestHandlerTest.java
new file mode 100644
index 0000000000..e6b5163f59
--- /dev/null
+++ b/mso-api-handlers/mso-api-handler-infra/src/test/java/org/onap/so/apihandlerinfra/CamundaRequestHandlerTest.java
@@ -0,0 +1,327 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP - SO
+ * ================================================================================
+ * Copyright (C) 2019 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.so.apihandlerinfra;
+
+import static org.junit.Assert.assertEquals;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.doThrow;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.Paths;
+import java.util.ArrayList;
+import java.util.List;
+import org.camunda.bpm.engine.impl.persistence.entity.HistoricActivityInstanceEntity;
+import org.camunda.bpm.engine.impl.persistence.entity.HistoricProcessInstanceEntity;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.ExpectedException;
+import org.junit.runner.RunWith;
+import org.mockito.InjectMocks;
+import org.mockito.Mock;
+import org.mockito.Spy;
+import org.mockito.junit.MockitoJUnitRunner;
+import org.onap.so.apihandlerinfra.exceptions.ContactCamundaException;
+import org.onap.so.apihandlerinfra.exceptions.RequestDbFailureException;
+import org.springframework.core.ParameterizedTypeReference;
+import org.springframework.core.env.Environment;
+import org.springframework.http.HttpEntity;
+import org.springframework.http.HttpHeaders;
+import org.springframework.http.HttpMethod;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.ResponseEntity;
+import org.springframework.web.client.HttpClientErrorException;
+import org.springframework.web.client.HttpStatusCodeException;
+import org.springframework.web.client.ResourceAccessException;
+import org.springframework.web.client.RestTemplate;
+import com.fasterxml.jackson.core.type.TypeReference;
+import com.fasterxml.jackson.databind.DeserializationFeature;
+import com.fasterxml.jackson.databind.ObjectMapper;
+
+@RunWith(MockitoJUnitRunner.class)
+public class CamundaRequestHandlerTest {
+
+ @Mock
+ private RestTemplate restTemplate;
+
+ @Mock
+ private Environment env;
+
+ @InjectMocks
+ @Spy
+ private CamundaRequestHandler camundaRequestHandler;
+
+ @Rule
+ public ExpectedException thrown = ExpectedException.none();
+
+ private static final String REQUEST_ID = "eca3a1b1-43ab-457e-ab1c-367263d148b4";
+ private ResponseEntity<List<HistoricActivityInstanceEntity>> activityInstanceResponse = null;
+ private ResponseEntity<List<HistoricProcessInstanceEntity>> processInstanceResponse = null;
+ private List<HistoricActivityInstanceEntity> activityInstanceList = null;
+ private List<HistoricProcessInstanceEntity> processInstanceList = null;
+
+
+
+ @Before
+ public void setup() throws IOException {
+ ObjectMapper mapper = new ObjectMapper().configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
+ activityInstanceList = mapper.readValue(
+ new String(Files.readAllBytes(
+ Paths.get("src/test/resources/OrchestrationRequest/ActivityInstanceHistoryResponse.json"))),
+ new TypeReference<List<HistoricActivityInstanceEntity>>() {});
+ processInstanceList = mapper.readValue(
+ new String(Files.readAllBytes(
+ Paths.get("src/test/resources/OrchestrationRequest/ProcessInstanceHistoryResponse.json"))),
+ new TypeReference<List<HistoricProcessInstanceEntity>>() {});
+ processInstanceResponse =
+ new ResponseEntity<List<HistoricProcessInstanceEntity>>(processInstanceList, HttpStatus.ACCEPTED);
+ activityInstanceResponse =
+ new ResponseEntity<List<HistoricActivityInstanceEntity>>(activityInstanceList, HttpStatus.ACCEPTED);
+
+ doReturn("/sobpmnengine/history/process-instance?variables=mso-request-id_eq_").when(env)
+ .getProperty("mso.camunda.rest.history.uri");
+ doReturn("/sobpmnengine/history/activity-instance?processInstanceId=").when(env)
+ .getProperty("mso.camunda.rest.activity.uri");
+ doReturn("auth").when(env).getRequiredProperty("mso.camundaAuth");
+ doReturn("key").when(env).getRequiredProperty("mso.msoKey");
+ doReturn("http://localhost:8089").when(env).getProperty("mso.camundaURL");
+ }
+
+ public HttpHeaders setHeaders() {
+ HttpHeaders headers = new HttpHeaders();
+ List<org.springframework.http.MediaType> acceptableMediaTypes = new ArrayList<>();
+ acceptableMediaTypes.add(org.springframework.http.MediaType.APPLICATION_JSON);
+ headers.setAccept(acceptableMediaTypes);
+ headers.add(HttpHeaders.AUTHORIZATION, "auth");
+
+ return headers;
+ }
+
+ @Test
+ public void getActivityNameTest() throws IOException {
+ String expectedActivityName = "Last task executed: BB to Execute";
+ String actualActivityName = camundaRequestHandler.getActivityName(activityInstanceList);
+
+ assertEquals(expectedActivityName, actualActivityName);
+ }
+
+ @Test
+ public void getActivityNameNullActivityNameTest() throws IOException {
+ String expectedActivityName = "Task name is null.";
+ HistoricActivityInstanceEntity activityInstance = new HistoricActivityInstanceEntity();
+ List<HistoricActivityInstanceEntity> activityInstanceList = new ArrayList<>();
+ activityInstanceList.add(activityInstance);
+
+ String actualActivityName = camundaRequestHandler.getActivityName(activityInstanceList);
+
+ assertEquals(expectedActivityName, actualActivityName);
+ }
+
+ @Test
+ public void getActivityNameNullListTest() throws IOException {
+ String expectedActivityName = "No results returned on activityInstance history lookup.";
+ List<HistoricActivityInstanceEntity> activityInstanceList = null;
+ String actualActivityName = camundaRequestHandler.getActivityName(activityInstanceList);
+
+ assertEquals(expectedActivityName, actualActivityName);
+ }
+
+ @Test
+ public void getActivityNameEmptyListTest() throws IOException {
+ String expectedActivityName = "No results returned on activityInstance history lookup.";
+ List<HistoricActivityInstanceEntity> activityInstanceList = new ArrayList<>();
+ String actualActivityName = camundaRequestHandler.getActivityName(activityInstanceList);
+
+ assertEquals(expectedActivityName, actualActivityName);
+ }
+
+ @Test
+ public void getTaskNameTest() throws IOException, ContactCamundaException {
+ doReturn(processInstanceResponse).when(camundaRequestHandler).getCamundaProcessInstanceHistory(REQUEST_ID);
+ doReturn(activityInstanceResponse).when(camundaRequestHandler)
+ .getCamundaActivityHistory("c4c6b647-a26e-11e9-b144-0242ac14000b", REQUEST_ID);
+ doReturn("Last task executed: BB to Execute").when(camundaRequestHandler).getActivityName(activityInstanceList);
+ String expectedTaskName = "Last task executed: BB to Execute";
+
+ String actualTaskName = camundaRequestHandler.getTaskName(REQUEST_ID);
+
+ assertEquals(expectedTaskName, actualTaskName);
+ }
+
+ @Test
+ public void getTaskNameNullProcessInstanceListTest() throws IOException, ContactCamundaException {
+ ResponseEntity<List<HistoricProcessInstanceEntity>> response = new ResponseEntity<>(null, HttpStatus.OK);
+ doReturn(response).when(camundaRequestHandler).getCamundaProcessInstanceHistory(REQUEST_ID);
+ String expected = "No processInstances returned for requestId: " + REQUEST_ID;
+
+ String actual = camundaRequestHandler.getTaskName(REQUEST_ID);
+
+ assertEquals(expected, actual);
+ }
+
+ @Test
+ public void getTaskNameNullProcessInstanceIdTest() throws IOException, ContactCamundaException {
+ HistoricProcessInstanceEntity processInstance = new HistoricProcessInstanceEntity();
+ List<HistoricProcessInstanceEntity> processInstanceList = new ArrayList<>();
+ processInstanceList.add(processInstance);
+ ResponseEntity<List<HistoricProcessInstanceEntity>> response =
+ new ResponseEntity<>(processInstanceList, HttpStatus.OK);
+ doReturn(response).when(camundaRequestHandler).getCamundaProcessInstanceHistory(REQUEST_ID);
+ String expected = "No processInstanceId returned for requestId: " + REQUEST_ID;
+
+ String actual = camundaRequestHandler.getTaskName(REQUEST_ID);
+
+ assertEquals(expected, actual);
+ }
+
+ @Test
+ public void getTaskNameProcessInstanceLookupFailureTest() throws IOException, ContactCamundaException {
+ doThrow(HttpClientErrorException.class).when(camundaRequestHandler)
+ .getCamundaProcessInstanceHistory(REQUEST_ID);
+
+ thrown.expect(ContactCamundaException.class);
+ camundaRequestHandler.getTaskName(REQUEST_ID);
+ }
+
+ @Test
+ public void getCamundaActivityHistoryTest() throws IOException, ContactCamundaException {
+ HttpHeaders headers = setHeaders();
+ HttpEntity<?> requestEntity = new HttpEntity<>(headers);
+ String targetUrl = "http://localhost:8089/sobpmnengine/history/activity-instance?processInstanceId="
+ + "c4c6b647-a26e-11e9-b144-0242ac14000b";
+ doReturn(activityInstanceResponse).when(restTemplate).exchange(targetUrl, HttpMethod.GET, requestEntity,
+ new ParameterizedTypeReference<List<HistoricActivityInstanceEntity>>() {});
+ doReturn(headers).when(camundaRequestHandler).setCamundaHeaders("auth", "key");
+ ResponseEntity<List<HistoricActivityInstanceEntity>> actualResponse =
+ camundaRequestHandler.getCamundaActivityHistory("c4c6b647-a26e-11e9-b144-0242ac14000b", REQUEST_ID);
+ assertEquals(activityInstanceResponse, actualResponse);
+ }
+
+ @Test
+ public void getCamundaActivityHistoryErrorTest() {
+ HttpHeaders headers = setHeaders();
+ HttpEntity<?> requestEntity = new HttpEntity<>(headers);
+ String targetUrl = "http://localhost:8089/sobpmnengine/history/activity-instance?processInstanceId="
+ + "c4c6b647-a26e-11e9-b144-0242ac14000b";
+ doThrow(new ResourceAccessException("IOException")).when(restTemplate).exchange(targetUrl, HttpMethod.GET,
+ requestEntity, new ParameterizedTypeReference<List<HistoricActivityInstanceEntity>>() {});
+ doReturn(headers).when(camundaRequestHandler).setCamundaHeaders("auth", "key");
+
+ try {
+ camundaRequestHandler.getCamundaActivityHistory("c4c6b647-a26e-11e9-b144-0242ac14000b", REQUEST_ID);
+ } catch (ContactCamundaException e) {
+ // Exception thrown after retries are completed
+ }
+
+ verify(restTemplate, times(4)).exchange(targetUrl, HttpMethod.GET, requestEntity,
+ new ParameterizedTypeReference<List<HistoricActivityInstanceEntity>>() {});
+ }
+
+ @Test
+ public void getCamundaProccesInstanceHistoryTest() throws IOException, ContactCamundaException {
+ HttpHeaders headers = setHeaders();
+ HttpEntity<?> requestEntity = new HttpEntity<>(headers);
+ String targetUrl =
+ "http://localhost:8089/sobpmnengine/history/process-instance?variables=mso-request-id_eq_" + REQUEST_ID;
+ doReturn(processInstanceResponse).when(restTemplate).exchange(targetUrl, HttpMethod.GET, requestEntity,
+ new ParameterizedTypeReference<List<HistoricProcessInstanceEntity>>() {});
+ doReturn(headers).when(camundaRequestHandler).setCamundaHeaders("auth", "key");
+
+ ResponseEntity<List<HistoricProcessInstanceEntity>> actualResponse =
+ camundaRequestHandler.getCamundaProcessInstanceHistory(REQUEST_ID);
+ assertEquals(processInstanceResponse, actualResponse);
+ }
+
+ @Test
+ public void getCamundaProccesInstanceHistoryRetryTest() {
+ HttpHeaders headers = setHeaders();
+ HttpEntity<?> requestEntity = new HttpEntity<>(headers);
+ String targetUrl =
+ "http://localhost:8089/sobpmnengine/history/process-instance?variables=mso-request-id_eq_" + REQUEST_ID;
+ doThrow(new ResourceAccessException("I/O error")).when(restTemplate).exchange(targetUrl, HttpMethod.GET,
+ requestEntity, new ParameterizedTypeReference<List<HistoricProcessInstanceEntity>>() {});
+ doReturn(headers).when(camundaRequestHandler).setCamundaHeaders("auth", "key");
+
+ try {
+ camundaRequestHandler.getCamundaProcessInstanceHistory(REQUEST_ID);
+ } catch (ResourceAccessException e) {
+ // Exception thrown after retries are completed
+ }
+ verify(restTemplate, times(4)).exchange(targetUrl, HttpMethod.GET, requestEntity,
+ new ParameterizedTypeReference<List<HistoricProcessInstanceEntity>>() {});
+ }
+
+ @Test
+ public void getCamundaProccesInstanceHistoryNoRetryTest() {
+ HttpHeaders headers = setHeaders();
+ HttpEntity<?> requestEntity = new HttpEntity<>(headers);
+ String targetUrl =
+ "http://localhost:8089/sobpmnengine/history/process-instance?variables=mso-request-id_eq_" + REQUEST_ID;
+ doThrow(HttpClientErrorException.class).when(restTemplate).exchange(targetUrl, HttpMethod.GET, requestEntity,
+ new ParameterizedTypeReference<List<HistoricProcessInstanceEntity>>() {});
+ doReturn(headers).when(camundaRequestHandler).setCamundaHeaders("auth", "key");
+
+ try {
+ camundaRequestHandler.getCamundaProcessInstanceHistory(REQUEST_ID);
+ } catch (HttpStatusCodeException e) {
+ // Exception thrown, no retries
+ }
+ verify(restTemplate, times(1)).exchange(targetUrl, HttpMethod.GET, requestEntity,
+ new ParameterizedTypeReference<List<HistoricProcessInstanceEntity>>() {});
+ }
+
+ @Test
+ public void getCamundaProccesInstanceHistoryFailThenSuccessTest() throws IOException, ContactCamundaException {
+ HttpHeaders headers = setHeaders();
+ HttpEntity<?> requestEntity = new HttpEntity<>(headers);
+ String targetUrl =
+ "http://localhost:8089/sobpmnengine/history/process-instance?variables=mso-request-id_eq_" + REQUEST_ID;
+ when(restTemplate.exchange(targetUrl, HttpMethod.GET, requestEntity,
+ new ParameterizedTypeReference<List<HistoricProcessInstanceEntity>>() {}))
+ .thenThrow(new ResourceAccessException("I/O Exception")).thenReturn(processInstanceResponse);
+ doReturn(headers).when(camundaRequestHandler).setCamundaHeaders("auth", "key");
+
+ ResponseEntity<List<HistoricProcessInstanceEntity>> actualResponse =
+ camundaRequestHandler.getCamundaProcessInstanceHistory(REQUEST_ID);
+ assertEquals(processInstanceResponse, actualResponse);
+ verify(restTemplate, times(2)).exchange(targetUrl, HttpMethod.GET, requestEntity,
+ new ParameterizedTypeReference<List<HistoricProcessInstanceEntity>>() {});
+ }
+
+ @Test
+ public void setCamundaHeadersTest() throws ContactCamundaException, RequestDbFailureException {
+ String encryptedAuth = "015E7ACF706C6BBF85F2079378BDD2896E226E09D13DC2784BA309E27D59AB9FAD3A5E039DF0BB8408"; // user:password
+ String key = "07a7159d3bf51a0e53be7a8f89699be7";
+
+ HttpHeaders headers = camundaRequestHandler.setCamundaHeaders(encryptedAuth, key);
+ List<org.springframework.http.MediaType> acceptedType = headers.getAccept();
+
+ String expectedAcceptedType = "application/json";
+ assertEquals(expectedAcceptedType, acceptedType.get(0).toString());
+ String basicAuth = headers.getFirst(HttpHeaders.AUTHORIZATION);
+ String expectedBasicAuth = "Basic dXNlcjpwYXNzd29yZA==";
+
+ assertEquals(expectedBasicAuth, basicAuth);
+ }
+}
diff --git a/mso-api-handlers/mso-api-handler-infra/src/test/java/org/onap/so/apihandlerinfra/OrchestrationRequestsTest.java b/mso-api-handlers/mso-api-handler-infra/src/test/java/org/onap/so/apihandlerinfra/OrchestrationRequestsTest.java
index f82f5ac746..12f0ffcc11 100644
--- a/mso-api-handlers/mso-api-handler-infra/src/test/java/org/onap/so/apihandlerinfra/OrchestrationRequestsTest.java
+++ b/mso-api-handlers/mso-api-handler-infra/src/test/java/org/onap/so/apihandlerinfra/OrchestrationRequestsTest.java
@@ -26,6 +26,7 @@ import static com.github.tomakehurst.wiremock.client.WireMock.equalTo;
import static com.github.tomakehurst.wiremock.client.WireMock.equalToJson;
import static com.github.tomakehurst.wiremock.client.WireMock.get;
import static com.github.tomakehurst.wiremock.client.WireMock.post;
+import static com.github.tomakehurst.wiremock.client.WireMock.urlMatching;
import static com.github.tomakehurst.wiremock.client.WireMock.urlPathEqualTo;
import static com.shazam.shazamcrest.MatcherAssert.assertThat;
import static com.shazam.shazamcrest.matcher.Matchers.sameBeanAs;
@@ -42,6 +43,7 @@ import java.util.Map;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import org.apache.http.HttpStatus;
+import org.junit.Before;
import org.junit.Test;
import org.onap.so.apihandler.common.ErrorNumbers;
import org.onap.so.db.request.beans.InfraActiveRequests;
@@ -92,6 +94,21 @@ public class OrchestrationRequestsTest extends BaseTest {
return list;
}
+ @Before
+ public void setup() throws IOException {
+ wireMockServer.stubFor(get(urlMatching("/sobpmnengine/history/process-instance.*")).willReturn(aResponse()
+ .withHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON)
+ .withBody(new String(Files.readAllBytes(
+ Paths.get("src/test/resources/OrchestrationRequest/ProcessInstanceHistoryResponse.json"))))
+ .withStatus(org.apache.http.HttpStatus.SC_OK)));
+ wireMockServer.stubFor(
+ get(("/sobpmnengine/history/activity-instance?processInstanceId=c4c6b647-a26e-11e9-b144-0242ac14000b"))
+ .willReturn(aResponse().withHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON)
+ .withBody(new String(Files.readAllBytes(Paths.get(
+ "src/test/resources/OrchestrationRequest/ActivityInstanceHistoryResponse.json"))))
+ .withStatus(HttpStatus.SC_OK)));
+ }
+
@Test
public void testGetOrchestrationRequest() throws Exception {
setupTestGetOrchestrationRequest();
diff --git a/mso-api-handlers/mso-api-handler-infra/src/test/java/org/onap/so/apihandlerinfra/OrchestrationRequestsUnitTest.java b/mso-api-handlers/mso-api-handler-infra/src/test/java/org/onap/so/apihandlerinfra/OrchestrationRequestsUnitTest.java
index fc548a715e..5023155768 100644
--- a/mso-api-handlers/mso-api-handler-infra/src/test/java/org/onap/so/apihandlerinfra/OrchestrationRequestsUnitTest.java
+++ b/mso-api-handlers/mso-api-handler-infra/src/test/java/org/onap/so/apihandlerinfra/OrchestrationRequestsUnitTest.java
@@ -25,6 +25,7 @@ import static org.hamcrest.CoreMatchers.equalTo;
import static org.hamcrest.CoreMatchers.is;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertThat;
+import static org.mockito.Mockito.doReturn;
import javax.ws.rs.core.Response;
import org.apache.commons.lang.StringUtils;
import org.junit.Before;
@@ -55,6 +56,8 @@ public class OrchestrationRequestsUnitTest {
private ResponseBuilder builder;
@Mock
private Response response;
+ @Mock
+ private CamundaRequestHandler camundaRequestHandler;
@Rule
public ExpectedException thrown = ExpectedException.none();
@InjectMocks
@@ -68,6 +71,7 @@ public class OrchestrationRequestsUnitTest {
private static final String FLOW_STATUS = "FlowStatus";
private static final String RETRY_STATUS_MESSAGE = "RetryStatusMessage";
private static final String ROLLBACK_STATUS_MESSAGE = "RollbackStatusMessage";
+ private static final String TASK_INFORMATION = " TASK INFORMATION: Last task executed: Call SDNC";
private InfraActiveRequests iar;
boolean includeCloudRequest = false;
private static final String ROLLBACK_EXT_SYSTEM_ERROR_SOURCE = "SDNC";
@@ -79,14 +83,23 @@ public class OrchestrationRequestsUnitTest {
iar.setRequestScope(SERVICE);
iar.setRequestId(REQUEST_ID);
iar.setServiceInstanceId(SERVICE_INSTANCE_ID);
+ iar.setExtSystemErrorSource(EXT_SYSTEM_ERROR_SOURCE);
+ iar.setRollbackExtSystemErrorSource(ROLLBACK_EXT_SYSTEM_ERROR_SOURCE);
+ iar.setFlowStatus(FLOW_STATUS);
+ iar.setRollbackStatusMessage(ROLLBACK_STATUS_MESSAGE);
+ iar.setRetryStatusMessage(RETRY_STATUS_MESSAGE);
}
@Test
public void mapInfraActiveRequestToRequestWithOriginalRequestIdTest() throws ApiException {
+ doReturn("Last task executed: Call SDNC").when(camundaRequestHandler).getTaskName(REQUEST_ID);
InstanceReferences instanceReferences = new InstanceReferences();
instanceReferences.setServiceInstanceId(SERVICE_INSTANCE_ID);
RequestStatus requestStatus = new RequestStatus();
requestStatus.setRequestState(iar.getRequestStatus());
+ requestStatus.setStatusMessage(String.format("FLOW STATUS: %s RETRY STATUS: %s ROLLBACK STATUS: %s",
+ FLOW_STATUS + TASK_INFORMATION, RETRY_STATUS_MESSAGE, ROLLBACK_STATUS_MESSAGE));
+
Request expected = new Request();
expected.setRequestId(REQUEST_ID);
expected.setOriginalRequestId(ORIGINAL_REQUEST_ID);
@@ -103,10 +116,13 @@ public class OrchestrationRequestsUnitTest {
@Test
public void mapInfraActiveRequestToRequestOriginalRequestIdNullTest() throws ApiException {
+ doReturn("Last task executed: Call SDNC").when(camundaRequestHandler).getTaskName(REQUEST_ID);
InstanceReferences instanceReferences = new InstanceReferences();
instanceReferences.setServiceInstanceId(SERVICE_INSTANCE_ID);
RequestStatus requestStatus = new RequestStatus();
requestStatus.setRequestState(iar.getRequestStatus());
+ requestStatus.setStatusMessage(String.format("FLOW STATUS: %s RETRY STATUS: %s ROLLBACK STATUS: %s",
+ FLOW_STATUS + TASK_INFORMATION, RETRY_STATUS_MESSAGE, ROLLBACK_STATUS_MESSAGE));
Request expected = new Request();
expected.setRequestId(REQUEST_ID);
expected.setInstanceReferences(instanceReferences);
@@ -120,10 +136,13 @@ public class OrchestrationRequestsUnitTest {
@Test
public void mapRequestStatusAndExtSysErrSrcToRequestFalseTest() throws ApiException {
+ doReturn("Last task executed: Call SDNC").when(camundaRequestHandler).getTaskName(REQUEST_ID);
InstanceReferences instanceReferences = new InstanceReferences();
instanceReferences.setServiceInstanceId(SERVICE_INSTANCE_ID);
RequestStatus requestStatus = new RequestStatus();
requestStatus.setRequestState(iar.getRequestStatus());
+ requestStatus.setStatusMessage(String.format("FLOW STATUS: %s RETRY STATUS: %s ROLLBACK STATUS: %s",
+ FLOW_STATUS + TASK_INFORMATION, RETRY_STATUS_MESSAGE, ROLLBACK_STATUS_MESSAGE));
Request expected = new Request();
expected.setRequestId(REQUEST_ID);
@@ -140,6 +159,7 @@ public class OrchestrationRequestsUnitTest {
@Test
public void mapRequestStatusAndExtSysErrSrcToRequestStatusDetailTest() throws ApiException {
+ doReturn(null).when(camundaRequestHandler).getTaskName(REQUEST_ID);
InstanceReferences instanceReferences = new InstanceReferences();
instanceReferences.setServiceInstanceId(SERVICE_INSTANCE_ID);
RequestStatus requestStatus = new RequestStatus();
@@ -157,11 +177,6 @@ public class OrchestrationRequestsUnitTest {
expected.setRequestScope(SERVICE);
includeCloudRequest = false;
- iar.setExtSystemErrorSource(EXT_SYSTEM_ERROR_SOURCE);
- iar.setRollbackExtSystemErrorSource(ROLLBACK_EXT_SYSTEM_ERROR_SOURCE);
- iar.setFlowStatus(FLOW_STATUS);
- iar.setRollbackStatusMessage(ROLLBACK_STATUS_MESSAGE);
- iar.setRetryStatusMessage(RETRY_STATUS_MESSAGE);
Request actual = orchestrationRequests.mapInfraActiveRequestToRequest(iar, includeCloudRequest,
OrchestrationRequestFormat.STATUSDETAIL.toString());
@@ -170,12 +185,13 @@ public class OrchestrationRequestsUnitTest {
@Test
public void mapRequestStatusAndExtSysErrSrcToRequestDetailTest() throws ApiException {
+ doReturn("Last task executed: Call SDNC").when(camundaRequestHandler).getTaskName(REQUEST_ID);
InstanceReferences instanceReferences = new InstanceReferences();
instanceReferences.setServiceInstanceId(SERVICE_INSTANCE_ID);
RequestStatus requestStatus = new RequestStatus();
requestStatus.setRequestState(iar.getRequestStatus());
requestStatus.setStatusMessage(String.format("FLOW STATUS: %s RETRY STATUS: %s ROLLBACK STATUS: %s",
- FLOW_STATUS, RETRY_STATUS_MESSAGE, ROLLBACK_STATUS_MESSAGE));
+ FLOW_STATUS + TASK_INFORMATION, RETRY_STATUS_MESSAGE, ROLLBACK_STATUS_MESSAGE));
Request expected = new Request();
expected.setRequestId(REQUEST_ID);
@@ -184,11 +200,78 @@ public class OrchestrationRequestsUnitTest {
expected.setRequestScope(SERVICE);
includeCloudRequest = false;
- iar.setExtSystemErrorSource(EXT_SYSTEM_ERROR_SOURCE);
- iar.setRollbackExtSystemErrorSource(ROLLBACK_EXT_SYSTEM_ERROR_SOURCE);
- iar.setFlowStatus(FLOW_STATUS);
- iar.setRollbackStatusMessage(ROLLBACK_STATUS_MESSAGE);
- iar.setRetryStatusMessage(RETRY_STATUS_MESSAGE);
+
+ Request actual = orchestrationRequests.mapInfraActiveRequestToRequest(iar, includeCloudRequest,
+ OrchestrationRequestFormat.DETAIL.toString());
+
+ assertThat(actual, sameBeanAs(expected));
+ }
+
+ @Test
+ public void mapRequestStatusAndExtSysErrSrcToRequestNoFlowStatusTest() throws ApiException {
+ InstanceReferences instanceReferences = new InstanceReferences();
+ instanceReferences.setServiceInstanceId(SERVICE_INSTANCE_ID);
+ RequestStatus requestStatus = new RequestStatus();
+ requestStatus.setRequestState(iar.getRequestStatus());
+ requestStatus.setStatusMessage(
+ String.format("RETRY STATUS: %s ROLLBACK STATUS: %s", RETRY_STATUS_MESSAGE, ROLLBACK_STATUS_MESSAGE));
+
+ Request expected = new Request();
+ expected.setRequestId(REQUEST_ID);
+ expected.setInstanceReferences(instanceReferences);
+ expected.setRequestStatus(requestStatus);
+ expected.setRequestScope(SERVICE);
+
+ includeCloudRequest = false;
+ iar.setFlowStatus(null);
+
+ Request actual = orchestrationRequests.mapInfraActiveRequestToRequest(iar, includeCloudRequest,
+ OrchestrationRequestFormat.DETAIL.toString());
+
+ assertThat(actual, sameBeanAs(expected));
+ }
+
+ @Test
+ public void mapRequestStatusAndExtSysErrSrcToRequestFlowStatusSuccessfulCompletionTest() throws ApiException {
+ InstanceReferences instanceReferences = new InstanceReferences();
+ instanceReferences.setServiceInstanceId(SERVICE_INSTANCE_ID);
+ RequestStatus requestStatus = new RequestStatus();
+ requestStatus.setRequestState(iar.getRequestStatus());
+ requestStatus.setStatusMessage(String.format("FLOW STATUS: %s RETRY STATUS: %s ROLLBACK STATUS: %s",
+ "Successfully completed all Building Blocks", RETRY_STATUS_MESSAGE, ROLLBACK_STATUS_MESSAGE));
+
+ Request expected = new Request();
+ expected.setRequestId(REQUEST_ID);
+ expected.setInstanceReferences(instanceReferences);
+ expected.setRequestStatus(requestStatus);
+ expected.setRequestScope(SERVICE);
+
+ includeCloudRequest = false;
+ iar.setFlowStatus("Successfully completed all Building Blocks");
+
+ Request actual = orchestrationRequests.mapInfraActiveRequestToRequest(iar, includeCloudRequest,
+ OrchestrationRequestFormat.DETAIL.toString());
+
+ assertThat(actual, sameBeanAs(expected));
+ }
+
+ @Test
+ public void mapRequestStatusAndExtSysErrSrcToRequestFlowStatusSuccessfulRollbackTest() throws ApiException {
+ InstanceReferences instanceReferences = new InstanceReferences();
+ instanceReferences.setServiceInstanceId(SERVICE_INSTANCE_ID);
+ RequestStatus requestStatus = new RequestStatus();
+ requestStatus.setRequestState(iar.getRequestStatus());
+ requestStatus.setStatusMessage(String.format("FLOW STATUS: %s RETRY STATUS: %s ROLLBACK STATUS: %s",
+ "All Rollback flows have completed successfully", RETRY_STATUS_MESSAGE, ROLLBACK_STATUS_MESSAGE));
+
+ Request expected = new Request();
+ expected.setRequestId(REQUEST_ID);
+ expected.setInstanceReferences(instanceReferences);
+ expected.setRequestStatus(requestStatus);
+ expected.setRequestScope(SERVICE);
+
+ includeCloudRequest = false;
+ iar.setFlowStatus("All Rollback flows have completed successfully");
Request actual = orchestrationRequests.mapInfraActiveRequestToRequest(iar, includeCloudRequest,
OrchestrationRequestFormat.DETAIL.toString());
diff --git a/mso-api-handlers/mso-api-handler-infra/src/test/java/org/onap/so/apihandlerinfra/RequestHandlerUtilsTest.java b/mso-api-handlers/mso-api-handler-infra/src/test/java/org/onap/so/apihandlerinfra/RequestHandlerUtilsTest.java
index 62a6f44a63..5306888570 100644
--- a/mso-api-handlers/mso-api-handler-infra/src/test/java/org/onap/so/apihandlerinfra/RequestHandlerUtilsTest.java
+++ b/mso-api-handlers/mso-api-handler-infra/src/test/java/org/onap/so/apihandlerinfra/RequestHandlerUtilsTest.java
@@ -76,6 +76,9 @@ public class RequestHandlerUtilsTest extends BaseTest {
@Autowired
private RequestHandlerUtils requestHandlerUtils;
+ @Autowired
+ private CamundaRequestHandler camundaRequestHandler;
+
@Value("${wiremock.server.port}")
private String wiremockPort;
@@ -327,7 +330,7 @@ public class RequestHandlerUtilsTest extends BaseTest {
public void setCamundaHeadersTest() throws ContactCamundaException, RequestDbFailureException {
String encryptedAuth = "015E7ACF706C6BBF85F2079378BDD2896E226E09D13DC2784BA309E27D59AB9FAD3A5E039DF0BB8408"; // user:password
String key = "07a7159d3bf51a0e53be7a8f89699be7";
- HttpHeaders headers = requestHandlerUtils.setCamundaHeaders(encryptedAuth, key);
+ HttpHeaders headers = camundaRequestHandler.setCamundaHeaders(encryptedAuth, key);
List<org.springframework.http.MediaType> acceptedType = headers.getAccept();
String expectedAcceptedType = "application/json";
assertEquals(expectedAcceptedType, acceptedType.get(0).toString());
diff --git a/mso-api-handlers/mso-api-handler-infra/src/test/java/org/onap/so/apihandlerinfra/ServiceInstancesTest.java b/mso-api-handlers/mso-api-handler-infra/src/test/java/org/onap/so/apihandlerinfra/ServiceInstancesTest.java
index b72e5124d1..4b2644bc00 100644
--- a/mso-api-handlers/mso-api-handler-infra/src/test/java/org/onap/so/apihandlerinfra/ServiceInstancesTest.java
+++ b/mso-api-handlers/mso-api-handler-infra/src/test/java/org/onap/so/apihandlerinfra/ServiceInstancesTest.java
@@ -2917,19 +2917,6 @@ public class ServiceInstancesTest extends BaseTest {
}
@Test
- public void setCamundaHeadersTest() throws ContactCamundaException, RequestDbFailureException {
- String encryptedAuth = "015E7ACF706C6BBF85F2079378BDD2896E226E09D13DC2784BA309E27D59AB9FAD3A5E039DF0BB8408"; // user:password
- String key = "07a7159d3bf51a0e53be7a8f89699be7";
- HttpHeaders headers = requestHandlerUtils.setCamundaHeaders(encryptedAuth, key);
- List<org.springframework.http.MediaType> acceptedType = headers.getAccept();
- String expectedAcceptedType = "application/json";
- assertEquals(expectedAcceptedType, acceptedType.get(0).toString());
- String basicAuth = headers.getFirst(HttpHeaders.AUTHORIZATION);
- String expectedBasicAuth = "Basic dXNlcjpwYXNzd29yZA==";
- assertEquals(expectedBasicAuth, basicAuth);
- }
-
- @Test
public void handleReplaceInstance_Test() throws JsonParseException, JsonMappingException, IOException {
String replaceVfModule = inputStream("/ReplaceVfModule.json");
ObjectMapper mapper = new ObjectMapper();
diff --git a/mso-api-handlers/mso-api-handler-infra/src/test/resources/OrchestrationRequest/ActivityInstanceHistoryResponse.json b/mso-api-handlers/mso-api-handler-infra/src/test/resources/OrchestrationRequest/ActivityInstanceHistoryResponse.json
new file mode 100644
index 0000000000..efd80f3347
--- /dev/null
+++ b/mso-api-handlers/mso-api-handler-infra/src/test/resources/OrchestrationRequest/ActivityInstanceHistoryResponse.json
@@ -0,0 +1,48 @@
+[
+ {
+ "id":"Call_BBToExecute:c4f603e4-a26e-11e9-b144-0242ac14000b",
+ "parentActivityInstanceId":"c4c6b647-a26e-11e9-b144-0242ac14000b",
+ "activityId":"Call_BBToExecute",
+ "activityName":"BB to Execute",
+ "activityType":"callActivity",
+ "processDefinitionKey":"ExecuteBuildingBlock",
+ "processDefinitionId":"ExecuteBuildingBlock:1:a46566de-a26b-11e9-b144-0242ac14000b",
+ "processInstanceId":"c4c6b647-a26e-11e9-b144-0242ac14000b",
+ "executionId":"c4f603e3-a26e-11e9-b144-0242ac14000b",
+ "taskId":null,
+ "calledProcessInstanceId":"c4f603e6-a26e-11e9-b144-0242ac14000b",
+ "calledCaseInstanceId":null,
+ "assignee":null,
+ "startTime":"2019-07-09T17:27:04.607+0000",
+ "endTime":"2019-07-09T17:27:05.545+0000",
+ "durationInMillis":938,
+ "canceled":true,
+ "completeScope":false,
+ "tenantId":null,
+ "removalTime":null,
+ "rootProcessInstanceId":"c2fd4066-a26e-11e9-b144-0242ac14000b"
+ },
+ {
+ "id":"EndEvent_0mvmk3i:c59b1d39-a26e-11e9-b144-0242ac14000b",
+ "parentActivityInstanceId":"SubProcess_0tv8zda:c5852427-a26e-11e9-b144-0242ac14000b",
+ "activityId":"EndEvent_0mvmk3i",
+ "activityName":null,
+ "activityType":"noneEndEvent",
+ "processDefinitionKey":"ExecuteBuildingBlock",
+ "processDefinitionId":"ExecuteBuildingBlock:1:a46566de-a26b-11e9-b144-0242ac14000b",
+ "processInstanceId":"c4c6b647-a26e-11e9-b144-0242ac14000b",
+ "executionId":"c5852426-a26e-11e9-b144-0242ac14000b",
+ "taskId":null,
+ "calledProcessInstanceId":null,
+ "calledCaseInstanceId":null,
+ "assignee":null,
+ "startTime":"2019-07-09T17:27:05.689+0000",
+ "endTime":"2019-07-09T17:27:05.689+0000",
+ "durationInMillis":0,
+ "canceled":false,
+ "completeScope":true,
+ "tenantId":null,
+ "removalTime":null,
+ "rootProcessInstanceId":"c2fd4066-a26e-11e9-b144-0242ac14000b"
+ }
+ ] \ No newline at end of file
diff --git a/mso-api-handlers/mso-api-handler-infra/src/test/resources/OrchestrationRequest/OrchestrationFilterResponse.json b/mso-api-handlers/mso-api-handler-infra/src/test/resources/OrchestrationRequest/OrchestrationFilterResponse.json
index 3b2eca7ce2..96fed36d45 100644
--- a/mso-api-handlers/mso-api-handler-infra/src/test/resources/OrchestrationRequest/OrchestrationFilterResponse.json
+++ b/mso-api-handlers/mso-api-handler-infra/src/test/resources/OrchestrationRequest/OrchestrationFilterResponse.json
@@ -61,7 +61,7 @@
},
"requestStatus": {
"requestState": "COMPLETE",
- "statusMessage": "STATUS: Vf Module has been deleted successfully. FLOW STATUS: Building blocks 1 of 3 completed. ROLLBACK STATUS: Rollback has been completed successfully.",
+ "statusMessage": "STATUS: Vf Module has been deleted successfully. FLOW STATUS: Building blocks 1 of 3 completed. TASK INFORMATION: Last task executed: BB to Execute ROLLBACK STATUS: Rollback has been completed successfully.",
"percentProgress": 100,
"timestamp": "Thu, 22 Dec 2016 08:30:28 GMT"
}
diff --git a/mso-api-handlers/mso-api-handler-infra/src/test/resources/OrchestrationRequest/OrchestrationList.json b/mso-api-handlers/mso-api-handler-infra/src/test/resources/OrchestrationRequest/OrchestrationList.json
index baddb21617..801841313a 100644
--- a/mso-api-handlers/mso-api-handler-infra/src/test/resources/OrchestrationRequest/OrchestrationList.json
+++ b/mso-api-handlers/mso-api-handler-infra/src/test/resources/OrchestrationRequest/OrchestrationList.json
@@ -58,7 +58,7 @@
},
"requestStatus":{
"requestState":"PENDING",
- "statusMessage":"FLOW STATUS: Building blocks 1 of 3 completed. RETRY STATUS: Retry 2/5 will be started in 8 min. ROLLBACK STATUS: Rollback has been completed successfully.",
+ "statusMessage":"FLOW STATUS: Building blocks 1 of 3 completed. TASK INFORMATION: Last task executed: BB to Execute RETRY STATUS: Retry 2/5 will be started in 8 min. ROLLBACK STATUS: Rollback has been completed successfully.",
"percentProgress":0,
"timestamp": "Thu, 22 Dec 2016 08:30:28 GMT"
}
@@ -321,7 +321,7 @@
},
"requestStatus":{
"requestState":"PENDING",
- "statusMessage":"STATUS: Adding members. FLOW STATUS: Building blocks 1 of 3 completed. RETRY STATUS: Retry 2/5 will be started in 8 min. ROLLBACK STATUS: Rollback has been completed successfully.",
+ "statusMessage":"STATUS: Adding members. FLOW STATUS: Building blocks 1 of 3 completed. TASK INFORMATION: Last task executed: BB to Execute RETRY STATUS: Retry 2/5 will be started in 8 min. ROLLBACK STATUS: Rollback has been completed successfully.",
"percentProgress":0,
"timestamp": "Thu, 22 Dec 2016 08:30:28 GMT"
}
diff --git a/mso-api-handlers/mso-api-handler-infra/src/test/resources/OrchestrationRequest/ProcessInstanceHistoryResponse.json b/mso-api-handlers/mso-api-handler-infra/src/test/resources/OrchestrationRequest/ProcessInstanceHistoryResponse.json
new file mode 100644
index 0000000000..faa283463b
--- /dev/null
+++ b/mso-api-handlers/mso-api-handler-infra/src/test/resources/OrchestrationRequest/ProcessInstanceHistoryResponse.json
@@ -0,0 +1,44 @@
+[
+ {
+ "id":"c2fd4066-a26e-11e9-b144-0242ac14000b",
+ "businessKey":"84eacc7b-b046-4333-9272-5e8513bdd4cc",
+ "processDefinitionId":"WorkflowActionBB:1:a461210d-a26b-11e9-b144-0242ac14000b",
+ "processDefinitionKey":"WorkflowActionBB",
+ "processDefinitionName":"WorkflowActionBB",
+ "processDefinitionVersion":1,
+ "startTime":"2019-07-09T17:27:01.299+0000",
+ "endTime":"2019-07-09T17:27:06.585+0000",
+ "removalTime":null,
+ "durationInMillis":5286,
+ "startUserId":null,
+ "startActivityId":"Start_WorkflowActionBB",
+ "deleteReason":null,
+ "rootProcessInstanceId":"c2fd4066-a26e-11e9-b144-0242ac14000b",
+ "superProcessInstanceId":null,
+ "superCaseInstanceId":null,
+ "caseInstanceId":null,
+ "tenantId":null,
+ "state":"COMPLETED"
+ },
+ {
+ "id":"c4c6b647-a26e-11e9-b144-0242ac14000b",
+ "businessKey":null,
+ "processDefinitionId":"ExecuteBuildingBlock:1:a46566de-a26b-11e9-b144-0242ac14000b",
+ "processDefinitionKey":"ExecuteBuildingBlock",
+ "processDefinitionName":"ExecuteBuildingBlock",
+ "processDefinitionVersion":1,
+ "startTime":"2019-07-09T17:27:04.298+0000",
+ "endTime":"2019-07-09T17:27:05.690+0000",
+ "removalTime":null,
+ "durationInMillis":1392,
+ "startUserId":null,
+ "startActivityId":"Start_ExecuteBuildingBlock",
+ "deleteReason":null,
+ "rootProcessInstanceId":"c2fd4066-a26e-11e9-b144-0242ac14000b",
+ "superProcessInstanceId":"c2fd4066-a26e-11e9-b144-0242ac14000b",
+ "superCaseInstanceId":null,
+ "caseInstanceId":null,
+ "tenantId":null,
+ "state":"COMPLETED"
+ }
+ ] \ No newline at end of file