This is an automated email from the ASF dual-hosted git repository.

fjtiradosarti pushed a commit to branch main
in repository 
https://gitbox.apache.org/repos/asf/incubator-kie-kogito-runtimes.git


The following commit(s) were added to refs/heads/main by this push:
     new d6abf18555 [Fix #4075] Generate message error from server response 
(#4076)
d6abf18555 is described below

commit d6abf185557d0fb2d51fe1417475f7e10f81007f
Author: Francisco Javier Tirado Sarti 
<[email protected]>
AuthorDate: Fri Oct 3 17:49:09 2025 +0200

    [Fix #4075] Generate message error from server response (#4076)
    
    * [Fix #4075] Generate message error from server response
    
    * [Fix #4075] Gonzalo's comments
---
 .../src/main/resources/application.properties      |  1 +
 .../quarkus/workflows/ConversionErrorFlowIT.java   | 55 ++++++++++++++++++++++
 .../quarkus/workflows/OperationsMockService.java   | 14 +++---
 ...ervice.java => OperationsMockServiceError.java} | 25 ++++------
 .../workflow/openapi/OpenApiWorkItemHandler.java   | 26 +++++++++-
 5 files changed, 96 insertions(+), 25 deletions(-)

diff --git 
a/quarkus/extensions/kogito-quarkus-serverless-workflow-extension/kogito-quarkus-serverless-workflow-integration-test/src/main/resources/application.properties
 
b/quarkus/extensions/kogito-quarkus-serverless-workflow-extension/kogito-quarkus-serverless-workflow-integration-test/src/main/resources/application.properties
index 0000ec86d9..1f77647f4a 100644
--- 
a/quarkus/extensions/kogito-quarkus-serverless-workflow-extension/kogito-quarkus-serverless-workflow-integration-test/src/main/resources/application.properties
+++ 
b/quarkus/extensions/kogito-quarkus-serverless-workflow-extension/kogito-quarkus-serverless-workflow-integration-test/src/main/resources/application.properties
@@ -41,6 +41,7 @@ quarkus.keycloak.devservices.enabled=false
 
 # OpenApi client properties, see OperationsMockService, which is mocking these 
two services
 
quarkus.rest-client."multiplication.cluster1".url=${multiplication-service-mock.url}
+quarkus.rest-client."multiplication.cluster3".url=${error-service-mock.url}
 quarkus.rest-client.subtraction.url=${subtraction-service-mock.url}
 quarkus.rest-client.petstore_openapi_yaml.url=${petstore-service-mock.url}
 quarkus.rest-client.array_yaml.url=${array-service-mock.url}
diff --git 
a/quarkus/extensions/kogito-quarkus-serverless-workflow-extension/kogito-quarkus-serverless-workflow-integration-test/src/test/java/org/kie/kogito/quarkus/workflows/ConversionErrorFlowIT.java
 
b/quarkus/extensions/kogito-quarkus-serverless-workflow-extension/kogito-quarkus-serverless-workflow-integration-test/src/test/java/org/kie/kogito/quarkus/workflows/ConversionErrorFlowIT.java
new file mode 100644
index 0000000000..565623b539
--- /dev/null
+++ 
b/quarkus/extensions/kogito-quarkus-serverless-workflow-extension/kogito-quarkus-serverless-workflow-integration-test/src/test/java/org/kie/kogito/quarkus/workflows/ConversionErrorFlowIT.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.quarkus.workflows;
+
+import java.util.Map;
+
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.Test;
+
+import io.quarkus.test.common.QuarkusTestResource;
+import io.quarkus.test.junit.QuarkusIntegrationTest;
+import io.restassured.RestAssured;
+import io.restassured.http.ContentType;
+
+import static io.restassured.RestAssured.given;
+import static org.hamcrest.CoreMatchers.is;
+
+@QuarkusTestResource(OperationsMockServiceError.class)
+@QuarkusIntegrationTest
+class ConversionErrorFlowIT {
+
+    @BeforeAll
+    static void init() {
+        RestAssured.enableLoggingOfRequestAndResponseIfValidationFails();
+    }
+
+    @Test
+    void sanityVerification() {
+        given()
+                .contentType(ContentType.JSON)
+                .when()
+                .body(Map.of("fahrenheit", "100", "clusterName", "cluster3"))
+                .post("/fahrenheit_to_celsius")
+                .then()
+                .statusCode(500)
+                .body("message", is("{\"difference\":68.0}"));
+    }
+
+}
diff --git 
a/quarkus/extensions/kogito-quarkus-serverless-workflow-extension/kogito-quarkus-serverless-workflow-integration-test/src/test/java/org/kie/kogito/quarkus/workflows/OperationsMockService.java
 
b/quarkus/extensions/kogito-quarkus-serverless-workflow-extension/kogito-quarkus-serverless-workflow-integration-test/src/test/java/org/kie/kogito/quarkus/workflows/OperationsMockService.java
index 4a698d3cce..dd497e0c83 100644
--- 
a/quarkus/extensions/kogito-quarkus-serverless-workflow-extension/kogito-quarkus-serverless-workflow-integration-test/src/test/java/org/kie/kogito/quarkus/workflows/OperationsMockService.java
+++ 
b/quarkus/extensions/kogito-quarkus-serverless-workflow-extension/kogito-quarkus-serverless-workflow-integration-test/src/test/java/org/kie/kogito/quarkus/workflows/OperationsMockService.java
@@ -35,11 +35,11 @@ import static 
com.github.tomakehurst.wiremock.core.WireMockConfiguration.options
 
 public class OperationsMockService implements 
QuarkusTestResourceLifecycleManager {
 
-    private static WireMockServer subtractionService;
-    private static WireMockServer multiplicationService;
+    private WireMockServer subtractionService;
+    private WireMockServer multiplicationService;
 
-    public static final String SUBTRACTION_SERVICE_MOCK_URL = 
"subtraction-service-mock.url";
-    public static final String MULTIPLICATION_SERVICE_MOCK_URL = 
"multiplication-service-mock.url";
+    public final String SUBTRACTION_SERVICE_MOCK_URL = 
"subtraction-service-mock.url";
+    public final String MULTIPLICATION_SERVICE_MOCK_URL = 
"multiplication-service-mock.url";
 
     @Override
     public Map<String, String> start() {
@@ -57,10 +57,11 @@ public class OperationsMockService implements 
QuarkusTestResourceLifecycleManage
     @Override
     public void stop() {
         if (multiplicationService != null) {
-            multiplicationService.stop();
+            multiplicationService.shutdown();
         }
         if (subtractionService != null) {
-            subtractionService.stop();
+            subtractionService.shutdown();
+            ;
         }
     }
 
@@ -68,7 +69,6 @@ public class OperationsMockService implements 
QuarkusTestResourceLifecycleManage
         final WireMockServer server = new 
WireMockServer(options().dynamicPort());
         server.start();
         server.stubFor(function.apply(post(urlEqualTo("/")))
-                .withPort(server.port())
                 .willReturn(aResponse()
                         .withHeader("Content-Type", "application/json")
                         .withBody(response)));
diff --git 
a/quarkus/extensions/kogito-quarkus-serverless-workflow-extension/kogito-quarkus-serverless-workflow-integration-test/src/test/java/org/kie/kogito/quarkus/workflows/OperationsMockService.java
 
b/quarkus/extensions/kogito-quarkus-serverless-workflow-extension/kogito-quarkus-serverless-workflow-integration-test/src/test/java/org/kie/kogito/quarkus/workflows/OperationsMockServiceError.java
similarity index 68%
copy from 
quarkus/extensions/kogito-quarkus-serverless-workflow-extension/kogito-quarkus-serverless-workflow-integration-test/src/test/java/org/kie/kogito/quarkus/workflows/OperationsMockService.java
copy to 
quarkus/extensions/kogito-quarkus-serverless-workflow-extension/kogito-quarkus-serverless-workflow-integration-test/src/test/java/org/kie/kogito/quarkus/workflows/OperationsMockServiceError.java
index 4a698d3cce..f7022858e1 100644
--- 
a/quarkus/extensions/kogito-quarkus-serverless-workflow-extension/kogito-quarkus-serverless-workflow-integration-test/src/test/java/org/kie/kogito/quarkus/workflows/OperationsMockService.java
+++ 
b/quarkus/extensions/kogito-quarkus-serverless-workflow-extension/kogito-quarkus-serverless-workflow-integration-test/src/test/java/org/kie/kogito/quarkus/workflows/OperationsMockServiceError.java
@@ -24,7 +24,6 @@ import java.util.function.UnaryOperator;
 
 import com.github.tomakehurst.wiremock.WireMockServer;
 import com.github.tomakehurst.wiremock.client.MappingBuilder;
-import com.github.tomakehurst.wiremock.matching.EqualToPattern;
 
 import io.quarkus.test.common.QuarkusTestResourceLifecycleManager;
 
@@ -33,34 +32,26 @@ import static 
com.github.tomakehurst.wiremock.client.WireMock.post;
 import static com.github.tomakehurst.wiremock.client.WireMock.urlEqualTo;
 import static 
com.github.tomakehurst.wiremock.core.WireMockConfiguration.options;
 
-public class OperationsMockService implements 
QuarkusTestResourceLifecycleManager {
+public class OperationsMockServiceError implements 
QuarkusTestResourceLifecycleManager {
 
-    private static WireMockServer subtractionService;
-    private static WireMockServer multiplicationService;
+    private WireMockServer errorService;
 
-    public static final String SUBTRACTION_SERVICE_MOCK_URL = 
"subtraction-service-mock.url";
-    public static final String MULTIPLICATION_SERVICE_MOCK_URL = 
"multiplication-service-mock.url";
+    public static final String ERROR_SERVICE_MOCK_URL = 
"error-service-mock.url";
 
     @Override
     public Map<String, String> start() {
-        multiplicationService =
-                startServer("{  \"product\": 37.808 }", p -> 
p.withHeader("pepe", new EqualToPattern("pepa")));
-        subtractionService =
+        errorService =
                 startServer("{ \"difference\": 68.0 }", p -> p);
 
         Map<String, String> result = new HashMap<>();
-        result.put(MULTIPLICATION_SERVICE_MOCK_URL, 
multiplicationService.baseUrl());
-        result.put(SUBTRACTION_SERVICE_MOCK_URL, subtractionService.baseUrl());
+        result.put(ERROR_SERVICE_MOCK_URL, errorService.baseUrl());
         return result;
     }
 
     @Override
     public void stop() {
-        if (multiplicationService != null) {
-            multiplicationService.stop();
-        }
-        if (subtractionService != null) {
-            subtractionService.stop();
+        if (errorService != null) {
+            errorService.shutdown();
         }
     }
 
@@ -68,8 +59,8 @@ public class OperationsMockService implements 
QuarkusTestResourceLifecycleManage
         final WireMockServer server = new 
WireMockServer(options().dynamicPort());
         server.start();
         server.stubFor(function.apply(post(urlEqualTo("/")))
-                .withPort(server.port())
                 .willReturn(aResponse()
+                        .withStatus(500)
                         .withHeader("Content-Type", "application/json")
                         .withBody(response)));
         return server;
diff --git 
a/quarkus/extensions/kogito-quarkus-serverless-workflow-extension/kogito-quarkus-serverless-workflow/src/main/java/org/kie/kogito/serverless/workflow/openapi/OpenApiWorkItemHandler.java
 
b/quarkus/extensions/kogito-quarkus-serverless-workflow-extension/kogito-quarkus-serverless-workflow/src/main/java/org/kie/kogito/serverless/workflow/openapi/OpenApiWorkItemHandler.java
index 00fc8339f6..daa6dbe298 100644
--- 
a/quarkus/extensions/kogito-quarkus-serverless-workflow-extension/kogito-quarkus-serverless-workflow/src/main/java/org/kie/kogito/serverless/workflow/openapi/OpenApiWorkItemHandler.java
+++ 
b/quarkus/extensions/kogito-quarkus-serverless-workflow-extension/kogito-quarkus-serverless-workflow/src/main/java/org/kie/kogito/serverless/workflow/openapi/OpenApiWorkItemHandler.java
@@ -18,6 +18,7 @@
  */
 package org.kie.kogito.serverless.workflow.openapi;
 
+import java.io.ByteArrayInputStream;
 import java.io.IOException;
 import java.lang.reflect.ParameterizedType;
 import java.util.Collection;
@@ -26,6 +27,7 @@ import java.util.List;
 import java.util.Map;
 import java.util.Optional;
 
+import org.eclipse.microprofile.rest.client.ext.ResponseExceptionMapper;
 import org.jbpm.process.instance.KogitoProcessContextImpl;
 import org.jbpm.util.ContextFactory;
 import org.jbpm.workflow.core.WorkflowProcess;
@@ -33,21 +35,28 @@ import 
org.kie.kogito.event.cloudevents.extension.ProcessMeta;
 import org.kie.kogito.internal.process.workitem.KogitoWorkItem;
 import org.kie.kogito.internal.process.workitem.WorkItemExecutionException;
 import org.kie.kogito.internal.utils.CaseInsensitiveSet;
+import org.kie.kogito.jackson.utils.ObjectMapperFactory;
 import org.kie.kogito.process.expr.ExpressionHandlerFactory;
 import org.kie.kogito.serverless.workflow.SWFConstants;
 import org.kie.kogito.serverless.workflow.WorkflowWorkItemHandler;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 import io.quarkus.restclient.runtime.RestClientBuilderFactory;
 
 import jakarta.ws.rs.WebApplicationException;
 import jakarta.ws.rs.client.ClientRequestContext;
 import jakarta.ws.rs.client.ClientRequestFilter;
+import jakarta.ws.rs.core.MediaType;
 import jakarta.ws.rs.core.MultivaluedMap;
+import jakarta.ws.rs.core.Response;
 
 public abstract class OpenApiWorkItemHandler<T> extends 
WorkflowWorkItemHandler {
 
     private static final Collection<String> excludedHeaders = new 
CaseInsensitiveSet("User-Agent", "Host", "Content-Length", "Accept", 
"Accept-Encoding", "Connection");
 
+    private static final Logger logger = 
LoggerFactory.getLogger(OpenApiWorkItemHandler.class);
+
     static String CONFIG_KEY_SUFFIX_PROP = "openApiConfigKeySuffix";
 
     @Override
@@ -69,7 +78,7 @@ public abstract class OpenApiWorkItemHandler<T> extends 
WorkflowWorkItemHandler
                     });
                 }
             }
-        }, Integer.MIN_VALUE).build(clazz);
+        }, Integer.MIN_VALUE).register((ResponseExceptionMapper) response -> 
new WebApplicationException(fromResponse(response), 
response.getStatus())).build(clazz);
         try {
             return internalExecute(ref, parameters);
         } catch (WebApplicationException ex) {
@@ -77,6 +86,21 @@ public abstract class OpenApiWorkItemHandler<T> extends 
WorkflowWorkItemHandler
         }
     }
 
+    private String fromResponse(Response response) {
+        Object entity = response.getEntity();
+        if (entity instanceof ByteArrayInputStream input) {
+            if 
(MediaType.APPLICATION_JSON_TYPE.equals(response.getMediaType())) {
+                try {
+                    return 
ObjectMapperFactory.get().readTree(input).toString();
+                } catch (IOException e) {
+                    logger.warn("Error parsing json error response {}", 
e.toString());
+                }
+            }
+            return new String(input.readAllBytes());
+        }
+        return entity != null ? entity.toString() : 
response.getStatusInfo().getReasonPhrase();
+    }
+
     private Optional<String> calculatedConfigKey(KogitoWorkItem workItem) {
         String configKeyExpr = (String) 
workItem.getNodeInstance().getNode().getMetaData().get("configKey");
         if (configKeyExpr == null) {


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to