diff --git a/DISCLAIMER b/DISCLAIMER-WIP
similarity index 100%
rename from DISCLAIMER
rename to DISCLAIMER-WIP
diff --git a/apps-integration-tests/integration-tests-data-index-service/integration-tests-data-index-service-common/src/test/java/org/kie/kogito/index/AbstractProcessDataIndexIT.java b/apps-integration-tests/integration-tests-data-index-service/integration-tests-data-index-service-common/src/test/java/org/kie/kogito/index/AbstractProcessDataIndexIT.java
index e2fb7f7b72..0e12e6d410 100644
--- a/apps-integration-tests/integration-tests-data-index-service/integration-tests-data-index-service-common/src/test/java/org/kie/kogito/index/AbstractProcessDataIndexIT.java
+++ b/apps-integration-tests/integration-tests-data-index-service/integration-tests-data-index-service-common/src/test/java/org/kie/kogito/index/AbstractProcessDataIndexIT.java
@@ -30,7 +30,6 @@
import java.util.Map;
import java.util.concurrent.atomic.AtomicReference;
-import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.testcontainers.shaded.com.fasterxml.jackson.databind.JsonNode;
import org.testcontainers.shaded.com.fasterxml.jackson.databind.ObjectMapper;
@@ -92,7 +91,6 @@ protected ValidatableResponse addCheck(ValidatableResponse res) {
}
@Test
- @Disabled
public void testProcessInstanceEvents() throws IOException {
String pId = given()
.contentType(ContentType.JSON)
@@ -113,13 +111,13 @@ public void testProcessInstanceEvents() throws IOException {
.contentType(ContentType.JSON)
.queryParam("user", "admin")
.queryParam("group", "managers")
- .pathParam("processId", pId)
.when()
- .get("/approvals/{processId}/tasks")
+ .get("/usertasks/instance")
.then()
.statusCode(200)
+ .log().body()
.body("$.size()", is(1))
- .body("[0].name", is("firstLineApproval"))
+ .body("[0].taskName", is("firstLineApproval"))
.body("[0].id", notNullValue())
.extract()
.path("[0].id");
@@ -152,7 +150,7 @@ public void testProcessInstanceEvents() throws IOException {
.body("data.Approvals[0].metadata.userTasks.size()", is(1))
.body("data.Approvals[0].metadata.userTasks[0].id", is(flTaskId))
.body("data.Approvals[0].metadata.userTasks[0].name", is("firstLineApproval"))
- .body("data.Approvals[0].metadata.userTasks[0].state", is("Ready")));
+ .body("data.Approvals[0].metadata.userTasks[0].state", is("Reserved")));
}
await()
@@ -187,7 +185,22 @@ public void testProcessInstanceEvents() throws IOException {
.body("data.UserTaskInstances.size()", is(1))
.body("data.UserTaskInstances[0].id", is(flTaskId))
.body("data.UserTaskInstances[0].name", is("firstLineApproval"))
- .body("data.UserTaskInstances[0].state", is("Ready")));
+ .body("data.UserTaskInstances[0].state", is("Reserved")));
+
+ String workItemId = given()
+ .contentType(ContentType.JSON)
+ .queryParam("user", "admin")
+ .queryParam("group", "managers")
+ .pathParam("processId", pId)
+ .when()
+ .get("/approvals/{processId}/tasks")
+ .then()
+ .statusCode(200)
+ .body("$.size()", is(1))
+ .body("[0].name", is("firstLineApproval"))
+ .body("[0].id", notNullValue())
+ .extract()
+ .path("[0].id");
await()
.atMost(TIMEOUT)
@@ -196,7 +209,7 @@ public void testProcessInstanceEvents() throws IOException {
.queryParam("user", "admin")
.queryParam("group", "managers")
.pathParam("processId", pId)
- .pathParam("taskId", flTaskId)
+ .pathParam("taskId", workItemId)
.body(singletonMap("approved", true))
.post("/approvals/{processId}/firstLineApproval/{taskId}")
.then()
@@ -324,6 +337,7 @@ public void testProcessGatewayAPI() throws IOException {
.when().post("/graphql")
.then()
.statusCode(200)
+ .log().body()
.body("data.UserTaskInstances[0].description", nullValue())
.body("data.UserTaskInstances[0].potentialGroups[0]", equalTo("managers"))
.extract().path("data.UserTaskInstances[0].id");
@@ -335,6 +349,7 @@ public void testProcessGatewayAPI() throws IOException {
.when().post("/graphql")
.then()
.statusCode(200)
+ .log().body()
.body("errors", nullValue())
.extract().path("data.UserTaskInstances[0].schema");
checkExpectedTaskSchema(taskSchema);
@@ -474,9 +489,8 @@ public void testProcessGatewayAPIComments(String taskId, String processInstanceI
.when()
.queryParam("user", "manager")
.queryParam("group", "managers")
- .pathParam("id", processInstanceId)
.pathParam("taskId", taskId)
- .get("/approvals/{id}/firstLineApproval/{taskId}/comments")
+ .get("/usertasks/instance/{taskId}/comments")
.then()
.statusCode(200)
.body("size()", is(1))
@@ -585,9 +599,8 @@ public void testProcessGatewayAPIAttachments(String taskId, String processInstan
.when()
.queryParam("user", "manager")
.queryParam("group", "managers")
- .pathParam("id", processInstanceId)
.pathParam("taskId", taskId)
- .get("/approvals/{id}/firstLineApproval/{taskId}/attachments")
+ .get("/usertasks/instance/{taskId}/attachments")
.then()
.statusCode(200)
.body("size()", is(1))
@@ -710,9 +723,8 @@ private void checkExpectedTaskSchema(String taskSchema) throws IOException {
assertEquals("object", schemaJsonNode.at("/type").asText());
// Check Schema phases
- assertEquals(4, schemaJsonNode.at("/phases").size());
+ assertEquals(3, schemaJsonNode.at("/phases").size());
assertTrue(schemaJsonNode.get("phases").toString().contains("abort"));
- assertTrue(schemaJsonNode.get("phases").toString().contains("claim"));
assertTrue(schemaJsonNode.get("phases").toString().contains("skip"));
assertTrue(schemaJsonNode.get("phases").toString().contains("complete"));
diff --git a/apps-integration-tests/integration-tests-trusty-service/integration-tests-trusty-service-springboot/pom.xml b/apps-integration-tests/integration-tests-trusty-service/integration-tests-trusty-service-springboot/pom.xml
index 1f01ab3b42..fd37954413 100644
--- a/apps-integration-tests/integration-tests-trusty-service/integration-tests-trusty-service-springboot/pom.xml
+++ b/apps-integration-tests/integration-tests-trusty-service/integration-tests-trusty-service-springboot/pom.xml
@@ -33,7 +33,7 @@
org.kie.kogito/integration-tests-trusty-service-springboot:${project.version}
**/KogitoApplication.java
- 2.8.0
+ 3.3.1
eclipse-temurin:17-jre
diff --git a/data-index/data-index-common/src/main/java/org/kie/kogito/index/api/KogitoRuntimeCommonClient.java b/data-index/data-index-common/src/main/java/org/kie/kogito/index/api/KogitoRuntimeCommonClient.java
index 7e86049fc3..1df466aa4d 100644
--- a/data-index/data-index-common/src/main/java/org/kie/kogito/index/api/KogitoRuntimeCommonClient.java
+++ b/data-index/data-index-common/src/main/java/org/kie/kogito/index/api/KogitoRuntimeCommonClient.java
@@ -7,7 +7,7 @@
* "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
+ * 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
@@ -118,8 +118,11 @@ public CompletableFuture sendDeleteClientRequest(WebClient webClient, String req
protected void asyncHttpResponseTreatment(AsyncResult> res, CompletableFuture future, String logMessage) {
if (res.succeeded() && (res.result().statusCode() == 200 || res.result().statusCode() == 201)) {
- future.complete(res.result().bodyAsString() != null ? res.result().bodyAsString() : "Successfully performed: " + logMessage);
+ String jsonMessage = res.result().bodyAsString();
+ LOGGER.trace("Result {}", jsonMessage);
+ future.complete(jsonMessage != null ? jsonMessage : "Successfully performed: " + logMessage);
} else {
+ LOGGER.trace("Error {}", logMessage);
future.completeExceptionally(new DataIndexServiceException(getErrorMessage(logMessage, res.result())));
}
}
diff --git a/data-index/data-index-common/src/main/java/org/kie/kogito/index/service/IndexingService.java b/data-index/data-index-common/src/main/java/org/kie/kogito/index/service/IndexingService.java
index f3cd153d5b..5fbf4d6536 100644
--- a/data-index/data-index-common/src/main/java/org/kie/kogito/index/service/IndexingService.java
+++ b/data-index/data-index-common/src/main/java/org/kie/kogito/index/service/IndexingService.java
@@ -79,15 +79,8 @@ public class IndexingService {
public void indexProcessInstanceEvent(ProcessInstanceDataEvent> event) {
ProcessInstanceStorage storage = manager.getProcessInstanceStorage();
if (event instanceof MultipleProcessInstanceDataEvent) {
- for (ProcessInstanceDataEvent> item : ((MultipleProcessInstanceDataEvent) event).getData())
- indexProccessInstanceEvent(storage, item);
- } else {
- indexProccessInstanceEvent(storage, event);
- }
- }
-
- private void indexProccessInstanceEvent(ProcessInstanceStorage storage, ProcessInstanceDataEvent> event) {
- if (event instanceof ProcessInstanceErrorDataEvent) {
+ storage.indexGroup(((MultipleProcessInstanceDataEvent) event));
+ } else if (event instanceof ProcessInstanceErrorDataEvent) {
storage.indexError((ProcessInstanceErrorDataEvent) event);
} else if (event instanceof ProcessInstanceNodeDataEvent) {
storage.indexNode((ProcessInstanceNodeDataEvent) event);
@@ -112,16 +105,8 @@ public void indexProcessDefinition(ProcessDefinitionDataEvent definitionDataEven
public void indexUserTaskInstanceEvent(UserTaskInstanceDataEvent event) {
UserTaskInstanceStorage storage = manager.getUserTaskInstanceStorage();
if (event instanceof MultipleUserTaskInstanceDataEvent) {
- for (UserTaskInstanceDataEvent> item : ((MultipleUserTaskInstanceDataEvent) event).getData()) {
- indexUserTaskInstanceEvent(storage, item);
- }
- } else {
- indexUserTaskInstanceEvent(storage, event);
- }
- }
-
- private void indexUserTaskInstanceEvent(UserTaskInstanceStorage storage, UserTaskInstanceDataEvent> event) {
- if (event instanceof UserTaskInstanceAssignmentDataEvent) {
+ storage.indexGroup((MultipleUserTaskInstanceDataEvent) event);
+ } else if (event instanceof UserTaskInstanceAssignmentDataEvent) {
storage.indexAssignment((UserTaskInstanceAssignmentDataEvent) event);
} else if (event instanceof UserTaskInstanceAttachmentDataEvent) {
storage.indexAttachment((UserTaskInstanceAttachmentDataEvent) event);
diff --git a/data-index/data-index-graphql/src/main/resources/basic.schema.graphqls b/data-index/data-index-graphql/src/main/resources/basic.schema.graphqls
index 4e6f30b764..741c0d4e89 100644
--- a/data-index/data-index-graphql/src/main/resources/basic.schema.graphqls
+++ b/data-index/data-index-graphql/src/main/resources/basic.schema.graphqls
@@ -367,6 +367,7 @@ type UserTaskInstance {
endpoint: String
comments: [Comment!]
attachments: [Attachment!]
+ externalReferenceId : String
}
input UserTaskInstanceArgument {
diff --git a/data-index/data-index-service/data-index-service-common/src/main/java/org/kie/kogito/index/service/api/KogitoRuntimeClientImpl.java b/data-index/data-index-service/data-index-service-common/src/main/java/org/kie/kogito/index/service/api/KogitoRuntimeClientImpl.java
index beabe661a9..badbe77b24 100644
--- a/data-index/data-index-service/data-index-service-common/src/main/java/org/kie/kogito/index/service/api/KogitoRuntimeClientImpl.java
+++ b/data-index/data-index-service/data-index-service-common/src/main/java/org/kie/kogito/index/service/api/KogitoRuntimeClientImpl.java
@@ -28,11 +28,13 @@
import org.kie.kogito.index.model.ProcessInstance;
import org.kie.kogito.index.model.UserTaskInstance;
import org.kie.kogito.index.service.DataIndexServiceException;
+import org.kie.kogito.usertask.model.CommentInfo;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import io.vertx.core.AsyncResult;
import io.vertx.core.buffer.Buffer;
+import io.vertx.core.json.Json;
import io.vertx.core.json.JsonObject;
import io.vertx.ext.web.client.HttpRequest;
import io.vertx.ext.web.client.HttpResponse;
@@ -58,15 +60,15 @@ class KogitoRuntimeClientImpl extends KogitoRuntimeCommonClient implements Kogit
public static final String CANCEL_NODE_INSTANCE_PATH = "/management/processes/%s/instances/%s/nodeInstances/%s"; // nodeInstance Id
public static final String GET_TASK_SCHEMA_PATH = "/%s/%s/%s/%s/schema";
- public static final String UPDATE_USER_TASK_INSTANCE_PATH = "/management/processes/%s/instances/%s/tasks/%s";
+ public static final String UPDATE_USER_TASK_INSTANCE_PATH = "/management/usertasks/%s";
- public static final String CREATE_USER_TASK_INSTANCE_COMMENT_PATH = "/%s/%s/%s/%s/comments";
- public static final String UPDATE_USER_TASK_INSTANCE_COMMENT_PATH = "/%s/%s/%s/%s/comments/%s";
- public static final String DELETE_USER_TASK_INSTANCE_COMMENT_PATH = "/%s/%s/%s/%s/comments/%s";
+ public static final String CREATE_USER_TASK_INSTANCE_COMMENT_PATH = "/usertasks/instance/%s/comments";
+ public static final String UPDATE_USER_TASK_INSTANCE_COMMENT_PATH = "/usertasks/instance/%s/comments/%s";
+ public static final String DELETE_USER_TASK_INSTANCE_COMMENT_PATH = "/usertasks/instance/%s/comments/%s";
- public static final String CREATE_USER_TASK_INSTANCE_ATTACHMENT_PATH = "/%s/%s/%s/%s/attachments";
- public static final String UPDATE_USER_TASK_INSTANCE_ATTACHMENT_PATH = "/%s/%s/%s/%s/attachments/%s";
- public static final String DELETE_USER_TASK_INSTANCE_ATTACHMENT_PATH = "/%s/%s/%s/%s/attachments/%s";
+ public static final String CREATE_USER_TASK_INSTANCE_ATTACHMENT_PATH = "/usertasks/instance/%s/attachments";
+ public static final String UPDATE_USER_TASK_INSTANCE_ATTACHMENT_PATH = "/usertasks/instance/%s/attachments/%s";
+ public static final String DELETE_USER_TASK_INSTANCE_ATTACHMENT_PATH = "/usertasks/instance/%s/attachments/%s";
private static final Logger LOGGER = LoggerFactory.getLogger(KogitoRuntimeClientImpl.class);
@@ -137,7 +139,8 @@ public CompletableFuture cancelNodeInstance(String serviceURL, ProcessIn
@Override
public CompletableFuture getUserTaskSchema(String serviceURL, UserTaskInstance userTaskInstance, String user, List groups) {
String requestURI = format(GET_TASK_SCHEMA_PATH, userTaskInstance.getProcessId(), userTaskInstance.getProcessInstanceId(),
- userTaskInstance.getName(), userTaskInstance.getId()) + "?" + getUserGroupsURIParameter(user, groups);
+ userTaskInstance.getName(), userTaskInstance.getExternalReferenceId()) + "?" + getUserGroupsURIParameter(user, groups);
+ LOGGER.trace("get user task schema service {} and URI {}", serviceURL, requestURI);
return sendGetClientRequest(getWebClient(serviceURL), requestURI,
"Get User Task schema for task:" + userTaskInstance.getName() + " with id: " + userTaskInstance.getId(),
null);
@@ -146,44 +149,40 @@ public CompletableFuture getUserTaskSchema(String serviceURL, UserTaskIn
@Override
public CompletableFuture updateUserTaskInstance(String serviceURL, UserTaskInstance userTaskInstance, String user,
List groups, Map taskInfo) {
- String requestURI = format(UPDATE_USER_TASK_INSTANCE_PATH, userTaskInstance.getProcessId(), userTaskInstance.getProcessInstanceId(),
- userTaskInstance.getId()) + "?" + getUserGroupsURIParameter(user, groups);
+ String requestURI = format(UPDATE_USER_TASK_INSTANCE_PATH, userTaskInstance.getId()) + "?" + getUserGroupsURIParameter(user, groups);
+ LOGGER.trace("Send request to {}", requestURI);
return sendPatchClientRequest(getWebClient(serviceURL), requestURI,
- "Update user task instance:" + userTaskInstance.getName() + " with id: " + userTaskInstance.getId(),
+ "Update user task instance: " + userTaskInstance.getName() + " with id: " + userTaskInstance.getId(),
new JsonObject(taskInfo));
}
@Override
public CompletableFuture createUserTaskInstanceComment(String serviceURL, UserTaskInstance userTaskInstance, String user, List groups, String commentInfo) {
- String requestURI = format(CREATE_USER_TASK_INSTANCE_COMMENT_PATH, userTaskInstance.getProcessId(), userTaskInstance.getProcessInstanceId(), userTaskInstance.getName(),
- userTaskInstance.getId()) + "?" + getUserGroupsURIParameter(user, groups);
+ String requestURI = format(CREATE_USER_TASK_INSTANCE_COMMENT_PATH, userTaskInstance.getId()) + "?" + getUserGroupsURIParameter(user, groups);
return sendPostWithBodyClientRequest(getWebClient(serviceURL), requestURI,
"Adding comment to UserTask:" + userTaskInstance.getName() + " with id: " + userTaskInstance.getId(),
- commentInfo, MediaType.TEXT_PLAIN);
+ Json.encode(new CommentInfo(commentInfo)), MediaType.APPLICATION_JSON);
}
@Override
public CompletableFuture updateUserTaskInstanceComment(String serviceURL, UserTaskInstance userTaskInstance, String user, List groups, String commentId, String commentInfo) {
- String requestURI = format(UPDATE_USER_TASK_INSTANCE_COMMENT_PATH, userTaskInstance.getProcessId(), userTaskInstance.getProcessInstanceId(), userTaskInstance.getName(),
- userTaskInstance.getId(), commentId) + "?" + getUserGroupsURIParameter(user, groups);
+ String requestURI = format(UPDATE_USER_TASK_INSTANCE_COMMENT_PATH, userTaskInstance.getId(), commentId) + "?" + getUserGroupsURIParameter(user, groups);
return sendPutClientRequest(getWebClient(serviceURL),
requestURI,
"Update UserTask: " + userTaskInstance.getName() + " comment:" + commentId + " with taskid: " + userTaskInstance.getId(),
- commentInfo, MediaType.TEXT_PLAIN);
+ Json.encode(new CommentInfo(commentInfo)), MediaType.APPLICATION_JSON);
}
@Override
public CompletableFuture deleteUserTaskInstanceComment(String serviceURL, UserTaskInstance userTaskInstance, String user, List groups, String commentId) {
- String requestURI = format(DELETE_USER_TASK_INSTANCE_COMMENT_PATH, userTaskInstance.getProcessId(), userTaskInstance.getProcessInstanceId(),
- userTaskInstance.getName(), userTaskInstance.getId(), commentId) + "?" + getUserGroupsURIParameter(user, groups);
+ String requestURI = format(DELETE_USER_TASK_INSTANCE_COMMENT_PATH, userTaskInstance.getId(), commentId) + "?" + getUserGroupsURIParameter(user, groups);
return sendDeleteClientRequest(getWebClient(serviceURL), requestURI,
"Delete comment : " + commentId + "of Task: " + userTaskInstance.getName() + " with taskid: " + userTaskInstance.getId());
}
@Override
public CompletableFuture createUserTaskInstanceAttachment(String serviceURL, UserTaskInstance userTaskInstance, String user, List groups, String name, String uri) {
- String requestURI = format(CREATE_USER_TASK_INSTANCE_ATTACHMENT_PATH, userTaskInstance.getProcessId(), userTaskInstance.getProcessInstanceId(), userTaskInstance.getName(),
- userTaskInstance.getId()) + "?" + getUserGroupsURIParameter(user, groups);
+ String requestURI = format(CREATE_USER_TASK_INSTANCE_ATTACHMENT_PATH, userTaskInstance.getId()) + "?" + getUserGroupsURIParameter(user, groups);
return sendPostWithBodyClientRequest(getWebClient(serviceURL), requestURI,
"Adding attachment to UserTask:" + userTaskInstance.getName() + " with id: " + userTaskInstance.getId(),
"{ \"name\": \"" + name + "\", \"uri\": \"" + uri + "\" }", MediaType.APPLICATION_JSON);
@@ -192,8 +191,7 @@ public CompletableFuture createUserTaskInstanceAttachment(String service
@Override
public CompletableFuture updateUserTaskInstanceAttachment(String serviceURL, UserTaskInstance userTaskInstance, String user,
List groups, String attachmentId, String name, String uri) {
- String requestURI = format(UPDATE_USER_TASK_INSTANCE_ATTACHMENT_PATH, userTaskInstance.getProcessId(), userTaskInstance.getProcessInstanceId(), userTaskInstance.getName(),
- userTaskInstance.getId(), attachmentId) + "?" + getUserGroupsURIParameter(user, groups);
+ String requestURI = format(UPDATE_USER_TASK_INSTANCE_ATTACHMENT_PATH, userTaskInstance.getId(), attachmentId) + "?" + getUserGroupsURIParameter(user, groups);
return sendJSONPutClientRequest(getWebClient(serviceURL),
requestURI,
"Update UserTask: " + userTaskInstance.getName() + " attachment:" + attachmentId +
@@ -203,8 +201,7 @@ public CompletableFuture updateUserTaskInstanceAttachment(String service
@Override
public CompletableFuture deleteUserTaskInstanceAttachment(String serviceURL, UserTaskInstance userTaskInstance, String user, List groups, String attachmentId) {
- String requestURI = format(DELETE_USER_TASK_INSTANCE_ATTACHMENT_PATH, userTaskInstance.getProcessId(), userTaskInstance.getProcessInstanceId(),
- userTaskInstance.getName(), userTaskInstance.getId(), attachmentId) + "?" + getUserGroupsURIParameter(user, groups);
+ String requestURI = format(DELETE_USER_TASK_INSTANCE_ATTACHMENT_PATH, userTaskInstance.getId(), attachmentId) + "?" + getUserGroupsURIParameter(user, groups);
return sendDeleteClientRequest(getWebClient(serviceURL), requestURI,
"Delete attachment : " + attachmentId + "of Task: " + userTaskInstance.getName() + " with taskid: " + userTaskInstance.getId());
}
@@ -225,10 +222,10 @@ protected CompletableFuture sendPostWithBodyClientRequest(WebClient webClient, S
.putHeader("Authorization", getAuthHeader())
.putHeader("Content-Type", contentType);
if (MediaType.APPLICATION_JSON.equals(contentType)) {
- LOGGER.debug("Sending Json Body: {} POST to URI {}", body, requestURI);
+ LOGGER.trace("Sending Json Body: {} POST to URI {}", body, requestURI);
request.sendJson(new JsonObject(body), res -> asyncHttpResponseTreatment(res, future, logMessage));
} else {
- LOGGER.debug("Sending Buffer(Body): {} POST to URI {}", body, requestURI);
+ LOGGER.trace("Sending Buffer(Body): {} POST to URI {}", body, requestURI);
request.sendBuffer(Buffer.buffer(body), res -> asyncHttpResponseTreatment(res, future, logMessage));
}
return future;
@@ -253,10 +250,10 @@ protected CompletableFuture sendPutClientRequest(WebClient webClient, String req
.putHeader("Authorization", getAuthHeader())
.putHeader("Content-Type", contentType);
if (MediaType.APPLICATION_JSON.equals(contentType)) {
- LOGGER.debug("Sending Json Body: {} PUT to URI {}", body, requestURI);
+ LOGGER.info("Sending Json Body: {} PUT to URI {}", body, requestURI);
request.sendJson(new JsonObject(body), res -> asyncHttpResponseTreatment(res, future, logMessage));
} else {
- LOGGER.debug("Sending Buffer(Body): {} PUT to URI {}", body, requestURI);
+ LOGGER.info("Sending Buffer(Body): {} PUT to URI {}", body, requestURI);
request.sendBuffer(Buffer.buffer(body), res -> asyncHttpResponseTreatment(res, future, logMessage));
}
return future;
diff --git a/data-index/data-index-service/data-index-service-common/src/test/java/org/kie/kogito/index/service/AbstractIndexingServiceIT.java b/data-index/data-index-service/data-index-service-common/src/test/java/org/kie/kogito/index/service/AbstractIndexingServiceIT.java
index 9843238378..dd24ab69e9 100644
--- a/data-index/data-index-service/data-index-service-common/src/test/java/org/kie/kogito/index/service/AbstractIndexingServiceIT.java
+++ b/data-index/data-index-service/data-index-service-common/src/test/java/org/kie/kogito/index/service/AbstractIndexingServiceIT.java
@@ -477,7 +477,7 @@ protected void validateUserTaskInstance(String query, UserTaskInstanceStateDataE
.body("data.UserTaskInstances[0].lastUpdate", anything())
.body("data.UserTaskInstances[0].endpoint",
is(event.getSource().toString() + "/" + event.getData().getProcessInstanceId() + "/" + event.getData().getUserTaskName() + "/"
- + event.getData().getUserTaskInstanceId())));
+ + event.getData().getExternalReferenceId())));
}
}
diff --git a/data-index/data-index-service/data-index-service-common/src/test/java/org/kie/kogito/index/service/api/KogitoRuntimeClientTest.java b/data-index/data-index-service/data-index-service-common/src/test/java/org/kie/kogito/index/service/api/KogitoRuntimeClientTest.java
index 62fbd15702..28acb2caf3 100644
--- a/data-index/data-index-service/data-index-service-common/src/test/java/org/kie/kogito/index/service/api/KogitoRuntimeClientTest.java
+++ b/data-index/data-index-service/data-index-service-common/src/test/java/org/kie/kogito/index/service/api/KogitoRuntimeClientTest.java
@@ -35,6 +35,7 @@
import org.kie.kogito.index.model.UserTaskInstance;
import org.kie.kogito.index.service.DataIndexServiceException;
import org.kie.kogito.index.test.TestUtils;
+import org.kie.kogito.usertask.model.CommentInfo;
import org.mockito.ArgumentCaptor;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;
@@ -44,6 +45,7 @@
import io.vertx.core.AsyncResult;
import io.vertx.core.Handler;
import io.vertx.core.Vertx;
+import io.vertx.core.json.Json;
import io.vertx.core.json.JsonObject;
import io.vertx.ext.web.client.HttpRequest;
import io.vertx.ext.web.client.HttpResponse;
@@ -58,12 +60,10 @@
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.junit.jupiter.api.Assertions.fail;
import static org.kie.kogito.index.service.api.KogitoRuntimeClientImpl.ABORT_PROCESS_INSTANCE_PATH;
-import static org.kie.kogito.index.service.api.KogitoRuntimeClientImpl.CANCEL_JOB_PATH;
import static org.kie.kogito.index.service.api.KogitoRuntimeClientImpl.CANCEL_NODE_INSTANCE_PATH;
import static org.kie.kogito.index.service.api.KogitoRuntimeClientImpl.GET_PROCESS_INSTANCE_DIAGRAM_PATH;
import static org.kie.kogito.index.service.api.KogitoRuntimeClientImpl.GET_PROCESS_INSTANCE_NODE_DEFINITIONS_PATH;
import static org.kie.kogito.index.service.api.KogitoRuntimeClientImpl.GET_PROCESS_INSTANCE_SOURCE_PATH;
-import static org.kie.kogito.index.service.api.KogitoRuntimeClientImpl.RESCHEDULE_JOB_PATH;
import static org.kie.kogito.index.service.api.KogitoRuntimeClientImpl.RETRIGGER_NODE_INSTANCE_PATH;
import static org.kie.kogito.index.service.api.KogitoRuntimeClientImpl.RETRY_PROCESS_INSTANCE_PATH;
import static org.kie.kogito.index.service.api.KogitoRuntimeClientImpl.SKIP_PROCESS_INSTANCE_PATH;
@@ -72,6 +72,7 @@
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.ArgumentMatchers.isNull;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.spy;
@@ -401,8 +402,9 @@ public void testGetUserTaskSchema() {
UserTaskInstance taskInstance = createUserTaskInstance(PROCESS_INSTANCE_ID, TASK_ID, "InProgress");
client.getUserTaskSchema(SERVICE_URL, taskInstance, "jdoe", Collections.singletonList("managers"));
- verify(client).sendGetClientRequest(webClientMock, "/travels/" + PROCESS_INSTANCE_ID + "/TaskName/" + TASK_ID + "/schema?user=jdoe&group=managers",
- "Get User Task schema for task:TaskName with id: " + taskInstance.getId(), null);
+ verify(client).sendGetClientRequest(eq(webClientMock),
+ eq("/travels/" + PROCESS_INSTANCE_ID + "/TaskName/" + taskInstance.getExternalReferenceId() + "/schema?user=jdoe&group=managers"),
+ eq("Get User Task schema for task:TaskName with id: " + taskInstance.getId()), isNull());
ArgumentCaptor handlerCaptor = ArgumentCaptor.forClass(Handler.class);
verify(httpRequestMock).send(handlerCaptor.capture());
verify(httpRequestMock).putHeader(eq("Authorization"), eq("Bearer " + AUTHORIZED_TOKEN));
@@ -421,8 +423,8 @@ public void testUpdateUserTaskInstance() {
client.updateUserTaskInstance(SERVICE_URL, taskInstance, "jdoe", Collections.singletonList("managers"), taskInfo);
ArgumentCaptor jsonCaptor = ArgumentCaptor.forClass(JsonObject.class);
verify(client).sendPatchClientRequest(eq(webClientMock),
- eq("/management/processes/travels/instances/" + PROCESS_INSTANCE_ID + "/tasks/" + TASK_ID + "?user=jdoe&group=managers"),
- eq("Update user task instance:" + taskInstance.getName() + " with id: " + taskInstance.getId()),
+ eq("/management/usertasks/" + TASK_ID + "?user=jdoe&group=managers"),
+ eq("Update user task instance: " + taskInstance.getName() + " with id: " + taskInstance.getId()),
jsonCaptor.capture());
assertThat(jsonCaptor.getValue().getString("description")).isEqualTo("NewDescription");
ArgumentCaptor handlerCaptor = ArgumentCaptor.forClass(Handler.class);
@@ -443,10 +445,11 @@ public void testCreateUserTaskInstanceComment() {
client.createUserTaskInstanceComment(SERVICE_URL, taskInstance, "jdoe", Collections.singletonList("managers"), commentInfo);
verify(client).sendPostWithBodyClientRequest(eq(webClientMock),
- eq("/travels/" + PROCESS_INSTANCE_ID + "/" + taskInstance.getName() + "/" + TASK_ID + "/comments?user=jdoe&group=managers"),
- eq("Adding comment to UserTask:" + taskInstance.getName() + " with id: " + taskInstance.getId()), eq(commentInfo), eq("text/plain"));
+ eq("/usertasks/instance/" + TASK_ID + "/comments?user=jdoe&group=managers"),
+ eq("Adding comment to UserTask:" + taskInstance.getName() + " with id: " + taskInstance.getId()),
+ eq(Json.encode(new CommentInfo(commentInfo))), eq("application/json"));
ArgumentCaptor handlerCaptor = ArgumentCaptor.forClass(Handler.class);
- verify(httpRequestMock).sendBuffer(any(), handlerCaptor.capture());
+ verify(httpRequestMock).sendJson(any(), handlerCaptor.capture());
checkResponseHandling(handlerCaptor.getValue());
}
@@ -462,7 +465,7 @@ public void testCreateUserTaskInstanceAttachment() {
client.createUserTaskInstanceAttachment(SERVICE_URL, taskInstance, "jdoe", Collections.singletonList("managers"), attachmentName, attachmentUri);
verify(client).sendPostWithBodyClientRequest(eq(webClientMock),
- eq("/travels/" + PROCESS_INSTANCE_ID + "/" + taskInstance.getName() + "/" + TASK_ID + "/attachments?user=jdoe&group=managers"),
+ eq("/usertasks/instance/" + TASK_ID + "/attachments?user=jdoe&group=managers"),
eq("Adding attachment to UserTask:" + taskInstance.getName() + " with id: " + taskInstance.getId()),
eq("{ \"name\": \"" + attachmentName + "\", \"uri\": \"" + attachmentUri + "\" }"), eq("application/json"));
ArgumentCaptor handlerCaptor = ArgumentCaptor.forClass(Handler.class);
@@ -484,12 +487,12 @@ public void testUpdateUserTaskInstanceComment() {
client.updateUserTaskInstanceComment(SERVICE_URL, taskInstance, "jdoe", Collections.singletonList("managers"), commentId, commentInfo);
verify(client).sendPutClientRequest(eq(webClientMock),
- eq("/travels/" + PROCESS_INSTANCE_ID + "/" + taskInstance.getName() + "/" + TASK_ID + "/comments/" + commentId + "?user=jdoe&group=managers"),
+ eq("/usertasks/instance/" + TASK_ID + "/comments/" + commentId + "?user=jdoe&group=managers"),
eq("Update UserTask: " + taskInstance.getName() + " comment:" + commentId + " with taskid: " + taskInstance.getId()),
- eq(commentInfo), eq("text/plain"));
+ eq(Json.encode(new CommentInfo(commentInfo))), eq("application/json"));
ArgumentCaptor handlerCaptor = ArgumentCaptor.forClass(Handler.class);
- verify(httpRequestMock).sendBuffer(any(), handlerCaptor.capture());
+ verify(httpRequestMock).sendJson(any(), handlerCaptor.capture());
checkResponseHandling(handlerCaptor.getValue());
}
@@ -503,7 +506,7 @@ public void testDeleteTaskInstanceComment() {
client.deleteUserTaskInstanceComment(SERVICE_URL, taskInstance, "jdoe", Collections.singletonList("managers"), commentId);
verify(client).sendDeleteClientRequest(eq(webClientMock),
- eq("/travels/" + PROCESS_INSTANCE_ID + "/" + taskInstance.getName() + "/" + TASK_ID + "/comments/" + commentId + "?user=jdoe&group=managers"),
+ eq("/usertasks/instance/" + TASK_ID + "/comments/" + commentId + "?user=jdoe&group=managers"),
eq("Delete comment : " + commentId + "of Task: " + taskInstance.getName() + " with taskid: " + taskInstance.getId()));
ArgumentCaptor handlerCaptor = ArgumentCaptor.forClass(Handler.class);
verify(httpRequestMock).send(handlerCaptor.capture());
@@ -524,7 +527,7 @@ public void testUpdateUserTaskInstanceAttachment() {
client.updateUserTaskInstanceAttachment(SERVICE_URL, taskInstance, "jdoe", Collections.singletonList("managers"),
attachmentId, attachmentName, attachmentContent);
verify(client).sendJSONPutClientRequest(eq(webClientMock),
- eq("/travels/" + PROCESS_INSTANCE_ID + "/" + taskInstance.getName() + "/" + TASK_ID + "/attachments/" + attachmentId + "?user=jdoe&group=managers"),
+ eq("/usertasks/instance/" + TASK_ID + "/attachments/" + attachmentId + "?user=jdoe&group=managers"),
eq("Update UserTask: " + taskInstance.getName() + " attachment:" + attachmentId +
" with taskid: " + taskInstance.getId() + "with: " + attachmentName +
" and info:" + attachmentContent),
@@ -546,7 +549,7 @@ public void testDeleteTaskInstanceAttachment() {
client.deleteUserTaskInstanceAttachment(SERVICE_URL, taskInstance, "jdoe", Collections.singletonList("managers"), attachmentId);
verify(client).sendDeleteClientRequest(eq(webClientMock),
- eq("/travels/" + PROCESS_INSTANCE_ID + "/" + taskInstance.getName() + "/" + TASK_ID + "/attachments/" + attachmentId + "?user=jdoe&group=managers"),
+ eq("/usertasks/instance/" + TASK_ID + "/attachments/" + attachmentId + "?user=jdoe&group=managers"),
eq("Delete attachment : " + attachmentId + "of Task: " + taskInstance.getName() + " with taskid: " + taskInstance.getId()));
ArgumentCaptor handlerCaptor = ArgumentCaptor.forClass(Handler.class);
verify(httpRequestMock).send(handlerCaptor.capture());
diff --git a/data-index/data-index-service/data-index-service-inmemory/src/main/resources/application.properties b/data-index/data-index-service/data-index-service-inmemory/src/main/resources/application.properties
index e6eb7e8ccd..8f28492088 100644
--- a/data-index/data-index-service/data-index-service-inmemory/src/main/resources/application.properties
+++ b/data-index/data-index-service/data-index-service-inmemory/src/main/resources/application.properties
@@ -34,6 +34,7 @@ quarkus.flyway.locations=classpath:kie-flyway/db/data-index/postgresql
quarkus.hibernate-orm.jdbc.timezone=UTC
quarkus.hibernate-orm.database.generation=update
quarkus.hibernate-orm.database.generation.halt-on-error=true
+quarkus.hibernate-orm.physical-naming-strategy=org.hibernate.boot.model.naming.CamelCaseToUnderscoresNamingStrategy
#Container image
quarkus.container-image.build=${quarkus.build.image:true}
diff --git a/data-index/data-index-storage/data-index-storage-api/src/main/java/org/kie/kogito/index/model/UserTaskInstance.java b/data-index/data-index-storage/data-index-storage-api/src/main/java/org/kie/kogito/index/model/UserTaskInstance.java
index 8572edcaf8..b87d73777f 100644
--- a/data-index/data-index-storage/data-index-storage-api/src/main/java/org/kie/kogito/index/model/UserTaskInstance.java
+++ b/data-index/data-index-storage/data-index-storage-api/src/main/java/org/kie/kogito/index/model/UserTaskInstance.java
@@ -28,6 +28,7 @@ public class UserTaskInstance extends UserTaskInstanceMeta {
private ObjectNode inputs;
private ObjectNode outputs;
private String endpoint;
+ private String externalReferenceId;
public String getProcessId() {
return processId;
@@ -94,4 +95,12 @@ public ObjectNode getOutputs() {
public void setOutputs(ObjectNode outputs) {
this.outputs = outputs;
}
+
+ public String getExternalReferenceId() {
+ return externalReferenceId;
+ }
+
+ public void setExternalReferenceId(String externalReferenceId) {
+ this.externalReferenceId = externalReferenceId;
+ }
}
diff --git a/data-index/data-index-storage/data-index-storage-api/src/main/java/org/kie/kogito/index/storage/ProcessInstanceStorage.java b/data-index/data-index-storage/data-index-storage-api/src/main/java/org/kie/kogito/index/storage/ProcessInstanceStorage.java
index 753caf66bc..674cc17bd4 100644
--- a/data-index/data-index-storage/data-index-storage-api/src/main/java/org/kie/kogito/index/storage/ProcessInstanceStorage.java
+++ b/data-index/data-index-storage/data-index-storage-api/src/main/java/org/kie/kogito/index/storage/ProcessInstanceStorage.java
@@ -18,6 +18,7 @@
*/
package org.kie.kogito.index.storage;
+import org.kie.kogito.event.process.MultipleProcessInstanceDataEvent;
import org.kie.kogito.event.process.ProcessInstanceErrorDataEvent;
import org.kie.kogito.event.process.ProcessInstanceNodeDataEvent;
import org.kie.kogito.event.process.ProcessInstanceSLADataEvent;
@@ -28,6 +29,8 @@
public interface ProcessInstanceStorage extends StorageFetcher {
+ void indexGroup(MultipleProcessInstanceDataEvent event);
+
void indexError(ProcessInstanceErrorDataEvent event);
void indexNode(ProcessInstanceNodeDataEvent event);
diff --git a/data-index/data-index-storage/data-index-storage-api/src/main/java/org/kie/kogito/index/storage/UserTaskInstanceStorage.java b/data-index/data-index-storage/data-index-storage-api/src/main/java/org/kie/kogito/index/storage/UserTaskInstanceStorage.java
index f315ae4f73..58c586fd62 100644
--- a/data-index/data-index-storage/data-index-storage-api/src/main/java/org/kie/kogito/index/storage/UserTaskInstanceStorage.java
+++ b/data-index/data-index-storage/data-index-storage-api/src/main/java/org/kie/kogito/index/storage/UserTaskInstanceStorage.java
@@ -18,6 +18,7 @@
*/
package org.kie.kogito.index.storage;
+import org.kie.kogito.event.usertask.MultipleUserTaskInstanceDataEvent;
import org.kie.kogito.event.usertask.UserTaskInstanceAssignmentDataEvent;
import org.kie.kogito.event.usertask.UserTaskInstanceAttachmentDataEvent;
import org.kie.kogito.event.usertask.UserTaskInstanceCommentDataEvent;
@@ -40,4 +41,6 @@ public interface UserTaskInstanceStorage extends StorageFetcher event : events.getData()) {
+ if (event instanceof ProcessInstanceErrorDataEvent) {
+ index(event, errorMerger);
+ } else if (event instanceof ProcessInstanceNodeDataEvent) {
+ index(event, nodeMerger);
+ } else if (event instanceof ProcessInstanceSLADataEvent) {
+ index(event, slaMerger);
+ } else if (event instanceof ProcessInstanceStateDataEvent) {
+ index(event, stateMerger);
+ } else if (event instanceof ProcessInstanceVariableDataEvent) {
+ index(event, variableMerger);
+ }
+ }
+ }
+
private > void index(T event, ProcessInstanceEventMerger merger) {
ProcessInstance processInstance = storage.get(event.getKogitoProcessInstanceId());
if (processInstance == null) {
diff --git a/data-index/data-index-storage/data-index-storage-common/src/main/java/org/kie/kogito/index/storage/ModelUserTaskInstanceStorage.java b/data-index/data-index-storage/data-index-storage-common/src/main/java/org/kie/kogito/index/storage/ModelUserTaskInstanceStorage.java
index 20f98a396c..e76104c9e5 100644
--- a/data-index/data-index-storage/data-index-storage-common/src/main/java/org/kie/kogito/index/storage/ModelUserTaskInstanceStorage.java
+++ b/data-index/data-index-storage/data-index-storage-common/src/main/java/org/kie/kogito/index/storage/ModelUserTaskInstanceStorage.java
@@ -20,6 +20,7 @@
import java.util.ArrayList;
+import org.kie.kogito.event.usertask.MultipleUserTaskInstanceDataEvent;
import org.kie.kogito.event.usertask.UserTaskInstanceAssignmentDataEvent;
import org.kie.kogito.event.usertask.UserTaskInstanceAttachmentDataEvent;
import org.kie.kogito.event.usertask.UserTaskInstanceCommentDataEvent;
@@ -53,7 +54,6 @@ public ModelUserTaskInstanceStorage(Storage storage) {
@Override
public void indexAssignment(UserTaskInstanceAssignmentDataEvent event) {
index(event, assignmentMerger);
-
}
@Override
@@ -76,13 +76,30 @@ public void indexState(UserTaskInstanceStateDataEvent event) {
@Override
public void indexVariable(UserTaskInstanceVariableDataEvent event) {
index(event, variableMerger);
-
}
@Override
public void indexComment(UserTaskInstanceCommentDataEvent event) {
index(event, commentMerger);
+ }
+ @Override
+ public void indexGroup(MultipleUserTaskInstanceDataEvent events) {
+ for (UserTaskInstanceDataEvent> event : events.getData()) {
+ if (event instanceof UserTaskInstanceAssignmentDataEvent) {
+ index((UserTaskInstanceAssignmentDataEvent) event, assignmentMerger);
+ } else if (event instanceof UserTaskInstanceAttachmentDataEvent) {
+ index((UserTaskInstanceAttachmentDataEvent) event, attachmentMerger);
+ } else if (event instanceof UserTaskInstanceDeadlineDataEvent) {
+ index((UserTaskInstanceDeadlineDataEvent) event, deadlineMerger);
+ } else if (event instanceof UserTaskInstanceStateDataEvent) {
+ index((UserTaskInstanceStateDataEvent) event, stateMerger);
+ } else if (event instanceof UserTaskInstanceCommentDataEvent) {
+ index((UserTaskInstanceCommentDataEvent) event, commentMerger);
+ } else if (event instanceof UserTaskInstanceVariableDataEvent) {
+ index((UserTaskInstanceVariableDataEvent) event, variableMerger);
+ }
+ }
}
private > void index(T event, UserTaskInstanceEventMerger merger) {
diff --git a/data-index/data-index-storage/data-index-storage-common/src/main/java/org/kie/kogito/index/storage/merger/UserTaskInstanceStateEventMerger.java b/data-index/data-index-storage/data-index-storage-common/src/main/java/org/kie/kogito/index/storage/merger/UserTaskInstanceStateEventMerger.java
index 8cf9d9fd75..8e813f07e5 100644
--- a/data-index/data-index-storage/data-index-storage-common/src/main/java/org/kie/kogito/index/storage/merger/UserTaskInstanceStateEventMerger.java
+++ b/data-index/data-index-storage/data-index-storage-common/src/main/java/org/kie/kogito/index/storage/merger/UserTaskInstanceStateEventMerger.java
@@ -58,9 +58,10 @@ public UserTaskInstance merge(UserTaskInstance task, UserTaskInstanceDataEvent
}
task.setActualOwner(event.getData().getActualOwner());
task.setEndpoint(
- event.getSource() == null ? null : getEndpoint(event.getSource(), event.getData().getProcessInstanceId(), event.getData().getUserTaskName(), event.getData().getUserTaskInstanceId()));
+ event.getSource() == null ? null : getEndpoint(event.getSource(), event.getData().getProcessInstanceId(), event.getData().getUserTaskName(), event.getData().getExternalReferenceId()));
task.setLastUpdate(toZonedDateTime(event.getData().getEventDate()));
task.setReferenceName(event.getData().getUserTaskReferenceName());
+ task.setExternalReferenceId(event.getData().getExternalReferenceId());
LOGGER.debug("value after merging: {}", task);
return task;
}
diff --git a/data-index/data-index-storage/data-index-storage-infinispan/src/main/java/org/kie/kogito/index/infinispan/protostream/UserTaskInstanceMarshaller.java b/data-index/data-index-storage/data-index-storage-infinispan/src/main/java/org/kie/kogito/index/infinispan/protostream/UserTaskInstanceMarshaller.java
index b3ba2e74f3..ff852b572f 100644
--- a/data-index/data-index-storage/data-index-storage-infinispan/src/main/java/org/kie/kogito/index/infinispan/protostream/UserTaskInstanceMarshaller.java
+++ b/data-index/data-index-storage/data-index-storage-infinispan/src/main/java/org/kie/kogito/index/infinispan/protostream/UserTaskInstanceMarshaller.java
@@ -57,6 +57,7 @@ public class UserTaskInstanceMarshaller extends AbstractMarshaller implements Me
protected static final String ENDPOINT = "endpoint";
protected static final String COMMENTS = "comments";
protected static final String ATTACHMENTS = "attachments";
+ protected static final String EXTERNAL_REFERENCE_ID = "externalReferenceId";
public UserTaskInstanceMarshaller(ObjectMapper mapper) {
super(mapper);
@@ -89,6 +90,7 @@ public UserTaskInstance readFrom(ProtoStreamReader reader) throws IOException {
ut.setEndpoint(reader.readString(ENDPOINT));
ut.setComments(reader.readCollection(COMMENTS, new ArrayList<>(), Comment.class));
ut.setAttachments(reader.readCollection(ATTACHMENTS, new ArrayList<>(), Attachment.class));
+ ut.setExternalReferenceId(reader.readString(EXTERNAL_REFERENCE_ID));
return ut;
}
@@ -118,6 +120,7 @@ public void writeTo(ProtoStreamWriter writer, UserTaskInstance ut) throws IOExce
writer.writeString(ENDPOINT, ut.getEndpoint());
writer.writeCollection(COMMENTS, ut.getComments(), Comment.class);
writer.writeCollection(ATTACHMENTS, ut.getAttachments(), Attachment.class);
+ writer.writeString(EXTERNAL_REFERENCE_ID, ut.getExternalReferenceId());
}
@Override
diff --git a/data-index/data-index-storage/data-index-storage-infinispan/src/test/java/org/kie/kogito/index/infinispan/protostream/UserTaskInstanceMarshallerTest.java b/data-index/data-index-storage/data-index-storage-infinispan/src/test/java/org/kie/kogito/index/infinispan/protostream/UserTaskInstanceMarshallerTest.java
index 6c19ae9b54..07f98b1ac7 100644
--- a/data-index/data-index-storage/data-index-storage-infinispan/src/test/java/org/kie/kogito/index/infinispan/protostream/UserTaskInstanceMarshallerTest.java
+++ b/data-index/data-index-storage/data-index-storage-infinispan/src/test/java/org/kie/kogito/index/infinispan/protostream/UserTaskInstanceMarshallerTest.java
@@ -47,6 +47,7 @@
import static org.kie.kogito.index.infinispan.protostream.UserTaskInstanceMarshaller.DESCRIPTION;
import static org.kie.kogito.index.infinispan.protostream.UserTaskInstanceMarshaller.ENDPOINT;
import static org.kie.kogito.index.infinispan.protostream.UserTaskInstanceMarshaller.EXCLUDED_USERS;
+import static org.kie.kogito.index.infinispan.protostream.UserTaskInstanceMarshaller.EXTERNAL_REFERENCE_ID;
import static org.kie.kogito.index.infinispan.protostream.UserTaskInstanceMarshaller.ID;
import static org.kie.kogito.index.infinispan.protostream.UserTaskInstanceMarshaller.INPUTS;
import static org.kie.kogito.index.infinispan.protostream.UserTaskInstanceMarshaller.LAST_UPDATE;
@@ -100,6 +101,7 @@ static void setup() {
TASK.setReferenceName("referenceName");
TASK.setLastUpdate(ZonedDateTime.now(ZoneOffset.UTC).truncatedTo(ChronoUnit.MILLIS));
TASK.setEndpoint("endpoint");
+ TASK.setExternalReferenceId("externalReferenceId");
TASK.setComments(List.of(Comment.builder()
.id("attId")
.content("Text comment")
@@ -144,6 +146,7 @@ void testReadFrom() throws IOException {
when(reader.readString(ENDPOINT)).thenReturn(TASK.getEndpoint());
when(reader.readCollection(eq(COMMENTS), any(), eq(Comment.class))).thenReturn(TASK.getComments());
when(reader.readCollection(eq(ATTACHMENTS), any(), eq(Attachment.class))).thenReturn(TASK.getAttachments());
+ when(reader.readString(EXTERNAL_REFERENCE_ID)).thenReturn(TASK.getExternalReferenceId());
UserTaskInstance task = marshaller.readFrom(reader);
@@ -174,6 +177,7 @@ void testReadFrom() throws IOException {
inOrder.verify(reader).readString(ENDPOINT);
inOrder.verify(reader).readCollection(COMMENTS, new ArrayList<>(), Comment.class);
inOrder.verify(reader).readCollection(ATTACHMENTS, new ArrayList<>(), Attachment.class);
+ inOrder.verify(reader).readString(EXTERNAL_REFERENCE_ID);
verifyNoMoreInteractions(reader);
}
@@ -209,6 +213,7 @@ void testWriteTo() throws IOException {
inOrder.verify(writer).writeString(ENDPOINT, TASK.getEndpoint());
inOrder.verify(writer).writeCollection(COMMENTS, TASK.getComments(), Comment.class);
inOrder.verify(writer).writeCollection(ATTACHMENTS, TASK.getAttachments(), Attachment.class);
+ inOrder.verify(writer).writeString(EXTERNAL_REFERENCE_ID, TASK.getExternalReferenceId());
verifyNoMoreInteractions(writer);
}
diff --git a/data-index/data-index-storage/data-index-storage-jpa-common/src/main/java/org/kie/kogito/index/jpa/model/UserTaskInstanceEntity.java b/data-index/data-index-storage/data-index-storage-jpa-common/src/main/java/org/kie/kogito/index/jpa/model/UserTaskInstanceEntity.java
index 0021a0eb20..314174ed1a 100644
--- a/data-index/data-index-storage/data-index-storage-jpa-common/src/main/java/org/kie/kogito/index/jpa/model/UserTaskInstanceEntity.java
+++ b/data-index/data-index-storage/data-index-storage-jpa-common/src/main/java/org/kie/kogito/index/jpa/model/UserTaskInstanceEntity.java
@@ -91,6 +91,16 @@ public class UserTaskInstanceEntity extends AbstractEntity {
@OneToMany(cascade = CascadeType.ALL, mappedBy = "userTask", orphanRemoval = true, fetch = FetchType.LAZY)
private List attachments;
+ private String externalReferenceId;
+
+ public String getExternalReferenceId() {
+ return externalReferenceId;
+ }
+
+ public void setExternalReferenceId(String externalReferenceId) {
+ this.externalReferenceId = externalReferenceId;
+ }
+
@Override
public String getId() {
return id;
diff --git a/data-index/data-index-storage/data-index-storage-jpa-common/src/main/java/org/kie/kogito/index/jpa/storage/ProcessInstanceEntityStorage.java b/data-index/data-index-storage/data-index-storage-jpa-common/src/main/java/org/kie/kogito/index/jpa/storage/ProcessInstanceEntityStorage.java
index 386aabcf78..8796f3204a 100644
--- a/data-index/data-index-storage/data-index-storage-jpa-common/src/main/java/org/kie/kogito/index/jpa/storage/ProcessInstanceEntityStorage.java
+++ b/data-index/data-index-storage/data-index-storage-jpa-common/src/main/java/org/kie/kogito/index/jpa/storage/ProcessInstanceEntityStorage.java
@@ -20,9 +20,12 @@
import java.time.ZonedDateTime;
import java.util.ArrayList;
-import java.util.Date;
+import java.util.HashMap;
+import java.util.Map;
import java.util.Set;
+import org.kie.kogito.event.process.MultipleProcessInstanceDataEvent;
+import org.kie.kogito.event.process.ProcessInstanceDataEvent;
import org.kie.kogito.event.process.ProcessInstanceErrorDataEvent;
import org.kie.kogito.event.process.ProcessInstanceErrorEventBody;
import org.kie.kogito.event.process.ProcessInstanceNodeDataEvent;
@@ -64,43 +67,51 @@ public ProcessInstanceEntityStorage(ProcessInstanceEntityRepository repository,
super(repository, ProcessInstanceEntity.class, mapper::mapToModel);
}
+ @Override
+ @Transactional
+ public void indexGroup(MultipleProcessInstanceDataEvent events) {
+ Map piMap = new HashMap<>();
+ for (ProcessInstanceDataEvent> event : events.getData()) {
+ indexEvent(piMap.computeIfAbsent(event.getKogitoProcessInstanceId(), id -> findOrInit(event)), event);
+ }
+ }
+
@Override
@Transactional
public void indexError(ProcessInstanceErrorDataEvent event) {
- indexError(event.getData());
+ indexError(findOrInit(event), event.getData());
}
@Override
@Transactional
public void indexNode(ProcessInstanceNodeDataEvent event) {
- indexNode(event.getData());
+ indexNode(findOrInit(event), event.getData());
}
@Override
@Transactional
public void indexSLA(ProcessInstanceSLADataEvent event) {
- indexSLA(event.getData());
-
+ indexSla(findOrInit(event), event.getData());
}
@Override
@Transactional
public void indexState(ProcessInstanceStateDataEvent event) {
- indexState(event.getData(), event.getKogitoAddons() == null ? Set.of() : Set.of(event.getKogitoAddons().split(",")), event.getSource() == null ? null : event.getSource().toString());
+ indexState(findOrInit(event), event);
}
@Override
@Transactional
public void indexVariable(ProcessInstanceVariableDataEvent event) {
- indexVariable(event.getData());
+ indexVariable(findOrInit(event), event.getData());
}
- private ProcessInstanceEntity findOrInit(String processId, String processInstanceId, Date date) {
- return repository.findByIdOptional(processInstanceId).orElseGet(() -> {
+ private ProcessInstanceEntity findOrInit(ProcessInstanceDataEvent> event) {
+ return repository.findByIdOptional(event.getKogitoProcessInstanceId()).orElseGet(() -> {
ProcessInstanceEntity pi = new ProcessInstanceEntity();
- pi.setProcessId(processId);
- pi.setId(processInstanceId);
- pi.setLastUpdate(toZonedDateTime(date));
+ pi.setProcessId(event.getKogitoProcessId());
+ pi.setId(event.getKogitoProcessInstanceId());
+ pi.setLastUpdate(toZonedDateTime(event.getTime()));
pi.setNodes(new ArrayList<>());
pi.setMilestones(new ArrayList<>());
repository.persist(pi);
@@ -108,8 +119,21 @@ private ProcessInstanceEntity findOrInit(String processId, String processInstanc
});
}
- private void indexError(ProcessInstanceErrorEventBody error) {
- ProcessInstanceEntity pi = findOrInit(error.getProcessId(), error.getProcessInstanceId(), error.getEventDate());
+ private void indexEvent(ProcessInstanceEntity pi, ProcessInstanceDataEvent> event) {
+ if (event instanceof ProcessInstanceErrorDataEvent) {
+ indexError(pi, ((ProcessInstanceErrorDataEvent) event).getData());
+ } else if (event instanceof ProcessInstanceNodeDataEvent) {
+ indexNode(pi, ((ProcessInstanceNodeDataEvent) event).getData());
+ } else if (event instanceof ProcessInstanceSLADataEvent) {
+ indexSla(pi, ((ProcessInstanceSLADataEvent) event).getData());
+ } else if (event instanceof ProcessInstanceStateDataEvent) {
+ indexState(pi, (ProcessInstanceStateDataEvent) event);
+ } else if (event instanceof ProcessInstanceVariableDataEvent) {
+ indexVariable(pi, ((ProcessInstanceVariableDataEvent) event).getData());
+ }
+ }
+
+ private void indexError(ProcessInstanceEntity pi, ProcessInstanceErrorEventBody error) {
ProcessInstanceErrorEntity errorEntity = pi.getError();
if (errorEntity == null) {
errorEntity = new ProcessInstanceErrorEntity();
@@ -118,16 +142,13 @@ private void indexError(ProcessInstanceErrorEventBody error) {
errorEntity.setMessage(error.getErrorMessage());
errorEntity.setNodeDefinitionId(error.getNodeDefinitionId());
pi.setState(CommonUtils.ERROR_STATE);
- repository.flush();
}
- private void indexNode(ProcessInstanceNodeEventBody data) {
- ProcessInstanceEntity pi = findOrInit(data.getProcessId(), data.getProcessInstanceId(), data.getEventDate());
+ private void indexNode(ProcessInstanceEntity pi, ProcessInstanceNodeEventBody data) {
pi.getNodes().stream().filter(n -> n.getId().equals(data.getNodeInstanceId())).findAny().ifPresentOrElse(n -> updateNode(n, data), () -> createNode(pi, data));
if ("MilestoneNode".equals(data.getNodeType())) {
pi.getMilestones().stream().filter(n -> n.getId().equals(data.getNodeInstanceId())).findAny().ifPresentOrElse(n -> updateMilestone(n, data), () -> createMilestone(pi, data));
}
- repository.flush();
}
private MilestoneEntity createMilestone(ProcessInstanceEntity pi, ProcessInstanceNodeEventBody data) {
@@ -146,9 +167,10 @@ private MilestoneEntity updateMilestone(MilestoneEntity milestone, ProcessInstan
private NodeInstanceEntity createNode(ProcessInstanceEntity pi, ProcessInstanceNodeEventBody data) {
NodeInstanceEntity node = new NodeInstanceEntity();
- pi.getNodes().add(node);
node.setProcessInstance(pi);
- return updateNode(node, data);
+ updateNode(node, data);
+ pi.getNodes().add(node);
+ return node;
}
private NodeInstanceEntity updateNode(NodeInstanceEntity nodeInstance, ProcessInstanceNodeEventBody body) {
@@ -159,7 +181,6 @@ private NodeInstanceEntity updateNode(NodeInstanceEntity nodeInstance, ProcessIn
nodeInstance.setType(body.getNodeType());
ZonedDateTime eventDate = toZonedDateTime(body.getEventDate());
switch (body.getEventType()) {
-
case EVENT_TYPE_ENTER:
nodeInstance.setEnter(eventDate);
break;
@@ -174,13 +195,12 @@ private NodeInstanceEntity updateNode(NodeInstanceEntity nodeInstance, ProcessIn
return nodeInstance;
}
- private void indexSLA(ProcessInstanceSLAEventBody data) {
- findOrInit(data.getProcessId(), data.getProcessInstanceId(), data.getEventDate());
- repository.flush();
+ private void indexState(ProcessInstanceEntity pi, ProcessInstanceStateDataEvent event) {
+ indexState(pi, event.getData(), (event.getKogitoAddons() == null || event.getKogitoAddons().isEmpty()) ? Set.of() : Set.of(event.getKogitoAddons().split(",")),
+ event.getSource() == null ? null : event.getSource().toString());
}
- private void indexState(ProcessInstanceStateEventBody data, Set addons, String endpoint) {
- ProcessInstanceEntity pi = findOrInit(data.getProcessId(), data.getProcessInstanceId(), data.getEventDate());
+ private void indexState(ProcessInstanceEntity pi, ProcessInstanceStateEventBody data, Set addons, String endpoint) {
pi.setVersion(data.getProcessVersion());
pi.setProcessName(data.getProcessName());
pi.setRootProcessInstanceId(data.getRootProcessInstanceId());
@@ -199,13 +219,13 @@ private void indexState(ProcessInstanceStateEventBody data, Set addons,
pi.setLastUpdate(toZonedDateTime(data.getEventDate()));
pi.setAddons(addons);
pi.setEndpoint(endpoint);
- repository.flush();
}
- private void indexVariable(ProcessInstanceVariableEventBody data) {
- ProcessInstanceEntity pi = findOrInit(data.getProcessId(), data.getProcessInstanceId(), data.getEventDate());
+ private void indexVariable(ProcessInstanceEntity pi, ProcessInstanceVariableEventBody data) {
pi.setVariables(JsonUtils.mergeVariable(data.getVariableName(), data.getVariableValue(), pi.getVariables()));
- repository.flush();
}
+ private void indexSla(ProcessInstanceEntity orInit, ProcessInstanceSLAEventBody data) {
+ // SLA does nothing for now
+ }
}
diff --git a/data-index/data-index-storage/data-index-storage-jpa-common/src/main/java/org/kie/kogito/index/jpa/storage/UserTaskInstanceEntityStorage.java b/data-index/data-index-storage/data-index-storage-jpa-common/src/main/java/org/kie/kogito/index/jpa/storage/UserTaskInstanceEntityStorage.java
index 1e2c127a36..5204db6574 100644
--- a/data-index/data-index-storage/data-index-storage-jpa-common/src/main/java/org/kie/kogito/index/jpa/storage/UserTaskInstanceEntityStorage.java
+++ b/data-index/data-index-storage/data-index-storage-jpa-common/src/main/java/org/kie/kogito/index/jpa/storage/UserTaskInstanceEntityStorage.java
@@ -19,15 +19,19 @@
package org.kie.kogito.index.jpa.storage;
import java.net.URI;
+import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
+import java.util.Map;
+import org.kie.kogito.event.usertask.MultipleUserTaskInstanceDataEvent;
import org.kie.kogito.event.usertask.UserTaskInstanceAssignmentDataEvent;
import org.kie.kogito.event.usertask.UserTaskInstanceAssignmentEventBody;
import org.kie.kogito.event.usertask.UserTaskInstanceAttachmentDataEvent;
import org.kie.kogito.event.usertask.UserTaskInstanceAttachmentEventBody;
import org.kie.kogito.event.usertask.UserTaskInstanceCommentDataEvent;
import org.kie.kogito.event.usertask.UserTaskInstanceCommentEventBody;
+import org.kie.kogito.event.usertask.UserTaskInstanceDataEvent;
import org.kie.kogito.event.usertask.UserTaskInstanceDeadlineDataEvent;
import org.kie.kogito.event.usertask.UserTaskInstanceStateDataEvent;
import org.kie.kogito.event.usertask.UserTaskInstanceStateEventBody;
@@ -66,20 +70,69 @@ public UserTaskInstanceEntityStorage(UserTaskInstanceEntityRepository repository
super(repository, UserTaskInstanceEntity.class, mapper::mapToModel);
}
- private UserTaskInstanceEntity findOrInit(String taskId) {
- return repository.findByIdOptional(taskId).orElseGet(() -> {
- UserTaskInstanceEntity ut = new UserTaskInstanceEntity();
- ut.setId(taskId);
- repository.persist(ut);
- return ut;
- });
+ @Override
+ @Transactional
+ public void indexGroup(MultipleUserTaskInstanceDataEvent events) {
+ Map taskMap = new HashMap<>();
+ for (UserTaskInstanceDataEvent> event : events.getData()) {
+ indexEvent(taskMap.computeIfAbsent(event.getKogitoUserTaskInstanceId(), id -> findOrInit(id)), event);
+ }
}
@Override
@Transactional
public void indexAssignment(UserTaskInstanceAssignmentDataEvent event) {
+ indexAssignment(findOrInit(event), event);
+ }
+
+ @Override
+ @Transactional
+ public void indexAttachment(UserTaskInstanceAttachmentDataEvent event) {
+ indexAttachment(findOrInit(event), event);
+ }
+
+ @Override
+ @Transactional
+ public void indexDeadline(UserTaskInstanceDeadlineDataEvent event) {
+ indexDeadline(findOrInit(event), event);
+ }
+
+ @Override
+ @Transactional
+ public void indexState(UserTaskInstanceStateDataEvent event) {
+ indexState(findOrInit(event), event);
+ }
+
+ @Override
+ @Transactional
+ public void indexComment(UserTaskInstanceCommentDataEvent event) {
+ indexComment(findOrInit(event), event);
+ }
+
+ @Override
+ @Transactional
+ public void indexVariable(UserTaskInstanceVariableDataEvent event) {
+ indexVariable(findOrInit(event), event);
+ }
+
+ private void indexEvent(UserTaskInstanceEntity task, UserTaskInstanceDataEvent> event) {
+ if (event instanceof UserTaskInstanceAssignmentDataEvent) {
+ indexAssignment(task, (UserTaskInstanceAssignmentDataEvent) event);
+ } else if (event instanceof UserTaskInstanceAttachmentDataEvent) {
+ indexAttachment(task, (UserTaskInstanceAttachmentDataEvent) event);
+ } else if (event instanceof UserTaskInstanceDeadlineDataEvent) {
+ indexDeadline(task, (UserTaskInstanceDeadlineDataEvent) event);
+ } else if (event instanceof UserTaskInstanceStateDataEvent) {
+ indexState(task, (UserTaskInstanceStateDataEvent) event);
+ } else if (event instanceof UserTaskInstanceCommentDataEvent) {
+ indexComment(task, (UserTaskInstanceCommentDataEvent) event);
+ } else if (event instanceof UserTaskInstanceVariableDataEvent) {
+ indexVariable(task, (UserTaskInstanceVariableDataEvent) event);
+ }
+ }
+
+ private void indexAssignment(UserTaskInstanceEntity userTaskInstance, UserTaskInstanceAssignmentDataEvent event) {
UserTaskInstanceAssignmentEventBody body = event.getData();
- UserTaskInstanceEntity userTaskInstance = findOrInit(event.getKogitoUserTaskInstanceId());
switch (body.getAssignmentType()) {
case "USER_OWNERS":
userTaskInstance.setPotentialUsers(new HashSet<>(body.getUsers()));
@@ -97,13 +150,9 @@ public void indexAssignment(UserTaskInstanceAssignmentDataEvent event) {
userTaskInstance.setAdminUsers(new HashSet<>(body.getUsers()));
break;
}
- repository.flush();
}
- @Override
- @Transactional
- public void indexAttachment(UserTaskInstanceAttachmentDataEvent event) {
- UserTaskInstanceEntity userTaskInstance = findOrInit(event.getKogitoUserTaskInstanceId());
+ private void indexAttachment(UserTaskInstanceEntity userTaskInstance, UserTaskInstanceAttachmentDataEvent event) {
UserTaskInstanceAttachmentEventBody body = event.getData();
List attachments = userTaskInstance.getAttachments();
switch (body.getEventType()) {
@@ -127,17 +176,12 @@ public void indexAttachment(UserTaskInstanceAttachmentDataEvent event) {
}
}
- @Override
- @Transactional
- public void indexDeadline(UserTaskInstanceDeadlineDataEvent event) {
- findOrInit(event.getKogitoUserTaskInstanceId());
+ private void indexDeadline(UserTaskInstanceEntity userTaskInstance, UserTaskInstanceDeadlineDataEvent event) {
+ // deadlines ignored for now
}
- @Override
- @Transactional
- public void indexState(UserTaskInstanceStateDataEvent event) {
+ private void indexState(UserTaskInstanceEntity task, UserTaskInstanceStateDataEvent event) {
UserTaskInstanceStateEventBody body = event.getData();
- UserTaskInstanceEntity task = findOrInit(event.getKogitoUserTaskInstanceId());
task.setProcessInstanceId(body.getProcessInstanceId());
task.setProcessId(event.getKogitoProcessId());
task.setRootProcessId(event.getKogitoRootProcessId());
@@ -153,9 +197,10 @@ public void indexState(UserTaskInstanceStateDataEvent event) {
}
task.setActualOwner(event.getData().getActualOwner());
task.setEndpoint(
- event.getSource() == null ? null : getEndpoint(event.getSource(), event.getData().getProcessInstanceId(), event.getData().getUserTaskName(), event.getData().getUserTaskInstanceId()));
+ event.getSource() == null ? null : getEndpoint(event.getSource(), event.getData().getProcessInstanceId(), event.getData().getUserTaskName(), event.getData().getExternalReferenceId()));
task.setLastUpdate(toZonedDateTime(event.getData().getEventDate()));
task.setReferenceName(event.getData().getUserTaskReferenceName());
+ task.setExternalReferenceId(body.getExternalReferenceId());
}
private String getEndpoint(URI source, String pId, String taskName, String taskId) {
@@ -163,11 +208,8 @@ private String getEndpoint(URI source, String pId, String taskName, String taskI
return source.toString() + format("/%s/%s/%s", pId, name, taskId);
}
- @Override
- @Transactional
- public void indexComment(UserTaskInstanceCommentDataEvent event) {
+ private void indexComment(UserTaskInstanceEntity userTaskInstance, UserTaskInstanceCommentDataEvent event) {
UserTaskInstanceCommentEventBody body = event.getData();
- UserTaskInstanceEntity userTaskInstance = findOrInit(event.getKogitoUserTaskInstanceId());
List comments = userTaskInstance.getComments();
switch (body.getEventType()) {
case UserTaskInstanceCommentEventBody.EVENT_TYPE_ADDED:
@@ -190,10 +232,7 @@ public void indexComment(UserTaskInstanceCommentDataEvent event) {
}
}
- @Override
- @Transactional
- public void indexVariable(UserTaskInstanceVariableDataEvent event) {
- UserTaskInstanceEntity userTaskInstance = findOrInit(event.getKogitoUserTaskInstanceId());
+ private void indexVariable(UserTaskInstanceEntity userTaskInstance, UserTaskInstanceVariableDataEvent event) {
UserTaskInstanceVariableEventBody body = event.getData();
if (body.getVariableType().equals("INPUT")) {
ObjectNode objectNode = userTaskInstance.getInputs();
@@ -211,4 +250,17 @@ public void indexVariable(UserTaskInstanceVariableDataEvent event) {
userTaskInstance.setOutputs(objectNode);
}
}
+
+ private UserTaskInstanceEntity findOrInit(UserTaskInstanceDataEvent> event) {
+ return findOrInit(event.getKogitoUserTaskInstanceId());
+ }
+
+ private UserTaskInstanceEntity findOrInit(String taskId) {
+ return repository.findByIdOptional(taskId).orElseGet(() -> {
+ UserTaskInstanceEntity ut = new UserTaskInstanceEntity();
+ ut.setId(taskId);
+ repository.persist(ut);
+ return ut;
+ });
+ }
}
diff --git a/data-index/data-index-storage/data-index-storage-jpa-common/src/test/java/org/kie/kogito/index/jpa/mapper/AbstractUserTaskInstanceEntityMapperIT.java b/data-index/data-index-storage/data-index-storage-jpa-common/src/test/java/org/kie/kogito/index/jpa/mapper/AbstractUserTaskInstanceEntityMapperIT.java
index 6d4dd31e24..f9e8b2f7c4 100644
--- a/data-index/data-index-storage/data-index-storage-jpa-common/src/test/java/org/kie/kogito/index/jpa/mapper/AbstractUserTaskInstanceEntityMapperIT.java
+++ b/data-index/data-index-storage/data-index-storage-jpa-common/src/test/java/org/kie/kogito/index/jpa/mapper/AbstractUserTaskInstanceEntityMapperIT.java
@@ -71,6 +71,7 @@ void setup() {
String processId = "testProcessId";
String rootProcessId = "testRootProcessId";
String rootProcessInstanceId = "testRootProcessInstanceId";
+ String externalReferenceId = "testExternalReferenceId";
Map object = new HashMap<>();
object.put("test", "testValue");
ObjectNode inputs = jsonMapper.createObjectNode().put("testInput", "testValue");
@@ -124,6 +125,7 @@ void setup() {
userTaskInstance.setOutputs(outputs);
userTaskInstance.setComments(singletonList(comment));
userTaskInstance.setAttachments(singletonList(attachment));
+ userTaskInstance.setExternalReferenceId(externalReferenceId);
userTaskInstanceEntity.setId(testId);
userTaskInstanceEntity.setDescription(description);
@@ -148,6 +150,7 @@ void setup() {
userTaskInstanceEntity.setOutputs(outputs);
userTaskInstanceEntity.setComments(singletonList(commentEntity));
userTaskInstanceEntity.setAttachments(singletonList(attachmentEntity));
+ userTaskInstanceEntity.setExternalReferenceId(externalReferenceId);
}
@Test
diff --git a/data-index/data-index-storage/data-index-storage-jpa/src/main/resources/kie-flyway/db/data-index/ansi/V1.45.0.5__add_external_reference_id.sql b/data-index/data-index-storage/data-index-storage-jpa/src/main/resources/kie-flyway/db/data-index/ansi/V1.45.0.5__add_external_reference_id.sql
new file mode 100644
index 0000000000..918b9369c6
--- /dev/null
+++ b/data-index/data-index-storage/data-index-storage-jpa/src/main/resources/kie-flyway/db/data-index/ansi/V1.45.0.5__add_external_reference_id.sql
@@ -0,0 +1,20 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.
+ */
+
+alter table tasks add external_reference_id character varying(4000)
diff --git a/data-index/data-index-storage/data-index-storage-mongodb/src/main/java/org/kie/kogito/index/mongodb/model/UserTaskInstanceEntity.java b/data-index/data-index-storage/data-index-storage-mongodb/src/main/java/org/kie/kogito/index/mongodb/model/UserTaskInstanceEntity.java
index a027ad3843..c97c753dc0 100644
--- a/data-index/data-index-storage/data-index-storage-mongodb/src/main/java/org/kie/kogito/index/mongodb/model/UserTaskInstanceEntity.java
+++ b/data-index/data-index-storage/data-index-storage-mongodb/src/main/java/org/kie/kogito/index/mongodb/model/UserTaskInstanceEntity.java
@@ -76,6 +76,8 @@ public class UserTaskInstanceEntity {
List attachments;
+ private String externalReferenceId;
+
public String getId() {
return id;
}
@@ -268,6 +270,14 @@ public void setAttachments(List attachments) {
this.attachments = attachments;
}
+ public void setExternalReferenceId(String externalReferenceId) {
+ this.externalReferenceId = externalReferenceId;
+ }
+
+ public String getExternalReferenceId() {
+ return externalReferenceId;
+ }
+
@Override
public boolean equals(Object o) {
if (this == o) {
@@ -435,4 +445,5 @@ public int hashCode() {
return Objects.hash(id);
}
}
+
}
diff --git a/data-index/data-index-storage/data-index-storage-mongodb/src/main/java/org/kie/kogito/index/mongodb/model/UserTaskInstanceEntityMapper.java b/data-index/data-index-storage/data-index-storage-mongodb/src/main/java/org/kie/kogito/index/mongodb/model/UserTaskInstanceEntityMapper.java
index b7479af604..1a8b9add5d 100644
--- a/data-index/data-index-storage/data-index-storage-mongodb/src/main/java/org/kie/kogito/index/mongodb/model/UserTaskInstanceEntityMapper.java
+++ b/data-index/data-index-storage/data-index-storage-mongodb/src/main/java/org/kie/kogito/index/mongodb/model/UserTaskInstanceEntityMapper.java
@@ -79,6 +79,7 @@ public UserTaskInstanceEntity mapToEntity(String key, UserTaskInstance instance)
entity.setEndpoint(instance.getEndpoint());
entity.setComments(Optional.ofNullable(instance.getComments()).map(comments -> comments.stream().map(this::fromComment).collect(toList())).orElse(null));
entity.setAttachments(Optional.ofNullable(instance.getAttachments()).map(attachments -> attachments.stream().map(this::fromAttachment).collect(toList())).orElse(null));
+ entity.setExternalReferenceId(instance.getExternalReferenceId());
return entity;
}
@@ -113,6 +114,7 @@ public UserTaskInstance mapToModel(UserTaskInstanceEntity entity) {
instance.setEndpoint(entity.getEndpoint());
instance.setComments(Optional.ofNullable(entity.getComments()).map(comments -> comments.stream().map(this::toComment).collect(toList())).orElse(null));
instance.setAttachments(Optional.ofNullable(entity.getAttachments()).map(attachments -> attachments.stream().map(this::toAttachment).collect(toList())).orElse(null));
+ instance.setExternalReferenceId(entity.getExternalReferenceId());
return instance;
}
diff --git a/data-index/data-index-storage/data-index-storage-mongodb/src/test/java/org/kie/kogito/index/mongodb/model/UserTaskInstanceEntityMapperTest.java b/data-index/data-index-storage/data-index-storage-mongodb/src/test/java/org/kie/kogito/index/mongodb/model/UserTaskInstanceEntityMapperTest.java
index 9340704383..013ba7a041 100644
--- a/data-index/data-index-storage/data-index-storage-mongodb/src/test/java/org/kie/kogito/index/mongodb/model/UserTaskInstanceEntityMapperTest.java
+++ b/data-index/data-index-storage/data-index-storage-mongodb/src/test/java/org/kie/kogito/index/mongodb/model/UserTaskInstanceEntityMapperTest.java
@@ -64,6 +64,7 @@ static void setup() {
String processId = "testProcessId";
String rootProcessId = "testRootProcessId";
String rootProcessInstanceId = "testRootProcessInstanceId";
+ String externalReferenceId = "testExternalReferenceId";
ObjectNode object = MAPPER.createObjectNode();
object.put("test", "testValue");
ObjectNode inputs = object;
@@ -114,6 +115,7 @@ static void setup() {
userTaskInstance.setOutputs(outputs);
userTaskInstance.setComments(List.of(comment));
userTaskInstance.setAttachments(List.of(attachment));
+ userTaskInstance.setExternalReferenceId(externalReferenceId);
userTaskInstanceEntity = new UserTaskInstanceEntity();
userTaskInstanceEntity.setId(testId);
@@ -139,6 +141,7 @@ static void setup() {
userTaskInstanceEntity.setOutputs(jsonNodeToDocument(outputs));
userTaskInstanceEntity.setComments(List.of(commentEntity));
userTaskInstanceEntity.setAttachments(List.of(attachmentEntity));
+ userTaskInstanceEntity.setExternalReferenceId(externalReferenceId);
}
@Test
diff --git a/data-index/data-index-storage/data-index-storage-postgresql/src/main/resources/kie-flyway/db/data-index/postgresql/V1.45.0.5__add_external_reference_id.sql b/data-index/data-index-storage/data-index-storage-postgresql/src/main/resources/kie-flyway/db/data-index/postgresql/V1.45.0.5__add_external_reference_id.sql
new file mode 100644
index 0000000000..908ee2b249
--- /dev/null
+++ b/data-index/data-index-storage/data-index-storage-postgresql/src/main/resources/kie-flyway/db/data-index/postgresql/V1.45.0.5__add_external_reference_id.sql
@@ -0,0 +1,20 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.
+ */
+
+alter table tasks add external_reference_id varchar(4000);
diff --git a/data-index/data-index-storage/data-index-storage-protobuf/src/main/resources/META-INF/kogito-index.proto b/data-index/data-index-storage/data-index-storage-protobuf/src/main/resources/META-INF/kogito-index.proto
index 18f01a6014..5c23eecefa 100644
--- a/data-index/data-index-storage/data-index-storage-protobuf/src/main/resources/META-INF/kogito-index.proto
+++ b/data-index/data-index-storage/data-index-storage-protobuf/src/main/resources/META-INF/kogito-index.proto
@@ -237,6 +237,7 @@ message UserTaskInstance {
repeated Comment comments = 23;
/* @Field(store = Store.YES) */
repeated Attachment attachments = 24;
+ optional string externalReferenceId = 25;
}
/* @Indexed */
@@ -275,6 +276,7 @@ message UserTaskInstanceMeta {
repeated Comment comments = 17;
/* @Field(store = Store.YES) */
repeated Attachment attachments = 18;
+ optional string externalReferenceId = 25;
}
/* @Indexed */
diff --git a/data-index/data-index-test-utils/src/main/java/org/kie/kogito/index/test/TestUtils.java b/data-index/data-index-test-utils/src/main/java/org/kie/kogito/index/test/TestUtils.java
index 68946a056c..600d52824e 100644
--- a/data-index/data-index-test-utils/src/main/java/org/kie/kogito/index/test/TestUtils.java
+++ b/data-index/data-index-test-utils/src/main/java/org/kie/kogito/index/test/TestUtils.java
@@ -286,6 +286,7 @@ public static UserTaskInstanceStateDataEvent getUserTaskCloudEvent(String taskId
.actualOwner(actualOwner)
.eventDate(new Date())
.processInstanceId(processInstanceId)
+ .externalReferenceId("testExternalReferenceId")
.build();
UserTaskInstanceStateDataEvent event = new UserTaskInstanceStateDataEvent(URI.create("http://localhost:8080/" + processId).toString(), null, null, body.metaData(), body);
event.setKogitoProcessId(processId);
@@ -422,6 +423,7 @@ public static UserTaskInstance getUserTaskInstance(String taskId, String process
task.setPotentialGroups(singleton("potentialGroup"));
task.setComments(List.of(Comment.builder().id("commentId" + taskId).content("Comment 1").updatedBy("kogito").build()));
task.setAttachments(List.of(Attachment.builder().id("attachmentId" + taskId).content("http://linltodoc.com/1").name("doc1").updatedBy("kogito").build()));
+ task.setExternalReferenceId("testExternalReferenceId");
return task;
}
}
diff --git a/jitexecutor/jitexecutor-dmn/src/main/java/org/kie/kogito/jitexecutor/dmn/DMNEvaluator.java b/jitexecutor/jitexecutor-dmn/src/main/java/org/kie/kogito/jitexecutor/dmn/DMNEvaluator.java
index 979f4159bd..92ec93303f 100644
--- a/jitexecutor/jitexecutor-dmn/src/main/java/org/kie/kogito/jitexecutor/dmn/DMNEvaluator.java
+++ b/jitexecutor/jitexecutor-dmn/src/main/java/org/kie/kogito/jitexecutor/dmn/DMNEvaluator.java
@@ -22,7 +22,9 @@
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
+import java.util.List;
import java.util.Map;
+import java.util.Optional;
import org.kie.api.io.Resource;
import org.kie.dmn.api.core.DMNContext;
@@ -36,6 +38,7 @@
import org.kie.internal.io.ResourceFactory;
import org.kie.kogito.jitexecutor.common.requests.MultipleResourcesPayload;
import org.kie.kogito.jitexecutor.common.requests.ResourceWithURI;
+import org.kie.kogito.jitexecutor.dmn.responses.JITDMNResult;
import org.kie.kogito.jitexecutor.dmn.utils.ResolveByKey;
public class DMNEvaluator {
@@ -47,6 +50,7 @@ public static DMNEvaluator fromXML(String modelXML) {
Resource modelResource = ResourceFactory.newReaderResource(new StringReader(modelXML), "UTF-8");
DMNRuntime dmnRuntime = DMNRuntimeBuilder.fromDefaults().buildConfiguration()
.fromResources(Collections.singletonList(modelResource)).getOrElseThrow(RuntimeException::new);
+ dmnRuntime.addListener(new JITDMNListener());
DMNModel dmnModel = dmnRuntime.getModels().get(0);
return new DMNEvaluator(dmnModel, dmnRuntime);
}
@@ -73,9 +77,16 @@ public Collection getAllDMNModels() {
return dmnRuntime.getModels();
}
- public DMNResult evaluate(Map context) {
- DMNContext dmnContext = new DynamicDMNContextBuilder(dmnRuntime.newContext(), dmnModel).populateContextWith(context);
- return dmnRuntime.evaluateAll(dmnModel, dmnContext);
+ public JITDMNResult evaluate(Map context) {
+ DMNContext dmnContext =
+ new DynamicDMNContextBuilder(dmnRuntime.newContext(), dmnModel).populateContextWith(context);
+ DMNResult dmnResult = dmnRuntime.evaluateAll(dmnModel, dmnContext);
+ Optional> evaluationHitIds = dmnRuntime.getListeners().stream()
+ .filter(JITDMNListener.class::isInstance)
+ .findFirst()
+ .map(JITDMNListener.class::cast)
+ .map(JITDMNListener::getEvaluationHitIds);
+ return new JITDMNResult(getNamespace(), getName(), dmnResult, evaluationHitIds.orElse(Collections.emptyList()));
}
public static DMNEvaluator fromMultiple(MultipleResourcesPayload payload) {
diff --git a/jitexecutor/jitexecutor-dmn/src/main/java/org/kie/kogito/jitexecutor/dmn/JITDMNListener.java b/jitexecutor/jitexecutor-dmn/src/main/java/org/kie/kogito/jitexecutor/dmn/JITDMNListener.java
new file mode 100644
index 0000000000..9f753e7548
--- /dev/null
+++ b/jitexecutor/jitexecutor-dmn/src/main/java/org/kie/kogito/jitexecutor/dmn/JITDMNListener.java
@@ -0,0 +1,97 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.
+ */
+package org.kie.kogito.jitexecutor.dmn;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.kie.dmn.api.core.event.AfterConditionalEvaluationEvent;
+import org.kie.dmn.api.core.event.AfterEvaluateAllEvent;
+import org.kie.dmn.api.core.event.AfterEvaluateBKMEvent;
+import org.kie.dmn.api.core.event.AfterEvaluateContextEntryEvent;
+import org.kie.dmn.api.core.event.AfterEvaluateDecisionEvent;
+import org.kie.dmn.api.core.event.AfterEvaluateDecisionServiceEvent;
+import org.kie.dmn.api.core.event.AfterEvaluateDecisionTableEvent;
+import org.kie.dmn.api.core.event.AfterInvokeBKMEvent;
+import org.kie.dmn.api.core.event.DMNEvent;
+import org.kie.dmn.api.core.event.DMNRuntimeEventListener;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class JITDMNListener implements DMNRuntimeEventListener {
+
+ private final List evaluationHitIds = new ArrayList<>();
+
+ private static final Logger LOGGER = LoggerFactory.getLogger(JITDMNListener.class);
+
+ @Override
+ public void afterEvaluateDecisionTable(AfterEvaluateDecisionTableEvent event) {
+ logEvent(event);
+ evaluationHitIds.addAll(event.getSelectedIds());
+ }
+
+ @Override
+ public void afterEvaluateDecision(AfterEvaluateDecisionEvent event) {
+ logEvent(event);
+ }
+
+ @Override
+ public void afterEvaluateBKM(AfterEvaluateBKMEvent event) {
+ logEvent(event);
+ }
+
+ @Override
+ public void afterEvaluateContextEntry(AfterEvaluateContextEntryEvent event) {
+ logEvent(event);
+ }
+
+ @Override
+ public void afterEvaluateDecisionService(AfterEvaluateDecisionServiceEvent event) {
+ logEvent(event);
+ }
+
+ @Override
+ public void afterInvokeBKM(AfterInvokeBKMEvent event) {
+ logEvent(event);
+ }
+
+ @Override
+ public void afterEvaluateAll(AfterEvaluateAllEvent event) {
+ logEvent(event);
+ }
+
+ @Override
+ public void afterConditionalEvaluation(AfterConditionalEvaluationEvent event) {
+ logEvent(event);
+ evaluationHitIds.add(event.getExecutedId());
+ }
+
+ public List getEvaluationHitIds() {
+ return evaluationHitIds;
+ }
+
+ private void logEvent(DMNEvent toLog) {
+ LOGGER.info("{} event {}", toLog.getClass().getSimpleName(), toLog);
+ }
+
+ private void logEvent(AfterConditionalEvaluationEvent toLog) {
+ LOGGER.info("{} event {}", toLog.getClass().getSimpleName(), toLog);
+ }
+
+}
diff --git a/jitexecutor/jitexecutor-dmn/src/main/java/org/kie/kogito/jitexecutor/dmn/JITDMNServiceImpl.java b/jitexecutor/jitexecutor-dmn/src/main/java/org/kie/kogito/jitexecutor/dmn/JITDMNServiceImpl.java
index 320f1a9609..bb0b6513c8 100644
--- a/jitexecutor/jitexecutor-dmn/src/main/java/org/kie/kogito/jitexecutor/dmn/JITDMNServiceImpl.java
+++ b/jitexecutor/jitexecutor-dmn/src/main/java/org/kie/kogito/jitexecutor/dmn/JITDMNServiceImpl.java
@@ -76,8 +76,7 @@ public JITDMNServiceImpl(int explainabilityLimeSampleSize, int explainabilityLim
@Override
public JITDMNResult evaluateModel(String modelXML, Map context) {
DMNEvaluator dmnEvaluator = DMNEvaluator.fromXML(modelXML);
- DMNResult dmnResult = dmnEvaluator.evaluate(context);
- return new JITDMNResult(dmnEvaluator.getNamespace(), dmnEvaluator.getName(), dmnResult);
+ return dmnEvaluator.evaluate(context);
}
@Override
diff --git a/jitexecutor/jitexecutor-dmn/src/main/java/org/kie/kogito/jitexecutor/dmn/responses/JITDMNResult.java b/jitexecutor/jitexecutor-dmn/src/main/java/org/kie/kogito/jitexecutor/dmn/responses/JITDMNResult.java
index bfaea16420..4f43a123f6 100644
--- a/jitexecutor/jitexecutor-dmn/src/main/java/org/kie/kogito/jitexecutor/dmn/responses/JITDMNResult.java
+++ b/jitexecutor/jitexecutor-dmn/src/main/java/org/kie/kogito/jitexecutor/dmn/responses/JITDMNResult.java
@@ -21,6 +21,7 @@
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Arrays;
+import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@@ -49,16 +50,23 @@ public class JITDMNResult implements Serializable,
private Map decisionResults = new HashMap<>();
+ private List evaluationHitIds;
+
public JITDMNResult() {
// Intentionally blank.
}
public JITDMNResult(String namespace, String modelName, org.kie.dmn.api.core.DMNResult dmnResult) {
+ this(namespace, modelName, dmnResult, Collections.emptyList());
+ }
+
+ public JITDMNResult(String namespace, String modelName, org.kie.dmn.api.core.DMNResult dmnResult, List evaluationHitIds) {
this.namespace = namespace;
this.modelName = modelName;
this.setDmnContext(dmnResult.getContext().getAll());
this.setMessages(dmnResult.getMessages());
this.setDecisionResults(dmnResult.getDecisionResults());
+ this.evaluationHitIds = evaluationHitIds;
}
public String getNamespace() {
@@ -102,6 +110,14 @@ public void setDecisionResults(List extends DMNDecisionResult> decisionResults
}
}
+ public List getEvaluationHitIds() {
+ return evaluationHitIds;
+ }
+
+ public void setEvaluationHitIds(List evaluationHitIds) {
+ this.evaluationHitIds = evaluationHitIds;
+ }
+
@JsonIgnore
@Override
public DMNContext getContext() {
@@ -151,6 +167,7 @@ public String toString() {
.append(", dmnContext=").append(dmnContext)
.append(", messages=").append(messages)
.append(", decisionResults=").append(decisionResults)
+ .append(", evaluationHitIds=").append(evaluationHitIds)
.append("]").toString();
}
}
diff --git a/jitexecutor/jitexecutor-dmn/src/test/java/org/kie/kogito/jitexecutor/dmn/JITDMNServiceImplTest.java b/jitexecutor/jitexecutor-dmn/src/test/java/org/kie/kogito/jitexecutor/dmn/JITDMNServiceImplTest.java
index 3169dce379..e99957ef0c 100644
--- a/jitexecutor/jitexecutor-dmn/src/test/java/org/kie/kogito/jitexecutor/dmn/JITDMNServiceImplTest.java
+++ b/jitexecutor/jitexecutor-dmn/src/test/java/org/kie/kogito/jitexecutor/dmn/JITDMNServiceImplTest.java
@@ -19,8 +19,11 @@
package org.kie.kogito.jitexecutor.dmn;
import java.io.IOException;
+import java.math.BigDecimal;
+import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
+import java.util.List;
import java.util.Map;
import org.junit.jupiter.api.Assertions;
@@ -43,7 +46,7 @@ public static void setup() throws IOException {
}
@Test
- public void testModelEvaluation() {
+ void testModelEvaluation() {
Map context = new HashMap<>();
context.put("FICO Score", 800);
context.put("DTI Ratio", .1);
@@ -57,7 +60,141 @@ public void testModelEvaluation() {
}
@Test
- public void testExplainability() throws IOException {
+ void testDecisionTableModelEvaluation() throws IOException {
+ String decisionTableModel = getModelFromIoUtils("valid_models/DMNv1_x/LoanEligibility.dmn");
+ Map client = new HashMap<>();
+ client.put("age", 43);
+ client.put("salary", 1950);
+ client.put("existing payments", 100);
+
+ Map loan = new HashMap<>();
+ loan.put("duration", 15);
+ loan.put("installment", 180);
+ Map context = new HashMap<>();
+
+ context.put("Client", client);
+ context.put("Loan", loan);
+ context.put("SupremeDirector", "No");
+ context.put("Bribe", 10);
+ JITDMNResult dmnResult = jitdmnService.evaluateModel(decisionTableModel, context);
+
+ Assertions.assertEquals("LoanEligibility", dmnResult.getModelName());
+ Assertions.assertEquals("https://github.com/kiegroup/kogito-examples/dmn-quarkus-listener-example", dmnResult.getNamespace());
+ Assertions.assertTrue(dmnResult.getMessages().isEmpty());
+ Assertions.assertEquals("Yes", dmnResult.getDecisionResultByName("Eligibility").getResult());
+ }
+
+ @Test
+ void testEvaluationHitIds() throws IOException {
+ final String thenElementId = "_6481FF12-61B5-451C-B775-4143D9B6CD6B";
+ final String elseElementId = "_2CD02CB2-6B56-45C4-B461-405E89D45633";
+ final String ruleId0 = "_1578BD9E-2BF9-4BFC-8956-1A736959C937";
+ final String ruleId1 = "_31CD7AA3-A806-4E7E-B512-821F82043620";
+ final String ruleId3 = "_2545E1A8-93D3-4C8A-A0ED-8AD8B10A58F9";
+ final String ruleId4 = "_510A50DA-D5A4-4F06-B0BE-7F8F2AA83740";
+ String decisionTableModel = getModelFromIoUtils("valid_models/DMNv1_5/RiskScore_Simple.dmn");
+ Map context = new HashMap<>();
+ context.put("Credit Score", "Poor");
+ context.put("DTI", 33);
+ JITDMNResult dmnResult = jitdmnService.evaluateModel(decisionTableModel, context);
+
+ Assertions.assertEquals("DMN_A77074C1-21FE-4F7E-9753-F84661569AFC", dmnResult.getModelName());
+ Assertions.assertTrue(dmnResult.getMessages().isEmpty());
+ Assertions.assertEquals(BigDecimal.valueOf(50), dmnResult.getDecisionResultByName("Risk Score").getResult());
+ List evaluationHitIds = dmnResult.getEvaluationHitIds();
+ Assertions.assertNotNull(evaluationHitIds);
+ Assertions.assertEquals(3, evaluationHitIds.size());
+ Assertions.assertTrue(evaluationHitIds.contains(elseElementId));
+ Assertions.assertTrue(evaluationHitIds.contains(ruleId0));
+ Assertions.assertTrue(evaluationHitIds.contains(ruleId3));
+
+ context = new HashMap<>();
+ context.put("Credit Score", "Excellent");
+ context.put("DTI", 10);
+ dmnResult = jitdmnService.evaluateModel(decisionTableModel, context);
+
+ Assertions.assertTrue(dmnResult.getMessages().isEmpty());
+ Assertions.assertEquals(BigDecimal.valueOf(20), dmnResult.getDecisionResultByName("Risk Score").getResult());
+ evaluationHitIds = dmnResult.getEvaluationHitIds();
+ Assertions.assertNotNull(evaluationHitIds);
+ Assertions.assertEquals(3, evaluationHitIds.size());
+ Assertions.assertTrue(evaluationHitIds.contains(thenElementId));
+ Assertions.assertTrue(evaluationHitIds.contains(ruleId1));
+ Assertions.assertTrue(evaluationHitIds.contains(ruleId4));
+ }
+
+ @Test
+ void testConditionalWithNestedDecisionTableFromRiskScoreEvaluation() throws IOException {
+ final String thenElementId = "_6481FF12-61B5-451C-B775-4143D9B6CD6B";
+ final String thenRuleId0 = "_D1753442-03F0-414B-94F8-6A86182DF6EB";
+ final String thenRuleId4 = "_E787BA51-E31D-449B-A432-50BE7466A15E";
+ final String elseElementId = "_2CD02CB2-6B56-45C4-B461-405E89D45633";
+ final String elseRuleId2 = "_945A5471-9F91-4751-9D96-74978F6FB12B";
+ final String elseRuleId5 = "_654BBFBC-9B84-4BD8-9D0B-13E8DD1B9F5D";
+ String decisionTableModel = getModelFromIoUtils("valid_models/DMNv1_5/RiskScore_Conditional.dmn");
+
+ Map context = new HashMap<>();
+ context.put("Credit Score", "Poor");
+ context.put("DTI", 33);
+ context.put("World Region", "Asia");
+ JITDMNResult dmnResult = jitdmnService.evaluateModel(decisionTableModel, context);
+
+ Assertions.assertTrue(dmnResult.getMessages().isEmpty());
+ Assertions.assertEquals(BigDecimal.valueOf(50), dmnResult.getDecisionResultByName("Risk Score").getResult());
+ List evaluationHitIds = dmnResult.getEvaluationHitIds();
+ Assertions.assertNotNull(evaluationHitIds);
+ Assertions.assertEquals(3, evaluationHitIds.size());
+ Assertions.assertTrue(evaluationHitIds.contains(thenElementId));
+ Assertions.assertTrue(evaluationHitIds.contains(thenRuleId0));
+ Assertions.assertTrue(evaluationHitIds.contains(thenRuleId4));
+
+ context = new HashMap<>();
+ context.put("Credit Score", "Excellent");
+ context.put("DTI", 10);
+ context.put("World Region", "Europe");
+ dmnResult = jitdmnService.evaluateModel(decisionTableModel, context);
+
+ Assertions.assertTrue(dmnResult.getMessages().isEmpty());
+ Assertions.assertEquals(BigDecimal.valueOf(30), dmnResult.getDecisionResultByName("Risk Score").getResult());
+ evaluationHitIds = dmnResult.getEvaluationHitIds();
+ Assertions.assertNotNull(evaluationHitIds);
+ Assertions.assertEquals(3, evaluationHitIds.size());
+ Assertions.assertTrue(evaluationHitIds.contains(elseElementId));
+ Assertions.assertTrue(evaluationHitIds.contains(elseRuleId2));
+ Assertions.assertTrue(evaluationHitIds.contains(elseRuleId5));
+ }
+
+ @Test
+ void testMultipleHitRulesEvaluation() throws IOException {
+ final String rule0 = "_E5C380DA-AF7B-4401-9804-C58296EC09DD";
+ final String rule1 = "_DFD65E8B-5648-4BFD-840F-8C76B8DDBD1A";
+ final String rule2 = "_E80EE7F7-1C0C-4050-B560-F33611F16B05";
+ String decisionTableModel = getModelFromIoUtils("valid_models/DMNv1_5/MultipleHitRules.dmn");
+
+ final List numbers = new ArrayList<>();
+ numbers.add(BigDecimal.valueOf(10));
+ numbers.add(BigDecimal.valueOf(2));
+ numbers.add(BigDecimal.valueOf(1));
+ final Map context = new HashMap<>();
+ context.put("Numbers", numbers);
+ final JITDMNResult dmnResult = jitdmnService.evaluateModel(decisionTableModel, context);
+
+ final List expectedStatistcs = new ArrayList<>();
+ expectedStatistcs.add(BigDecimal.valueOf(6));
+ expectedStatistcs.add(BigDecimal.valueOf(3));
+ expectedStatistcs.add(BigDecimal.valueOf(1));
+ Assertions.assertTrue(dmnResult.getMessages().isEmpty());
+ Assertions.assertEquals(expectedStatistcs, dmnResult.getDecisionResultByName("Statistics").getResult());
+ final List evaluationHitIds = dmnResult.getEvaluationHitIds();
+ Assertions.assertNotNull(evaluationHitIds);
+ Assertions.assertEquals(6, evaluationHitIds.size());
+ Assertions.assertEquals(3, evaluationHitIds.stream().filter(rule0::equals).count());
+ Assertions.assertEquals(2, evaluationHitIds.stream().filter(rule1::equals).count());
+ Assertions.assertEquals(1, evaluationHitIds.stream().filter(rule2::equals).count());
+ }
+
+ @Test
+ void testExplainability() throws IOException {
String allTypesModel = getModelFromIoUtils("valid_models/DMNv1_x/allTypes.dmn");
Map context = new HashMap<>();
diff --git a/jitexecutor/jitexecutor-dmn/src/test/java/org/kie/kogito/jitexecutor/dmn/api/JITDMNResourceTest.java b/jitexecutor/jitexecutor-dmn/src/test/java/org/kie/kogito/jitexecutor/dmn/api/JITDMNResourceTest.java
index d728d112c3..6c29603088 100644
--- a/jitexecutor/jitexecutor-dmn/src/test/java/org/kie/kogito/jitexecutor/dmn/api/JITDMNResourceTest.java
+++ b/jitexecutor/jitexecutor-dmn/src/test/java/org/kie/kogito/jitexecutor/dmn/api/JITDMNResourceTest.java
@@ -22,10 +22,17 @@
import java.util.HashMap;
import java.util.Map;
+import org.assertj.core.api.Assertions;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
import org.kie.kogito.jitexecutor.dmn.requests.JITDMNPayload;
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.DeserializationFeature;
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.node.ArrayNode;
+
import io.quarkus.test.junit.QuarkusTest;
import io.restassured.http.ContentType;
@@ -38,15 +45,25 @@ public class JITDMNResourceTest {
private static String model;
private static String modelWithExtensionElements;
+ private static String modelWithEvaluationHitIds;
+
+ private static final ObjectMapper MAPPER = new ObjectMapper();
+
+ private static final String EVALUATION_HIT_IDS_FIELD_NAME = "evaluationHitIds";
+
+ static {
+ MAPPER.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
+ }
@BeforeAll
public static void setup() throws IOException {
model = getModelFromIoUtils("invalid_models/DMNv1_x/test.dmn");
modelWithExtensionElements = getModelFromIoUtils("valid_models/DMNv1_x/testWithExtensionElements.dmn");
+ modelWithEvaluationHitIds = getModelFromIoUtils("valid_models/DMNv1_5/RiskScore_Simple.dmn");
}
@Test
- public void testjitEndpoint() {
+ void testjitEndpoint() {
JITDMNPayload jitdmnpayload = new JITDMNPayload(model, buildContext());
given()
.contentType(ContentType.JSON)
@@ -58,7 +75,7 @@ public void testjitEndpoint() {
}
@Test
- public void testjitdmnResultEndpoint() {
+ void testjitdmnResultEndpoint() {
JITDMNPayload jitdmnpayload = new JITDMNPayload(model, buildContext());
given()
.contentType(ContentType.JSON)
@@ -70,7 +87,34 @@ public void testjitdmnResultEndpoint() {
}
@Test
- public void testjitExplainabilityEndpoint() {
+ void testjitdmnResultEndpointWithEvaluationHitIds() throws JsonProcessingException {
+ JITDMNPayload jitdmnpayload = new JITDMNPayload(modelWithEvaluationHitIds, buildRiskScoreContext());
+ final String elseElementId = "_2CD02CB2-6B56-45C4-B461-405E89D45633";
+ final String ruleId0 = "_1578BD9E-2BF9-4BFC-8956-1A736959C937";
+ final String ruleId3 = "_2545E1A8-93D3-4C8A-A0ED-8AD8B10A58F9";
+ String response = given().contentType(ContentType.JSON)
+ .body(jitdmnpayload)
+ .when().post("/jitdmn/dmnresult")
+ .then()
+ .statusCode(200)
+ .body(containsString("Risk Score"),
+ containsString("Loan Pre-Qualification"),
+ containsString(EVALUATION_HIT_IDS_FIELD_NAME),
+ containsString(elseElementId),
+ containsString(ruleId0),
+ containsString(ruleId3))
+ .extract()
+ .asString();
+ JsonNode retrieved = MAPPER.readTree(response);
+ ArrayNode evaluationHitIdsNode = (ArrayNode) retrieved.get(EVALUATION_HIT_IDS_FIELD_NAME);
+ Assertions.assertThat(evaluationHitIdsNode).hasSize(3)
+ .anyMatch(node -> node.asText().equals(elseElementId))
+ .anyMatch(node -> node.asText().equals(ruleId0))
+ .anyMatch(node -> node.asText().equals(ruleId3));
+ }
+
+ @Test
+ void testjitExplainabilityEndpoint() {
JITDMNPayload jitdmnpayload = new JITDMNPayload(model, buildContext());
given()
.contentType(ContentType.JSON)
@@ -78,11 +122,12 @@ public void testjitExplainabilityEndpoint() {
.when().post("/jitdmn/evaluateAndExplain")
.then()
.statusCode(200)
- .body(containsString("dmnResult"), containsString("saliencies"), containsString("xls2dmn"), containsString("featureName"));
+ .body(containsString("dmnResult"), containsString("saliencies"), containsString("xls2dmn"),
+ containsString("featureName"));
}
@Test
- public void testjitdmnWithExtensionElements() {
+ void testjitdmnWithExtensionElements() {
Map context = new HashMap<>();
context.put("m", 1);
context.put("n", 2);
@@ -97,6 +142,13 @@ public void testjitdmnWithExtensionElements() {
.body(containsString("m"), containsString("n"), containsString("sum"));
}
+ private Map buildRiskScoreContext() {
+ Map context = new HashMap<>();
+ context.put("Credit Score", "Poor");
+ context.put("DTI", 33);
+ return context;
+ }
+
private Map buildContext() {
Map context = new HashMap<>();
context.put("FICO Score", 800);
diff --git a/jitexecutor/jitexecutor-runner/src/main/resources/application.properties b/jitexecutor/jitexecutor-runner/src/main/resources/application.properties
index 47e4b5dc93..0dfac610c5 100644
--- a/jitexecutor/jitexecutor-runner/src/main/resources/application.properties
+++ b/jitexecutor/jitexecutor-runner/src/main/resources/application.properties
@@ -22,6 +22,6 @@ quarkus.http.cors=true
quarkus.swagger-ui.always-include=true
quarkus.native.additional-build-args=\
- --initialize-at-run-time=com.thoughtworks.xstream.converters.extended.DynamicProxyConverter$Reflections\\,org.kie.dmn.core.compiler.execmodelbased.AbstractModelEvaluator\\,org.kie.dmn.core.pmml.DMNKiePMMLTrustyInvocationEvaluator,\
+ --initialize-at-run-time=org.apache.hc.client5.http.impl.auth.NTLMEngineImpl\\,com.thoughtworks.xstream.converters.extended.DynamicProxyConverter$Reflections\\,org.kie.dmn.core.compiler.execmodelbased.AbstractModelEvaluator\\,org.kie.dmn.core.pmml.DMNKiePMMLTrustyInvocationEvaluator,\
-H:IncludeResourceBundles=com.sun.org.apache.xerces.internal.impl.xpath.regex.message,\
--allow-incomplete-classpath
\ No newline at end of file