diff --git a/.ci/jenkins/dsl/jobs.groovy b/.ci/jenkins/dsl/jobs.groovy index dbaab3b735..7ed896181a 100644 --- a/.ci/jenkins/dsl/jobs.groovy +++ b/.ci/jenkins/dsl/jobs.groovy @@ -193,7 +193,7 @@ void createSetupBranchJob() { GIT_AUTHOR_CREDS_ID: "${GIT_AUTHOR_CREDENTIALS_ID}", GIT_AUTHOR_PUSH_CREDS_ID: "${GIT_AUTHOR_PUSH_CREDENTIALS_ID}", - MAVEN_SETTINGS_CONFIG_FILE_ID: "${MAVEN_SETTINGS_FILE_ID}", + MAVEN_SETTINGS_CONFIG_FILE_ID: Utils.getMavenSettingsConfigFileId(this, JobType.NIGHTLY.name), IS_MAIN_BRANCH: "${Utils.isMainBranch(this)}" ]) @@ -220,10 +220,10 @@ void setupReleaseDeployJob() { GIT_AUTHOR_CREDS_ID: "${GIT_AUTHOR_CREDENTIALS_ID}", GIT_AUTHOR_PUSH_CREDS_ID: "${GIT_AUTHOR_PUSH_CREDENTIALS_ID}", - MAVEN_SETTINGS_CONFIG_FILE_ID: "${MAVEN_SETTINGS_FILE_ID}", + MAVEN_SETTINGS_CONFIG_FILE_ID: Utils.getMavenSettingsConfigFileId(this, JobType.RELEASE.name), MAVEN_DEPENDENCIES_REPOSITORY: "${MAVEN_ARTIFACTS_REPOSITORY}", - MAVEN_DEPLOY_REPOSITORY: "${MAVEN_ARTIFACTS_UPLOAD_REPOSITORY_URL}", - MAVEN_REPO_CREDS_ID: "${MAVEN_ARTIFACTS_UPLOAD_REPOSITORY_CREDS_ID}", + MAVEN_DEPLOY_REPOSITORY: Utils.getMavenArtifactsUploadRepositoryUrl(this, JobType.RELEASE.name), + MAVEN_REPO_CREDS_ID: Utils.getMavenArtifactsUploadRepositoryCredentialsId(this, JobType.RELEASE.name), RELEASE_GPG_SIGN_KEY_CREDS_ID: Utils.getReleaseGpgSignKeyCredentialsId(this), RELEASE_GPG_SIGN_PASSPHRASE_CREDS_ID: Utils.getReleaseGpgSignPassphraseCredentialsId(this) @@ -259,7 +259,7 @@ void setupReleasePromoteJob() { GIT_AUTHOR_CREDS_ID: "${GIT_AUTHOR_CREDENTIALS_ID}", GIT_AUTHOR_PUSH_CREDS_ID: "${GIT_AUTHOR_PUSH_CREDENTIALS_ID}", - MAVEN_SETTINGS_CONFIG_FILE_ID: "${MAVEN_SETTINGS_FILE_ID}", + MAVEN_SETTINGS_CONFIG_FILE_ID: Utils.getMavenSettingsConfigFileId(this, JobType.RELEASE.name), MAVEN_DEPENDENCIES_REPOSITORY: "${MAVEN_ARTIFACTS_REPOSITORY}", MAVEN_DEPLOY_REPOSITORY: "${MAVEN_ARTIFACTS_REPOSITORY}", ]) @@ -291,10 +291,10 @@ void setupWeeklyDeployJob() { GIT_AUTHOR_CREDS_ID: "${GIT_AUTHOR_CREDENTIALS_ID}", GIT_AUTHOR_PUSH_CREDS_ID: "${GIT_AUTHOR_PUSH_CREDENTIALS_ID}", - MAVEN_SETTINGS_CONFIG_FILE_ID: "${MAVEN_SETTINGS_FILE_ID}", + MAVEN_SETTINGS_CONFIG_FILE_ID: Utils.getMavenSettingsConfigFileId(this, JobType.NIGHTLY.name), MAVEN_DEPENDENCIES_REPOSITORY: "${MAVEN_ARTIFACTS_REPOSITORY}", - MAVEN_DEPLOY_REPOSITORY: "${MAVEN_ARTIFACTS_UPLOAD_REPOSITORY_URL}", - MAVEN_REPO_CREDS_ID: "${MAVEN_ARTIFACTS_UPLOAD_REPOSITORY_CREDS_ID}", + MAVEN_DEPLOY_REPOSITORY: Utils.getMavenArtifactsUploadRepositoryUrl(this, JobType.NIGHTLY.name), + MAVEN_REPO_CREDS_ID: Utils.getMavenArtifactsUploadRepositoryCredentialsId(this, JobType.NIGHTLY.name), ]) KogitoJobTemplate.createPipelineJob(this, jobParams)?.with { parameters { diff --git a/.github/workflows/publish-jitexecutor-native-rc.yml b/.github/workflows/publish-jitexecutor-native-rc.yml index e6893a814a..ff68a4dbf7 100644 --- a/.github/workflows/publish-jitexecutor-native-rc.yml +++ b/.github/workflows/publish-jitexecutor-native-rc.yml @@ -23,7 +23,7 @@ jobs: strategy: fail-fast: true matrix: - os: [ubuntu-latest, macos-latest, windows-latest] + os: [ubuntu-latest, macos-13, windows-latest] steps: - name: Set version diff --git a/.github/workflows/publish-jitexecutor-native.yml b/.github/workflows/publish-jitexecutor-native.yml index e11e964aa6..99d1cb8ee4 100644 --- a/.github/workflows/publish-jitexecutor-native.yml +++ b/.github/workflows/publish-jitexecutor-native.yml @@ -18,7 +18,7 @@ jobs: strategy: fail-fast: true matrix: - os: [ubuntu-latest, macos-latest, windows-latest] + os: [ubuntu-latest, macos-13, windows-latest] steps: - name: Get current date diff --git a/.mvn/wrapper/maven-wrapper.jar b/.mvn/wrapper/maven-wrapper.jar deleted file mode 100644 index bf82ff01c6..0000000000 Binary files a/.mvn/wrapper/maven-wrapper.jar and /dev/null differ 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-audit/data-audit-common-service/src/main/java/org/kie/kogito/app/audit/json/JsonProcessInstanceDataEventDeserializer.java b/data-audit/data-audit-common-service/src/main/java/org/kie/kogito/app/audit/json/JsonProcessInstanceDataEventDeserializer.java deleted file mode 100644 index de164e6ff3..0000000000 --- a/data-audit/data-audit-common-service/src/main/java/org/kie/kogito/app/audit/json/JsonProcessInstanceDataEventDeserializer.java +++ /dev/null @@ -1,79 +0,0 @@ -/* - * 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.app.audit.json; - -import java.io.IOException; - -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.ProcessInstanceNodeDataEvent; -import org.kie.kogito.event.process.ProcessInstanceSLADataEvent; -import org.kie.kogito.event.process.ProcessInstanceStateDataEvent; -import org.kie.kogito.event.process.ProcessInstanceVariableDataEvent; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import com.fasterxml.jackson.core.JsonParser; -import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.databind.DeserializationContext; -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.deser.std.StdDeserializer; - -public class JsonProcessInstanceDataEventDeserializer extends StdDeserializer> { - - private static final Logger LOGGER = LoggerFactory.getLogger(JsonProcessInstanceDataEventDeserializer.class); - - private static final long serialVersionUID = 6152014726577574241L; - - public JsonProcessInstanceDataEventDeserializer() { - this(null); - } - - public JsonProcessInstanceDataEventDeserializer(Class vc) { - super(vc); - } - - @Override - public ProcessInstanceDataEvent deserialize(JsonParser jp, DeserializationContext ctxt) - throws IOException, JsonProcessingException { - JsonNode node = jp.getCodec().readTree(jp); - LOGGER.debug("Deserialize process instance data event: {}", node); - String type = node.get("type").asText(); - - switch (type) { - case MultipleProcessInstanceDataEvent.TYPE: - return jp.getCodec().treeToValue(node, MultipleProcessInstanceDataEvent.class); - case "ProcessInstanceErrorDataEvent": - return (ProcessInstanceDataEvent) jp.getCodec().treeToValue(node, ProcessInstanceErrorDataEvent.class); - case "ProcessInstanceNodeDataEvent": - return (ProcessInstanceDataEvent) jp.getCodec().treeToValue(node, ProcessInstanceNodeDataEvent.class); - case "ProcessInstanceSLADataEvent": - return (ProcessInstanceDataEvent) jp.getCodec().treeToValue(node, ProcessInstanceSLADataEvent.class); - case "ProcessInstanceStateDataEvent": - return (ProcessInstanceDataEvent) jp.getCodec().treeToValue(node, ProcessInstanceStateDataEvent.class); - case "ProcessInstanceVariableDataEvent": - return (ProcessInstanceDataEvent) jp.getCodec().treeToValue(node, ProcessInstanceVariableDataEvent.class); - default: - LOGGER.warn("Unknown type {} in json data {}", type, node); - return (ProcessInstanceDataEvent) jp.getCodec().treeToValue(node, ProcessInstanceDataEvent.class); - - } - } -} \ No newline at end of file diff --git a/data-audit/data-audit-common-service/src/main/java/org/kie/kogito/app/audit/json/JsonUserTaskInstanceDataEventDeserializer.java b/data-audit/data-audit-common-service/src/main/java/org/kie/kogito/app/audit/json/JsonUserTaskInstanceDataEventDeserializer.java deleted file mode 100644 index 32e53e4f98..0000000000 --- a/data-audit/data-audit-common-service/src/main/java/org/kie/kogito/app/audit/json/JsonUserTaskInstanceDataEventDeserializer.java +++ /dev/null @@ -1,82 +0,0 @@ -/* - * 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.app.audit.json; - -import java.io.IOException; - -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; -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.UserTaskInstanceVariableDataEvent; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import com.fasterxml.jackson.core.JsonParser; -import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.databind.DeserializationContext; -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.deser.std.StdDeserializer; - -public class JsonUserTaskInstanceDataEventDeserializer extends StdDeserializer> { - - private static final Logger LOGGER = LoggerFactory.getLogger(JsonUserTaskInstanceDataEventDeserializer.class); - - private static final long serialVersionUID = -6626663191296012306L; - - public JsonUserTaskInstanceDataEventDeserializer() { - this(null); - } - - public JsonUserTaskInstanceDataEventDeserializer(Class vc) { - super(vc); - } - - @Override - public UserTaskInstanceDataEvent deserialize(JsonParser jp, DeserializationContext ctxt) - throws IOException, JsonProcessingException { - JsonNode node = jp.getCodec().readTree(jp); - LOGGER.debug("Deserialize user task instance data event: {}", node); - String type = node.get("type").asText(); - - switch (type) { - case MultipleUserTaskInstanceDataEvent.TYPE: - return jp.getCodec().treeToValue(node, MultipleUserTaskInstanceDataEvent.class); - case "UserTaskInstanceAssignmentDataEvent": - return (UserTaskInstanceDataEvent) jp.getCodec().treeToValue(node, UserTaskInstanceAssignmentDataEvent.class); - case "UserTaskInstanceAttachmentDataEvent": - return (UserTaskInstanceDataEvent) jp.getCodec().treeToValue(node, UserTaskInstanceAttachmentDataEvent.class); - case "UserTaskInstanceCommentDataEvent": - return (UserTaskInstanceDataEvent) jp.getCodec().treeToValue(node, UserTaskInstanceCommentDataEvent.class); - case "UserTaskInstanceDeadlineDataEvent": - return (UserTaskInstanceDataEvent) jp.getCodec().treeToValue(node, UserTaskInstanceDeadlineDataEvent.class); - case "UserTaskInstanceStateDataEvent": - return (UserTaskInstanceDataEvent) jp.getCodec().treeToValue(node, UserTaskInstanceStateDataEvent.class); - case "UserTaskInstanceVariableDataEvent": - return (UserTaskInstanceDataEvent) jp.getCodec().treeToValue(node, UserTaskInstanceVariableDataEvent.class); - default: - LOGGER.warn("Unknown type {} in json data {}", type, node); - return (UserTaskInstanceDataEvent) jp.getCodec().treeToValue(node, UserTaskInstanceDataEvent.class); - - } - } -} \ No newline at end of file diff --git a/data-audit/data-audit-common-service/src/main/java/org/kie/kogito/app/audit/json/JsonUtils.java b/data-audit/data-audit-common-service/src/main/java/org/kie/kogito/app/audit/json/JsonUtils.java index 52ece97fd5..3006244f04 100644 --- a/data-audit/data-audit-common-service/src/main/java/org/kie/kogito/app/audit/json/JsonUtils.java +++ b/data-audit/data-audit-common-service/src/main/java/org/kie/kogito/app/audit/json/JsonUtils.java @@ -19,13 +19,10 @@ package org.kie.kogito.app.audit.json; import org.kie.kogito.event.job.JobInstanceDataEvent; -import org.kie.kogito.event.process.ProcessInstanceDataEvent; -import org.kie.kogito.event.usertask.UserTaskInstanceDataEvent; import com.fasterxml.jackson.databind.DeserializationFeature; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.module.SimpleModule; -import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule; import io.cloudevents.jackson.JsonFormat; @@ -41,15 +38,7 @@ public static ObjectMapper getObjectMapper() { } public static ObjectMapper configure(ObjectMapper objectMapper) { - objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); - objectMapper.registerModule(JsonFormat.getCloudEventJacksonModule()); - objectMapper.registerModule(new JavaTimeModule()); - - SimpleModule module = new SimpleModule("Kogito Cloud Events"); - module.addDeserializer(ProcessInstanceDataEvent.class, new JsonProcessInstanceDataEventDeserializer()); - module.addDeserializer(UserTaskInstanceDataEvent.class, new JsonUserTaskInstanceDataEventDeserializer()); - module.addDeserializer(JobInstanceDataEvent.class, new JsonJobDataEventDeserializer()); - objectMapper.registerModule(module); - return objectMapper; + return objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false).registerModule(JsonFormat.getCloudEventJacksonModule()) + .registerModule(new SimpleModule("Data Audit").addDeserializer(JobInstanceDataEvent.class, new JsonJobDataEventDeserializer())).findAndRegisterModules(); } } 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/json/JsonProcessInstanceDataEventDeserializer.java b/data-index/data-index-common/src/main/java/org/kie/kogito/index/json/JsonProcessInstanceDataEventDeserializer.java deleted file mode 100644 index 261bcc4084..0000000000 --- a/data-index/data-index-common/src/main/java/org/kie/kogito/index/json/JsonProcessInstanceDataEventDeserializer.java +++ /dev/null @@ -1,79 +0,0 @@ -/* - * 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.index.json; - -import java.io.IOException; - -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.ProcessInstanceNodeDataEvent; -import org.kie.kogito.event.process.ProcessInstanceSLADataEvent; -import org.kie.kogito.event.process.ProcessInstanceStateDataEvent; -import org.kie.kogito.event.process.ProcessInstanceVariableDataEvent; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import com.fasterxml.jackson.core.JsonParser; -import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.databind.DeserializationContext; -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.deser.std.StdDeserializer; - -public class JsonProcessInstanceDataEventDeserializer extends StdDeserializer> { - - private static final Logger LOGGER = LoggerFactory.getLogger(JsonProcessInstanceDataEventDeserializer.class); - - private static final long serialVersionUID = 6152014726577574241L; - - public JsonProcessInstanceDataEventDeserializer() { - this(null); - } - - public JsonProcessInstanceDataEventDeserializer(Class vc) { - super(vc); - } - - @Override - public ProcessInstanceDataEvent deserialize(JsonParser jp, DeserializationContext ctxt) - throws IOException, JsonProcessingException { - JsonNode node = jp.getCodec().readTree(jp); - LOGGER.debug("Deserialize process instance data event: {}", node); - String type = node.get("type").asText(); - - switch (type) { - case MultipleProcessInstanceDataEvent.TYPE: - return jp.getCodec().treeToValue(node, MultipleProcessInstanceDataEvent.class); - case "ProcessInstanceErrorDataEvent": - return (ProcessInstanceDataEvent) jp.getCodec().treeToValue(node, ProcessInstanceErrorDataEvent.class); - case "ProcessInstanceNodeDataEvent": - return (ProcessInstanceDataEvent) jp.getCodec().treeToValue(node, ProcessInstanceNodeDataEvent.class); - case "ProcessInstanceSLADataEvent": - return (ProcessInstanceDataEvent) jp.getCodec().treeToValue(node, ProcessInstanceSLADataEvent.class); - case "ProcessInstanceStateDataEvent": - return (ProcessInstanceDataEvent) jp.getCodec().treeToValue(node, ProcessInstanceStateDataEvent.class); - case "ProcessInstanceVariableDataEvent": - return (ProcessInstanceDataEvent) jp.getCodec().treeToValue(node, ProcessInstanceVariableDataEvent.class); - default: - LOGGER.warn("Unknown type {} in json data {}", type, node); - return (ProcessInstanceDataEvent) jp.getCodec().treeToValue(node, ProcessInstanceDataEvent.class); - - } - } -} \ No newline at end of file diff --git a/data-index/data-index-common/src/main/java/org/kie/kogito/index/json/JsonUserTaskInstanceDataEventDeserializer.java b/data-index/data-index-common/src/main/java/org/kie/kogito/index/json/JsonUserTaskInstanceDataEventDeserializer.java deleted file mode 100644 index 3a515a5e8b..0000000000 --- a/data-index/data-index-common/src/main/java/org/kie/kogito/index/json/JsonUserTaskInstanceDataEventDeserializer.java +++ /dev/null @@ -1,82 +0,0 @@ -/* - * 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.index.json; - -import java.io.IOException; - -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; -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.UserTaskInstanceVariableDataEvent; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import com.fasterxml.jackson.core.JsonParser; -import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.databind.DeserializationContext; -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.deser.std.StdDeserializer; - -public class JsonUserTaskInstanceDataEventDeserializer extends StdDeserializer> { - - private static final Logger LOGGER = LoggerFactory.getLogger(JsonUserTaskInstanceDataEventDeserializer.class); - - private static final long serialVersionUID = -6626663191296012306L; - - public JsonUserTaskInstanceDataEventDeserializer() { - this(null); - } - - public JsonUserTaskInstanceDataEventDeserializer(Class vc) { - super(vc); - } - - @Override - public UserTaskInstanceDataEvent deserialize(JsonParser jp, DeserializationContext ctxt) - throws IOException, JsonProcessingException { - JsonNode node = jp.getCodec().readTree(jp); - LOGGER.debug("Deserialize user task instance data event: {}", node); - String type = node.get("type").asText(); - - switch (type) { - case MultipleUserTaskInstanceDataEvent.TYPE: - return jp.getCodec().treeToValue(node, MultipleUserTaskInstanceDataEvent.class); - case "UserTaskInstanceAssignmentDataEvent": - return (UserTaskInstanceDataEvent) jp.getCodec().treeToValue(node, UserTaskInstanceAssignmentDataEvent.class); - case "UserTaskInstanceAttachmentDataEvent": - return (UserTaskInstanceDataEvent) jp.getCodec().treeToValue(node, UserTaskInstanceAttachmentDataEvent.class); - case "UserTaskInstanceCommentDataEvent": - return (UserTaskInstanceDataEvent) jp.getCodec().treeToValue(node, UserTaskInstanceCommentDataEvent.class); - case "UserTaskInstanceDeadlineDataEvent": - return (UserTaskInstanceDataEvent) jp.getCodec().treeToValue(node, UserTaskInstanceDeadlineDataEvent.class); - case "UserTaskInstanceStateDataEvent": - return (UserTaskInstanceDataEvent) jp.getCodec().treeToValue(node, UserTaskInstanceStateDataEvent.class); - case "UserTaskInstanceVariableDataEvent": - return (UserTaskInstanceDataEvent) jp.getCodec().treeToValue(node, UserTaskInstanceVariableDataEvent.class); - default: - LOGGER.warn("Unknown type {} in json data {}", type, node); - return (UserTaskInstanceDataEvent) jp.getCodec().treeToValue(node, UserTaskInstanceDataEvent.class); - - } - } -} diff --git a/data-index/data-index-common/src/main/java/org/kie/kogito/index/json/JsonUtils.java b/data-index/data-index-common/src/main/java/org/kie/kogito/index/json/JsonUtils.java index 8dbf880581..c660fb31ce 100644 --- a/data-index/data-index-common/src/main/java/org/kie/kogito/index/json/JsonUtils.java +++ b/data-index/data-index-common/src/main/java/org/kie/kogito/index/json/JsonUtils.java @@ -18,17 +18,13 @@ */ package org.kie.kogito.index.json; -import org.kie.kogito.event.process.ProcessInstanceDataEvent; -import org.kie.kogito.event.usertask.UserTaskInstanceDataEvent; import org.kie.kogito.jackson.utils.JsonObjectUtils; import org.kie.kogito.jackson.utils.MergeUtils; import org.kie.kogito.jackson.utils.ObjectMapperFactory; import com.fasterxml.jackson.databind.DeserializationFeature; import com.fasterxml.jackson.databind.ObjectMapper; -import com.fasterxml.jackson.databind.module.SimpleModule; import com.fasterxml.jackson.databind.node.ObjectNode; -import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule; import io.cloudevents.jackson.JsonFormat; @@ -44,15 +40,7 @@ public static ObjectMapper getObjectMapper() { } public static ObjectMapper configure(ObjectMapper objectMapper) { - objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); - objectMapper.registerModule(JsonFormat.getCloudEventJacksonModule()); - objectMapper.registerModule(new JavaTimeModule()); - - SimpleModule module = new SimpleModule("Kogito Cloud Events"); - module.addDeserializer(ProcessInstanceDataEvent.class, new JsonProcessInstanceDataEventDeserializer()); - module.addDeserializer(UserTaskInstanceDataEvent.class, new JsonUserTaskInstanceDataEventDeserializer()); - objectMapper.registerModule(module); - return objectMapper; + return objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false).registerModule(JsonFormat.getCloudEventJacksonModule()).findAndRegisterModules(); } public static ObjectNode mergeVariable(String variableName, Object variableValue, ObjectNode variables) { 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-common/src/test/java/org/kie/kogito/index/event/DataEventDeserializerTest.java b/data-index/data-index-common/src/test/java/org/kie/kogito/index/event/DataEventDeserializerTest.java index 03f4625fc4..80b4ae9c66 100644 --- a/data-index/data-index-common/src/test/java/org/kie/kogito/index/event/DataEventDeserializerTest.java +++ b/data-index/data-index-common/src/test/java/org/kie/kogito/index/event/DataEventDeserializerTest.java @@ -44,8 +44,7 @@ public class DataEventDeserializerTest { @BeforeAll public void beforeAll() { - mapper = new ObjectMapper(); - JsonUtils.configure(mapper); + mapper = JsonUtils.configure(new ObjectMapper()); } @Test diff --git a/data-index/data-index-graphql/src/main/java/org/kie/kogito/index/graphql/GraphQLInstrumentation.java b/data-index/data-index-graphql/src/main/java/org/kie/kogito/index/graphql/GraphQLInstrumentation.java index a479318c7b..65b3b82b66 100644 --- a/data-index/data-index-graphql/src/main/java/org/kie/kogito/index/graphql/GraphQLInstrumentation.java +++ b/data-index/data-index-graphql/src/main/java/org/kie/kogito/index/graphql/GraphQLInstrumentation.java @@ -20,6 +20,7 @@ import com.fasterxml.jackson.databind.JsonNode; +import graphql.execution.instrumentation.InstrumentationState; import graphql.execution.instrumentation.SimpleInstrumentation; import graphql.execution.instrumentation.parameters.InstrumentationExecutionParameters; import graphql.execution.instrumentation.parameters.InstrumentationFieldFetchParameters; @@ -36,7 +37,7 @@ public class GraphQLInstrumentation extends SimpleInstrumentation { GraphQLSchemaManager manager; @Override - public DataFetcher instrumentDataFetcher(DataFetcher dataFetcher, InstrumentationFieldFetchParameters parameters) { + public DataFetcher instrumentDataFetcher(DataFetcher dataFetcher, InstrumentationFieldFetchParameters parameters, InstrumentationState instrumentationState) { if (parameters.getEnvironment().getSource() instanceof JsonNode && dataFetcher instanceof PropertyDataFetcher) { return new JsonPropertyDataFetcher(); } else { @@ -45,7 +46,7 @@ public DataFetcher instrumentDataFetcher(DataFetcher dataFetcher, Instrume } @Override - public GraphQLSchema instrumentSchema(GraphQLSchema schema, InstrumentationExecutionParameters parameters) { + public GraphQLSchema instrumentSchema(GraphQLSchema schema, InstrumentationExecutionParameters parameters, InstrumentationState instrumentationState) { return manager.getGraphQLSchema(); } } 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/main/java/org/kie/kogito/index/service/messaging/KogitoIndexEventConverter.java b/data-index/data-index-service/data-index-service-common/src/main/java/org/kie/kogito/index/service/messaging/KogitoIndexEventConverter.java index cef45271e0..0b29028820 100644 --- a/data-index/data-index-service/data-index-service-common/src/main/java/org/kie/kogito/index/service/messaging/KogitoIndexEventConverter.java +++ b/data-index/data-index-service/data-index-service-common/src/main/java/org/kie/kogito/index/service/messaging/KogitoIndexEventConverter.java @@ -21,11 +21,13 @@ import java.io.IOException; import java.lang.reflect.Type; import java.util.Collection; -import java.util.function.Supplier; import org.eclipse.microprofile.reactive.messaging.Message; -import org.kie.kogito.event.AbstractDataEvent; +import org.kie.kogito.event.Converter; import org.kie.kogito.event.DataEvent; +import org.kie.kogito.event.DataEventFactory; +import org.kie.kogito.event.impl.JacksonCloudEventDataConverter; +import org.kie.kogito.event.impl.JacksonTypeCloudEventDataConverter; import org.kie.kogito.event.process.MultipleProcessInstanceDataEvent; import org.kie.kogito.event.process.ProcessDefinitionDataEvent; import org.kie.kogito.event.process.ProcessDefinitionEventBody; @@ -40,6 +42,7 @@ import org.kie.kogito.event.process.ProcessInstanceStateEventBody; import org.kie.kogito.event.process.ProcessInstanceVariableDataEvent; import org.kie.kogito.event.process.ProcessInstanceVariableEventBody; +import org.kie.kogito.event.serializer.MultipleProcessDataInstanceConverterFactory; import org.kie.kogito.event.usertask.MultipleUserTaskInstanceDataEvent; import org.kie.kogito.event.usertask.UserTaskInstanceAssignmentDataEvent; import org.kie.kogito.event.usertask.UserTaskInstanceAssignmentEventBody; @@ -64,6 +67,7 @@ import com.fasterxml.jackson.databind.ObjectMapper; import io.cloudevents.CloudEvent; +import io.cloudevents.CloudEventData; import io.cloudevents.core.message.MessageReader; import io.cloudevents.http.vertx.VertxMessageFactory; import io.quarkus.reactivemessaging.http.runtime.IncomingHttpMetadata; @@ -71,6 +75,7 @@ import io.vertx.core.MultiMap; import io.vertx.core.buffer.Buffer; +import jakarta.annotation.PostConstruct; import jakarta.enterprise.context.ApplicationScoped; import jakarta.inject.Inject; @@ -90,6 +95,38 @@ public int getPriority() { return CONVERTER_DEFAULT_PRIORITY - 2; } + private Converter errorConverter; + private Converter nodeConverter; + private Converter slaConverter; + private Converter varConverter; + private Converter stateConverter; + private Converter assignConverter; + private Converter attachConverter; + private Converter commentConverter; + private Converter deadlineConverter; + private Converter taskStateConverter; + private Converter taskVariableConverter; + private Converter>> taskCollectionConverter; + private Converter definitionConverter; + + @PostConstruct + void init() { + this.errorConverter = new JacksonCloudEventDataConverter<>(objectMapper, ProcessInstanceErrorEventBody.class); + this.nodeConverter = new JacksonCloudEventDataConverter<>(objectMapper, ProcessInstanceNodeEventBody.class); + this.slaConverter = new JacksonCloudEventDataConverter<>(objectMapper, ProcessInstanceSLAEventBody.class); + this.varConverter = new JacksonCloudEventDataConverter<>(objectMapper, ProcessInstanceVariableEventBody.class); + this.stateConverter = new JacksonCloudEventDataConverter<>(objectMapper, ProcessInstanceStateEventBody.class); + this.assignConverter = new JacksonCloudEventDataConverter<>(objectMapper, UserTaskInstanceAssignmentEventBody.class); + this.attachConverter = new JacksonCloudEventDataConverter<>(objectMapper, UserTaskInstanceAttachmentEventBody.class); + this.commentConverter = new JacksonCloudEventDataConverter<>(objectMapper, UserTaskInstanceCommentEventBody.class); + this.deadlineConverter = new JacksonCloudEventDataConverter<>(objectMapper, UserTaskInstanceDeadlineEventBody.class); + this.taskStateConverter = new JacksonCloudEventDataConverter<>(objectMapper, UserTaskInstanceStateEventBody.class); + this.taskVariableConverter = new JacksonCloudEventDataConverter<>(objectMapper, UserTaskInstanceVariableEventBody.class); + this.taskCollectionConverter = new JacksonTypeCloudEventDataConverter<>(objectMapper, new TypeReference>>() { + }); + this.definitionConverter = new JacksonCloudEventDataConverter<>(objectMapper, ProcessDefinitionEventBody.class); + } + @Override public boolean canConvert(Message message, Type type) { return isIndexable(type) && @@ -133,12 +170,7 @@ public Message convert(Message message, Type type) { } private ProcessDefinitionDataEvent buildProcessDefinitionEvent(CloudEvent cloudEvent) throws IOException { - ProcessDefinitionDataEvent event = new ProcessDefinitionDataEvent(); - applyCloudEventAttributes(cloudEvent, event); - if (cloudEvent.getData() != null) { - event.setData(objectMapper.readValue(cloudEvent.getData().toBytes(), ProcessDefinitionEventBody.class)); - } - return event; + return DataEventFactory.from(new ProcessDefinitionDataEvent(), cloudEvent, definitionConverter); } @Inject @@ -148,19 +180,18 @@ public void setObjectMapper(ObjectMapper objectMapper) { private DataEvent buildProcessInstanceDataEventVariant(CloudEvent cloudEvent) throws IOException { switch (cloudEvent.getType()) { - case MultipleProcessInstanceDataEvent.TYPE: - return buildDataEvent(cloudEvent, objectMapper, MultipleProcessInstanceDataEvent::new, new TypeReference>>() { - }); - case "ProcessInstanceErrorDataEvent": - return buildDataEvent(cloudEvent, objectMapper, ProcessInstanceErrorDataEvent::new, ProcessInstanceErrorEventBody.class); - case "ProcessInstanceNodeDataEvent": - return buildDataEvent(cloudEvent, objectMapper, ProcessInstanceNodeDataEvent::new, ProcessInstanceNodeEventBody.class); - case "ProcessInstanceSLADataEvent": - return buildDataEvent(cloudEvent, objectMapper, ProcessInstanceSLADataEvent::new, ProcessInstanceSLAEventBody.class); - case "ProcessInstanceStateDataEvent": - return buildDataEvent(cloudEvent, objectMapper, ProcessInstanceStateDataEvent::new, ProcessInstanceStateEventBody.class); - case "ProcessInstanceVariableDataEvent": - return buildDataEvent(cloudEvent, objectMapper, ProcessInstanceVariableDataEvent::new, ProcessInstanceVariableEventBody.class); + case MultipleProcessInstanceDataEvent.MULTIPLE_TYPE: + return DataEventFactory.from(new MultipleProcessInstanceDataEvent(), cloudEvent, MultipleProcessDataInstanceConverterFactory.fromCloudEvent(cloudEvent, objectMapper)); + case ProcessInstanceErrorDataEvent.ERROR_TYPE: + return DataEventFactory.from(new ProcessInstanceErrorDataEvent(), cloudEvent, errorConverter); + case ProcessInstanceNodeDataEvent.NODE_TYPE: + return DataEventFactory.from(new ProcessInstanceNodeDataEvent(), cloudEvent, nodeConverter); + case ProcessInstanceSLADataEvent.SLA_TYPE: + return DataEventFactory.from(new ProcessInstanceSLADataEvent(), cloudEvent, slaConverter); + case ProcessInstanceStateDataEvent.STATE_TYPE: + return DataEventFactory.from(new ProcessInstanceStateDataEvent(), cloudEvent, stateConverter); + case ProcessInstanceVariableDataEvent.VAR_TYPE: + return DataEventFactory.from(new ProcessInstanceVariableDataEvent(), cloudEvent, varConverter); default: throw new IllegalArgumentException("Unknown ProcessInstanceDataEvent variant: " + cloudEvent.getType()); } @@ -169,20 +200,19 @@ private DataEvent buildProcessInstanceDataEventVariant(CloudEvent cloudEvent) private DataEvent buildUserTaskInstanceDataEvent(CloudEvent cloudEvent) throws IOException { switch (cloudEvent.getType()) { case MultipleUserTaskInstanceDataEvent.TYPE: - return buildDataEvent(cloudEvent, objectMapper, MultipleUserTaskInstanceDataEvent::new, new TypeReference>>() { - }); + return DataEventFactory.from(new MultipleUserTaskInstanceDataEvent(), cloudEvent, taskCollectionConverter); case "UserTaskInstanceAssignmentDataEvent": - return buildDataEvent(cloudEvent, objectMapper, UserTaskInstanceAssignmentDataEvent::new, UserTaskInstanceAssignmentEventBody.class); + return DataEventFactory.from(new UserTaskInstanceAssignmentDataEvent(), cloudEvent, assignConverter); case "UserTaskInstanceAttachmentDataEvent": - return buildDataEvent(cloudEvent, objectMapper, UserTaskInstanceAttachmentDataEvent::new, UserTaskInstanceAttachmentEventBody.class); + return DataEventFactory.from(new UserTaskInstanceAttachmentDataEvent(), cloudEvent, attachConverter); case "UserTaskInstanceCommentDataEvent": - return buildDataEvent(cloudEvent, objectMapper, UserTaskInstanceCommentDataEvent::new, UserTaskInstanceCommentEventBody.class); + return DataEventFactory.from(new UserTaskInstanceCommentDataEvent(), cloudEvent, commentConverter); case "UserTaskInstanceDeadlineDataEvent": - return buildDataEvent(cloudEvent, objectMapper, UserTaskInstanceDeadlineDataEvent::new, UserTaskInstanceDeadlineEventBody.class); + return DataEventFactory.from(new UserTaskInstanceDeadlineDataEvent(), cloudEvent, deadlineConverter); case "UserTaskInstanceStateDataEvent": - return buildDataEvent(cloudEvent, objectMapper, UserTaskInstanceStateDataEvent::new, UserTaskInstanceStateEventBody.class); + return DataEventFactory.from(new UserTaskInstanceStateDataEvent(), cloudEvent, taskStateConverter); case "UserTaskInstanceVariableDataEvent": - return buildDataEvent(cloudEvent, objectMapper, UserTaskInstanceVariableDataEvent::new, UserTaskInstanceVariableEventBody.class); + return DataEventFactory.from(new UserTaskInstanceVariableDataEvent(), cloudEvent, taskVariableConverter); default: throw new IllegalArgumentException("Unknown UserTaskInstanceDataEvent variant: " + cloudEvent.getType()); } @@ -203,41 +233,4 @@ private KogitoJobCloudEvent buildKogitoJobCloudEvent(CloudEvent cloudEvent) thro return jobCloudEvent; } - private static , T> E buildDataEvent(CloudEvent cloudEvent, ObjectMapper objectMapper, Supplier supplier, TypeReference typeReference) throws IOException { - E dataEvent = buildEvent(cloudEvent, objectMapper, supplier); - if (cloudEvent.getData() != null) { - dataEvent.setData(objectMapper.readValue(cloudEvent.getData().toBytes(), typeReference)); - } - return dataEvent; - } - - private static , T> E buildDataEvent(CloudEvent cloudEvent, ObjectMapper objectMapper, Supplier supplier, Class clazz) throws IOException { - E dataEvent = buildEvent(cloudEvent, objectMapper, supplier); - if (cloudEvent.getData() != null) { - dataEvent.setData(objectMapper.readValue(cloudEvent.getData().toBytes(), clazz)); - } - return dataEvent; - } - - private static > E buildEvent(CloudEvent cloudEvent, ObjectMapper objectMapper, Supplier supplier) throws IOException { - E dataEvent = supplier.get(); - applyCloudEventAttributes(cloudEvent, dataEvent); - applyExtensions(cloudEvent, dataEvent); - return dataEvent; - } - - private static void applyCloudEventAttributes(CloudEvent cloudEvent, AbstractDataEvent dataEvent) { - dataEvent.setSpecVersion(cloudEvent.getSpecVersion()); - dataEvent.setId(cloudEvent.getId()); - dataEvent.setType(cloudEvent.getType()); - dataEvent.setSource(cloudEvent.getSource()); - dataEvent.setDataContentType(cloudEvent.getDataContentType()); - dataEvent.setDataSchema(cloudEvent.getDataSchema()); - dataEvent.setSubject(cloudEvent.getSubject()); - dataEvent.setTime(cloudEvent.getTime()); - } - - private static void applyExtensions(CloudEvent cloudEvent, AbstractDataEvent dataEvent) { - cloudEvent.getExtensionNames().forEach(extensionName -> dataEvent.addExtensionAttribute(extensionName, cloudEvent.getExtension(extensionName))); - } } diff --git a/data-index/data-index-service/data-index-service-common/src/main/resources/META-INF/microprofile-config.properties b/data-index/data-index-service/data-index-service-common/src/main/resources/META-INF/microprofile-config.properties index 15ec93572e..331e25555d 100644 --- a/data-index/data-index-service/data-index-service-common/src/main/resources/META-INF/microprofile-config.properties +++ b/data-index/data-index-service/data-index-service-common/src/main/resources/META-INF/microprofile-config.properties @@ -17,15 +17,6 @@ # under the License. # -# Quarkus -quarkus.log.level=INFO -quarkus.log.console.enable=true -quarkus.log.console.level=INFO -quarkus.log.category."org.kie.kogito".level=INFO -#quarkus.log.category."io.vertx".level=INFO -quarkus.log.category."graphql".level=INFO -quarkus.log.category."org.apache.kafka".level=INFO - # Quarkus HTTP quarkus.http.port=8180 quarkus.http.test-port=8181 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-common/src/test/java/org/kie/kogito/index/service/messaging/AbstractMessagingHttpConsumerIT.java b/data-index/data-index-service/data-index-service-common/src/test/java/org/kie/kogito/index/service/messaging/AbstractMessagingHttpConsumerIT.java index d9a1364fcf..6513658fbf 100644 --- a/data-index/data-index-service/data-index-service-common/src/test/java/org/kie/kogito/index/service/messaging/AbstractMessagingHttpConsumerIT.java +++ b/data-index/data-index-service/data-index-service-common/src/test/java/org/kie/kogito/index/service/messaging/AbstractMessagingHttpConsumerIT.java @@ -22,6 +22,7 @@ import java.util.Collection; import java.util.List; +import org.kie.kogito.event.process.KogitoMarshallEventSupport; import org.kie.kogito.event.process.MultipleProcessInstanceDataEvent; import org.kie.kogito.event.process.ProcessDefinitionDataEvent; import org.kie.kogito.event.process.ProcessInstanceDataEvent; @@ -76,7 +77,7 @@ protected void sendJobEvent() throws Exception { } protected void sendProcessInstanceEventCollection() throws Exception { - Collection> events = List.of( + Collection> events = List.of( getProcessCloudEvent("travels", "processId-UUID1", ProcessInstanceState.ACTIVE, null, null, null, "user1"), getProcessCloudEvent("travels", "processId-UUID2", ProcessInstanceState.ACTIVE, null, null, null, "user2")); connector.source(KOGITO_PROCESSINSTANCES_EVENTS).send(new MultipleProcessInstanceDataEvent(URI.create("test"), events)); diff --git a/data-index/data-index-service/data-index-service-common/src/test/java/org/kie/kogito/index/service/messaging/AbstractMessagingKafkaConsumerIT.java b/data-index/data-index-service/data-index-service-common/src/test/java/org/kie/kogito/index/service/messaging/AbstractMessagingKafkaConsumerIT.java index c8091f1ee0..fd85d8dfeb 100644 --- a/data-index/data-index-service/data-index-service-common/src/test/java/org/kie/kogito/index/service/messaging/AbstractMessagingKafkaConsumerIT.java +++ b/data-index/data-index-service/data-index-service-common/src/test/java/org/kie/kogito/index/service/messaging/AbstractMessagingKafkaConsumerIT.java @@ -25,6 +25,7 @@ import org.eclipse.microprofile.config.inject.ConfigProperty; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; +import org.kie.kogito.event.process.KogitoMarshallEventSupport; import org.kie.kogito.event.process.MultipleProcessInstanceDataEvent; import org.kie.kogito.event.process.ProcessInstanceDataEvent; import org.kie.kogito.event.usertask.MultipleUserTaskInstanceDataEvent; @@ -81,7 +82,7 @@ protected void sendJobEvent() throws Exception { @Override protected void sendProcessInstanceEventCollection() throws Exception { - Collection> events = List.of( + Collection> events = List.of( getProcessCloudEvent("travels", "processId-UUID1", ProcessInstanceState.ACTIVE, null, null, null, "user1"), getProcessCloudEvent("travels", "processId-UUID2", ProcessInstanceState.ACTIVE, null, null, null, "user2")); kafkaClient.produce(ObjectMapperFactory.get().writeValueAsString(new MultipleProcessInstanceDataEvent(URI.create("test"), events)), KOGITO_PROCESSINSTANCES_EVENTS); diff --git a/data-index/data-index-service/data-index-service-common/src/test/java/org/kie/kogito/index/service/messaging/BlockingMessagingEventConsumerTest.java b/data-index/data-index-service/data-index-service-common/src/test/java/org/kie/kogito/index/service/messaging/BlockingMessagingEventConsumerTest.java index c8ac500d96..5fce1f4c80 100644 --- a/data-index/data-index-service/data-index-service-common/src/test/java/org/kie/kogito/index/service/messaging/BlockingMessagingEventConsumerTest.java +++ b/data-index/data-index-service/data-index-service-common/src/test/java/org/kie/kogito/index/service/messaging/BlockingMessagingEventConsumerTest.java @@ -28,6 +28,7 @@ import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import org.kie.kogito.event.DataEvent; +import org.kie.kogito.event.process.KogitoMarshallEventSupport; import org.kie.kogito.event.process.MultipleProcessInstanceDataEvent; import org.kie.kogito.event.process.ProcessDefinitionDataEvent; import org.kie.kogito.event.process.ProcessInstanceDataEvent; @@ -70,9 +71,9 @@ void setUp() { @Test void testOnProcessInstanceEvent() { // Arrange - ProcessInstanceDataEvent event1 = mock(ProcessInstanceDataEvent.class); - ProcessInstanceDataEvent event2 = mock(ProcessInstanceDataEvent.class); - Collection> events = Arrays.asList(event1, event2); + ProcessInstanceDataEvent event1 = mock(ProcessInstanceDataEvent.class); + ProcessInstanceDataEvent event2 = mock(ProcessInstanceDataEvent.class); + Collection> events = Arrays.asList(event1, event2); MultipleProcessInstanceDataEvent event = new MultipleProcessInstanceDataEvent(URI.create("dummy"), events); // Act @@ -129,8 +130,8 @@ void testOnProcessDefinitionDataEvent() { @Test void testErrorHandlingInOnProcessInstanceEvent() { // Arrange - ProcessInstanceDataEvent event = mock(ProcessInstanceDataEvent.class); - Collection> events = Arrays.asList(event); + ProcessInstanceDataEvent event = mock(ProcessInstanceDataEvent.class); + Collection> events = Arrays.asList(event); doThrow(new RuntimeException("On purpose! Indexing failed")).when(indexingService).indexProcessInstanceEvent(event); // Act diff --git a/data-index/data-index-service/data-index-service-common/src/test/java/org/kie/kogito/index/service/messaging/KogitoIndexEventConverterTest.java b/data-index/data-index-service/data-index-service-common/src/test/java/org/kie/kogito/index/service/messaging/KogitoIndexEventConverterTest.java index c9ce83ace9..d4bfb38dc7 100644 --- a/data-index/data-index-service/data-index-service-common/src/test/java/org/kie/kogito/index/service/messaging/KogitoIndexEventConverterTest.java +++ b/data-index/data-index-service/data-index-service-common/src/test/java/org/kie/kogito/index/service/messaging/KogitoIndexEventConverterTest.java @@ -101,6 +101,7 @@ void setUp() { ObjectMapper objectMapper = JsonUtils.getObjectMapper(); new ObjectMapperProducer().customize(objectMapper); converter.setObjectMapper(objectMapper); + converter.init(); } @Test 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..d7b4b2778f 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 @@ -28,12 +28,13 @@ quarkus.datasource.db-kind=postgresql #Flyway - It's safe to enable Flyway by default for in-memory storage quarkus.flyway.migrate-at-start=true quarkus.flyway.baseline-on-migrate=true -quarkus.flyway.locations=classpath:kie-flyway/db/data-index/postgresql +quarkus.flyway.locations=classpath:kie-flyway/db/data-index/postgresql,classpath:kie-flyway/db/persistence-commons/postgresql #Hibernate 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-service/data-index-service-postgresql/src/main/resources/application.properties b/data-index/data-index-service/data-index-service-postgresql/src/main/resources/application.properties index 4b9e5a219e..acd24a5c60 100644 --- a/data-index/data-index-service/data-index-service-postgresql/src/main/resources/application.properties +++ b/data-index/data-index-service/data-index-service-postgresql/src/main/resources/application.properties @@ -38,4 +38,4 @@ quarkus.container-image.group=org.kie.kogito quarkus.jib.jvm-arguments=-Dquarkus.http.port=8080 # Flyway Locations -quarkus.flyway.locations=classpath:kie-flyway/db/data-index/postgresql \ No newline at end of file +quarkus.flyway.locations=classpath:kie-flyway/db/data-index/postgresql,classpath:kie-flyway/db/persistence-commons/postgresql \ No newline at end of file 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(), 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-common/src/test/java/org/kie/kogito/index/jpa/storage/AbstractProcessInstanceStorageIT.java b/data-index/data-index-storage/data-index-storage-jpa-common/src/test/java/org/kie/kogito/index/jpa/storage/AbstractProcessInstanceStorageIT.java index 1ea09ce497..b60f7ed300 100644 --- a/data-index/data-index-storage/data-index-storage-jpa-common/src/test/java/org/kie/kogito/index/jpa/storage/AbstractProcessInstanceStorageIT.java +++ b/data-index/data-index-storage/data-index-storage-jpa-common/src/test/java/org/kie/kogito/index/jpa/storage/AbstractProcessInstanceStorageIT.java @@ -20,29 +20,158 @@ import java.util.UUID; -import org.apache.commons.lang3.RandomStringUtils; +import org.assertj.core.api.Assertions; import org.junit.jupiter.api.Test; -import org.kie.kogito.index.jpa.model.ProcessInstanceEntityRepository; +import org.kie.kogito.event.process.ProcessInstanceNodeEventBody; +import org.kie.kogito.index.model.ProcessInstance; import org.kie.kogito.index.model.ProcessInstanceState; import org.kie.kogito.index.test.TestUtils; import jakarta.inject.Inject; +import jakarta.transaction.Transactional; public abstract class AbstractProcessInstanceStorageIT { + private static final String PROCESS_ID = "travels"; + private static final String TRAVELER_NAME = "John"; + private static final String TRAVELER_LAST_NAME = "Doe"; @Inject - ProcessInstanceEntityRepository repository; + ProcessInstanceEntityStorage storage; @Test - public void testProcessInstanceEntity() { + @Transactional + public void testProcessInstanceStateEvent() { + String processInstanceId = createNewProcessInstance(); + + ProcessInstance processInstance = storage.get(processInstanceId); + Assertions.assertThat(processInstance) + .isNotNull() + .hasFieldOrPropertyWithValue("id", processInstanceId) + .hasFieldOrPropertyWithValue("processId", PROCESS_ID) + .hasFieldOrPropertyWithValue("state", ProcessInstanceState.ACTIVE.ordinal()) + .hasFieldOrPropertyWithValue("rootProcessInstanceId", null) + .hasFieldOrPropertyWithValue("rootProcessId", null) + .hasFieldOrPropertyWithValue("variables", null); + + storage.indexState(TestUtils.createProcessInstanceEvent(processInstanceId, PROCESS_ID, null, null, ProcessInstanceState.COMPLETED.ordinal())); + + processInstance = storage.get(processInstanceId); + Assertions.assertThat(processInstance) + .isNotNull() + .hasFieldOrPropertyWithValue("id", processInstanceId) + .hasFieldOrPropertyWithValue("processId", PROCESS_ID) + .hasFieldOrPropertyWithValue("state", ProcessInstanceState.COMPLETED.ordinal()) + .hasFieldOrPropertyWithValue("rootProcessInstanceId", null) + .hasFieldOrPropertyWithValue("rootProcessId", null) + .hasFieldOrPropertyWithValue("variables", null); + } + + @Test + @Transactional + public void testProcessInstanceErrorEvent() { + String processInstanceId = createNewProcessInstance(); + + ProcessInstance processInstance = storage.get(processInstanceId); + + Assertions.assertThat(processInstance.getError()) + .isNull(); + + String nodeDefinitionId = UUID.randomUUID().toString(); + storage.indexError(TestUtils.createProcessInstanceErrorDataEvent(processInstanceId, PROCESS_ID, TRAVELER_NAME, "This is really wrong", nodeDefinitionId, UUID.randomUUID().toString())); + + processInstance = storage.get(processInstanceId); + + Assertions.assertThat(processInstance.getError()) + .isNotNull() + .hasFieldOrPropertyWithValue("nodeDefinitionId", nodeDefinitionId) + .hasFieldOrPropertyWithValue("message", "This is really wrong"); + } + + @Test + @Transactional + public void testProcessInstanceNodeEvent() { + String processInstanceId = createNewProcessInstance(); + + ProcessInstance processInstance = storage.get(processInstanceId); + + Assertions.assertThat(processInstance.getNodes()) + .isEmpty(); + + String nodeDefinitionId = UUID.randomUUID().toString(); + String nodeInstanceId = UUID.randomUUID().toString(); + + storage.indexNode(TestUtils.createProcessInstanceNodeDataEvent(processInstanceId, PROCESS_ID, nodeDefinitionId, nodeInstanceId, "nodeName", "BoundaryEventNode", + ProcessInstanceNodeEventBody.EVENT_TYPE_ENTER)); + + processInstance = storage.get(processInstanceId); + + Assertions.assertThat(processInstance.getNodes()) + .hasSize(1); + + Assertions.assertThat(processInstance.getNodes().get(0)) + .hasNoNullFieldsOrPropertiesExcept("exit") + .hasFieldOrPropertyWithValue("name", "nodeName") + .hasFieldOrPropertyWithValue("type", "BoundaryEventNode") + .hasFieldOrPropertyWithValue("definitionId", nodeDefinitionId) + .hasFieldOrPropertyWithValue("nodeId", nodeDefinitionId) + .hasFieldOrPropertyWithValue("id", nodeInstanceId); + + storage.indexNode(TestUtils.createProcessInstanceNodeDataEvent(processInstanceId, PROCESS_ID, nodeDefinitionId, nodeInstanceId, "nodeName", "BoundaryEventNode", + ProcessInstanceNodeEventBody.EVENT_TYPE_EXIT)); + + processInstance = storage.get(processInstanceId); + + Assertions.assertThat(processInstance.getNodes()) + .hasSize(1); + + Assertions.assertThat(processInstance.getNodes().get(0)) + .hasNoNullFieldsOrProperties() + .hasFieldOrPropertyWithValue("name", "nodeName") + .hasFieldOrPropertyWithValue("type", "BoundaryEventNode") + .hasFieldOrPropertyWithValue("definitionId", nodeDefinitionId) + .hasFieldOrPropertyWithValue("nodeId", nodeDefinitionId) + .hasFieldOrPropertyWithValue("id", nodeInstanceId); + } + + @Test + @Transactional + public void testProcessInstanceVariableEvent() { + String processInstanceId = createNewProcessInstance(); + + ProcessInstance processInstance = storage.get(processInstanceId); + + Assertions.assertThat(processInstance.getVariables()) + .isNull(); + + storage.indexVariable(TestUtils.createProcessInstanceVariableEvent(processInstanceId, PROCESS_ID, TRAVELER_NAME, TRAVELER_LAST_NAME)); + + processInstance = storage.get(processInstanceId); + + Assertions.assertThatObject(processInstance.getVariables()) + .isNotNull() + .extracting(jsonNodes -> jsonNodes.at("/traveller/firstName").asText(), jsonNodes -> jsonNodes.at("/traveller/lastName").asText()) + .contains(TRAVELER_NAME, TRAVELER_LAST_NAME); + } + + private String createNewProcessInstance() { String processInstanceId = UUID.randomUUID().toString(); - TestUtils - .createProcessInstance(processInstanceId, RandomStringUtils.randomAlphabetic(5), UUID.randomUUID().toString(), - RandomStringUtils.randomAlphabetic(10), ProcessInstanceState.ACTIVE.ordinal(), 0L); - TestUtils - .createProcessInstance(processInstanceId, RandomStringUtils.randomAlphabetic(5), UUID.randomUUID().toString(), - RandomStringUtils.randomAlphabetic(10), ProcessInstanceState.COMPLETED.ordinal(), 1000L); + Assertions.assertThat(storage.get(processInstanceId)) + .isNull(); + + storage.indexState(TestUtils.createProcessInstanceEvent(processInstanceId, PROCESS_ID, null, null, ProcessInstanceState.ACTIVE.ordinal())); + + ProcessInstance processInstance = storage.get(processInstanceId); + Assertions.assertThat(processInstance) + .isNotNull() + .hasFieldOrPropertyWithValue("id", processInstanceId) + .hasFieldOrPropertyWithValue("processId", PROCESS_ID) + .hasFieldOrPropertyWithValue("state", ProcessInstanceState.ACTIVE.ordinal()) + .hasFieldOrPropertyWithValue("rootProcessInstanceId", null) + .hasFieldOrPropertyWithValue("rootProcessId", null) + .hasFieldOrPropertyWithValue("variables", null); + + return processInstanceId; } } diff --git a/data-index/data-index-storage/data-index-storage-jpa-common/src/test/java/org/kie/kogito/index/jpa/storage/AbstractUserTaskInstanceStorageIT.java b/data-index/data-index-storage/data-index-storage-jpa-common/src/test/java/org/kie/kogito/index/jpa/storage/AbstractUserTaskInstanceStorageIT.java index 9b8c0056c9..d44d534955 100644 --- a/data-index/data-index-storage/data-index-storage-jpa-common/src/test/java/org/kie/kogito/index/jpa/storage/AbstractUserTaskInstanceStorageIT.java +++ b/data-index/data-index-storage/data-index-storage-jpa-common/src/test/java/org/kie/kogito/index/jpa/storage/AbstractUserTaskInstanceStorageIT.java @@ -18,19 +18,226 @@ */ package org.kie.kogito.index.jpa.storage; -import java.util.UUID; +import java.net.URI; +import java.util.*; import org.apache.commons.lang3.RandomStringUtils; +import org.assertj.core.api.Assertions; import org.junit.jupiter.api.Test; +import org.kie.kogito.event.usertask.UserTaskInstanceAttachmentEventBody; +import org.kie.kogito.index.jpa.model.UserTaskInstanceEntity; import org.kie.kogito.index.jpa.model.UserTaskInstanceEntityRepository; +import org.kie.kogito.index.model.UserTaskInstance; +import org.kie.kogito.index.storage.UserTaskInstanceStorage; import org.kie.kogito.index.test.TestUtils; import jakarta.inject.Inject; +import jakarta.transaction.Transactional; public abstract class AbstractUserTaskInstanceStorageIT { + private static final String PROCESS_INSTANCE_ID = "87daz3446-2386-4056-91dc-dbc3804d157c"; + private static final String PROCESS_ID = "travels"; + private static final String TASK_NAME = "HR Interview"; + + @Inject + UserTaskInstanceStorage storage; + @Inject - UserTaskInstanceEntityRepository repository; + UserTaskInstanceEntityRepository userTaskInstanceRepository; + + @Test + @Transactional + public void testUserTaskStateEvent() { + String taskId = createUserTaskInstance(); + + storage.indexState(TestUtils.createUserTaskStateEvent(taskId, TASK_NAME, PROCESS_INSTANCE_ID, PROCESS_ID, "Completed")); + + UserTaskInstance task = storage.get(taskId); + + Assertions.assertThat(task) + .isNotNull() + .hasFieldOrPropertyWithValue("id", taskId) + .hasFieldOrPropertyWithValue("name", TASK_NAME) + .hasFieldOrPropertyWithValue("processId", PROCESS_ID) + .hasFieldOrPropertyWithValue("processInstanceId", PROCESS_INSTANCE_ID) + .hasFieldOrPropertyWithValue("state", "Completed"); + } + + @Test + @Transactional + public void testUserTaskAssignmentEvents() { + + String taskId = createUserTaskInstance(); + + UserTaskInstance task = storage.get(taskId); + + Assertions.assertThat(task) + .hasFieldOrPropertyWithValue("potentialUsers", null) + .hasFieldOrPropertyWithValue("potentialGroups", null) + .hasFieldOrPropertyWithValue("adminGroups", null) + .hasFieldOrPropertyWithValue("adminUsers", null) + .hasFieldOrPropertyWithValue("excludedUsers", null); + + storage.indexAssignment(TestUtils.createUserTaskAssignmentEvent(taskId, PROCESS_INSTANCE_ID, PROCESS_ID, "USER_OWNERS", "John")); + storage.indexAssignment(TestUtils.createUserTaskAssignmentEvent(taskId, PROCESS_INSTANCE_ID, PROCESS_ID, "USER_GROUPS", "user-group")); + storage.indexAssignment(TestUtils.createUserTaskAssignmentEvent(taskId, PROCESS_INSTANCE_ID, PROCESS_ID, "ADMIN_GROUPS", "administrators")); + storage.indexAssignment(TestUtils.createUserTaskAssignmentEvent(taskId, PROCESS_INSTANCE_ID, PROCESS_ID, "ADMIN_USERS", "super-user")); + storage.indexAssignment(TestUtils.createUserTaskAssignmentEvent(taskId, PROCESS_INSTANCE_ID, PROCESS_ID, "USERS_EXCLUDED", "excluded-user")); + + task = storage.get(taskId); + + Assertions.assertThat(task.getPotentialUsers()) + .containsExactly("John"); + Assertions.assertThat(task.getPotentialGroups()) + .containsExactly("user-group"); + Assertions.assertThat(task.getAdminGroups()) + .containsExactly("administrators"); + Assertions.assertThat(task.getAdminUsers()) + .containsExactly("super-user"); + Assertions.assertThat(task.getExcludedUsers()) + .containsExactly("excluded-user"); + } + + @Transactional + @Test + public void testUserTaskVariableEvents() { + String taskId = createUserTaskInstance(); + + UserTaskInstance task = storage.get(taskId); + + Assertions.assertThat(task.getInputs()) + .isNull(); + Assertions.assertThat(task.getOutputs()) + .isNull(); + + Map person = new HashMap<>(); + person.put("firstName", "John"); + person.put("lastName", "Doe"); + + storage.indexVariable(TestUtils.createUserTaskVariableEvent(taskId, PROCESS_INSTANCE_ID, PROCESS_ID, "person", person, "INPUT")); + + task = storage.get(taskId); + + Assertions.assertThatObject(task.getInputs()) + .isNotNull() + .extracting(jsonNodes -> jsonNodes.at("/person/firstName").asText(), jsonNodes -> jsonNodes.at("/person/lastName").asText()) + .contains("John", "Doe"); + + Assertions.assertThat(task.getOutputs()) + .isNull(); + + person = new HashMap<>(); + person.put("age", 50); + person.put("married", true); + + storage.indexVariable(TestUtils.createUserTaskVariableEvent(taskId, PROCESS_INSTANCE_ID, PROCESS_ID, "person", person, "OUTPUT")); + + task = storage.get(taskId); + + Assertions.assertThatObject(task.getOutputs()) + .isNotNull() + .extracting(jsonNodes -> jsonNodes.at("/person/age").asInt(), jsonNodes -> jsonNodes.at("/person/married").asBoolean()) + .contains(50, true); + } + + @Transactional + @Test + public void testUserTaskCommentEvents() { + String taskId = createUserTaskInstance(); + + UserTaskInstance task = storage.get(taskId); + + Assertions.assertThat(task.getComments()) + .isEmpty(); + + String commentId = UUID.randomUUID().toString(); + storage.indexComment( + TestUtils.createUserTaskCommentEvent(taskId, PROCESS_INSTANCE_ID, PROCESS_ID, commentId, "this is a comment", "John", UserTaskInstanceAttachmentEventBody.EVENT_TYPE_ADDED)); + + task = storage.get(taskId); + + Assertions.assertThat(task.getComments()) + .hasSize(1); + + Assertions.assertThat(task.getComments().get(0)) + .hasNoNullFieldsOrProperties() + .hasFieldOrPropertyWithValue("id", commentId) + .hasFieldOrPropertyWithValue("content", "this is a comment") + .hasFieldOrPropertyWithValue("updatedBy", "John"); + + storage.indexComment( + TestUtils.createUserTaskCommentEvent(taskId, PROCESS_INSTANCE_ID, PROCESS_ID, commentId, "this is an updated comment", "John", UserTaskInstanceAttachmentEventBody.EVENT_TYPE_CHANGE)); + + task = storage.get(taskId); + + Assertions.assertThat(task.getComments()) + .hasSize(1); + + Assertions.assertThat(task.getComments().get(0)) + .hasNoNullFieldsOrProperties() + .hasFieldOrPropertyWithValue("id", commentId) + .hasFieldOrPropertyWithValue("content", "this is an updated comment") + .hasFieldOrPropertyWithValue("updatedBy", "John"); + + storage.indexComment( + TestUtils.createUserTaskCommentEvent(taskId, PROCESS_INSTANCE_ID, PROCESS_ID, commentId, "this is an updated comment", "John", UserTaskInstanceAttachmentEventBody.EVENT_TYPE_DELETED)); + + task = storage.get(taskId); + + Assertions.assertThat(task.getComments()) + .hasSize(0); + } + + @Transactional + @Test + public void testUserTaskAttachmentEvents() { + String taskId = createUserTaskInstance(); + + UserTaskInstance task = storage.get(taskId); + + Assertions.assertThat(task.getAttachments()) + .isEmpty(); + + String attachmentId = UUID.randomUUID().toString(); + storage.indexAttachment(TestUtils.createUserTaskAttachmentEvent(taskId, PROCESS_INSTANCE_ID, PROCESS_ID, attachmentId, "Attachment-1", URI.create("http://localhost:8080/my-doc.txt"), "John", + UserTaskInstanceAttachmentEventBody.EVENT_TYPE_ADDED)); + + task = storage.get(taskId); + + Assertions.assertThat(task.getAttachments()) + .hasSize(1); + + Assertions.assertThat(task.getAttachments().get(0)) + .hasNoNullFieldsOrProperties() + .hasFieldOrPropertyWithValue("id", attachmentId) + .hasFieldOrPropertyWithValue("name", "Attachment-1") + .hasFieldOrPropertyWithValue("content", "http://localhost:8080/my-doc.txt") + .hasFieldOrPropertyWithValue("updatedBy", "John"); + + storage.indexAttachment(TestUtils.createUserTaskAttachmentEvent(taskId, PROCESS_INSTANCE_ID, PROCESS_ID, attachmentId, "Attachment-1.2", URI.create("http://localhost:8080/my-doc2.txt"), + "John", UserTaskInstanceAttachmentEventBody.EVENT_TYPE_CHANGE)); + + task = storage.get(taskId); + + Assertions.assertThat(task.getAttachments()) + .hasSize(1); + + Assertions.assertThat(task.getAttachments().get(0)) + .hasNoNullFieldsOrProperties() + .hasFieldOrPropertyWithValue("id", attachmentId) + .hasFieldOrPropertyWithValue("name", "Attachment-1.2") + .hasFieldOrPropertyWithValue("content", "http://localhost:8080/my-doc2.txt") + .hasFieldOrPropertyWithValue("updatedBy", "John"); + + storage.indexAttachment(TestUtils.createUserTaskAttachmentEvent(taskId, PROCESS_INSTANCE_ID, PROCESS_ID, attachmentId, "Attachment-1", URI.create("http://localhost:8080/my-doc2.txt"), "John", + UserTaskInstanceAttachmentEventBody.EVENT_TYPE_DELETED)); + + task = storage.get(taskId); + + Assertions.assertThat(task.getAttachments()) + .hasSize(0); + } @Test public void testUserTaskInstanceEntity() { @@ -46,4 +253,26 @@ public void testUserTaskInstanceEntity() { RandomStringUtils.randomAlphabetic(10), "Completed", 1000L); } + private String createUserTaskInstance() { + String taskId = UUID.randomUUID().toString(); + + storage.indexState(TestUtils.createUserTaskStateEvent(taskId, TASK_NAME, PROCESS_INSTANCE_ID, PROCESS_ID, "InProgress")); + + UserTaskInstance task = storage.get(taskId); + + Assertions.assertThat(task) + .isNotNull() + .hasFieldOrPropertyWithValue("id", taskId) + .hasFieldOrPropertyWithValue("name", TASK_NAME) + .hasFieldOrPropertyWithValue("processId", PROCESS_ID) + .hasFieldOrPropertyWithValue("processInstanceId", PROCESS_INSTANCE_ID) + .hasFieldOrPropertyWithValue("state", "InProgress"); + + // Initializing comments and attachments just for the test + UserTaskInstanceEntity taskInstanceEntity = userTaskInstanceRepository.findById(taskId); + taskInstanceEntity.setComments(new ArrayList<>()); + taskInstanceEntity.setAttachments(new ArrayList<>()); + + return taskId; + } } diff --git a/data-index/data-index-storage/data-index-storage-jpa/pom.xml b/data-index/data-index-storage/data-index-storage-jpa/pom.xml index 393cc0901d..7db734cf5e 100644 --- a/data-index/data-index-storage/data-index-storage-jpa/pom.xml +++ b/data-index/data-index-storage/data-index-storage-jpa/pom.xml @@ -38,7 +38,7 @@ src/main/resources/${path.to.flyway.location} ${path.to.postgresql.storage}/${path.to.script.folder} target/classes/${path.to.flyway.location} - org.kie.kogito.index.jpa + org.kie.kogito.index.jpa @@ -60,6 +60,11 @@ quarkus-test-h2 test + + io.quarkus + quarkus-jdbc-postgresql + test + org.kie.kogito data-index-storage-api diff --git a/data-index/data-index-storage/data-index-storage-jpa/src/main/resources/META-INF/kie-flyway.properties b/data-index/data-index-storage/data-index-storage-jpa/src/main/resources/META-INF/kie-flyway.properties index 41c52109f4..35f70ad9f3 100644 --- a/data-index/data-index-storage/data-index-storage-jpa/src/main/resources/META-INF/kie-flyway.properties +++ b/data-index/data-index-storage/data-index-storage-jpa/src/main/resources/META-INF/kie-flyway.properties @@ -19,5 +19,5 @@ module.name=data-index -module.locations.postgresql=classpath:kie-flyway/db/data-index/postgresql,classpath:kie-flyway/db/persistence-commons/postgresql -module.locations.default=classpath:kie-flyway/db/data-index/ansi,classpath:kie-flyway/db/persistence-commons/ansi \ No newline at end of file +module.locations.postgresql=classpath:kie-flyway/db/data-index/postgresql +module.locations.default=classpath:kie-flyway/db/data-index/ansi \ No newline at end of file diff --git a/data-index/data-index-storage/data-index-storage-jpa/src/main/resources/META-INF/orm.xml b/data-index/data-index-storage/data-index-storage-jpa/src/main/resources/META-INF/orm.xml deleted file mode 100644 index 2e9789c752..0000000000 --- a/data-index/data-index-storage/data-index-storage-jpa/src/main/resources/META-INF/orm.xml +++ /dev/null @@ -1,34 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/data-index/data-index-storage/data-index-storage-jpa/src/main/resources/kie-flyway/db/data-index/ansi/V1.33.0__data_index_create.sql b/data-index/data-index-storage/data-index-storage-jpa/src/main/resources/kie-flyway/db/data-index/ansi/V1.33.0__data_index_create.sql index 564a9c72e9..3aa01f1e84 100644 --- a/data-index/data-index-storage/data-index-storage-jpa/src/main/resources/kie-flyway/db/data-index/ansi/V1.33.0__data_index_create.sql +++ b/data-index/data-index-storage/data-index-storage-jpa/src/main/resources/kie-flyway/db/data-index/ansi/V1.33.0__data_index_create.sql @@ -98,7 +98,7 @@ create table processes root_process_instance_id varchar(255), start_time timestamp, state integer, - variables varbinary(max), + variables varchar(max), CONSTRAINT processes_pk PRIMARY KEY (id), CONSTRAINT processes_variables_json CHECK (variables IS JSON) ); @@ -124,10 +124,10 @@ create table tasks completed timestamp, description varchar(255), endpoint varchar(255), - inputs varbinary(max), + inputs varchar(max), last_update timestamp, name varchar(255), - outputs varbinary(max), + outputs varchar(max), priority varchar(255), process_id varchar(255), process_instance_id varchar(255), diff --git a/data-index/data-index-storage/data-index-storage-jpa/src/main/resources/kie-flyway/db/data-index/ansi/V1.44.0__data_index_definitions.sql b/data-index/data-index-storage/data-index-storage-jpa/src/main/resources/kie-flyway/db/data-index/ansi/V1.44.0__data_index_definitions.sql index 4f361d57c1..2dbdee38e1 100644 --- a/data-index/data-index-storage/data-index-storage-jpa/src/main/resources/kie-flyway/db/data-index/ansi/V1.44.0__data_index_definitions.sql +++ b/data-index/data-index-storage/data-index-storage-jpa/src/main/resources/kie-flyway/db/data-index/ansi/V1.44.0__data_index_definitions.sql @@ -19,28 +19,28 @@ create table definitions ( - id varchar2(255) not null, - version varchar2(255) not null, - name varchar2(255), + id varchar(255) not null, + version varchar(255) not null, + name varchar(255), source bytea, - type varchar2(255), - endpoint varchar2(255), + type varchar(255), + endpoint varchar(255), primary key (id, version) ); create table definitions_addons ( - process_id varchar2(255) not null, - process_version varchar2(255) not null, - addon varchar2(255) not null, + process_id varchar(255) not null, + process_version varchar(255) not null, + addon varchar(255) not null, primary key (process_id, process_version, addon) ); create table definitions_roles ( - process_id varchar2(255) not null, - process_version varchar2(255) not null, - role varchar2(255) not null, + process_id varchar(255) not null, + process_version varchar(255) not null, + role varchar(255) not null, primary key (process_id, process_version, role) ); @@ -57,4 +57,4 @@ alter table definitions_roles on delete cascade; alter table processes - add column version varchar2(255); \ No newline at end of file + add column version varchar(255); \ No newline at end of file diff --git a/data-index/data-index-storage/data-index-storage-jpa/src/main/resources/kie-flyway/db/data-index/ansi/V1.45.0.0__data_index_node_definitions.sql b/data-index/data-index-storage/data-index-storage-jpa/src/main/resources/kie-flyway/db/data-index/ansi/V1.45.0.0__data_index_node_definitions.sql index 7bce973a34..e318e7d5f8 100644 --- a/data-index/data-index-storage/data-index-storage-jpa/src/main/resources/kie-flyway/db/data-index/ansi/V1.45.0.0__data_index_node_definitions.sql +++ b/data-index/data-index-storage/data-index-storage-jpa/src/main/resources/kie-flyway/db/data-index/ansi/V1.45.0.0__data_index_node_definitions.sql @@ -19,22 +19,22 @@ create table definitions_nodes ( - id varchar2(255) not null, - name varchar2(255), - type varchar2(255), - unique_id varchar2(255), - process_id varchar2(255) not null, - process_version varchar2(255) not null, + id varchar(255) not null, + name varchar(255), + type varchar(255), + unique_id varchar(255), + process_id varchar(255) not null, + process_version varchar(255) not null, primary key (id, process_id, process_version) ); create table definitions_nodes_metadata ( - node_id varchar2(255) not null, - process_id varchar2(255) not null, - process_version varchar2(255) not null, - value varchar2(255), - key varchar2(255) not null, + node_id varchar(255) not null, + process_id varchar(255) not null, + process_version varchar(255) not null, + value varchar(255), + key varchar(255) not null, primary key (node_id, process_id, process_version, key) ); diff --git a/data-index/data-index-storage/data-index-storage-jpa/src/main/resources/kie-flyway/db/data-index/ansi/V1.45.0.2__data_index_definitions_add_colums.sql b/data-index/data-index-storage/data-index-storage-jpa/src/main/resources/kie-flyway/db/data-index/ansi/V1.45.0.2__data_index_definitions_add_colums.sql index 8abae1b55a..30dad9ca80 100644 --- a/data-index/data-index-storage/data-index-storage-jpa/src/main/resources/kie-flyway/db/data-index/ansi/V1.45.0.2__data_index_definitions_add_colums.sql +++ b/data-index/data-index-storage/data-index-storage-jpa/src/main/resources/kie-flyway/db/data-index/ansi/V1.45.0.2__data_index_definitions_add_colums.sql @@ -19,18 +19,18 @@ create table definitions_annotations ( - value varchar2(255) not null, - process_id varchar2(255) not null, - process_version varchar2(255) not null, + value varchar(255) not null, + process_id varchar(255) not null, + process_version varchar(255) not null, primary key (value, process_id, process_version) ); create table definitions_metadata ( - process_id varchar2(255) not null, - process_version varchar2(255) not null, - value varchar2(255), - key varchar2(255) not null, + process_id varchar(255) not null, + process_version varchar(255) not null, + value varchar(255), + key varchar(255) not null, primary key (process_id, process_version, key) ); 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-jpa/src/main/resources/kie-flyway/db/data-index/ansi/readme.txt b/data-index/data-index-storage/data-index-storage-jpa/src/main/resources/kie-flyway/db/data-index/ansi/readme.txt new file mode 100644 index 0000000000..e08db4d0ae --- /dev/null +++ b/data-index/data-index-storage/data-index-storage-jpa/src/main/resources/kie-flyway/db/data-index/ansi/readme.txt @@ -0,0 +1,2 @@ +Ensure migration scripts are developed to support several executions over the same database without any error. +This feature will make sure this migration execution would be compatible with other needed flyway migrations without broking the chain. \ No newline at end of file diff --git a/data-index/data-index-storage/data-index-storage-jpa/src/test/java/org/kie/kogito/index/jdbc/H2QuarkusTestProfile.java b/data-index/data-index-storage/data-index-storage-jpa/src/test/java/org/kie/kogito/index/jdbc/H2QuarkusTestProfile.java new file mode 100644 index 0000000000..b42ab3699d --- /dev/null +++ b/data-index/data-index-storage/data-index-storage-jpa/src/test/java/org/kie/kogito/index/jdbc/H2QuarkusTestProfile.java @@ -0,0 +1,30 @@ +/* + * 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.index.jdbc; + +import io.quarkus.test.junit.QuarkusTestProfile; + +public class H2QuarkusTestProfile implements QuarkusTestProfile { + + @Override + public String getConfigProfile() { + return "test-h2"; + } +} diff --git a/data-index/data-index-storage/data-index-storage-jpa/src/test/java/org/kie/kogito/index/jdbc/PostgreSQLQuarkusTestProfile.java b/data-index/data-index-storage/data-index-storage-jpa/src/test/java/org/kie/kogito/index/jdbc/PostgreSQLQuarkusTestProfile.java new file mode 100644 index 0000000000..4445c0f4ff --- /dev/null +++ b/data-index/data-index-storage/data-index-storage-jpa/src/test/java/org/kie/kogito/index/jdbc/PostgreSQLQuarkusTestProfile.java @@ -0,0 +1,30 @@ +/* + * 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.index.jdbc; + +import io.quarkus.test.junit.QuarkusTestProfile; + +public class PostgreSQLQuarkusTestProfile implements QuarkusTestProfile { + + @Override + public String getConfigProfile() { + return "test-postgresql"; + } +} diff --git a/data-index/data-index-storage/data-index-storage-jpa/src/test/java/org/kie/kogito/index/jdbc/query/JobEntityQueryIT.java b/data-index/data-index-storage/data-index-storage-jpa/src/test/java/org/kie/kogito/index/jdbc/query/H2JobEntityQueryIT.java similarity index 75% rename from data-index/data-index-storage/data-index-storage-jpa/src/test/java/org/kie/kogito/index/jdbc/query/JobEntityQueryIT.java rename to data-index/data-index-storage/data-index-storage-jpa/src/test/java/org/kie/kogito/index/jdbc/query/H2JobEntityQueryIT.java index a99c7eeabd..88aa60b863 100644 --- a/data-index/data-index-storage/data-index-storage-jpa/src/test/java/org/kie/kogito/index/jdbc/query/JobEntityQueryIT.java +++ b/data-index/data-index-storage/data-index-storage-jpa/src/test/java/org/kie/kogito/index/jdbc/query/H2JobEntityQueryIT.java @@ -18,14 +18,19 @@ */ package org.kie.kogito.index.jdbc.query; +import org.kie.kogito.index.jdbc.H2QuarkusTestProfile; import org.kie.kogito.index.jpa.query.AbstractJobEntityQueryIT; +import io.quarkus.test.TestTransaction; import io.quarkus.test.common.QuarkusTestResource; import io.quarkus.test.h2.H2DatabaseTestResource; import io.quarkus.test.junit.QuarkusTest; +import io.quarkus.test.junit.TestProfile; @QuarkusTest -@QuarkusTestResource(H2DatabaseTestResource.class) -class JobEntityQueryIT extends AbstractJobEntityQueryIT { +@TestTransaction +@QuarkusTestResource(value = H2DatabaseTestResource.class, restrictToAnnotatedClass = true) +@TestProfile(H2QuarkusTestProfile.class) +class H2JobEntityQueryIT extends AbstractJobEntityQueryIT { } diff --git a/data-index/data-index-storage/data-index-storage-jpa/src/test/java/org/kie/kogito/index/jdbc/query/ProcessDefinitionEntityQueryIT.java b/data-index/data-index-storage/data-index-storage-jpa/src/test/java/org/kie/kogito/index/jdbc/query/H2ProcessDefinitionEntityQueryIT.java similarity index 74% rename from data-index/data-index-storage/data-index-storage-jpa/src/test/java/org/kie/kogito/index/jdbc/query/ProcessDefinitionEntityQueryIT.java rename to data-index/data-index-storage/data-index-storage-jpa/src/test/java/org/kie/kogito/index/jdbc/query/H2ProcessDefinitionEntityQueryIT.java index c99803b83a..704c46164b 100644 --- a/data-index/data-index-storage/data-index-storage-jpa/src/test/java/org/kie/kogito/index/jdbc/query/ProcessDefinitionEntityQueryIT.java +++ b/data-index/data-index-storage/data-index-storage-jpa/src/test/java/org/kie/kogito/index/jdbc/query/H2ProcessDefinitionEntityQueryIT.java @@ -18,14 +18,19 @@ */ package org.kie.kogito.index.jdbc.query; +import org.kie.kogito.index.jdbc.H2QuarkusTestProfile; import org.kie.kogito.index.jpa.query.AbstractProcessDefinitionEntityQueryIT; +import io.quarkus.test.TestTransaction; import io.quarkus.test.common.QuarkusTestResource; import io.quarkus.test.h2.H2DatabaseTestResource; import io.quarkus.test.junit.QuarkusTest; +import io.quarkus.test.junit.TestProfile; @QuarkusTest -@QuarkusTestResource(H2DatabaseTestResource.class) -class ProcessDefinitionEntityQueryIT extends AbstractProcessDefinitionEntityQueryIT { +@TestTransaction +@QuarkusTestResource(value = H2DatabaseTestResource.class, restrictToAnnotatedClass = true) +@TestProfile(H2QuarkusTestProfile.class) +class H2ProcessDefinitionEntityQueryIT extends AbstractProcessDefinitionEntityQueryIT { } diff --git a/data-index/data-index-storage/data-index-storage-jpa/src/test/java/org/kie/kogito/index/jdbc/query/ProcessInstanceEntityQueryIT.java b/data-index/data-index-storage/data-index-storage-jpa/src/test/java/org/kie/kogito/index/jdbc/query/H2ProcessInstanceEntityQueryIT.java similarity index 75% rename from data-index/data-index-storage/data-index-storage-jpa/src/test/java/org/kie/kogito/index/jdbc/query/ProcessInstanceEntityQueryIT.java rename to data-index/data-index-storage/data-index-storage-jpa/src/test/java/org/kie/kogito/index/jdbc/query/H2ProcessInstanceEntityQueryIT.java index 10bd679b53..c68e22d9d0 100644 --- a/data-index/data-index-storage/data-index-storage-jpa/src/test/java/org/kie/kogito/index/jdbc/query/ProcessInstanceEntityQueryIT.java +++ b/data-index/data-index-storage/data-index-storage-jpa/src/test/java/org/kie/kogito/index/jdbc/query/H2ProcessInstanceEntityQueryIT.java @@ -18,15 +18,20 @@ */ package org.kie.kogito.index.jdbc.query; +import org.kie.kogito.index.jdbc.H2QuarkusTestProfile; import org.kie.kogito.index.jpa.query.AbstractProcessInstanceEntityQueryIT; +import io.quarkus.test.TestTransaction; import io.quarkus.test.common.QuarkusTestResource; import io.quarkus.test.h2.H2DatabaseTestResource; import io.quarkus.test.junit.QuarkusTest; +import io.quarkus.test.junit.TestProfile; @QuarkusTest -@QuarkusTestResource(H2DatabaseTestResource.class) -class ProcessInstanceEntityQueryIT extends AbstractProcessInstanceEntityQueryIT { +@TestTransaction +@QuarkusTestResource(value = H2DatabaseTestResource.class, restrictToAnnotatedClass = true) +@TestProfile(H2QuarkusTestProfile.class) +class H2ProcessInstanceEntityQueryIT extends AbstractProcessInstanceEntityQueryIT { @Override protected Boolean isDateTimeAsLong() { diff --git a/data-index/data-index-storage/data-index-storage-jpa/src/test/java/org/kie/kogito/index/jdbc/query/UserTaskInstanceEntityQueryIT.java b/data-index/data-index-storage/data-index-storage-jpa/src/test/java/org/kie/kogito/index/jdbc/query/H2UserTaskInstanceEntityQueryIT.java similarity index 74% rename from data-index/data-index-storage/data-index-storage-jpa/src/test/java/org/kie/kogito/index/jdbc/query/UserTaskInstanceEntityQueryIT.java rename to data-index/data-index-storage/data-index-storage-jpa/src/test/java/org/kie/kogito/index/jdbc/query/H2UserTaskInstanceEntityQueryIT.java index abaffc8741..79e6ea184b 100644 --- a/data-index/data-index-storage/data-index-storage-jpa/src/test/java/org/kie/kogito/index/jdbc/query/UserTaskInstanceEntityQueryIT.java +++ b/data-index/data-index-storage/data-index-storage-jpa/src/test/java/org/kie/kogito/index/jdbc/query/H2UserTaskInstanceEntityQueryIT.java @@ -18,14 +18,19 @@ */ package org.kie.kogito.index.jdbc.query; +import org.kie.kogito.index.jdbc.H2QuarkusTestProfile; import org.kie.kogito.index.jpa.query.AbstractUserTaskInstanceEntityQueryIT; +import io.quarkus.test.TestTransaction; import io.quarkus.test.common.QuarkusTestResource; import io.quarkus.test.h2.H2DatabaseTestResource; import io.quarkus.test.junit.QuarkusTest; +import io.quarkus.test.junit.TestProfile; @QuarkusTest -@QuarkusTestResource(H2DatabaseTestResource.class) -class UserTaskInstanceEntityQueryIT extends AbstractUserTaskInstanceEntityQueryIT { +@TestTransaction +@QuarkusTestResource(value = H2DatabaseTestResource.class, restrictToAnnotatedClass = true) +@TestProfile(H2QuarkusTestProfile.class) +class H2UserTaskInstanceEntityQueryIT extends AbstractUserTaskInstanceEntityQueryIT { } diff --git a/data-index/data-index-storage/data-index-storage-jpa/src/test/java/org/kie/kogito/index/jdbc/query/PostgreSQLJobEntityQueryIT.java b/data-index/data-index-storage/data-index-storage-jpa/src/test/java/org/kie/kogito/index/jdbc/query/PostgreSQLJobEntityQueryIT.java new file mode 100644 index 0000000000..049b7596de --- /dev/null +++ b/data-index/data-index-storage/data-index-storage-jpa/src/test/java/org/kie/kogito/index/jdbc/query/PostgreSQLJobEntityQueryIT.java @@ -0,0 +1,36 @@ +/* + * 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.index.jdbc.query; + +import org.kie.kogito.index.jdbc.PostgreSQLQuarkusTestProfile; +import org.kie.kogito.index.jpa.query.AbstractJobEntityQueryIT; +import org.kie.kogito.testcontainers.quarkus.PostgreSqlQuarkusTestResource; + +import io.quarkus.test.TestTransaction; +import io.quarkus.test.common.QuarkusTestResource; +import io.quarkus.test.junit.QuarkusTest; +import io.quarkus.test.junit.TestProfile; + +@QuarkusTest +@TestTransaction +@QuarkusTestResource(value = PostgreSqlQuarkusTestResource.class, restrictToAnnotatedClass = true) +@TestProfile(PostgreSQLQuarkusTestProfile.class) +class PostgreSQLJobEntityQueryIT extends AbstractJobEntityQueryIT { + +} diff --git a/data-index/data-index-storage/data-index-storage-jpa/src/test/java/org/kie/kogito/index/jdbc/query/PostgreSQLProcessDefinitionEntityQueryIT.java b/data-index/data-index-storage/data-index-storage-jpa/src/test/java/org/kie/kogito/index/jdbc/query/PostgreSQLProcessDefinitionEntityQueryIT.java new file mode 100644 index 0000000000..55d756025d --- /dev/null +++ b/data-index/data-index-storage/data-index-storage-jpa/src/test/java/org/kie/kogito/index/jdbc/query/PostgreSQLProcessDefinitionEntityQueryIT.java @@ -0,0 +1,36 @@ +/* + * 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.index.jdbc.query; + +import org.kie.kogito.index.jdbc.PostgreSQLQuarkusTestProfile; +import org.kie.kogito.index.jpa.query.AbstractProcessDefinitionEntityQueryIT; +import org.kie.kogito.testcontainers.quarkus.PostgreSqlQuarkusTestResource; + +import io.quarkus.test.TestTransaction; +import io.quarkus.test.common.QuarkusTestResource; +import io.quarkus.test.junit.QuarkusTest; +import io.quarkus.test.junit.TestProfile; + +@QuarkusTest +@TestTransaction +@QuarkusTestResource(value = PostgreSqlQuarkusTestResource.class, restrictToAnnotatedClass = true) +@TestProfile(PostgreSQLQuarkusTestProfile.class) +class PostgreSQLProcessDefinitionEntityQueryIT extends AbstractProcessDefinitionEntityQueryIT { + +} diff --git a/data-index/data-index-storage/data-index-storage-jpa/src/test/java/org/kie/kogito/index/jdbc/query/PostgreSQLProcessInstanceEntityQueryIT.java b/data-index/data-index-storage/data-index-storage-jpa/src/test/java/org/kie/kogito/index/jdbc/query/PostgreSQLProcessInstanceEntityQueryIT.java new file mode 100644 index 0000000000..13fddcf9c0 --- /dev/null +++ b/data-index/data-index-storage/data-index-storage-jpa/src/test/java/org/kie/kogito/index/jdbc/query/PostgreSQLProcessInstanceEntityQueryIT.java @@ -0,0 +1,40 @@ +/* + * 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.index.jdbc.query; + +import org.kie.kogito.index.jdbc.PostgreSQLQuarkusTestProfile; +import org.kie.kogito.index.jpa.query.AbstractProcessInstanceEntityQueryIT; +import org.kie.kogito.testcontainers.quarkus.PostgreSqlQuarkusTestResource; + +import io.quarkus.test.TestTransaction; +import io.quarkus.test.common.QuarkusTestResource; +import io.quarkus.test.junit.QuarkusTest; +import io.quarkus.test.junit.TestProfile; + +@QuarkusTest +@TestTransaction +@QuarkusTestResource(value = PostgreSqlQuarkusTestResource.class, restrictToAnnotatedClass = true) +@TestProfile(PostgreSQLQuarkusTestProfile.class) +class PostgreSQLProcessInstanceEntityQueryIT extends AbstractProcessInstanceEntityQueryIT { + + @Override + protected Boolean isDateTimeAsLong() { + return false; + } +} diff --git a/data-index/data-index-storage/data-index-storage-jpa/src/test/java/org/kie/kogito/index/jdbc/query/PostgreSQLUserTaskInstanceEntityQueryIT.java b/data-index/data-index-storage/data-index-storage-jpa/src/test/java/org/kie/kogito/index/jdbc/query/PostgreSQLUserTaskInstanceEntityQueryIT.java new file mode 100644 index 0000000000..1574f3833c --- /dev/null +++ b/data-index/data-index-storage/data-index-storage-jpa/src/test/java/org/kie/kogito/index/jdbc/query/PostgreSQLUserTaskInstanceEntityQueryIT.java @@ -0,0 +1,36 @@ +/* + * 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.index.jdbc.query; + +import org.kie.kogito.index.jdbc.PostgreSQLQuarkusTestProfile; +import org.kie.kogito.index.jpa.query.AbstractUserTaskInstanceEntityQueryIT; +import org.kie.kogito.testcontainers.quarkus.PostgreSqlQuarkusTestResource; + +import io.quarkus.test.TestTransaction; +import io.quarkus.test.common.QuarkusTestResource; +import io.quarkus.test.junit.QuarkusTest; +import io.quarkus.test.junit.TestProfile; + +@QuarkusTest +@TestTransaction +@QuarkusTestResource(value = PostgreSqlQuarkusTestResource.class, restrictToAnnotatedClass = true) +@TestProfile(PostgreSQLQuarkusTestProfile.class) +class PostgreSQLUserTaskInstanceEntityQueryIT extends AbstractUserTaskInstanceEntityQueryIT { + +} diff --git a/data-index/data-index-storage/data-index-storage-jpa/src/test/java/org/kie/kogito/index/jdbc/storage/JobStorageIT.java b/data-index/data-index-storage/data-index-storage-jpa/src/test/java/org/kie/kogito/index/jdbc/storage/H2JobStorageIT.java similarity index 79% rename from data-index/data-index-storage/data-index-storage-jpa/src/test/java/org/kie/kogito/index/jdbc/storage/JobStorageIT.java rename to data-index/data-index-storage/data-index-storage-jpa/src/test/java/org/kie/kogito/index/jdbc/storage/H2JobStorageIT.java index 88c5db0fbb..3a6815e467 100644 --- a/data-index/data-index-storage/data-index-storage-jpa/src/test/java/org/kie/kogito/index/jdbc/storage/JobStorageIT.java +++ b/data-index/data-index-storage/data-index-storage-jpa/src/test/java/org/kie/kogito/index/jdbc/storage/H2JobStorageIT.java @@ -18,14 +18,16 @@ */ package org.kie.kogito.index.jdbc.storage; +import org.kie.kogito.index.jdbc.H2QuarkusTestProfile; import org.kie.kogito.index.jpa.storage.AbstractJobStorageIT; -import io.quarkus.test.common.QuarkusTestResource; -import io.quarkus.test.h2.H2DatabaseTestResource; +import io.quarkus.test.TestTransaction; import io.quarkus.test.junit.QuarkusTest; +import io.quarkus.test.junit.TestProfile; @QuarkusTest -@QuarkusTestResource(H2DatabaseTestResource.class) -public class JobStorageIT extends AbstractJobStorageIT { +@TestTransaction +@TestProfile(H2QuarkusTestProfile.class) +public class H2JobStorageIT extends AbstractJobStorageIT { } diff --git a/data-index/data-index-storage/data-index-storage-jpa/src/test/java/org/kie/kogito/index/jdbc/storage/ProcessDefinitionStorageIT.java b/data-index/data-index-storage/data-index-storage-jpa/src/test/java/org/kie/kogito/index/jdbc/storage/H2ProcessDefinitionStorageIT.java similarity index 78% rename from data-index/data-index-storage/data-index-storage-jpa/src/test/java/org/kie/kogito/index/jdbc/storage/ProcessDefinitionStorageIT.java rename to data-index/data-index-storage/data-index-storage-jpa/src/test/java/org/kie/kogito/index/jdbc/storage/H2ProcessDefinitionStorageIT.java index b0369d8369..ab110245e0 100644 --- a/data-index/data-index-storage/data-index-storage-jpa/src/test/java/org/kie/kogito/index/jdbc/storage/ProcessDefinitionStorageIT.java +++ b/data-index/data-index-storage/data-index-storage-jpa/src/test/java/org/kie/kogito/index/jdbc/storage/H2ProcessDefinitionStorageIT.java @@ -18,14 +18,16 @@ */ package org.kie.kogito.index.jdbc.storage; +import org.kie.kogito.index.jdbc.H2QuarkusTestProfile; import org.kie.kogito.index.jpa.storage.AbstractProcessDefinitionStorageIT; -import io.quarkus.test.common.QuarkusTestResource; -import io.quarkus.test.h2.H2DatabaseTestResource; +import io.quarkus.test.TestTransaction; import io.quarkus.test.junit.QuarkusTest; +import io.quarkus.test.junit.TestProfile; @QuarkusTest -@QuarkusTestResource(H2DatabaseTestResource.class) -class ProcessDefinitionStorageIT extends AbstractProcessDefinitionStorageIT { +@TestTransaction +@TestProfile(H2QuarkusTestProfile.class) +class H2ProcessDefinitionStorageIT extends AbstractProcessDefinitionStorageIT { } diff --git a/data-index/data-index-storage/data-index-storage-jpa/src/test/java/org/kie/kogito/index/jdbc/storage/ProcessInstanceStorageIT.java b/data-index/data-index-storage/data-index-storage-jpa/src/test/java/org/kie/kogito/index/jdbc/storage/H2ProcessInstanceStorageIT.java similarity index 77% rename from data-index/data-index-storage/data-index-storage-jpa/src/test/java/org/kie/kogito/index/jdbc/storage/ProcessInstanceStorageIT.java rename to data-index/data-index-storage/data-index-storage-jpa/src/test/java/org/kie/kogito/index/jdbc/storage/H2ProcessInstanceStorageIT.java index 9f40d50928..3b73dd3fb3 100644 --- a/data-index/data-index-storage/data-index-storage-jpa/src/test/java/org/kie/kogito/index/jdbc/storage/ProcessInstanceStorageIT.java +++ b/data-index/data-index-storage/data-index-storage-jpa/src/test/java/org/kie/kogito/index/jdbc/storage/H2ProcessInstanceStorageIT.java @@ -18,13 +18,15 @@ */ package org.kie.kogito.index.jdbc.storage; +import org.kie.kogito.index.jdbc.H2QuarkusTestProfile; import org.kie.kogito.index.jpa.storage.AbstractProcessInstanceStorageIT; -import io.quarkus.test.common.QuarkusTestResource; -import io.quarkus.test.h2.H2DatabaseTestResource; +import io.quarkus.test.TestTransaction; import io.quarkus.test.junit.QuarkusTest; +import io.quarkus.test.junit.TestProfile; @QuarkusTest -@QuarkusTestResource(H2DatabaseTestResource.class) -public class ProcessInstanceStorageIT extends AbstractProcessInstanceStorageIT { +@TestTransaction +@TestProfile(H2QuarkusTestProfile.class) +public class H2ProcessInstanceStorageIT extends AbstractProcessInstanceStorageIT { } diff --git a/data-index/data-index-storage/data-index-storage-jpa/src/test/java/org/kie/kogito/index/jdbc/storage/UserTaskInstanceStorageIT.java b/data-index/data-index-storage/data-index-storage-jpa/src/test/java/org/kie/kogito/index/jdbc/storage/H2UserTaskInstanceStorageIT.java similarity index 77% rename from data-index/data-index-storage/data-index-storage-jpa/src/test/java/org/kie/kogito/index/jdbc/storage/UserTaskInstanceStorageIT.java rename to data-index/data-index-storage/data-index-storage-jpa/src/test/java/org/kie/kogito/index/jdbc/storage/H2UserTaskInstanceStorageIT.java index 4a6b9921e5..b8b5105c6a 100644 --- a/data-index/data-index-storage/data-index-storage-jpa/src/test/java/org/kie/kogito/index/jdbc/storage/UserTaskInstanceStorageIT.java +++ b/data-index/data-index-storage/data-index-storage-jpa/src/test/java/org/kie/kogito/index/jdbc/storage/H2UserTaskInstanceStorageIT.java @@ -18,13 +18,15 @@ */ package org.kie.kogito.index.jdbc.storage; +import org.kie.kogito.index.jdbc.H2QuarkusTestProfile; import org.kie.kogito.index.jpa.storage.AbstractUserTaskInstanceStorageIT; -import io.quarkus.test.common.QuarkusTestResource; -import io.quarkus.test.h2.H2DatabaseTestResource; +import io.quarkus.test.TestTransaction; import io.quarkus.test.junit.QuarkusTest; +import io.quarkus.test.junit.TestProfile; @QuarkusTest -@QuarkusTestResource(H2DatabaseTestResource.class) -public class UserTaskInstanceStorageIT extends AbstractUserTaskInstanceStorageIT { +@TestTransaction +@TestProfile(H2QuarkusTestProfile.class) +public class H2UserTaskInstanceStorageIT extends AbstractUserTaskInstanceStorageIT { } diff --git a/data-index/data-index-storage/data-index-storage-jpa/src/test/java/org/kie/kogito/index/jdbc/storage/PostgreSQLJobStorageIT.java b/data-index/data-index-storage/data-index-storage-jpa/src/test/java/org/kie/kogito/index/jdbc/storage/PostgreSQLJobStorageIT.java new file mode 100644 index 0000000000..df8d352480 --- /dev/null +++ b/data-index/data-index-storage/data-index-storage-jpa/src/test/java/org/kie/kogito/index/jdbc/storage/PostgreSQLJobStorageIT.java @@ -0,0 +1,36 @@ +/* + * 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.index.jdbc.storage; + +import org.kie.kogito.index.jdbc.PostgreSQLQuarkusTestProfile; +import org.kie.kogito.index.jpa.storage.AbstractJobStorageIT; +import org.kie.kogito.testcontainers.quarkus.PostgreSqlQuarkusTestResource; + +import io.quarkus.test.TestTransaction; +import io.quarkus.test.common.QuarkusTestResource; +import io.quarkus.test.junit.QuarkusTest; +import io.quarkus.test.junit.TestProfile; + +@QuarkusTest +@TestTransaction +@QuarkusTestResource(value = PostgreSqlQuarkusTestResource.class, restrictToAnnotatedClass = true) +@TestProfile(PostgreSQLQuarkusTestProfile.class) +public class PostgreSQLJobStorageIT extends AbstractJobStorageIT { + +} diff --git a/data-index/data-index-storage/data-index-storage-jpa/src/test/java/org/kie/kogito/index/jdbc/storage/PostgreSQLProcessDefinitionStorageIT.java b/data-index/data-index-storage/data-index-storage-jpa/src/test/java/org/kie/kogito/index/jdbc/storage/PostgreSQLProcessDefinitionStorageIT.java new file mode 100644 index 0000000000..31c2f1109d --- /dev/null +++ b/data-index/data-index-storage/data-index-storage-jpa/src/test/java/org/kie/kogito/index/jdbc/storage/PostgreSQLProcessDefinitionStorageIT.java @@ -0,0 +1,36 @@ +/* + * 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.index.jdbc.storage; + +import org.kie.kogito.index.jdbc.PostgreSQLQuarkusTestProfile; +import org.kie.kogito.index.jpa.storage.AbstractProcessDefinitionStorageIT; +import org.kie.kogito.testcontainers.quarkus.PostgreSqlQuarkusTestResource; + +import io.quarkus.test.TestTransaction; +import io.quarkus.test.common.QuarkusTestResource; +import io.quarkus.test.junit.QuarkusTest; +import io.quarkus.test.junit.TestProfile; + +@QuarkusTest +@TestTransaction +@QuarkusTestResource(value = PostgreSqlQuarkusTestResource.class, restrictToAnnotatedClass = true) +@TestProfile(PostgreSQLQuarkusTestProfile.class) +class PostgreSQLProcessDefinitionStorageIT extends AbstractProcessDefinitionStorageIT { + +} diff --git a/data-index/data-index-storage/data-index-storage-jpa/src/test/java/org/kie/kogito/index/jdbc/storage/PostgreSQLProcessInstanceStorageIT.java b/data-index/data-index-storage/data-index-storage-jpa/src/test/java/org/kie/kogito/index/jdbc/storage/PostgreSQLProcessInstanceStorageIT.java new file mode 100644 index 0000000000..19c7e61237 --- /dev/null +++ b/data-index/data-index-storage/data-index-storage-jpa/src/test/java/org/kie/kogito/index/jdbc/storage/PostgreSQLProcessInstanceStorageIT.java @@ -0,0 +1,35 @@ +/* + * 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.index.jdbc.storage; + +import org.kie.kogito.index.jdbc.PostgreSQLQuarkusTestProfile; +import org.kie.kogito.index.jpa.storage.AbstractProcessInstanceStorageIT; +import org.kie.kogito.testcontainers.quarkus.PostgreSqlQuarkusTestResource; + +import io.quarkus.test.TestTransaction; +import io.quarkus.test.common.QuarkusTestResource; +import io.quarkus.test.junit.QuarkusTest; +import io.quarkus.test.junit.TestProfile; + +@QuarkusTest +@TestTransaction +@QuarkusTestResource(value = PostgreSqlQuarkusTestResource.class, restrictToAnnotatedClass = true) +@TestProfile(PostgreSQLQuarkusTestProfile.class) +public class PostgreSQLProcessInstanceStorageIT extends AbstractProcessInstanceStorageIT { +} diff --git a/data-index/data-index-storage/data-index-storage-jpa/src/test/java/org/kie/kogito/index/jdbc/storage/PostgreSQLUserTaskInstanceStorageIT.java b/data-index/data-index-storage/data-index-storage-jpa/src/test/java/org/kie/kogito/index/jdbc/storage/PostgreSQLUserTaskInstanceStorageIT.java new file mode 100644 index 0000000000..f0284db9f0 --- /dev/null +++ b/data-index/data-index-storage/data-index-storage-jpa/src/test/java/org/kie/kogito/index/jdbc/storage/PostgreSQLUserTaskInstanceStorageIT.java @@ -0,0 +1,35 @@ +/* + * 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.index.jdbc.storage; + +import org.kie.kogito.index.jdbc.PostgreSQLQuarkusTestProfile; +import org.kie.kogito.index.jpa.storage.AbstractUserTaskInstanceStorageIT; +import org.kie.kogito.testcontainers.quarkus.PostgreSqlQuarkusTestResource; + +import io.quarkus.test.TestTransaction; +import io.quarkus.test.common.QuarkusTestResource; +import io.quarkus.test.junit.QuarkusTest; +import io.quarkus.test.junit.TestProfile; + +@QuarkusTest +@TestTransaction +@QuarkusTestResource(value = PostgreSqlQuarkusTestResource.class, restrictToAnnotatedClass = true) +@TestProfile(PostgreSQLQuarkusTestProfile.class) +public class PostgreSQLUserTaskInstanceStorageIT extends AbstractUserTaskInstanceStorageIT { +} diff --git a/data-index/data-index-storage/data-index-storage-jpa/src/test/resources/application.properties b/data-index/data-index-storage/data-index-storage-jpa/src/test/resources/application.properties index a5b6fe7459..eb83483fe9 100644 --- a/data-index/data-index-storage/data-index-storage-jpa/src/test/resources/application.properties +++ b/data-index/data-index-storage/data-index-storage-jpa/src/test/resources/application.properties @@ -21,13 +21,19 @@ kogito.apps.persistence.type=jdbc kie.flyway.enabled=true -# Data source -quarkus.datasource.db-kind=h2 -quarkus.datasource.jdbc.url=jdbc:h2:tcp://localhost/mem:test;NON_KEYWORDS=VALUE,KEY +# Data sources +%test-postgresql.quarkus.datasource.db-kind=postgresql +%test-postgresql.quarkus.datasource.devservices.enabled=false +%test-h2.quarkus.datasource.db-kind=h2 +%test-h2.quarkus.datasource.username=kogito +%test-h2.quarkus.datasource.jdbc.url=jdbc:h2:mem:default;NON_KEYWORDS=VALUE,KEY + # Hibernate quarkus.hibernate-orm.physical-naming-strategy=org.hibernate.boot.model.naming.CamelCaseToUnderscoresNamingStrategy quarkus.hibernate-orm.jdbc.timezone=UTC -quarkus.hibernate-orm.log.sql=true +# Enforcing flush to ensure data is correctly stored in DB +quarkus.hibernate-orm.flush.mode=always + # Disabling Security for tests quarkus.oidc.enabled=false 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/META-INF/kie-flyway.properties b/data-index/data-index-storage/data-index-storage-postgresql/src/main/resources/META-INF/kie-flyway.properties index 383546a8fe..4adfed0d42 100644 --- a/data-index/data-index-storage/data-index-storage-postgresql/src/main/resources/META-INF/kie-flyway.properties +++ b/data-index/data-index-storage/data-index-storage-postgresql/src/main/resources/META-INF/kie-flyway.properties @@ -19,4 +19,4 @@ module.name=data-index -module.locations.postgresql=classpath:kie-flyway/db/data-index/postgresql,classpath:kie-flyway/db/persistence-commons/postgresql \ No newline at end of file +module.locations.postgresql=classpath:kie-flyway/db/data-index/postgresql \ No newline at end of file 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-postgresql/src/test/java/org/kie/kogito/index/postgresql/storage/ProcessInstanceStorageIT.java b/data-index/data-index-storage/data-index-storage-postgresql/src/test/java/org/kie/kogito/index/postgresql/storage/ProcessInstanceStorageIT.java index 0ad8baf9b6..0ac176627c 100644 --- a/data-index/data-index-storage/data-index-storage-postgresql/src/test/java/org/kie/kogito/index/postgresql/storage/ProcessInstanceStorageIT.java +++ b/data-index/data-index-storage/data-index-storage-postgresql/src/test/java/org/kie/kogito/index/postgresql/storage/ProcessInstanceStorageIT.java @@ -21,10 +21,12 @@ import org.kie.kogito.index.jpa.storage.AbstractProcessInstanceStorageIT; import org.kie.kogito.testcontainers.quarkus.PostgreSqlQuarkusTestResource; +import io.quarkus.test.TestTransaction; import io.quarkus.test.common.QuarkusTestResource; import io.quarkus.test.junit.QuarkusTest; @QuarkusTest +@TestTransaction @QuarkusTestResource(PostgreSqlQuarkusTestResource.class) public class ProcessInstanceStorageIT extends AbstractProcessInstanceStorageIT { } diff --git a/data-index/data-index-storage/data-index-storage-postgresql/src/test/resources/application.properties b/data-index/data-index-storage/data-index-storage-postgresql/src/test/resources/application.properties index b5637dfd64..a91fc1a378 100644 --- a/data-index/data-index-storage/data-index-storage-postgresql/src/test/resources/application.properties +++ b/data-index/data-index-storage/data-index-storage-postgresql/src/test/resources/application.properties @@ -25,8 +25,7 @@ quarkus.datasource.username=kogito quarkus.datasource.password=kogito quarkus.datasource.jdbc.url=jdbc:postgresql://localhost:5432/kogito # Hibernate -quarkus.hibernate-orm.database.generation=drop-and-create -quarkus.hibernate-orm.database.generation.halt-on-error=true + quarkus.hibernate-orm.physical-naming-strategy=org.hibernate.boot.model.naming.CamelCaseToUnderscoresNamingStrategy quarkus.hibernate-orm.jdbc.timezone=UTC quarkus.hibernate-orm.log.sql=true 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/data-index/kogito-addons-quarkus-data-index/kogito-addons-quarkus-data-index-inmemory/runtime/src/main/resources/application.properties b/data-index/kogito-addons-quarkus-data-index/kogito-addons-quarkus-data-index-inmemory/runtime/src/main/resources/application.properties index 17182933f0..36c137123b 100644 --- a/data-index/kogito-addons-quarkus-data-index/kogito-addons-quarkus-data-index-inmemory/runtime/src/main/resources/application.properties +++ b/data-index/kogito-addons-quarkus-data-index/kogito-addons-quarkus-data-index-inmemory/runtime/src/main/resources/application.properties @@ -32,7 +32,7 @@ quarkus.hibernate-orm.datasource=data_index quarkus.hibernate-orm.physical-naming-strategy=org.hibernate.boot.model.naming.CamelCaseToUnderscoresNamingStrategy #Flyway -quarkus.flyway."data_index".locations=classpath:/kie-flyway/db/data-index/postgresql +quarkus.flyway."data_index".locations=classpath:/kie-flyway/db/data-index/postgresql,classpath:kie-flyway/db/persistence-commons/postgresql quarkus.flyway."data_index".migrate-at-start=true kie.flyway.modules."data-index".enabled=false \ No newline at end of file diff --git a/jitexecutor/jitexecutor-common/src/main/java/org/kie/kogito/jitexecutor/common/Constants.java b/jitexecutor/jitexecutor-common/src/main/java/org/kie/kogito/jitexecutor/common/Constants.java index ed8079006b..17999225e6 100644 --- a/jitexecutor/jitexecutor-common/src/main/java/org/kie/kogito/jitexecutor/common/Constants.java +++ b/jitexecutor/jitexecutor-common/src/main/java/org/kie/kogito/jitexecutor/common/Constants.java @@ -6,9 +6,9 @@ * 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 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 3a7bafe229..86e68c4729 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 @@ -32,6 +32,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 { @@ -43,6 +44,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); if (dmnModel.hasErrors()) { List messages = dmnModel.getMessages(DMNMessage.Severity.ERROR); @@ -75,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.emptyMap())); } 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..2da2e74e4c --- /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.HashMap; +import java.util.Map; + +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 Map evaluationHitIds = new HashMap<>(); + + private static final Logger LOGGER = LoggerFactory.getLogger(JITDMNListener.class); + + @Override + public void afterEvaluateDecisionTable(AfterEvaluateDecisionTableEvent event) { + logEvent(event); + event.getSelectedIds().forEach(s -> evaluationHitIds.compute(s, (k, v) -> v == null ? 1 : v + 1)); + } + + @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.compute(event.getExecutedId(), (k, v) -> v == null ? 1 : v + 1); + } + + public Map 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..c444dd0148 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 Map evaluationHitIds; + public JITDMNResult() { // Intentionally blank. } public JITDMNResult(String namespace, String modelName, org.kie.dmn.api.core.DMNResult dmnResult) { + this(namespace, modelName, dmnResult, Collections.emptyMap()); + } + + public JITDMNResult(String namespace, String modelName, org.kie.dmn.api.core.DMNResult dmnResult, Map 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 decisionResults } } + public Map getEvaluationHitIds() { + return evaluationHitIds; + } + + public void setEvaluationHitIds(Map 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..0e627f7a33 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,142 @@ 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()); + Map evaluationHitIds = dmnResult.getEvaluationHitIds(); + Assertions.assertNotNull(evaluationHitIds); + Assertions.assertEquals(3, evaluationHitIds.size()); + Assertions.assertTrue(evaluationHitIds.containsKey(elseElementId)); + Assertions.assertTrue(evaluationHitIds.containsKey(ruleId0)); + Assertions.assertTrue(evaluationHitIds.containsKey(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.containsKey(thenElementId)); + Assertions.assertTrue(evaluationHitIds.containsKey(ruleId1)); + Assertions.assertTrue(evaluationHitIds.containsKey(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()); + Map evaluationHitIds = dmnResult.getEvaluationHitIds(); + Assertions.assertNotNull(evaluationHitIds); + Assertions.assertEquals(3, evaluationHitIds.size()); + Assertions.assertTrue(evaluationHitIds.containsKey(thenElementId)); + Assertions.assertTrue(evaluationHitIds.containsKey(thenRuleId0)); + Assertions.assertTrue(evaluationHitIds.containsKey(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.containsKey(elseElementId)); + Assertions.assertTrue(evaluationHitIds.containsKey(elseRuleId2)); + Assertions.assertTrue(evaluationHitIds.containsKey(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 Map evaluationHitIds = dmnResult.getEvaluationHitIds(); + Assertions.assertNotNull(evaluationHitIds); + Assertions.assertEquals(3, evaluationHitIds.size()); + Assertions.assertEquals(3, evaluationHitIds.get(rule0)); + Assertions.assertEquals(2, evaluationHitIds.get(rule1)); + Assertions.assertEquals(1, evaluationHitIds.get(rule2)); + } + + @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..cacf238916 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 @@ -19,13 +19,23 @@ package org.kie.kogito.jitexecutor.dmn.api; import java.io.IOException; +import java.math.BigDecimal; +import java.util.ArrayList; import java.util.HashMap; +import java.util.List; 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.ObjectNode; + import io.quarkus.test.junit.QuarkusTest; import io.restassured.http.ContentType; @@ -36,18 +46,28 @@ @QuarkusTest public class JITDMNResourceTest { - private static String model; + private static String invalidModel; private static String modelWithExtensionElements; + private static String modelWithMultipleEvaluationHitIds; + + 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"); + invalidModel = getModelFromIoUtils("invalid_models/DMNv1_x/test.dmn"); modelWithExtensionElements = getModelFromIoUtils("valid_models/DMNv1_x/testWithExtensionElements.dmn"); + modelWithMultipleEvaluationHitIds = getModelFromIoUtils("valid_models/DMNv1_5/MultipleHitRules.dmn"); } @Test - public void testjitEndpoint() { - JITDMNPayload jitdmnpayload = new JITDMNPayload(model, buildContext()); + void testjitEndpoint() { + JITDMNPayload jitdmnpayload = new JITDMNPayload(invalidModel, buildContext()); given() .contentType(ContentType.JSON) .body(jitdmnpayload) @@ -58,31 +78,57 @@ public void testjitEndpoint() { } @Test - public void testjitdmnResultEndpoint() { - JITDMNPayload jitdmnpayload = new JITDMNPayload(model, buildContext()); + void testjitdmnResultEndpoint() { + JITDMNPayload jitdmnpayload = new JITDMNPayload(modelWithMultipleEvaluationHitIds, buildMultipleHitContext()); given() .contentType(ContentType.JSON) .body(jitdmnpayload) .when().post("/jitdmn/dmnresult") .then() .statusCode(200) - .body(containsString("Loan Approval"), containsString("Approved"), containsString("xls2dmn")); + .body(containsString("Statistics")); } @Test - public void testjitExplainabilityEndpoint() { - JITDMNPayload jitdmnpayload = new JITDMNPayload(model, buildContext()); + void testjitdmnResultEndpointWithEvaluationHitIds() throws JsonProcessingException { + JITDMNPayload jitdmnpayload = new JITDMNPayload(modelWithMultipleEvaluationHitIds, buildMultipleHitContext()); + 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 response = given().contentType(ContentType.JSON) + .body(jitdmnpayload) + .when().post("/jitdmn/dmnresult") + .then() + .statusCode(200) + .body(containsString("Statistics"), + containsString(EVALUATION_HIT_IDS_FIELD_NAME), + containsString(rule0), + containsString(rule1), + containsString(rule2)) + .extract() + .asString(); + JsonNode retrieved = MAPPER.readTree(response); + ObjectNode evaluationHitIdsNode = (ObjectNode) retrieved.get(EVALUATION_HIT_IDS_FIELD_NAME); + Assertions.assertThat(evaluationHitIdsNode).hasSize(3); + final Map expectedEvaluationHitIds = Map.of(rule0, 3, rule1, 2, rule2, 1); + evaluationHitIdsNode.fields().forEachRemaining(entry -> Assertions.assertThat(expectedEvaluationHitIds).containsEntry(entry.getKey(), entry.getValue().asInt())); + } + + @Test + void testjitExplainabilityEndpoint() { + JITDMNPayload jitdmnpayload = new JITDMNPayload(invalidModel, buildContext()); given() .contentType(ContentType.JSON) .body(jitdmnpayload) .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); @@ -104,4 +150,14 @@ private Map buildContext() { context.put("PITI Ratio", .1); return context; } + + private Map buildMultipleHitContext() { + 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); + return context; + } } 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 diff --git a/jobs-service/jobs-service-common/src/main/java/org/kie/kogito/jobs/service/scheduler/BaseTimerJobScheduler.java b/jobs-service/jobs-service-common/src/main/java/org/kie/kogito/jobs/service/scheduler/BaseTimerJobScheduler.java index ac080cdb82..49e777ba8c 100644 --- a/jobs-service/jobs-service-common/src/main/java/org/kie/kogito/jobs/service/scheduler/BaseTimerJobScheduler.java +++ b/jobs-service/jobs-service-common/src/main/java/org/kie/kogito/jobs/service/scheduler/BaseTimerJobScheduler.java @@ -343,7 +343,8 @@ private PublisherBuilder handleRetry(CompletionStage fut .build()) .map(jobRepository::save) .flatMapCompletionStage(p -> p)) - .peek(job -> LOGGER.debug("Retry executed {}", job)); + .peek(job -> LOGGER.debug("Retry executed {}", job)) + .onError(errorHandler -> LOGGER.error("Failed to retrieve job due to {}", errorHandler.getMessage())); } private PointInTimeTrigger getRetryTrigger() { diff --git a/jobs-service/jobs-service-common/src/main/java/org/kie/kogito/jobs/service/scheduler/JobSchedulerManager.java b/jobs-service/jobs-service-common/src/main/java/org/kie/kogito/jobs/service/scheduler/JobSchedulerManager.java index b0bd05feac..2211c3aeef 100644 --- a/jobs-service/jobs-service-common/src/main/java/org/kie/kogito/jobs/service/scheduler/JobSchedulerManager.java +++ b/jobs-service/jobs-service-common/src/main/java/org/kie/kogito/jobs/service/scheduler/JobSchedulerManager.java @@ -118,6 +118,9 @@ enum LoadJobErrorStrategy { } private void startJobsLoadingFromRepositoryTask() { + LOGGER.info( + "Starting with configuration: schedulerChunkInMinutes={}, loadJobIntervalInMinutes={}, loadJobFromCurrentTimeIntervalInMinutes={}, loadJobRetries={}, loadJobErrorStrategy={}", + schedulerChunkInMinutes, loadJobIntervalInMinutes, loadJobFromCurrentTimeIntervalInMinutes, loadJobRetries, loadJobErrorStrategy); //guarantee it starts the task just in case it is not already active initialLoading.set(true); if (periodicTimerIdForLoadJobs.get() < 0) { @@ -129,6 +132,13 @@ private void startJobsLoadingFromRepositoryTask() { schedulerChunkInMinutes); loadJobIntervalInMinutes = schedulerChunkInMinutes; } + if (loadJobFromCurrentTimeIntervalInMinutes < loadJobIntervalInMinutes) { + LOGGER.warn("The loadJobFromCurrentTimeIntervalInMinutes value ({}) is smaller than loadJobIntervalInMinutes ({}). " + + "This can potentially lead to overdue timers not getting rescheduled during the periodic job loading.", + loadJobFromCurrentTimeIntervalInMinutes, + loadJobIntervalInMinutes); + + } //first execution vertx.runOnContext(this::loadJobDetails); //next executions to run periodically @@ -198,6 +208,15 @@ private boolean isNotScheduled(JobDetails jobDetails) { Date triggerFireTime = jobDetails.getTrigger().hasNextFireTime(); ZonedDateTime nextFireTime = triggerFireTime != null ? DateUtil.instantToZonedDateTime(triggerFireTime.toInstant()) : null; boolean scheduled = scheduler.scheduled(jobDetails.getId()).isPresent(); + // cancel an overdue timer to have it rescheduled + if (!initialLoading.get() && nextFireTime != null && nextFireTime.isBefore(DateUtil.now())) { + LOGGER.debug("Job found, id: {}, nextFireTime: {}, created: {}, status: {} is overdue and will be rescheduled", jobDetails.getId(), + nextFireTime, + jobDetails.getCreated(), + jobDetails.getStatus()); + scheduler.cancel(jobDetails.getId()); + return true; + } LOGGER.debug("Job found, id: {}, nextFireTime: {}, created: {}, status: {}, already scheduled: {}", jobDetails.getId(), nextFireTime, jobDetails.getCreated(), diff --git a/jobs-service/jobs-service-common/src/main/java/org/kie/kogito/jobs/service/scheduler/impl/TimerDelegateJobScheduler.java b/jobs-service/jobs-service-common/src/main/java/org/kie/kogito/jobs/service/scheduler/impl/TimerDelegateJobScheduler.java index 6b30c30b0b..b64bd87b95 100644 --- a/jobs-service/jobs-service-common/src/main/java/org/kie/kogito/jobs/service/scheduler/impl/TimerDelegateJobScheduler.java +++ b/jobs-service/jobs-service-common/src/main/java/org/kie/kogito/jobs/service/scheduler/impl/TimerDelegateJobScheduler.java @@ -62,6 +62,9 @@ public TimerDelegateJobScheduler(ReactiveJobRepository jobRepository, @ConfigProperty(name = "kogito.jobs-service.forceExecuteExpiredJobsOnServiceStart", defaultValue = "true") boolean forceExecuteExpiredJobsOnServiceStart, JobExecutorResolver jobExecutorResolver, VertxTimerServiceScheduler delegate) { super(jobRepository, backoffRetryMillis, maxIntervalLimitToRetryMillis, schedulerChunkInMinutes, forceExecuteExpiredJobs, forceExecuteExpiredJobsOnServiceStart); + LOGGER.info( + "Creating JobScheduler with backoffRetryMillis={}, maxIntervalLimitToRetryMillis={}, schedulerChunkInMinutes={}, forceExecuteExpiredJobs={}, forceExecuteExpiredJobsOnServiceStart={}", + backoffRetryMillis, maxIntervalLimitToRetryMillis, schedulerChunkInMinutes, forceExecuteExpiredJobs, forceExecuteExpiredJobsOnServiceStart); this.jobExecutorResolver = jobExecutorResolver; this.delegate = delegate; } diff --git a/jobs-service/jobs-service-storage-jpa/src/main/java/org/kie/kogito/jobs/service/repository/jpa/converter/JsonBinaryConverter.java b/jobs-service/jobs-service-storage-jpa/src/main/java/org/kie/kogito/jobs/service/repository/jpa/converter/JsonBinaryConverter.java index b269ab9eaf..924fae07fa 100644 --- a/jobs-service/jobs-service-storage-jpa/src/main/java/org/kie/kogito/jobs/service/repository/jpa/converter/JsonBinaryConverter.java +++ b/jobs-service/jobs-service-storage-jpa/src/main/java/org/kie/kogito/jobs/service/repository/jpa/converter/JsonBinaryConverter.java @@ -27,19 +27,19 @@ import jakarta.persistence.AttributeConverter; -public class JsonBinaryConverter implements AttributeConverter { +public class JsonBinaryConverter implements AttributeConverter { @Override - public byte[] convertToDatabaseColumn(ObjectNode attribute) { + public String convertToDatabaseColumn(ObjectNode attribute) { try { - return attribute == null ? null : ObjectMapperFactory.get().writeValueAsBytes(attribute); + return attribute == null ? null : ObjectMapperFactory.get().writeValueAsString(attribute); } catch (IOException e) { throw new UncheckedIOException(e); } } @Override - public ObjectNode convertToEntityAttribute(byte[] dbData) { + public ObjectNode convertToEntityAttribute(String dbData) { try { return dbData == null ? null : ObjectMapperFactory.get().readValue(dbData, ObjectNode.class); } catch (IOException e) { diff --git a/persistence-commons/persistence-commons-postgresql/src/main/resources/application.properties b/jobs-service/jobs-service-storage-jpa/src/main/resources/application.properties similarity index 100% rename from persistence-commons/persistence-commons-postgresql/src/main/resources/application.properties rename to jobs-service/jobs-service-storage-jpa/src/main/resources/application.properties diff --git a/jobs-service/jobs-service-storage-jpa/src/main/resources/kie-flyway/db/jobs-service/ansi/V2.0.0__Create_Tables.sql b/jobs-service/jobs-service-storage-jpa/src/main/resources/kie-flyway/db/jobs-service/ansi/V2.0.0__Create_Tables.sql index b48a32a95c..eaf988097c 100644 --- a/jobs-service/jobs-service-storage-jpa/src/main/resources/kie-flyway/db/jobs-service/ansi/V2.0.0__Create_Tables.sql +++ b/jobs-service/jobs-service-storage-jpa/src/main/resources/kie-flyway/db/jobs-service/ansi/V2.0.0__Create_Tables.sql @@ -27,8 +27,8 @@ create table job_details execution_counter integer, scheduled_id varchar(40), priority integer, - recipient varbinary(max), - trigger varbinary(max), + recipient varchar(max), + trigger varchar(max), fire_time timestamp, execution_timeout bigint, execution_timeout_unit varchar(40), diff --git a/jobs-service/kogito-addons-jobs-service/kogito-addons-quarkus-jobs/src/main/java/org/kie/kogito/jobs/embedded/EmbeddedJobExecutor.java b/jobs-service/kogito-addons-jobs-service/kogito-addons-quarkus-jobs/src/main/java/org/kie/kogito/jobs/embedded/EmbeddedJobExecutor.java index 347eedcb69..ead3bbf2a2 100644 --- a/jobs-service/kogito-addons-jobs-service/kogito-addons-quarkus-jobs/src/main/java/org/kie/kogito/jobs/embedded/EmbeddedJobExecutor.java +++ b/jobs-service/kogito-addons-jobs-service/kogito-addons-quarkus-jobs/src/main/java/org/kie/kogito/jobs/embedded/EmbeddedJobExecutor.java @@ -56,7 +56,15 @@ public Uni execute(JobDetails jobDetails) { InVMRecipient recipient = (InVMRecipient) recipientModel.getRecipient(); String timerId = recipient.getPayload().getData().timerId(); String processInstanceId = recipient.getPayload().getData().processInstanceId(); - Optional> process = processes.processByProcessInstanceId(processInstanceId); + Optional> process; + try { + process = processes.processByProcessInstanceId(processInstanceId); + } catch (Exception ex) { + return Uni.createFrom().failure( + new JobExecutionException(jobDetails.getId(), + "Unexpected error when executing Embedded request for job: " + jobDetails.getId() + ". " + ex.getMessage(), + ex)); + } if (process.isEmpty()) { return Uni.createFrom().item( JobExecutionResponse.builder() diff --git a/kogito-apps-build-parent/pom.xml b/kogito-apps-build-parent/pom.xml index c5093d2eb0..72c89cabf6 100644 --- a/kogito-apps-build-parent/pom.xml +++ b/kogito-apps-build-parent/pom.xml @@ -66,6 +66,7 @@ 2.3.2 1.10.0 2.2.0 + 20231013 1.5.5.Final 1.5.1 22.0 @@ -158,6 +159,17 @@ com.redislabs jredisearch ${version.org.jredisearch} + + + org.json + json + + + + + org.json + json + ${version.org.json} org.apache.commons @@ -190,6 +202,11 @@ hibernate-ant ${version.org.hibernate} + + com.graphql-java + graphql-java + ${version.com.graphql-java-extended-scalars} + com.graphql-java graphql-java-extended-scalars diff --git a/mvnw b/mvnw deleted file mode 100755 index 41c0f0c23d..0000000000 --- a/mvnw +++ /dev/null @@ -1,310 +0,0 @@ -#!/bin/sh -# ---------------------------------------------------------------------------- -# 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. -# ---------------------------------------------------------------------------- - -# ---------------------------------------------------------------------------- -# Maven Start Up Batch script -# -# Required ENV vars: -# ------------------ -# JAVA_HOME - location of a JDK home dir -# -# Optional ENV vars -# ----------------- -# M2_HOME - location of maven2's installed home dir -# MAVEN_OPTS - parameters passed to the Java VM when running Maven -# e.g. to debug Maven itself, use -# set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000 -# MAVEN_SKIP_RC - flag to disable loading of mavenrc files -# ---------------------------------------------------------------------------- - -if [ -z "$MAVEN_SKIP_RC" ] ; then - - if [ -f /etc/mavenrc ] ; then - . /etc/mavenrc - fi - - if [ -f "$HOME/.mavenrc" ] ; then - . "$HOME/.mavenrc" - fi - -fi - -# OS specific support. $var _must_ be set to either true or false. -cygwin=false; -darwin=false; -mingw=false -case "`uname`" in - CYGWIN*) cygwin=true ;; - MINGW*) mingw=true;; - Darwin*) darwin=true - # Use /usr/libexec/java_home if available, otherwise fall back to /Library/Java/Home - # See https://developer.apple.com/library/mac/qa/qa1170/_index.html - if [ -z "$JAVA_HOME" ]; then - if [ -x "/usr/libexec/java_home" ]; then - export JAVA_HOME="`/usr/libexec/java_home`" - else - export JAVA_HOME="/Library/Java/Home" - fi - fi - ;; -esac - -if [ -z "$JAVA_HOME" ] ; then - if [ -r /etc/gentoo-release ] ; then - JAVA_HOME=`java-config --jre-home` - fi -fi - -if [ -z "$M2_HOME" ] ; then - ## resolve links - $0 may be a link to maven's home - PRG="$0" - - # need this for relative symlinks - while [ -h "$PRG" ] ; do - ls=`ls -ld "$PRG"` - link=`expr "$ls" : '.*-> \(.*\)$'` - if expr "$link" : '/.*' > /dev/null; then - PRG="$link" - else - PRG="`dirname "$PRG"`/$link" - fi - done - - saveddir=`pwd` - - M2_HOME=`dirname "$PRG"`/.. - - # make it fully qualified - M2_HOME=`cd "$M2_HOME" && pwd` - - cd "$saveddir" - # echo Using m2 at $M2_HOME -fi - -# For Cygwin, ensure paths are in UNIX format before anything is touched -if $cygwin ; then - [ -n "$M2_HOME" ] && - M2_HOME=`cygpath --unix "$M2_HOME"` - [ -n "$JAVA_HOME" ] && - JAVA_HOME=`cygpath --unix "$JAVA_HOME"` - [ -n "$CLASSPATH" ] && - CLASSPATH=`cygpath --path --unix "$CLASSPATH"` -fi - -# For Mingw, ensure paths are in UNIX format before anything is touched -if $mingw ; then - [ -n "$M2_HOME" ] && - M2_HOME="`(cd "$M2_HOME"; pwd)`" - [ -n "$JAVA_HOME" ] && - JAVA_HOME="`(cd "$JAVA_HOME"; pwd)`" -fi - -if [ -z "$JAVA_HOME" ]; then - javaExecutable="`which javac`" - if [ -n "$javaExecutable" ] && ! [ "`expr \"$javaExecutable\" : '\([^ ]*\)'`" = "no" ]; then - # readlink(1) is not available as standard on Solaris 10. - readLink=`which readlink` - if [ ! `expr "$readLink" : '\([^ ]*\)'` = "no" ]; then - if $darwin ; then - javaHome="`dirname \"$javaExecutable\"`" - javaExecutable="`cd \"$javaHome\" && pwd -P`/javac" - else - javaExecutable="`readlink -f \"$javaExecutable\"`" - fi - javaHome="`dirname \"$javaExecutable\"`" - javaHome=`expr "$javaHome" : '\(.*\)/bin'` - JAVA_HOME="$javaHome" - export JAVA_HOME - fi - fi -fi - -if [ -z "$JAVACMD" ] ; then - if [ -n "$JAVA_HOME" ] ; then - if [ -x "$JAVA_HOME/jre/sh/java" ] ; then - # IBM's JDK on AIX uses strange locations for the executables - JAVACMD="$JAVA_HOME/jre/sh/java" - else - JAVACMD="$JAVA_HOME/bin/java" - fi - else - JAVACMD="`which java`" - fi -fi - -if [ ! -x "$JAVACMD" ] ; then - echo "Error: JAVA_HOME is not defined correctly." >&2 - echo " We cannot execute $JAVACMD" >&2 - exit 1 -fi - -if [ -z "$JAVA_HOME" ] ; then - echo "Warning: JAVA_HOME environment variable is not set." -fi - -CLASSWORLDS_LAUNCHER=org.codehaus.plexus.classworlds.launcher.Launcher - -# traverses directory structure from process work directory to filesystem root -# first directory with .mvn subdirectory is considered project base directory -find_maven_basedir() { - - if [ -z "$1" ] - then - echo "Path not specified to find_maven_basedir" - return 1 - fi - - basedir="$1" - wdir="$1" - while [ "$wdir" != '/' ] ; do - if [ -d "$wdir"/.mvn ] ; then - basedir=$wdir - break - fi - # workaround for JBEAP-8937 (on Solaris 10/Sparc) - if [ -d "${wdir}" ]; then - wdir=`cd "$wdir/.."; pwd` - fi - # end of workaround - done - echo "${basedir}" -} - -# concatenates all lines of a file -concat_lines() { - if [ -f "$1" ]; then - echo "$(tr -s '\n' ' ' < "$1")" - fi -} - -BASE_DIR=`find_maven_basedir "$(pwd)"` -if [ -z "$BASE_DIR" ]; then - exit 1; -fi - -########################################################################################## -# Extension to allow automatically downloading the maven-wrapper.jar from Maven-central -# This allows using the maven wrapper in projects that prohibit checking in binary data. -########################################################################################## -if [ -r "$BASE_DIR/.mvn/wrapper/maven-wrapper.jar" ]; then - if [ "$MVNW_VERBOSE" = true ]; then - echo "Found .mvn/wrapper/maven-wrapper.jar" - fi -else - if [ "$MVNW_VERBOSE" = true ]; then - echo "Couldn't find .mvn/wrapper/maven-wrapper.jar, downloading it ..." - fi - if [ -n "$MVNW_REPOURL" ]; then - jarUrl="$MVNW_REPOURL/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar" - else - jarUrl="https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar" - fi - while IFS="=" read key value; do - case "$key" in (wrapperUrl) jarUrl="$value"; break ;; - esac - done < "$BASE_DIR/.mvn/wrapper/maven-wrapper.properties" - if [ "$MVNW_VERBOSE" = true ]; then - echo "Downloading from: $jarUrl" - fi - wrapperJarPath="$BASE_DIR/.mvn/wrapper/maven-wrapper.jar" - if $cygwin; then - wrapperJarPath=`cygpath --path --windows "$wrapperJarPath"` - fi - - if command -v wget > /dev/null; then - if [ "$MVNW_VERBOSE" = true ]; then - echo "Found wget ... using wget" - fi - if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then - wget "$jarUrl" -O "$wrapperJarPath" - else - wget --http-user=$MVNW_USERNAME --http-password=$MVNW_PASSWORD "$jarUrl" -O "$wrapperJarPath" - fi - elif command -v curl > /dev/null; then - if [ "$MVNW_VERBOSE" = true ]; then - echo "Found curl ... using curl" - fi - if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then - curl -o "$wrapperJarPath" "$jarUrl" -f - else - curl --user $MVNW_USERNAME:$MVNW_PASSWORD -o "$wrapperJarPath" "$jarUrl" -f - fi - - else - if [ "$MVNW_VERBOSE" = true ]; then - echo "Falling back to using Java to download" - fi - javaClass="$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.java" - # For Cygwin, switch paths to Windows format before running javac - if $cygwin; then - javaClass=`cygpath --path --windows "$javaClass"` - fi - if [ -e "$javaClass" ]; then - if [ ! -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then - if [ "$MVNW_VERBOSE" = true ]; then - echo " - Compiling MavenWrapperDownloader.java ..." - fi - # Compiling the Java class - ("$JAVA_HOME/bin/javac" "$javaClass") - fi - if [ -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then - # Running the downloader - if [ "$MVNW_VERBOSE" = true ]; then - echo " - Running MavenWrapperDownloader.java ..." - fi - ("$JAVA_HOME/bin/java" -cp .mvn/wrapper MavenWrapperDownloader "$MAVEN_PROJECTBASEDIR") - fi - fi - fi -fi -########################################################################################## -# End of extension -########################################################################################## - -export MAVEN_PROJECTBASEDIR=${MAVEN_BASEDIR:-"$BASE_DIR"} -if [ "$MVNW_VERBOSE" = true ]; then - echo $MAVEN_PROJECTBASEDIR -fi -MAVEN_OPTS="$(concat_lines "$MAVEN_PROJECTBASEDIR/.mvn/jvm.config") $MAVEN_OPTS" - -# For Cygwin, switch paths to Windows format before running java -if $cygwin; then - [ -n "$M2_HOME" ] && - M2_HOME=`cygpath --path --windows "$M2_HOME"` - [ -n "$JAVA_HOME" ] && - JAVA_HOME=`cygpath --path --windows "$JAVA_HOME"` - [ -n "$CLASSPATH" ] && - CLASSPATH=`cygpath --path --windows "$CLASSPATH"` - [ -n "$MAVEN_PROJECTBASEDIR" ] && - MAVEN_PROJECTBASEDIR=`cygpath --path --windows "$MAVEN_PROJECTBASEDIR"` -fi - -# Provide a "standardized" way to retrieve the CLI args that will -# work with both Windows and non-Windows executions. -MAVEN_CMD_LINE_ARGS="$MAVEN_CONFIG $@" -export MAVEN_CMD_LINE_ARGS - -WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain - -exec "$JAVACMD" \ - $MAVEN_OPTS \ - -classpath "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar" \ - "-Dmaven.home=${M2_HOME}" "-Dmaven.multiModuleProjectDirectory=${MAVEN_PROJECTBASEDIR}" \ - ${WRAPPER_LAUNCHER} $MAVEN_CONFIG "$@" diff --git a/mvnw.cmd b/mvnw.cmd deleted file mode 100644 index 86115719e5..0000000000 --- a/mvnw.cmd +++ /dev/null @@ -1,182 +0,0 @@ -@REM ---------------------------------------------------------------------------- -@REM Licensed to the Apache Software Foundation (ASF) under one -@REM or more contributor license agreements. See the NOTICE file -@REM distributed with this work for additional information -@REM regarding copyright ownership. The ASF licenses this file -@REM to you under the Apache License, Version 2.0 (the -@REM "License"); you may not use this file except in compliance -@REM with the License. You may obtain a copy of the License at -@REM -@REM http://www.apache.org/licenses/LICENSE-2.0 -@REM -@REM Unless required by applicable law or agreed to in writing, -@REM software distributed under the License is distributed on an -@REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -@REM KIND, either express or implied. See the License for the -@REM specific language governing permissions and limitations -@REM under the License. -@REM ---------------------------------------------------------------------------- - -@REM ---------------------------------------------------------------------------- -@REM Maven Start Up Batch script -@REM -@REM Required ENV vars: -@REM JAVA_HOME - location of a JDK home dir -@REM -@REM Optional ENV vars -@REM M2_HOME - location of maven2's installed home dir -@REM MAVEN_BATCH_ECHO - set to 'on' to enable the echoing of the batch commands -@REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a keystroke before ending -@REM MAVEN_OPTS - parameters passed to the Java VM when running Maven -@REM e.g. to debug Maven itself, use -@REM set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000 -@REM MAVEN_SKIP_RC - flag to disable loading of mavenrc files -@REM ---------------------------------------------------------------------------- - -@REM Begin all REM lines with '@' in case MAVEN_BATCH_ECHO is 'on' -@echo off -@REM set title of command window -title %0 -@REM enable echoing by setting MAVEN_BATCH_ECHO to 'on' -@if "%MAVEN_BATCH_ECHO%" == "on" echo %MAVEN_BATCH_ECHO% - -@REM set %HOME% to equivalent of $HOME -if "%HOME%" == "" (set "HOME=%HOMEDRIVE%%HOMEPATH%") - -@REM Execute a user defined script before this one -if not "%MAVEN_SKIP_RC%" == "" goto skipRcPre -@REM check for pre script, once with legacy .bat ending and once with .cmd ending -if exist "%HOME%\mavenrc_pre.bat" call "%HOME%\mavenrc_pre.bat" -if exist "%HOME%\mavenrc_pre.cmd" call "%HOME%\mavenrc_pre.cmd" -:skipRcPre - -@setlocal - -set ERROR_CODE=0 - -@REM To isolate internal variables from possible post scripts, we use another setlocal -@setlocal - -@REM ==== START VALIDATION ==== -if not "%JAVA_HOME%" == "" goto OkJHome - -echo. -echo Error: JAVA_HOME not found in your environment. >&2 -echo Please set the JAVA_HOME variable in your environment to match the >&2 -echo location of your Java installation. >&2 -echo. -goto error - -:OkJHome -if exist "%JAVA_HOME%\bin\java.exe" goto init - -echo. -echo Error: JAVA_HOME is set to an invalid directory. >&2 -echo JAVA_HOME = "%JAVA_HOME%" >&2 -echo Please set the JAVA_HOME variable in your environment to match the >&2 -echo location of your Java installation. >&2 -echo. -goto error - -@REM ==== END VALIDATION ==== - -:init - -@REM Find the project base dir, i.e. the directory that contains the folder ".mvn". -@REM Fallback to current working directory if not found. - -set MAVEN_PROJECTBASEDIR=%MAVEN_BASEDIR% -IF NOT "%MAVEN_PROJECTBASEDIR%"=="" goto endDetectBaseDir - -set EXEC_DIR=%CD% -set WDIR=%EXEC_DIR% -:findBaseDir -IF EXIST "%WDIR%"\.mvn goto baseDirFound -cd .. -IF "%WDIR%"=="%CD%" goto baseDirNotFound -set WDIR=%CD% -goto findBaseDir - -:baseDirFound -set MAVEN_PROJECTBASEDIR=%WDIR% -cd "%EXEC_DIR%" -goto endDetectBaseDir - -:baseDirNotFound -set MAVEN_PROJECTBASEDIR=%EXEC_DIR% -cd "%EXEC_DIR%" - -:endDetectBaseDir - -IF NOT EXIST "%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config" goto endReadAdditionalConfig - -@setlocal EnableExtensions EnableDelayedExpansion -for /F "usebackq delims=" %%a in ("%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config") do set JVM_CONFIG_MAVEN_PROPS=!JVM_CONFIG_MAVEN_PROPS! %%a -@endlocal & set JVM_CONFIG_MAVEN_PROPS=%JVM_CONFIG_MAVEN_PROPS% - -:endReadAdditionalConfig - -SET MAVEN_JAVA_EXE="%JAVA_HOME%\bin\java.exe" -set WRAPPER_JAR="%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.jar" -set WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain - -set DOWNLOAD_URL="https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar" - -FOR /F "tokens=1,2 delims==" %%A IN ("%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.properties") DO ( - IF "%%A"=="wrapperUrl" SET DOWNLOAD_URL=%%B -) - -@REM Extension to allow automatically downloading the maven-wrapper.jar from Maven-central -@REM This allows using the maven wrapper in projects that prohibit checking in binary data. -if exist %WRAPPER_JAR% ( - if "%MVNW_VERBOSE%" == "true" ( - echo Found %WRAPPER_JAR% - ) -) else ( - if not "%MVNW_REPOURL%" == "" ( - SET DOWNLOAD_URL="%MVNW_REPOURL%/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar" - ) - if "%MVNW_VERBOSE%" == "true" ( - echo Couldn't find %WRAPPER_JAR%, downloading it ... - echo Downloading from: %DOWNLOAD_URL% - ) - - powershell -Command "&{"^ - "$webclient = new-object System.Net.WebClient;"^ - "if (-not ([string]::IsNullOrEmpty('%MVNW_USERNAME%') -and [string]::IsNullOrEmpty('%MVNW_PASSWORD%'))) {"^ - "$webclient.Credentials = new-object System.Net.NetworkCredential('%MVNW_USERNAME%', '%MVNW_PASSWORD%');"^ - "}"^ - "[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12; $webclient.DownloadFile('%DOWNLOAD_URL%', '%WRAPPER_JAR%')"^ - "}" - if "%MVNW_VERBOSE%" == "true" ( - echo Finished downloading %WRAPPER_JAR% - ) -) -@REM End of extension - -@REM Provide a "standardized" way to retrieve the CLI args that will -@REM work with both Windows and non-Windows executions. -set MAVEN_CMD_LINE_ARGS=%* - -%MAVEN_JAVA_EXE% %JVM_CONFIG_MAVEN_PROPS% %MAVEN_OPTS% %MAVEN_DEBUG_OPTS% -classpath %WRAPPER_JAR% "-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" %WRAPPER_LAUNCHER% %MAVEN_CONFIG% %* -if ERRORLEVEL 1 goto error -goto end - -:error -set ERROR_CODE=1 - -:end -@endlocal & set ERROR_CODE=%ERROR_CODE% - -if not "%MAVEN_SKIP_RC%" == "" goto skipRcPost -@REM check for post script, once with legacy .bat ending and once with .cmd ending -if exist "%HOME%\mavenrc_post.bat" call "%HOME%\mavenrc_post.bat" -if exist "%HOME%\mavenrc_post.cmd" call "%HOME%\mavenrc_post.cmd" -:skipRcPost - -@REM pause the script if MAVEN_BATCH_PAUSE is set to 'on' -if "%MAVEN_BATCH_PAUSE%" == "on" pause - -if "%MAVEN_TERMINATE_CMD%" == "on" exit %ERROR_CODE% - -exit /B %ERROR_CODE% diff --git a/persistence-commons/kogito-ddl/pom.xml b/persistence-commons/kogito-ddl/pom.xml index ca095ec2fb..e8dbb6ae4a 100644 --- a/persistence-commons/kogito-ddl/pom.xml +++ b/persistence-commons/kogito-ddl/pom.xml @@ -72,17 +72,4 @@ - - - productized - - - productized - - - - src/assembly/productized-multi-repo-zip.xml - - - \ No newline at end of file diff --git a/persistence-commons/kogito-ddl/src/assembly/productized-multi-repo-zip.xml b/persistence-commons/kogito-ddl/src/assembly/productized-multi-repo-zip.xml deleted file mode 100644 index 4a590072c8..0000000000 --- a/persistence-commons/kogito-ddl/src/assembly/productized-multi-repo-zip.xml +++ /dev/null @@ -1,75 +0,0 @@ - - - db-scripts - - zip - - false - - - true - . - - org.kie:kie-ddl-runtimes:zip:db-scripts - - - - - - - ${project.root.dir}/persistence-commons/persistence-commons-postgresql/src/main/resources/kie-flyway/db/persistence-commons/postgresql - postgresql/persistence-commons - - *.sql - - - - - - ${project.root.dir}/data-index/data-index-storage/data-index-storage-postgresql/src/main/resources/kie-flyway/db/data-index/postgresql - postgresql/data-index - - *.sql - - - - - - ${project.root.dir}/data-audit/kogito-addons-data-audit-jpa/kogito-addons-data-audit-jpa-common/src/main/resources/kie-flyway/db/data-audit/postgresql - postgresql/data-audit - - *.sql - - - - - - ${project.root.dir}/jobs-service/jobs-service-postgresql-common/src/main/resources/kie-flyway/db/jobs-service/postgresql - postgresql/jobs-service - - *.sql - - - - diff --git a/.mvn/wrapper/maven-wrapper.properties b/persistence-commons/persistence-commons-jpa-base/src/main/resources/application.properties similarity index 72% rename from .mvn/wrapper/maven-wrapper.properties rename to persistence-commons/persistence-commons-jpa-base/src/main/resources/application.properties index dc3affce3d..c4820ddf59 100644 --- a/.mvn/wrapper/maven-wrapper.properties +++ b/persistence-commons/persistence-commons-jpa-base/src/main/resources/application.properties @@ -1,3 +1,4 @@ +# # 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 @@ -6,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 # -# https://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 @@ -14,5 +15,6 @@ # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. -distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.8.6/apache-maven-3.8.6-bin.zip -wrapperUrl=https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.1.1/maven-wrapper-3.1.1.jar +# + +quarkus.datasource.jdbc.additional-jdbc-properties.stringtype=unspecified diff --git a/persistence-commons/persistence-commons-jpa/src/main/resources/META-INF/kie-flyway.properties b/persistence-commons/persistence-commons-jpa/src/main/resources/META-INF/kie-flyway.properties new file mode 100644 index 0000000000..cf9d0ea888 --- /dev/null +++ b/persistence-commons/persistence-commons-jpa/src/main/resources/META-INF/kie-flyway.properties @@ -0,0 +1,23 @@ +# +# 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. +# + +module.name=persistence-commons + +module.locations.postgresql=classpath:kie-flyway/db/persistence-commons/postgresql +module.locations.default=classpath:kie-flyway/db/persistence-commons/ansi \ No newline at end of file diff --git a/persistence-commons/persistence-commons-jpa/src/main/resources/kie-flyway/db/persistence-commons/ansi/V1.5.0__kogito_apps_create_kogito_data_cache.sql b/persistence-commons/persistence-commons-jpa/src/main/resources/kie-flyway/db/persistence-commons/ansi/V1.5.0__kogito_apps_create_kogito_data_cache.sql index 3b6a41389d..bf660066aa 100644 --- a/persistence-commons/persistence-commons-jpa/src/main/resources/kie-flyway/db/persistence-commons/ansi/V1.5.0__kogito_apps_create_kogito_data_cache.sql +++ b/persistence-commons/persistence-commons-jpa/src/main/resources/kie-flyway/db/persistence-commons/ansi/V1.5.0__kogito_apps_create_kogito_data_cache.sql @@ -20,6 +20,6 @@ create table if not exists kogito_data_cache ( key varchar(255) not null, name varchar(255) not null, - json_value varbinary(max), + json_value varchar(max), primary key (key, name) ); \ No newline at end of file diff --git a/persistence-commons/persistence-commons-postgresql/src/main/resources/META-INF/kie-flyway.properties b/persistence-commons/persistence-commons-postgresql/src/main/resources/META-INF/kie-flyway.properties new file mode 100644 index 0000000000..4faa9f9836 --- /dev/null +++ b/persistence-commons/persistence-commons-postgresql/src/main/resources/META-INF/kie-flyway.properties @@ -0,0 +1,22 @@ +# +# 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. +# + +module.name=persistence-commons + +module.locations.postgresql=classpath:kie-flyway/db/persistence-commons/postgresql \ No newline at end of file diff --git a/persistence-commons/persistence-commons-redis/pom.xml b/persistence-commons/persistence-commons-redis/pom.xml index 5b0c0d6832..1a524df1d7 100644 --- a/persistence-commons/persistence-commons-redis/pom.xml +++ b/persistence-commons/persistence-commons-redis/pom.xml @@ -44,6 +44,16 @@ com.redislabs jredisearch + + + org.json + json + + + + + org.json + json io.quarkus