diff options
Diffstat (limited to 'mso-api-handlers/mso-api-handler-infra/src/main/java')
4 files changed, 219 insertions, 58 deletions
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 { |