Skip to content

Commit d31149a

Browse files
committed
initial ht subsystem
1 parent 48efab6 commit d31149a

File tree

169 files changed

+5189
-2573
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

169 files changed

+5189
-2573
lines changed

addons/common/human-task-prediction/api/pom.xml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,10 @@
5858
<artifactId>jbpm-deps-group-engine</artifactId>
5959
<type>pom</type>
6060
</dependency>
61+
<dependency>
62+
<groupId>org.kie.kogito</groupId>
63+
<artifactId>jbpm-usertask</artifactId>
64+
</dependency>
6165

6266

6367
<!-- test dependencies -->

addons/common/human-task-prediction/api/src/main/java/org/kie/kogito/prediction/api/PredictionAwareHumanTaskLifeCycle.java

Lines changed: 0 additions & 84 deletions
This file was deleted.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
/*
2+
* Licensed to the Apache Software Foundation (ASF) under one
3+
* or more contributor license agreements. See the NOTICE file
4+
* distributed with this work for additional information
5+
* regarding copyright ownership. The ASF licenses this file
6+
* to you under the Apache License, Version 2.0 (the
7+
* "License"); you may not use this file except in compliance
8+
* with the License. You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing,
13+
* software distributed under the License is distributed on an
14+
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15+
* KIND, either express or implied. See the License for the
16+
* specific language governing permissions and limitations
17+
* under the License.
18+
*/
19+
package org.kie.kogito.prediction.api;
20+
21+
import java.util.Optional;
22+
23+
import org.kie.kogito.internal.process.workitem.KogitoWorkItem;
24+
import org.kie.kogito.internal.process.workitem.KogitoWorkItemHandler;
25+
import org.kie.kogito.internal.process.workitem.KogitoWorkItemManager;
26+
import org.kie.kogito.internal.process.workitem.WorkItemTransition;
27+
import org.kie.kogito.process.workitems.impl.DefaultKogitoWorkItemHandler;
28+
import org.slf4j.Logger;
29+
import org.slf4j.LoggerFactory;
30+
31+
public class PredictionAwareHumanTaskWorkItemHandler extends DefaultKogitoWorkItemHandler {
32+
33+
private static final Logger logger = LoggerFactory.getLogger(PredictionAwareHumanTaskWorkItemHandler.class);
34+
35+
private PredictionService predictionService;
36+
37+
public PredictionAwareHumanTaskWorkItemHandler(PredictionService predictionService) {
38+
this.predictionService = predictionService;
39+
}
40+
41+
public Optional<WorkItemTransition> activateWorkItemHandler(KogitoWorkItemManager manager, KogitoWorkItemHandler handler, KogitoWorkItem workItem, WorkItemTransition transition) {
42+
PredictionOutcome outcome = predictionService.predict(workItem, workItem.getParameters());
43+
logger.debug("Prediction service returned confidence level {} for work item {}", outcome.getConfidenceLevel(), workItem.getStringId());
44+
45+
if (outcome.isCertain()) {
46+
workItem.setOutputs(outcome.getData());
47+
logger.debug("Prediction service is certain (confidence level {}) on the outputs, completing work item {}", outcome.getConfidenceLevel(), workItem.getStringId());
48+
49+
return Optional.of(this.newTransition("skip", workItem.getPhaseStatus(), outcome.getData()));
50+
} else if (outcome.isPresent()) {
51+
logger.debug("Prediction service is NOT certain (confidence level {}) on the outputs, setting recommended outputs on work item {}",
52+
outcome.getConfidenceLevel(),
53+
workItem.getStringId());
54+
workItem.setOutputs(outcome.getData());
55+
}
56+
return Optional.empty();
57+
}
58+
59+
public Optional<WorkItemTransition> completeWorkItemHandler(KogitoWorkItemManager manager, KogitoWorkItemHandler handler, KogitoWorkItem workItem, WorkItemTransition transition) {
60+
// upon actual transition train the data if it's completion phase
61+
predictionService.train(workItem, workItem.getParameters(), transition.data());
62+
return Optional.empty();
63+
}
64+
65+
}

addons/common/human-task-prediction/api/src/test/java/org/kie/kogito/prediction/api/PredictionAwareHumanTaskLifeCycleTest.java

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -25,11 +25,11 @@
2525
import java.util.concurrent.atomic.AtomicBoolean;
2626

2727
import org.drools.io.ClassPathResource;
28-
import org.jbpm.process.instance.impl.humantask.HumanTaskWorkItemHandler;
2928
import org.junit.jupiter.api.BeforeEach;
3029
import org.junit.jupiter.api.Test;
3130
import org.kie.kogito.Model;
3231
import org.kie.kogito.auth.SecurityPolicy;
32+
import org.kie.kogito.internal.process.workitem.Policy;
3333
import org.kie.kogito.process.ProcessConfig;
3434
import org.kie.kogito.process.ProcessInstance;
3535
import org.kie.kogito.process.WorkItem;
@@ -38,7 +38,6 @@
3838
import org.kie.kogito.process.impl.CachedWorkItemHandlerConfig;
3939
import org.kie.kogito.process.impl.DefaultProcessEventListenerConfig;
4040
import org.kie.kogito.process.impl.StaticProcessConfig;
41-
import org.kie.kogito.process.workitem.Policy;
4241
import org.kie.kogito.process.workitems.InternalKogitoWorkItem;
4342
import org.kie.kogito.services.identity.StaticIdentityProvider;
4443
import org.kie.kogito.services.uow.CollectingUnitOfWorkFactory;
@@ -50,7 +49,7 @@
5049

5150
public class PredictionAwareHumanTaskLifeCycleTest {
5251

53-
private Policy<?> securityPolicy = SecurityPolicy.of(new StaticIdentityProvider("john"));
52+
private Policy securityPolicy = SecurityPolicy.of(new StaticIdentityProvider("john"));
5453

5554
private AtomicBoolean predictNow;
5655
private List<String> trainedTasks;
@@ -88,7 +87,7 @@ public String getIdentifier() {
8887
};
8988

9089
CachedWorkItemHandlerConfig wiConfig = new CachedWorkItemHandlerConfig();
91-
wiConfig.register("Human Task", new HumanTaskWorkItemHandler(new PredictionAwareHumanTaskLifeCycle(predictionService)));
90+
wiConfig.register("Human Task", new PredictionAwareHumanTaskWorkItemHandler(predictionService));
9291
config = new StaticProcessConfig(wiConfig, new DefaultProcessEventListenerConfig(), new DefaultUnitOfWorkManager(new CollectingUnitOfWorkFactory()));
9392
}
9493

addons/common/human-task-prediction/smile/src/main/java/org/kie/kogito/predictions/smile/SmileRandomForest.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@
2828
import java.util.Set;
2929

3030
import org.kie.api.runtime.process.WorkItem;
31-
import org.kie.kogito.internal.process.runtime.KogitoWorkItem;
31+
import org.kie.kogito.internal.process.workitem.KogitoWorkItem;
3232
import org.kie.kogito.prediction.api.PredictionOutcome;
3333
import org.kie.kogito.prediction.api.PredictionService;
3434
import org.slf4j.Logger;

addons/common/human-task-prediction/smile/src/test/java/org/kie/kogito/predictions/smile/SmileRandomForestPredictionTest.java

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,11 +23,9 @@
2323
import java.util.Map;
2424

2525
import org.drools.io.ClassPathResource;
26-
import org.jbpm.process.instance.impl.humantask.HumanTaskWorkItemHandler;
2726
import org.junit.jupiter.api.BeforeEach;
2827
import org.junit.jupiter.api.Test;
2928
import org.kie.kogito.Model;
30-
import org.kie.kogito.prediction.api.PredictionAwareHumanTaskLifeCycle;
3129
import org.kie.kogito.prediction.api.PredictionService;
3230
import org.kie.kogito.process.ProcessConfig;
3331
import org.kie.kogito.process.ProcessInstance;
@@ -64,7 +62,7 @@ public void configure() {
6462

6563
predictionService = new SmileRandomForest(configuration);
6664
CachedWorkItemHandlerConfig wiConfig = new CachedWorkItemHandlerConfig();
67-
wiConfig.register("Human Task", new HumanTaskWorkItemHandler(new PredictionAwareHumanTaskLifeCycle(predictionService)));
65+
// wiConfig.register("Human Task", new UserTaskKogitoWorkItemHandler(new PredictionAwareHumanTaskLifeCycle(predictionService)));
6866
config = new StaticProcessConfig(wiConfig, new DefaultProcessEventListenerConfig(), new DefaultUnitOfWorkManager(new CollectingUnitOfWorkFactory()));
6967

7068
for (int i = 0; i < 10; i++) {

addons/common/persistence/jdbc/src/test/java/org/kie/persistence/jdbc/AbstractProcessInstancesIT.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
import org.junit.jupiter.api.Test;
3131
import org.kie.kogito.auth.IdentityProviders;
3232
import org.kie.kogito.auth.SecurityPolicy;
33+
import org.kie.kogito.internal.process.workitem.Policy;
3334
import org.kie.kogito.persistence.jdbc.JDBCProcessInstances;
3435
import org.kie.kogito.process.ProcessInstance;
3536
import org.kie.kogito.process.WorkItem;
@@ -56,7 +57,7 @@
5657
abstract class AbstractProcessInstancesIT {
5758

5859
public static final String TEST_ID = "02ac3854-46ee-42b7-8b63-5186c9889d96";
59-
public static SecurityPolicy securityPolicy = SecurityPolicy.of(IdentityProviders.of("john"));
60+
public static Policy securityPolicy = SecurityPolicy.of(IdentityProviders.of("john"));
6061

6162
DataSource dataSource;
6263

addons/common/task-management/src/main/java/org/kie/kogito/task/management/service/TaskManagementOperations.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
*/
1919
package org.kie.kogito.task.management.service;
2020

21-
import org.kie.kogito.process.workitem.Policy;
21+
import org.kie.kogito.internal.process.workitem.Policy;
2222

2323
public interface TaskManagementOperations {
2424

@@ -27,7 +27,7 @@ TaskInfo updateTask(String processId,
2727
String taskId,
2828
TaskInfo taskInfo,
2929
boolean replace,
30-
Policy<?>... policies);
30+
Policy... policies);
3131

32-
TaskInfo getTask(String processId, String processInstanceId, String taskId, Policy<?>... policies);
32+
TaskInfo getTask(String processId, String processInstanceId, String taskId, Policy... policies);
3333
}

addons/common/task-management/src/main/java/org/kie/kogito/task/management/service/TaskManagementService.java

Lines changed: 45 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -18,22 +18,22 @@
1818
*/
1919
package org.kie.kogito.task.management.service;
2020

21+
import java.util.Collections;
2122
import java.util.Map;
2223
import java.util.Map.Entry;
24+
import java.util.Set;
2325
import java.util.function.BiConsumer;
2426
import java.util.function.Consumer;
25-
import java.util.function.Supplier;
2627

27-
import org.jbpm.process.instance.impl.humantask.HumanTaskHelper;
28-
import org.jbpm.process.instance.impl.humantask.InternalHumanTaskWorkItem;
29-
import org.kie.kogito.internal.process.runtime.KogitoWorkItem;
28+
import org.kie.kogito.internal.process.workitem.KogitoWorkItem;
29+
import org.kie.kogito.internal.process.workitem.Policy;
3030
import org.kie.kogito.process.Process;
3131
import org.kie.kogito.process.ProcessConfig;
3232
import org.kie.kogito.process.ProcessInstance;
3333
import org.kie.kogito.process.ProcessInstanceNotFoundException;
3434
import org.kie.kogito.process.Processes;
35-
import org.kie.kogito.process.workitem.HumanTaskWorkItem;
36-
import org.kie.kogito.process.workitem.Policy;
35+
import org.kie.kogito.process.WorkItem;
36+
import org.kie.kogito.process.workitems.InternalKogitoWorkItem;
3737
import org.kie.kogito.services.uow.UnitOfWorkExecutor;
3838

3939
public class TaskManagementService implements TaskManagementOperations {
@@ -52,24 +52,16 @@ public TaskInfo updateTask(String processId,
5252
String taskId,
5353
TaskInfo taskInfo,
5454
boolean shouldReplace,
55-
Policy<?>... policies) {
55+
Policy... policies) {
5656
ProcessInstance<?> pi = getProcessInstance(processId, processInstanceId, taskId);
5757
KogitoWorkItem workItem = UnitOfWorkExecutor.executeInUnitOfWork(processConfig.unitOfWorkManager(),
5858
() -> pi.updateWorkItem(taskId,
5959
wi -> {
60-
InternalHumanTaskWorkItem humanTask = HumanTaskHelper.asHumanTask(wi);
61-
setField(humanTask::setAdminGroups, taskInfo::getAdminGroups, shouldReplace);
62-
setField(humanTask::setAdminUsers, taskInfo::getAdminUsers, shouldReplace);
63-
setField(humanTask::setExcludedUsers, taskInfo::getExcludedUsers, shouldReplace);
64-
setField(humanTask::setPotentialUsers, taskInfo::getPotentialUsers, shouldReplace);
65-
setField(humanTask::setPotentialGroups, taskInfo::getPotentialGroups, shouldReplace);
66-
setField(humanTask::setTaskPriority, taskInfo::getPriority, shouldReplace);
67-
setField(humanTask::setTaskDescription, taskInfo::getDescription, shouldReplace);
68-
setMap(humanTask::setParameters, humanTask::setParameter, taskInfo.getInputParams(),
69-
shouldReplace);
60+
InternalKogitoWorkItem task = (InternalKogitoWorkItem) wi;
61+
setMap(task::setParameters, task::setParameter, taskInfo.getInputParams(), shouldReplace);
7062
return wi;
7163
}, policies));
72-
return convert((HumanTaskWorkItem) workItem);
64+
return convert(workItem);
7365
}
7466

7567
private void setMap(Consumer<Map<String, Object>> allConsumer,
@@ -87,25 +79,44 @@ private void setMap(Consumer<Map<String, Object>> allConsumer,
8779
}
8880
}
8981

90-
private <T> boolean setField(Consumer<T> consumer, Supplier<T> supplier, boolean shouldReplace) {
91-
T value = supplier.get();
92-
boolean result = shouldReplace || value != null;
93-
if (result) {
94-
consumer.accept(value);
95-
}
96-
return result;
82+
@Override
83+
public TaskInfo getTask(String processId, String processInstanceId, String taskId, Policy... policies) {
84+
WorkItem workItem = getProcessInstance(processId, processInstanceId, taskId).workItem(taskId, policies);
85+
return convert(workItem);
9786
}
9887

99-
@Override
100-
public TaskInfo getTask(String processId, String processInstanceId, String taskId, Policy<?>... policies) {
101-
return convert(HumanTaskHelper.findTask(getProcessInstance(processId, processInstanceId, taskId), taskId,
102-
policies));
88+
private TaskInfo convert(WorkItem workItem) {
89+
return new TaskInfo(
90+
(String) workItem.getParameters().get("Description"),
91+
(String) workItem.getParameters().get("Priority"),
92+
toSet(workItem.getParameters().get("ActorId")),
93+
toSet(workItem.getParameters().get("GroupId")),
94+
toSet(workItem.getParameters().get("ExcludedUsersId")),
95+
toSet(workItem.getParameters().get("BusinessAdministratorId")),
96+
toSet(workItem.getParameters().get("BusinessGroupsId")),
97+
workItem.getParameters());
98+
}
99+
100+
private TaskInfo convert(KogitoWorkItem workItem) {
101+
return new TaskInfo(
102+
(String) workItem.getParameter("Description"),
103+
(String) workItem.getParameter("Priority"),
104+
toSet(workItem.getParameter("ActorId")),
105+
toSet(workItem.getParameter("GroupId")),
106+
toSet(workItem.getParameter("ExcludedUsersId")),
107+
toSet(workItem.getParameter("BusinessAdministratorId")),
108+
toSet(workItem.getParameter("BusinessGroupsId")),
109+
workItem.getParameters());
103110
}
104111

105-
private TaskInfo convert(HumanTaskWorkItem humanTask) {
106-
return new TaskInfo(humanTask.getTaskDescription(), humanTask.getTaskPriority(), humanTask.getPotentialUsers(),
107-
humanTask.getPotentialGroups(), humanTask.getExcludedUsers(), humanTask.getAdminUsers(),
108-
humanTask.getAdminGroups(), humanTask.getParameters());
112+
private Set<String> toSet(Object value) {
113+
if (value == null) {
114+
return Collections.emptySet();
115+
}
116+
if (value instanceof String string) {
117+
return Set.of(string.split(","));
118+
}
119+
return Collections.emptySet();
109120
}
110121

111122
private ProcessInstance<?> getProcessInstance(String processId, String processInstanceId, String taskId) {
@@ -125,4 +136,5 @@ private ProcessInstance<?> getProcessInstance(String processId, String processIn
125136
return process.instances().findById(processInstanceId).orElseThrow(
126137
() -> new ProcessInstanceNotFoundException(processInstanceId));
127138
}
139+
128140
}

0 commit comments

Comments
 (0)