This is an automated email from the ASF dual-hosted git repository.
gitgabrio pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/incubator-kie-kogito-apps.git
The following commit(s) were added to refs/heads/main by this push:
new 1d8f0773f [incubator-kie-issues#908] Validate new DMN 1.5 features
(#2014)
1d8f0773f is described below
commit 1d8f0773fe1e31c70e52c6480bdff1c03bbbb152
Author: Gabriele Cardosi <[email protected]>
AuthorDate: Fri Mar 15 13:58:09 2024 +0100
[incubator-kie-issues#908] Validate new DMN 1.5 features (#2014)
* [incubator-kie-issues#908] Testing DMN 1.5 features inside jitexecutor
* [incubator-kie-issues#908] Formatting!!!!!!
* [incubator-kie-issues#908] Fixing impsort!!!!!!
---------
Co-authored-by: Gabriele-Cardosi <[email protected]>
---
jitexecutor/jitexecutor-dmn/pom.xml | 13 ++
.../org/kie/kogito/jitexecutor/dmn/DMN15Test.java | 236 +++++++++++++++++++++
2 files changed, 249 insertions(+)
diff --git a/jitexecutor/jitexecutor-dmn/pom.xml
b/jitexecutor/jitexecutor-dmn/pom.xml
index 80a29975a..b0972e9a2 100644
--- a/jitexecutor/jitexecutor-dmn/pom.xml
+++ b/jitexecutor/jitexecutor-dmn/pom.xml
@@ -43,6 +43,13 @@
<type>pom</type>
<scope>import</scope>
</dependency>
+ <dependency>
+ <groupId>org.kie</groupId>
+ <artifactId>kie-dmn-test-resources</artifactId>
+ <version>${project.version}</version>
+ <classifier>tests</classifier>
+ <scope>test</scope>
+ </dependency>
</dependencies>
</dependencyManagement>
@@ -92,6 +99,12 @@
<artifactId>trusty-storage-api</artifactId>
</dependency>
+ <dependency>
+ <groupId>org.kie</groupId>
+ <artifactId>kie-dmn-test-resources</artifactId>
+ <classifier>tests</classifier>
+ <scope>test</scope>
+ </dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-junit5</artifactId>
diff --git
a/jitexecutor/jitexecutor-dmn/src/test/java/org/kie/kogito/jitexecutor/dmn/DMN15Test.java
b/jitexecutor/jitexecutor-dmn/src/test/java/org/kie/kogito/jitexecutor/dmn/DMN15Test.java
new file mode 100644
index 000000000..c700d02e0
--- /dev/null
+++
b/jitexecutor/jitexecutor-dmn/src/test/java/org/kie/kogito/jitexecutor/dmn/DMN15Test.java
@@ -0,0 +1,236 @@
+/*
+ * 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.io.IOException;
+import java.io.InputStream;
+import java.net.URL;
+import java.nio.charset.StandardCharsets;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+
+import org.drools.util.IoUtils;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.Test;
+import org.kie.dmn.api.core.DMNDecisionResult;
+import org.kie.dmn.api.core.DMNMessage;
+import org.kie.dmn.api.core.DMNResult;
+import org.kie.kogito.jitexecutor.common.requests.MultipleResourcesPayload;
+import org.kie.kogito.jitexecutor.common.requests.ResourceWithURI;
+import org.kie.kogito.jitexecutor.dmn.requests.JITDMNPayload;
+import org.kie.kogito.jitexecutor.dmn.responses.JITDMNDecisionResult;
+import org.kie.kogito.jitexecutor.dmn.responses.JITDMNMessage;
+import org.kie.kogito.jitexecutor.dmn.responses.JITDMNResult;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.fasterxml.jackson.databind.DeserializationFeature;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.module.SimpleModule;
+import com.fasterxml.jackson.databind.type.CollectionType;
+import com.fasterxml.jackson.datatype.jdk8.Jdk8Module;
+
+import io.quarkus.test.junit.QuarkusTest;
+import io.restassured.RestAssured;
+import io.restassured.http.ContentType;
+import io.restassured.response.ValidatableResponse;
+
+import static io.restassured.RestAssured.given;
+import static org.hamcrest.CoreMatchers.is;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+
+@QuarkusTest
+class DMN15Test {
+
+ private static final Logger LOG = LoggerFactory.getLogger(DMN15Test.class);
+ private static final ObjectMapper MAPPER;
+
+ static {
+ final var jitModule = new
SimpleModule().addAbstractTypeMapping(DMNResult.class, JITDMNResult.class)
+ .addAbstractTypeMapping(DMNDecisionResult.class,
JITDMNDecisionResult.class)
+ .addAbstractTypeMapping(DMNMessage.class, JITDMNMessage.class);
+
+ MAPPER = new ObjectMapper()
+ .registerModule(new Jdk8Module())
+ .registerModule(jitModule);
+ MAPPER.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES,
false);
+ }
+
+ private static final CollectionType LIST_OF_MSGS = MAPPER.getTypeFactory()
+ .constructCollectionType(List.class,
+ JITDMNMessage.class);
+
+ @BeforeAll
+ public static void setup() {
+ RestAssured.enableLoggingOfRequestAndResponseIfValidationFails();
+ }
+
+ @Test
+ void unnamedImport() throws IOException {
+ String URI1 = "Importing_EmptyNamed_Model.dmn";
+ String URI2 = "Imported_Model_Unamed.dmn";
+ ResourceWithURI model1 = new ResourceWithURI(URI1,
getModelFromIoUtils(URI1));
+ ResourceWithURI model2 = new ResourceWithURI(URI2,
getModelFromIoUtils(URI2));
+
+ JITDMNPayload jitdmnpayload = new JITDMNPayload(URI1, List.of(model1,
model2), Collections.EMPTY_MAP);
+ given()
+ .contentType(ContentType.JSON)
+ .body(jitdmnpayload)
+ .when().post("/jitdmn")
+ .then()
+ .statusCode(200)
+ .body("'Local Hello'", is("function Local Hello( Person )"))
+ .body("'Say Hello'", is("function Say Hello( Person )"));
+
+ String response = given()
+ .contentType(ContentType.JSON)
+ .body(new MultipleResourcesPayload(URI1, List.of(model1,
model2)))
+ .when()
+ .post("/jitdmn/validate")
+ .then()
+ .statusCode(200)
+ .extract()
+ .asString();
+ LOG.info("Validate response: {}", response);
+ List<JITDMNMessage> messages = MAPPER.readValue(response,
LIST_OF_MSGS);
+ assertEquals(0, messages.size());
+
+ Map<String, Object> context =
+ Map.of("A Person", Map.of("name", "John", "age", 47));
+ jitdmnpayload = new JITDMNPayload(URI1, List.of(model1, model2),
context);
+ given()
+ .contentType(ContentType.JSON)
+ .body(jitdmnpayload)
+ .when()
+ .post("/jitdmn/dmnresult")
+ .then()
+ .statusCode(200)
+ .body("decisionResults.result[0]", is("Hello John!"))
+ .body("decisionResults.result[1]", is("Local Hello John!"));
+ }
+
+ @Test
+ void forLoopDatesEvaluate() throws IOException {
+ String modelFileName = "ForLoopDatesEvaluate.dmn";
+ validate(getModelFromIoUtils(modelFileName));
+ String model = getModel(modelFileName);
+ Map<String, Object> expectedValues = Map.of("forloopdates[0]",
"2021-01-02",
+ "forloopdates[1]", "2021-01-03",
+ "forloopdates[2]", "2021-01-04");
+ endpoint(model, expectedValues);
+ expectedValues = Map.of("decisionResults.result[0][0]", "2021-01-02",
+ "decisionResults.result[0][1]", "2021-01-03",
+ "decisionResults.result[0][2]", "2021-01-04");
+ result(model, expectedValues);
+ }
+
+ @Test
+ void listReplaceEvaluate() throws IOException {
+ String modelFileName = "ListReplaceEvaluate.dmn";
+ validate(getModelFromIoUtils(modelFileName));
+ String model = getModel(modelFileName);
+ Map<String, Object> expectedValues = Map.of("listreplacenumbers[0]", 2,
+ "listreplacenumbers[1]", 4,
+ "listreplacenumbers[2]", 6,
+ "listreplacenumbers[3]", 8);
+ endpoint(model, expectedValues);
+ expectedValues = Map.of("decisionResults.result[0][0]", 2,
+ "decisionResults.result[0][1]", 4,
+ "decisionResults.result[0][2]", 6,
+ "decisionResults.result[0][3]", 8);
+ result(model, expectedValues);
+ }
+
+ @Test
+ void negationOfDurationEvaluate() throws IOException {
+ String modelFileName = "NegationOfDurationEvaluate.dmn";
+ validate(getModelFromIoUtils(modelFileName));
+ String model = getModel(modelFileName);
+ Map<String, Object> expectedValues = Map.of("durationnegation", true);
+ endpoint(model, expectedValues);
+ expectedValues = Map.of("decisionResults.result[0]", true);
+ result(model, expectedValues);
+ }
+
+ @Test
+ void dateToDateTimeFunction() throws IOException {
+ String modelFileName = "DateToDateTimeFunction.dmn";
+ validate(getModelFromIoUtils(modelFileName));
+ String model = getModel(modelFileName);
+ Map<String, Object> expectedValues = Map.of("normal", "function
normal( a, b )",
+ "usingNormal", "2021-05-31T00:00:00Z");
+ endpoint(model, expectedValues);
+ result(model, Map.of("decisionResults.result[0]",
"2021-05-31T00:00:00Z"));
+ }
+
+ private void result(String model, Map<String, Object> expectedValues) {
+ String payload = "{ \"model\": " + model + ", \"context\": {\n" +
+ "}}";
+ ValidatableResponse validatableResponse = given()
+ .contentType(ContentType.JSON)
+ .body(payload)
+ .when()
+ .post("/jitdmn/dmnresult")
+ .then()
+ .statusCode(200);
+ expectedValues.forEach((key, value) -> validatableResponse.body(key,
is(value)));
+ }
+
+ private void endpoint(String model, Map<String, Object> expectedValues) {
+ String payload = "{ \"model\": " + model + ", \"context\": {\n" +
+ "}}";
+ ValidatableResponse validatableResponse = given()
+ .contentType(ContentType.JSON)
+ .accept(ContentType.JSON)
+ .body(payload)
+ .post("/jitdmn")
+ .then()
+ .statusCode(200);
+ expectedValues.forEach((key, value) -> validatableResponse.body(key,
is(value)));
+ }
+
+ private void validate(String model) throws IOException {
+ String response = given()
+ .contentType(ContentType.XML)
+ .body(model)
+ .when()
+ .post("/jitdmn/validate")
+ .then()
+ .statusCode(200)
+ .extract()
+ .asString();
+ LOG.info("Validate response: {}", response);
+ List<JITDMNMessage> messages = MAPPER.readValue(response,
LIST_OF_MSGS);
+ assertEquals(0, messages.size());
+ }
+
+ private String getModelFromIoUtils(String modelFileName) throws
IOException {
+ return new
String(IoUtils.readBytesFromInputStream(Thread.currentThread().getContextClassLoader().getResourceAsStream(modelFileName)));
+ }
+
+ private String getModel(String modelFileName) throws IOException {
+ URL resource =
Thread.currentThread().getContextClassLoader().getResource(modelFileName);
+ assertNotNull(resource);
+ try (InputStream is = resource.openStream()) {
+ return MAPPER.writeValueAsString(new String(is.readAllBytes(),
StandardCharsets.UTF_8));
+ }
+ }
+}
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]