Skip to content

Commit

Permalink
[Fix #3390] Fixing patch and retrigger REST APIs (#3419)
Browse files Browse the repository at this point in the history
* [Fix #3390] Fixing patch

* [Fix #3390] Fixing node not found

* [Fix #3390] Adding IT
  • Loading branch information
fjtirado authored Mar 4, 2024
1 parent ff9a68e commit a23c343
Show file tree
Hide file tree
Showing 7 changed files with 134 additions and 23 deletions.
8 changes: 8 additions & 0 deletions api/kogito-api/src/main/java/org/kie/kogito/Model.java
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand All @@ -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;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
*/
package org.jbpm.workflow.instance;

import java.util.Date;
import java.util.Map;

import org.jbpm.process.instance.ContextInstance;
Expand Down Expand Up @@ -52,6 +53,8 @@ public interface NodeInstance extends KogitoNodeInstance {

String getSlaTimerId();

void internalSetTriggerTime(Date date);

default KogitoProcessInstance getKogitoProcessInstance() {
return (KogitoProcessInstance) getProcessInstance();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,11 @@ default NodeInstance getByNodeDefinitionId(final String nodeDefinitionId, NodeCo
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) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,6 @@
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;
Expand Down Expand Up @@ -372,19 +371,20 @@ public void setVersion(long version) {

@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;
}
Expand Down Expand Up @@ -704,6 +704,10 @@ public void retrigger() {
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();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,13 +21,15 @@
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;
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;

Expand Down Expand Up @@ -80,13 +82,34 @@ public JsonNodeModelOutput toModel() {

@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
Expand All @@ -103,21 +126,6 @@ public Map<String, Object> toMap() {
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();
Expand Down
Original file line number Diff line number Diff line change
@@ -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
}
]
}
Original file line number Diff line number Diff line change
@@ -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));
}

}

0 comments on commit a23c343

Please sign in to comment.