diff --git a/jitexecutor/jitexecutor-dmn/pom.xml b/jitexecutor/jitexecutor-dmn/pom.xml index f38b164c83..a2e705a419 100644 --- a/jitexecutor/jitexecutor-dmn/pom.xml +++ b/jitexecutor/jitexecutor-dmn/pom.xml @@ -121,6 +121,11 @@ assertj-core test + + org.mockito + mockito-junit-jupiter + test + 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 7c73c5eccc..54840c86b8 100644 --- a/jitexecutor/jitexecutor-dmn/src/main/java/org/kie/kogito/jitexecutor/dmn/DMNEvaluator.java +++ b/jitexecutor/jitexecutor-dmn/src/main/java/org/kie/kogito/jitexecutor/dmn/DMNEvaluator.java @@ -22,11 +22,15 @@ import java.util.Collection; import java.util.Collections; import java.util.HashMap; +import java.util.List; import java.util.Map; import java.util.Optional; +import java.util.stream.Collectors; +import org.kie.api.builder.Message; import org.kie.api.io.Resource; import org.kie.dmn.api.core.DMNContext; +import org.kie.dmn.api.core.DMNMessage; import org.kie.dmn.api.core.DMNModel; import org.kie.dmn.api.core.DMNResult; import org.kie.dmn.api.core.DMNRuntime; @@ -51,7 +55,43 @@ public static DMNEvaluator fromXML(String modelXML) { .fromResources(Collections.singletonList(modelResource)).getOrElseThrow(RuntimeException::new); dmnRuntime.addListener(new JITDMNListener()); DMNModel dmnModel = dmnRuntime.getModels().get(0); - return new DMNEvaluator(dmnModel, dmnRuntime); + return validateForErrors(dmnModel, dmnRuntime); + } + + public static DMNEvaluator fromMultiple(MultipleResourcesPayload payload) { + Map resources = new HashMap<>(); + for (ResourceWithURI r : payload.getResources()) { + Resource readerResource = ResourceFactory.newReaderResource(new StringReader(r.getContent()), "UTF-8"); + readerResource.setSourcePath(r.getURI()); + resources.put(r.getURI(), readerResource); + } + ResolveByKey rbk = new ResolveByKey(resources); + DMNRuntime dmnRuntime = DMNRuntimeBuilder.fromDefaults() + .setRelativeImportResolver((x, y, locationURI) -> rbk.readerByKey(locationURI)) + .buildConfiguration() + .fromResources(resources.values()) + .getOrElseThrow(RuntimeException::new); + DMNModel mainModel = null; + for (DMNModel m : dmnRuntime.getModels()) { + if (m.getResource().getSourcePath().equals(payload.getMainURI())) { + mainModel = m; + break; + } + } + if (mainModel == null) { + throw new IllegalStateException("Was not able to identify main model from MultipleResourcesPayload contents."); + } + return validateForErrors(mainModel, dmnRuntime); + } + + static DMNEvaluator validateForErrors(DMNModel dmnModel, DMNRuntime dmnRuntime) { + if (dmnModel.hasErrors()) { + List messages = dmnModel.getMessages(DMNMessage.Severity.ERROR); + String errorMessage = messages.stream().map(Message::getText).collect(Collectors.joining(", ")); + throw new IllegalStateException(errorMessage); + } else { + return new DMNEvaluator(dmnModel, dmnRuntime); + } } private DMNEvaluator(DMNModel dmnModel, DMNRuntime dmnRuntime) { @@ -88,29 +128,4 @@ public JITDMNResult evaluate(Map context) { return new JITDMNResult(getNamespace(), getName(), dmnResult, evaluationHitIds.orElse(Collections.emptyMap())); } - public static DMNEvaluator fromMultiple(MultipleResourcesPayload payload) { - Map resources = new HashMap<>(); - for (ResourceWithURI r : payload.getResources()) { - Resource readerResource = ResourceFactory.newReaderResource(new StringReader(r.getContent()), "UTF-8"); - readerResource.setSourcePath(r.getURI()); - resources.put(r.getURI(), readerResource); - } - ResolveByKey rbk = new ResolveByKey(resources); - DMNRuntime dmnRuntime = DMNRuntimeBuilder.fromDefaults() - .setRelativeImportResolver((x, y, locationURI) -> rbk.readerByKey(locationURI)) - .buildConfiguration() - .fromResources(resources.values()) - .getOrElseThrow(RuntimeException::new); - DMNModel mainModel = null; - for (DMNModel m : dmnRuntime.getModels()) { - if (m.getResource().getSourcePath().equals(payload.getMainURI())) { - mainModel = m; - break; - } - } - if (mainModel == null) { - throw new IllegalStateException("Was not able to identify main model from MultipleResourcesPayload contents."); - } - return new DMNEvaluator(mainModel, dmnRuntime); - } } diff --git a/jitexecutor/jitexecutor-dmn/src/main/java/org/kie/kogito/jitexecutor/dmn/api/DMNResourceHelper.java b/jitexecutor/jitexecutor-dmn/src/main/java/org/kie/kogito/jitexecutor/dmn/api/DMNResourceHelper.java new file mode 100644 index 0000000000..b06064acc2 --- /dev/null +++ b/jitexecutor/jitexecutor-dmn/src/main/java/org/kie/kogito/jitexecutor/dmn/api/DMNResourceHelper.java @@ -0,0 +1,38 @@ +/* + * 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.api; + +import java.util.function.Supplier; + +import jakarta.ws.rs.core.Response; + +public class DMNResourceHelper { + + private DMNResourceHelper() { + } + + public static Response manageResponse(Supplier responseSupplier) { + try { + return responseSupplier.get(); + } catch (Exception e) { + String errorMessage = e.getMessage() != null ? e.getMessage() : "Failed to get result due to " + e.getClass().getName(); + return Response.status(Response.Status.BAD_REQUEST).entity(errorMessage).build(); + } + } +} diff --git a/jitexecutor/jitexecutor-dmn/src/main/java/org/kie/kogito/jitexecutor/dmn/api/JITDMNResource.java b/jitexecutor/jitexecutor-dmn/src/main/java/org/kie/kogito/jitexecutor/dmn/api/JITDMNResource.java index 69d4eb8b87..19afd5c2e7 100644 --- a/jitexecutor/jitexecutor-dmn/src/main/java/org/kie/kogito/jitexecutor/dmn/api/JITDMNResource.java +++ b/jitexecutor/jitexecutor-dmn/src/main/java/org/kie/kogito/jitexecutor/dmn/api/JITDMNResource.java @@ -21,6 +21,7 @@ import java.util.HashMap; import java.util.Map; import java.util.Map.Entry; +import java.util.function.Supplier; import org.kie.dmn.core.internal.utils.MarshallingStubUtils; import org.kie.kogito.jitexecutor.dmn.JITDMNService; @@ -56,12 +57,15 @@ public Response jitdmn(JITDMNPayload payload) { LOGGER.debug("jitdmn/"); LOGGER.debug(payload.toString()); LOGGER.debug(LINEBREAK); - JITDMNResult evaluateAll = payload.getModel() != null ? jitdmnService.evaluateModel(payload.getModel(), payload.getContext()) : jitdmnService.evaluateModel(payload, payload.getContext()); - Map restResulk = new HashMap<>(); - for (Entry kv : evaluateAll.getContext().getAll().entrySet()) { - restResulk.put(kv.getKey(), MarshallingStubUtils.stubDMNResult(kv.getValue(), String::valueOf)); - } - return Response.ok(restResulk).build(); + Supplier supplier = () -> { + JITDMNResult evaluateAll = payload.getModel() != null ? jitdmnService.evaluateModel(payload.getModel(), payload.getContext()) : jitdmnService.evaluateModel(payload, payload.getContext()); + Map restResulk = new HashMap<>(); + for (Entry kv : evaluateAll.getContext().getAll().entrySet()) { + restResulk.put(kv.getKey(), MarshallingStubUtils.stubDMNResult(kv.getValue(), String::valueOf)); + } + return Response.ok(restResulk).build(); + }; + return DMNResourceHelper.manageResponse(supplier); } @POST @@ -73,8 +77,11 @@ public Response jitdmnResult(JITDMNPayload payload) { LOGGER.debug("jitdmn/dmnresult"); LOGGER.debug(payload.toString()); LOGGER.debug(LINEBREAK); - JITDMNResult dmnResult = payload.getModel() != null ? jitdmnService.evaluateModel(payload.getModel(), payload.getContext()) : jitdmnService.evaluateModel(payload, payload.getContext()); - return Response.ok(dmnResult).build(); + Supplier supplier = () -> { + JITDMNResult dmnResult = payload.getModel() != null ? jitdmnService.evaluateModel(payload.getModel(), payload.getContext()) : jitdmnService.evaluateModel(payload, payload.getContext()); + return Response.ok(dmnResult).build(); + }; + return DMNResourceHelper.manageResponse(supplier); } @POST @@ -86,9 +93,12 @@ public Response jitEvaluateAndExplain(JITDMNPayload payload) { LOGGER.debug("jitdmn/evaluateAndExplain"); LOGGER.debug(payload.toString()); LOGGER.debug(LINEBREAK); - DMNResultWithExplanation response = - payload.getModel() != null ? jitdmnService.evaluateModelAndExplain(payload.getModel(), payload.getContext()) : jitdmnService.evaluateModelAndExplain(payload, payload.getContext()); - return Response.ok(response).build(); + Supplier supplier = () -> { + DMNResultWithExplanation response = + payload.getModel() != null ? jitdmnService.evaluateModelAndExplain(payload.getModel(), payload.getContext()) : jitdmnService.evaluateModelAndExplain(payload, payload.getContext()); + return Response.ok(response).build(); + }; + return DMNResourceHelper.manageResponse(supplier); } } diff --git a/jitexecutor/jitexecutor-dmn/src/main/java/org/kie/kogito/jitexecutor/dmn/api/SchemaResource.java b/jitexecutor/jitexecutor-dmn/src/main/java/org/kie/kogito/jitexecutor/dmn/api/SchemaResource.java index b1ce72029c..674cff40b2 100644 --- a/jitexecutor/jitexecutor-dmn/src/main/java/org/kie/kogito/jitexecutor/dmn/api/SchemaResource.java +++ b/jitexecutor/jitexecutor-dmn/src/main/java/org/kie/kogito/jitexecutor/dmn/api/SchemaResource.java @@ -21,6 +21,7 @@ import java.util.Collections; import java.util.List; import java.util.Map; +import java.util.function.Supplier; import org.eclipse.microprofile.openapi.OASFactory; import org.eclipse.microprofile.openapi.models.OpenAPI; @@ -75,9 +76,12 @@ public Response schema(String payload) { LOGGER.debug("jitdmn/validate"); LOGGER.debug(payload); LOGGER.debug(LINEBREAK); - DMNModel dmnModel = DMNEvaluator.fromXML(payload).getDmnModel(); - DMNOASResult oasResult = DMNOASGeneratorFactory.generator(Collections.singletonList(dmnModel)).build(); - return fullSchema(dmnModel, oasResult, true); + Supplier supplier = () -> { + DMNModel dmnModel = DMNEvaluator.fromXML(payload).getDmnModel(); + DMNOASResult oasResult = DMNOASGeneratorFactory.generator(Collections.singletonList(dmnModel)).build(); + return fullSchema(dmnModel, oasResult, true); + }; + return DMNResourceHelper.manageResponse(supplier); } private Response fullSchema(DMNModel dmnModel, DMNOASResult oasResult, final boolean singleModel) { @@ -111,10 +115,13 @@ private Response fullSchema(DMNModel dmnModel, DMNOASResult oasResult, final boo @Consumes(MediaType.APPLICATION_JSON) @Produces(MediaType.APPLICATION_JSON) public Response schema(MultipleResourcesPayload payload) { - DMNEvaluator dmnEvaluator = DMNEvaluator.fromMultiple(payload); - DMNModel dmnModel = dmnEvaluator.getDmnModel(); - DMNOASResult oasResult = DMNOASGeneratorFactory.generator(dmnEvaluator.getAllDMNModels()).build(); - return fullSchema(dmnModel, oasResult, false); + Supplier supplier = () -> { + DMNEvaluator dmnEvaluator = DMNEvaluator.fromMultiple(payload); + DMNModel dmnModel = dmnEvaluator.getDmnModel(); + DMNOASResult oasResult = DMNOASGeneratorFactory.generator(dmnEvaluator.getAllDMNModels()).build(); + return fullSchema(dmnModel, oasResult, false); + }; + return DMNResourceHelper.manageResponse(supplier); } @POST @@ -122,9 +129,12 @@ public Response schema(MultipleResourcesPayload payload) { @Produces(MediaType.APPLICATION_JSON) @Path("form") public Response form(String payload) { - DMNModel dmnModel = DMNEvaluator.fromXML(payload).getDmnModel(); - DMNOASResult oasResult = DMNOASGeneratorFactory.generator(Collections.singletonList(dmnModel)).build(); - return formSchema(dmnModel, oasResult); + Supplier supplier = () -> { + DMNModel dmnModel = DMNEvaluator.fromXML(payload).getDmnModel(); + DMNOASResult oasResult = DMNOASGeneratorFactory.generator(Collections.singletonList(dmnModel)).build(); + return formSchema(dmnModel, oasResult); + }; + return DMNResourceHelper.manageResponse(supplier); } @POST @@ -132,10 +142,13 @@ public Response form(String payload) { @Produces(MediaType.APPLICATION_JSON) @Path("form") public Response form(MultipleResourcesPayload payload) { - DMNEvaluator dmnEvaluator = DMNEvaluator.fromMultiple(payload); - DMNModel dmnModel = dmnEvaluator.getDmnModel(); - DMNOASResult oasResult = DMNOASGeneratorFactory.generator(dmnEvaluator.getAllDMNModels()).build(); - return formSchema(dmnModel, oasResult); + Supplier supplier = () -> { + DMNEvaluator dmnEvaluator = DMNEvaluator.fromMultiple(payload); + DMNModel dmnModel = dmnEvaluator.getDmnModel(); + DMNOASResult oasResult = DMNOASGeneratorFactory.generator(dmnEvaluator.getAllDMNModels()).build(); + return formSchema(dmnModel, oasResult); + }; + return DMNResourceHelper.manageResponse(supplier); } private Response formSchema(DMNModel dmnModel, DMNOASResult oasResult) { diff --git a/jitexecutor/jitexecutor-dmn/src/test/java/org/kie/kogito/jitexecutor/dmn/DMNEvaluatorTest.java b/jitexecutor/jitexecutor-dmn/src/test/java/org/kie/kogito/jitexecutor/dmn/DMNEvaluatorTest.java new file mode 100644 index 0000000000..71a5edb1a7 --- /dev/null +++ b/jitexecutor/jitexecutor-dmn/src/test/java/org/kie/kogito/jitexecutor/dmn/DMNEvaluatorTest.java @@ -0,0 +1,91 @@ +/* + * 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.util.Collections; + +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; +import org.kie.dmn.api.core.DMNMessage; +import org.kie.dmn.api.core.DMNModel; +import org.kie.dmn.api.core.DMNRuntime; +import org.kie.dmn.core.impl.DMNRuntimeImpl; + +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.kie.kogito.jitexecutor.dmn.TestingUtils.getModelFromIoUtils; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +public class DMNEvaluatorTest { + + private static String model; + private static String invalidModel; + + @BeforeAll + public static void setup() throws IOException { + model = getModelFromIoUtils("invalid_models/DMNv1_x/test.dmn"); + invalidModel = getModelFromIoUtils("invalid_models/DMNv1_5/DMN-Invalid.dmn"); + } + + @Test + void testFromXMLSuccessModel() { + String modelXML = model; + + DMNEvaluator evaluator = DMNEvaluator.fromXML(modelXML); + assertNotNull(evaluator); + } + + @Test + public void testFromXMLModelWithError() { + String modelXML = invalidModel; + + assertThrows(IllegalStateException.class, () -> { + DMNEvaluator.fromXML(modelXML); + }); + } + + @Test + void testValidateForErrorsThrowsException() { + DMNModel dmnModel = mock(DMNModel.class); + DMNRuntime dmnRuntime = mock(DMNRuntime.class); + DMNMessage message = mock(DMNMessage.class); + + String errorMessage = "Error compiling FEEL expression 'Person Age >= 18' for name 'Can Drive?' on node 'Can Drive?': syntax error near 'Age'"; + when(message.getText()).thenReturn(errorMessage); + when(dmnModel.hasErrors()).thenReturn(true); + when(dmnModel.getMessages(DMNMessage.Severity.ERROR)).thenReturn(Collections.singletonList(message)); + + assertThrows(IllegalStateException.class, + () -> DMNEvaluator.validateForErrors(dmnModel, dmnRuntime), errorMessage); + } + + @Test + void testValidateForErrors() { + DMNModel dmnModel = mock(DMNModel.class); + DMNRuntime dmnRuntime = mock(DMNRuntimeImpl.class); + + when(dmnModel.hasErrors()).thenReturn(false); + DMNEvaluator evaluator = DMNEvaluator.validateForErrors(dmnModel, dmnRuntime); + + assertNotNull(evaluator); + } + +} diff --git a/jitexecutor/jitexecutor-dmn/src/test/java/org/kie/kogito/jitexecutor/dmn/DMNResourceHelperTest.java b/jitexecutor/jitexecutor-dmn/src/test/java/org/kie/kogito/jitexecutor/dmn/DMNResourceHelperTest.java new file mode 100644 index 0000000000..bd6ee56291 --- /dev/null +++ b/jitexecutor/jitexecutor-dmn/src/test/java/org/kie/kogito/jitexecutor/dmn/DMNResourceHelperTest.java @@ -0,0 +1,55 @@ +/* + * 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.function.Supplier; + +import org.junit.jupiter.api.Test; +import org.kie.kogito.jitexecutor.dmn.api.DMNResourceHelper; + +import jakarta.ws.rs.core.Response; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +public class DMNResourceHelperTest { + + @Test + public void testManageResponseWithSuccess() { + Supplier responseSupplier = () -> Response.ok("Success").build(); + try (Response response = DMNResourceHelper.manageResponse(responseSupplier)) { + assertEquals(Response.Status.OK.getStatusCode(), response.getStatus()); + assertEquals("Success", response.getEntity()); + } + + } + + @Test + public void testManageResponseWithFailure() { + Supplier responseSupplier = mock(Supplier.class); + when(responseSupplier.get()).thenThrow(new IllegalStateException("Error : Failed to validate")); + try (Response response = DMNResourceHelper.manageResponse(responseSupplier)) { + assertEquals(Response.Status.BAD_REQUEST.getStatusCode(), response.getStatus()); + assertEquals("Error : Failed to validate", response.getEntity()); + } + + } + +} diff --git a/jitexecutor/jitexecutor-dmn/src/test/java/org/kie/kogito/jitexecutor/dmn/TestingUtils.java b/jitexecutor/jitexecutor-dmn/src/test/java/org/kie/kogito/jitexecutor/dmn/TestingUtils.java index 257b0b4664..f83e0a805a 100644 --- a/jitexecutor/jitexecutor-dmn/src/test/java/org/kie/kogito/jitexecutor/dmn/TestingUtils.java +++ b/jitexecutor/jitexecutor-dmn/src/test/java/org/kie/kogito/jitexecutor/dmn/TestingUtils.java @@ -1,4 +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 @@ -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 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 cacf238916..99634d4d59 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 @@ -46,6 +46,7 @@ @QuarkusTest public class JITDMNResourceTest { + private static String model; private static String invalidModel; private static String modelWithExtensionElements; private static String modelWithMultipleEvaluationHitIds; @@ -60,14 +61,15 @@ public class JITDMNResourceTest { @BeforeAll public static void setup() throws IOException { - invalidModel = getModelFromIoUtils("invalid_models/DMNv1_x/test.dmn"); + model = getModelFromIoUtils("invalid_models/DMNv1_x/test.dmn"); + invalidModel = getModelFromIoUtils("invalid_models/DMNv1_5/DMN-Invalid.dmn"); modelWithExtensionElements = getModelFromIoUtils("valid_models/DMNv1_x/testWithExtensionElements.dmn"); modelWithMultipleEvaluationHitIds = getModelFromIoUtils("valid_models/DMNv1_5/MultipleHitRules.dmn"); } @Test void testjitEndpoint() { - JITDMNPayload jitdmnpayload = new JITDMNPayload(invalidModel, buildContext()); + JITDMNPayload jitdmnpayload = new JITDMNPayload(model, buildContext()); given() .contentType(ContentType.JSON) .body(jitdmnpayload) @@ -116,7 +118,7 @@ void testjitdmnResultEndpointWithEvaluationHitIds() throws JsonProcessingExcepti @Test void testjitExplainabilityEndpoint() { - JITDMNPayload jitdmnpayload = new JITDMNPayload(invalidModel, buildContext()); + JITDMNPayload jitdmnpayload = new JITDMNPayload(model, buildContext()); given() .contentType(ContentType.JSON) .body(jitdmnpayload) @@ -143,6 +145,42 @@ void testjitdmnWithExtensionElements() { .body(containsString("m"), containsString("n"), containsString("sum")); } + @Test + void testjitEndpointFailure() { + JITDMNPayload jitdmnpayload = new JITDMNPayload(invalidModel, buildContext()); + given() + .contentType(ContentType.JSON) + .body(jitdmnpayload) + .when().post("/jitdmn") + .then() + .statusCode(400) + .body(containsString("Error compiling FEEL expression 'Person Age >= 18' for name 'Can Drive?' on node 'Can Drive?': syntax error near 'Age'")); + } + + @Test + void testjitdmnEvaluateInvalidModel() { + JITDMNPayload jitdmnpayload = new JITDMNPayload(invalidModel, buildInvalidModelContext()); + given() + .contentType(ContentType.JSON) + .body(jitdmnpayload) + .when().post("/jitdmn/dmnresult") + .then() + .statusCode(400) + .body(containsString("Error compiling FEEL expression 'Person Age >= 18' for name 'Can Drive?' on node 'Can Drive?': syntax error near 'Age'")); + } + + @Test + void testjitdmnEvaluateAndExplainInvalidModel() { + JITDMNPayload jitdmnpayload = new JITDMNPayload(invalidModel, buildInvalidModelContext()); + given() + .contentType(ContentType.JSON) + .body(jitdmnpayload) + .when().post("/jitdmn/evaluateAndExplain") + .then() + .statusCode(400) + .body(containsString("Error compiling FEEL expression 'Person Age >= 18' for name 'Can Drive?' on node 'Can Drive?': syntax error near 'Age'")); + } + private Map buildContext() { Map context = new HashMap<>(); context.put("FICO Score", 800); @@ -160,4 +198,12 @@ private Map buildMultipleHitContext() { context.put("Numbers", numbers); return context; } + + private Map buildInvalidModelContext() { + Map context = new HashMap<>(); + context.put("Can Drive?", false); + context.put("Person Age", 14); + context.put("Id", 1); + return context; + } } diff --git a/jitexecutor/jitexecutor-dmn/src/test/java/org/kie/kogito/jitexecutor/dmn/api/SchemaResourceTest.java b/jitexecutor/jitexecutor-dmn/src/test/java/org/kie/kogito/jitexecutor/dmn/api/SchemaResourceTest.java index feb28be1c3..6cd22bd460 100644 --- a/jitexecutor/jitexecutor-dmn/src/test/java/org/kie/kogito/jitexecutor/dmn/api/SchemaResourceTest.java +++ b/jitexecutor/jitexecutor-dmn/src/test/java/org/kie/kogito/jitexecutor/dmn/api/SchemaResourceTest.java @@ -43,4 +43,17 @@ public void test() throws IOException { .statusCode(200) .body(containsString("InputSet"), containsString("x-dmn-type")); } + + @Test + public void testJitDmnValidate() throws IOException { + final String MODEL = getModelFromIoUtils("invalid_models/DMNv1_5/DMN-Invalid.dmn"); + given() + .contentType(ContentType.XML) + .body(MODEL) + .when().post("/jitdmn/schema") + .then() + .statusCode(400) + .body(containsString("Error compiling FEEL expression 'Person Age >= 18' for name 'Can Drive?' on node 'Can Drive?': syntax error near 'Age'")); + + } }