Skip to content

Commit

Permalink
[JBPM-9841] Start process with correlation key rest api should return…
Browse files Browse the repository at this point in the history
… 400 http status if correlation key already exist.
  • Loading branch information
abhijithumbe committed Aug 11, 2021
1 parent 8b1133d commit 1fe0df3
Show file tree
Hide file tree
Showing 3 changed files with 71 additions and 2 deletions.
Expand Up @@ -17,6 +17,7 @@

import java.io.PrintWriter;
import java.io.StringWriter;
import java.sql.SQLIntegrityConstraintViolationException;
import java.text.MessageFormat;
import java.util.Collections;
import java.util.List;
Expand Down Expand Up @@ -215,7 +216,10 @@ public static Response noContent(Variant v, Header... customHeaders) {
public static Response serviceUnavailable(Header... customHeaders) {
return createResponse("", ERROR_VARIANT, Response.Status.SERVICE_UNAVAILABLE, customHeaders);
}


public static Response conflict(String reason, Variant v, Header... customHeaders) {
return createResponse("\"" +reason + "\"", ERROR_VARIANT, Response.Status.CONFLICT, customHeaders);
}
protected static void applyCustomHeaders(Response.ResponseBuilder builder, Header... customHeaders) {
if (customHeaders != null && customHeaders.length > 0) {
for (Header header : customHeaders) {
Expand Down Expand Up @@ -264,4 +268,24 @@ public static String errorMessage(Throwable e, String defaultMessage) {
public static String errorMessage(Throwable e) {
return errorMessage(e, MessageFormat.format(UNEXPECTED_ERROR, e.getMessage()));
}

public static Boolean isCorrelationKeyAlreadyExists(Exception e) {
SQLIntegrityConstraintViolationException constraintViolationException = null;

Throwable t = e.getCause();
while ((t != null) && !(t instanceof SQLIntegrityConstraintViolationException))
t = t.getCause();

constraintViolationException = (SQLIntegrityConstraintViolationException) t;

/*
* 23000 SQLState is used by MySQL, MSSQL,Oracle,Postgres and MariaDB for constraint Violation.
* 'already exists' keyword is used in RuntimeException which is thrown by org.jbpm.persistence.JpaProcessPersistenceContext class to indicate that Correlation key already exists in database.
* */
if ((constraintViolationException != null && (constraintViolationException.getSQLState().equals("23000"))) || e.getMessage().contains("already exists")) {
return true;
}
return false;

}
}
Expand Up @@ -96,12 +96,14 @@
import static org.kie.server.api.rest.RestURI.COMPUTE_PROCESS_OUTCOME_POST_URI;
import static org.kie.server.remote.rest.common.util.RestUtils.badRequest;
import static org.kie.server.remote.rest.common.util.RestUtils.buildConversationIdHeader;
import static org.kie.server.remote.rest.common.util.RestUtils.conflict;
import static org.kie.server.remote.rest.common.util.RestUtils.createCorrectVariant;
import static org.kie.server.remote.rest.common.util.RestUtils.createResponse;
import static org.kie.server.remote.rest.common.util.RestUtils.errorMessage;
import static org.kie.server.remote.rest.common.util.RestUtils.forbidden;
import static org.kie.server.remote.rest.common.util.RestUtils.getContentType;
import static org.kie.server.remote.rest.common.util.RestUtils.getVariant;
import static org.kie.server.remote.rest.common.util.RestUtils.isCorrelationKeyAlreadyExists;
import static org.kie.server.remote.rest.common.util.RestUtils.internalServerError;
import static org.kie.server.remote.rest.common.util.RestUtils.noContent;
import static org.kie.server.remote.rest.common.util.RestUtils.notFound;
Expand Down Expand Up @@ -328,9 +330,12 @@ public Response startProcessWithCorrelationKeyFromNodeIds(@javax.ws.rs.core.Cont
} catch (SecurityException e) {
return forbidden(errorMessage(e, e.getMessage()), v, conversationIdHeader);
} catch (Exception e) {
if (isCorrelationKeyAlreadyExists(e)) {
return conflict(errorMessage(e, e.getMessage()), v, conversationIdHeader);
}
logger.error("Unexpected error during processing {}", e.getMessage(), e);
return internalServerError(
MessageFormat.format(CREATE_RESPONSE_ERROR, e.getMessage()), v);
MessageFormat.format(CREATE_RESPONSE_ERROR, e.getMessage()), v);
}
}

Expand Down Expand Up @@ -373,6 +378,9 @@ public Response startProcessWithCorrelation(@javax.ws.rs.core.Context HttpHeader
} catch (SecurityException e) {
return forbidden(errorMessage(e, e.getMessage()), v, conversationIdHeader);
} catch (Exception e) {
if (isCorrelationKeyAlreadyExists(e)) {
return conflict(errorMessage(e, e.getMessage()), v, conversationIdHeader);
}
logger.error("Unexpected error during processing {}", e.getMessage(), e);
return internalServerError(
MessageFormat.format(CREATE_RESPONSE_ERROR, e.getMessage()), v);
Expand Down
Expand Up @@ -45,6 +45,7 @@
import static org.kie.server.api.rest.RestURI.PROCESS_INST_ID;
import static org.kie.server.api.rest.RestURI.PROCESS_URI;
import static org.kie.server.api.rest.RestURI.START_PROCESS_POST_URI;
import static org.kie.server.api.rest.RestURI.START_PROCESS_WITH_CORRELATION_KEY_POST_URI;
import static org.kie.server.api.rest.RestURI.VAR_NAME;
import static org.kie.server.api.rest.RestURI.WORK_ITEM_ID;
import static org.kie.server.api.rest.RestURI.build;
Expand All @@ -57,6 +58,7 @@ public class ProcessServiceRestOnlyIntegrationTest extends RestJbpmBaseIntegrati

protected static final String CONTAINER_ID = "definition-project";
protected static final String NON_EXISTING_CONTAINER_ID = "non-existing-container";
protected static final String CORRELATION_KEY= "TestCorrelationKey";

@BeforeClass
public static void buildAndDeployArtifacts() {
Expand Down Expand Up @@ -109,6 +111,41 @@ public void testAbortAlreadyAbortedProcess() {
}
}

//JBPM-9841
@Test
public void testStartProcessWithExistingCorrelationKey() {
Map<String, Object> valuesMap = new HashMap<String, Object>();
valuesMap.put(RestURI.CONTAINER_ID, CONTAINER_ID);
valuesMap.put(RestURI.PROCESS_ID, PROCESS_ID_USERTASK);
valuesMap.put(RestURI.CORRELATION_KEY, CORRELATION_KEY);

Response response = null;
try {
// start process instance
WebTarget clientRequest = newRequest(build(TestConfig.getKieServerHttpUrl(), PROCESS_URI + "/" + START_PROCESS_WITH_CORRELATION_KEY_POST_URI, valuesMap));
logger.debug("[POST] " + clientRequest.getUri());
response = clientRequest.request(getMediaType()).post(createEntity(""));
assertThat(response.getStatus()).isEqualTo(Response.Status.CREATED.getStatusCode());

Long result = response.readEntity(JaxbLong.class).unwrap();
assertThat(result).isNotNull();
response.close();

//Start Process with same correlationKey to check response code
clientRequest = newRequest(build(TestConfig.getKieServerHttpUrl(), PROCESS_URI + "/" + START_PROCESS_WITH_CORRELATION_KEY_POST_URI, valuesMap));
logger.debug("[POST] " + clientRequest.getUri());
response = clientRequest.request(getMediaType()).post(createEntity(""));

assertThat(response.getStatus()).isEqualTo(Response.Status.CONFLICT.getStatusCode());
response.close();

} finally {
if (response != null) {
response.close();
}
}
}

@Test
public void testProcessWhichBelongsToAContainer() {
Map<String, Object> valuesMap = new HashMap<String, Object>();
Expand Down

0 comments on commit 1fe0df3

Please sign in to comment.