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 a23c343c7f [Fix #3390] Fixing patch and retrigger REST APIs (#3419)
a23c343c7f is described below

commit a23c343c7f9304c263d7340069c380552c03f801
Author: Francisco Javier Tirado Sarti 
<[email protected]>
AuthorDate: Mon Mar 4 19:46:32 2024 +0100

    [Fix #3390] Fixing patch and retrigger REST APIs (#3419)
    
    * [Fix #3390] Fixing patch
    
    * [Fix #3390] Fixing node not found
    
    * [Fix #3390] Adding IT
---
 .../src/main/java/org/kie/kogito/Model.java        |  8 +++
 .../org/jbpm/workflow/instance/NodeInstance.java   |  3 ++
 .../workflow/instance/NodeInstanceContainer.java   |  6 ++-
 .../process/impl/AbstractProcessInstance.java      | 12 +++--
 .../serverless/workflow/models/JsonNodeModel.java  | 44 +++++++++-------
 .../src/main/resources/division.sw.json            | 26 ++++++++++
 .../kie/kogito/quarkus/workflows/RetriggerIT.java  | 58 ++++++++++++++++++++++
 7 files changed, 134 insertions(+), 23 deletions(-)

diff --git a/api/kogito-api/src/main/java/org/kie/kogito/Model.java 
b/api/kogito-api/src/main/java/org/kie/kogito/Model.java
index 1d827230d1..fbe9acb8de 100644
--- a/api/kogito-api/src/main/java/org/kie/kogito/Model.java
+++ b/api/kogito-api/src/main/java/org/kie/kogito/Model.java
@@ -19,6 +19,8 @@
 package org.kie.kogito;
 
 import java.util.Map;
+import java.util.Map.Entry;
+import java.util.stream.Collectors;
 
 /**
  * Represents data model type of objects that are usually descriptor of data 
holders.
@@ -29,4 +31,10 @@ public interface Model extends MapInput, MapOutput {
     default void update(Map<String, Object> params) {
         Models.fromMap(this, params);
     }
+
+    default Map<String, Object> updatePartially(Map<String, Object> params) {
+        params = params.entrySet().stream().filter(e -> e.getValue() != 
null).collect(Collectors.toMap(Entry::getKey, Entry::getValue));
+        update(params);
+        return params;
+    }
 }
diff --git 
a/jbpm/jbpm-flow/src/main/java/org/jbpm/workflow/instance/NodeInstance.java 
b/jbpm/jbpm-flow/src/main/java/org/jbpm/workflow/instance/NodeInstance.java
index 47e84a4f42..bb4109242f 100755
--- a/jbpm/jbpm-flow/src/main/java/org/jbpm/workflow/instance/NodeInstance.java
+++ b/jbpm/jbpm-flow/src/main/java/org/jbpm/workflow/instance/NodeInstance.java
@@ -18,6 +18,7 @@
  */
 package org.jbpm.workflow.instance;
 
+import java.util.Date;
 import java.util.Map;
 
 import org.jbpm.process.instance.ContextInstance;
@@ -52,6 +53,8 @@ public interface NodeInstance extends KogitoNodeInstance {
 
     String getSlaTimerId();
 
+    void internalSetTriggerTime(Date date);
+
     default KogitoProcessInstance getKogitoProcessInstance() {
         return (KogitoProcessInstance) getProcessInstance();
     }
diff --git 
a/jbpm/jbpm-flow/src/main/java/org/jbpm/workflow/instance/NodeInstanceContainer.java
 
b/jbpm/jbpm-flow/src/main/java/org/jbpm/workflow/instance/NodeInstanceContainer.java
index 015fc35119..ac57332270 100755
--- 
a/jbpm/jbpm-flow/src/main/java/org/jbpm/workflow/instance/NodeInstanceContainer.java
+++ 
b/jbpm/jbpm-flow/src/main/java/org/jbpm/workflow/instance/NodeInstanceContainer.java
@@ -63,7 +63,11 @@ public interface NodeInstanceContainer extends 
KogitoNodeInstanceContainer {
         for (Node node : nodeContainer.getNodes()) {
 
             if (nodeDefinitionId.equals(node.getMetaData().get(UNIQUE_ID))) {
-                return getNodeInstance(node);
+                if (nodeContainer instanceof Node) {
+                    return ((NodeInstanceContainer) getNodeInstance((Node) 
nodeContainer)).getNodeInstance(node);
+                } else {
+                    return getNodeInstance(node);
+                }
             }
 
             if (node instanceof NodeContainer) {
diff --git 
a/jbpm/jbpm-flow/src/main/java/org/kie/kogito/process/impl/AbstractProcessInstance.java
 
b/jbpm/jbpm-flow/src/main/java/org/kie/kogito/process/impl/AbstractProcessInstance.java
index 154a1cec75..218a51da75 100644
--- 
a/jbpm/jbpm-flow/src/main/java/org/kie/kogito/process/impl/AbstractProcessInstance.java
+++ 
b/jbpm/jbpm-flow/src/main/java/org/kie/kogito/process/impl/AbstractProcessInstance.java
@@ -34,7 +34,6 @@ import java.util.concurrent.atomic.AtomicBoolean;
 import java.util.function.Consumer;
 import java.util.function.Function;
 import java.util.function.Predicate;
-import java.util.stream.Collectors;
 
 import org.jbpm.process.instance.InternalProcessRuntime;
 import org.jbpm.ruleflow.core.RuleFlowProcess;
@@ -372,19 +371,20 @@ public abstract class AbstractProcessInstance<T extends 
Model> implements Proces
 
     @Override
     public T updateVariables(T updates) {
-        return updateVariables(bind(updates));
+        Map<String, Object> map = bind(updates);
+        variables.update(map);
+        return updateVariables(map);
     }
 
     @Override
     public T updateVariablesPartially(T updates) {
-        return updateVariables(bind(updates).entrySet().stream().filter(e -> 
e.getValue() != null).collect(Collectors.toMap(Entry::getKey, 
Entry::getValue)));
+        return updateVariables(this.variables.updatePartially(bind(updates)));
     }
 
     private T updateVariables(Map<String, Object> map) {
         for (Entry<String, Object> entry : map.entrySet()) {
             processInstance().setVariable(entry.getKey(), entry.getValue());
         }
-        this.variables.update(map);
         addToUnitOfWork(pi -> ((MutableProcessInstances<T>) 
process.instances()).update(pi.id(), pi));
         return variables;
     }
@@ -704,6 +704,10 @@ public abstract class AbstractProcessInstance<T extends 
Model> implements Proces
                 pInstance.setState(STATE_ACTIVE);
                 pInstance.internalSetErrorNodeId(null);
                 pInstance.internalSetErrorMessage(null);
+                org.kie.api.runtime.process.NodeInstanceContainer 
nodeInstanceContainer = ni.getNodeInstanceContainer();
+                if (nodeInstanceContainer instanceof NodeInstance) {
+                    ((NodeInstance) 
nodeInstanceContainer).internalSetTriggerTime(new Date());
+                }
                 ni.trigger(null, Node.CONNECTION_DEFAULT_TYPE);
                 removeOnFinish();
             }
diff --git 
a/kogito-serverless-workflow/kogito-serverless-workflow-runtime/src/main/java/org/kie/kogito/serverless/workflow/models/JsonNodeModel.java
 
b/kogito-serverless-workflow/kogito-serverless-workflow-runtime/src/main/java/org/kie/kogito/serverless/workflow/models/JsonNodeModel.java
index b9fc6923fb..72b8c8145f 100644
--- 
a/kogito-serverless-workflow/kogito-serverless-workflow-runtime/src/main/java/org/kie/kogito/serverless/workflow/models/JsonNodeModel.java
+++ 
b/kogito-serverless-workflow/kogito-serverless-workflow-runtime/src/main/java/org/kie/kogito/serverless/workflow/models/JsonNodeModel.java
@@ -21,6 +21,7 @@ package org.kie.kogito.serverless.workflow.models;
 import java.util.Collections;
 import java.util.HashMap;
 import java.util.Map;
+import java.util.function.Function;
 
 import org.kie.kogito.MapInput;
 import org.kie.kogito.MapInputId;
@@ -28,6 +29,7 @@ import org.kie.kogito.MapOutput;
 import org.kie.kogito.MappableToModel;
 import org.kie.kogito.Model;
 import org.kie.kogito.jackson.utils.JsonObjectUtils;
+import org.kie.kogito.jackson.utils.MergeUtils;
 import org.kie.kogito.jackson.utils.ObjectMapperFactory;
 import org.kie.kogito.serverless.workflow.SWFConstants;
 
@@ -80,13 +82,34 @@ public class JsonNodeModel implements Model, MapInput, 
MapInputId, MapOutput, Ma
 
     @Override
     public void update(Map<String, Object> params) {
-        Map<String, Object> copy = mutableMap(params);
-        update((String) copy.remove("id"), copy);
+        update(params, w -> w);
+    }
+
+    @Override
+    public Map<String, Object> updatePartially(Map<String, Object> params) {
+        update(params, w -> MergeUtils.merge(w, this.workflowdata));
+        return toMap();
+    }
+
+    private void update(Map<String, Object> params, Function<JsonNode, 
JsonNode> merger) {
+        if (params.containsKey(SWFConstants.DEFAULT_WORKFLOW_VAR)) {
+            params = mutableMap(params);
+            this.workflowdata = 
merger.apply(JsonObjectUtils.fromValue(params.remove(SWFConstants.DEFAULT_WORKFLOW_VAR)));
+            this.additionalProperties = params;
+        } else {
+            this.workflowdata = 
merger.apply(JsonObjectUtils.fromValue(params));
+            this.additionalProperties = Collections.emptyMap();
+        }
+    }
+
+    private static Map<String, Object> mutableMap(Map<String, Object> map) {
+        return map instanceof HashMap ? map : new HashMap<>(map);
     }
 
     @Override
     public void fromMap(String id, Map<String, Object> params) {
-        update(id, mutableMap(params));
+        this.id = id;
+        update(params);
     }
 
     @Override
@@ -103,21 +126,6 @@ public class JsonNodeModel implements Model, MapInput, 
MapInputId, MapOutput, Ma
         return map;
     }
 
-    private void update(String id, Map<String, Object> params) {
-        this.id = id;
-        if (params.containsKey(SWFConstants.DEFAULT_WORKFLOW_VAR)) {
-            this.workflowdata = 
JsonObjectUtils.fromValue(params.remove(SWFConstants.DEFAULT_WORKFLOW_VAR)).deepCopy();
-            this.additionalProperties = params;
-        } else {
-            this.workflowdata = JsonObjectUtils.fromValue(params);
-            this.additionalProperties = Collections.emptyMap();
-        }
-    }
-
-    private static Map<String, Object> mutableMap(Map<String, Object> map) {
-        return map instanceof HashMap ? map : new HashMap<>(map);
-    }
-
     @Override
     public String toString() {
         StringBuilder sb = new StringBuilder();
diff --git 
a/quarkus/extensions/kogito-quarkus-serverless-workflow-extension/kogito-quarkus-serverless-workflow-integration-test/src/main/resources/division.sw.json
 
b/quarkus/extensions/kogito-quarkus-serverless-workflow-extension/kogito-quarkus-serverless-workflow-integration-test/src/main/resources/division.sw.json
new file mode 100644
index 0000000000..e6be4fecad
--- /dev/null
+++ 
b/quarkus/extensions/kogito-quarkus-serverless-workflow-extension/kogito-quarkus-serverless-workflow-integration-test/src/main/resources/division.sw.json
@@ -0,0 +1,26 @@
+{
+  "id": "division",
+  "version": "1.0",
+  "name": "Workflow Expression example",
+  "start": "divide",
+  "functions": [
+    {
+      "name": "divide",
+      "type": "expression",
+      "operation": ".number1 / .number2"
+    }
+  ],
+  "states": [
+    {
+      "name": "divide",
+      "type": "operation",
+      "actions": [
+        {
+          "name": "divide",
+          "functionRef": "divide"
+        }
+      ],
+      "end": true
+    }
+  ]
+}
diff --git 
a/quarkus/extensions/kogito-quarkus-serverless-workflow-extension/kogito-quarkus-serverless-workflow-integration-test/src/test/java/org/kie/kogito/quarkus/workflows/RetriggerIT.java
 
b/quarkus/extensions/kogito-quarkus-serverless-workflow-extension/kogito-quarkus-serverless-workflow-integration-test/src/test/java/org/kie/kogito/quarkus/workflows/RetriggerIT.java
new file mode 100644
index 0000000000..db4fad71f2
--- /dev/null
+++ 
b/quarkus/extensions/kogito-quarkus-serverless-workflow-extension/kogito-quarkus-serverless-workflow-integration-test/src/test/java/org/kie/kogito/quarkus/workflows/RetriggerIT.java
@@ -0,0 +1,58 @@
+/*
+ * 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 org.junit.jupiter.api.Test;
+
+import io.quarkus.test.junit.QuarkusIntegrationTest;
+import io.restassured.http.ContentType;
+
+import static io.restassured.RestAssured.given;
+import static org.hamcrest.CoreMatchers.is;
+
+@QuarkusIntegrationTest
+class RetriggerIT {
+
+    @Test
+    void testRetrigger() {
+        String id = given()
+                .contentType(ContentType.JSON)
+                .accept(ContentType.JSON)
+                .body("{\"number1\":2,\"number2\":0}").when()
+                .post("/division")
+                .then()
+                .statusCode(400)
+                .extract().path("id");
+
+        given()
+                .contentType(ContentType.JSON)
+                .accept(ContentType.JSON)
+                .body("{\"number2\":1}").when()
+                .patch("/division/{id}", id)
+                .then()
+                .statusCode(200);
+
+        given()
+                .contentType(ContentType.JSON)
+                .accept(ContentType.JSON).when()
+                
.post("/management/processes/division/instances/{id}/retrigger", id)
+                .then().statusCode(200).body("workflowdata.response", is(2));
+    }
+
+}


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

Reply via email to