Skip to content

Commit

Permalink
initial ht subsystem
Browse files Browse the repository at this point in the history
  • Loading branch information
elguardian committed Sep 5, 2024
1 parent 48efab6 commit d31149a
Show file tree
Hide file tree
Showing 169 changed files with 5,189 additions and 2,573 deletions.
4 changes: 4 additions & 0 deletions addons/common/human-task-prediction/api/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,10 @@
<artifactId>jbpm-deps-group-engine</artifactId>
<type>pom</type>
</dependency>
<dependency>
<groupId>org.kie.kogito</groupId>
<artifactId>jbpm-usertask</artifactId>
</dependency>


<!-- test dependencies -->
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
/*
* 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.prediction.api;

import java.util.Optional;

import org.kie.kogito.internal.process.workitem.KogitoWorkItem;
import org.kie.kogito.internal.process.workitem.KogitoWorkItemHandler;
import org.kie.kogito.internal.process.workitem.KogitoWorkItemManager;
import org.kie.kogito.internal.process.workitem.WorkItemTransition;
import org.kie.kogito.process.workitems.impl.DefaultKogitoWorkItemHandler;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class PredictionAwareHumanTaskWorkItemHandler extends DefaultKogitoWorkItemHandler {

private static final Logger logger = LoggerFactory.getLogger(PredictionAwareHumanTaskWorkItemHandler.class);

private PredictionService predictionService;

public PredictionAwareHumanTaskWorkItemHandler(PredictionService predictionService) {
this.predictionService = predictionService;
}

public Optional<WorkItemTransition> activateWorkItemHandler(KogitoWorkItemManager manager, KogitoWorkItemHandler handler, KogitoWorkItem workItem, WorkItemTransition transition) {
PredictionOutcome outcome = predictionService.predict(workItem, workItem.getParameters());
logger.debug("Prediction service returned confidence level {} for work item {}", outcome.getConfidenceLevel(), workItem.getStringId());

if (outcome.isCertain()) {
workItem.setOutputs(outcome.getData());
logger.debug("Prediction service is certain (confidence level {}) on the outputs, completing work item {}", outcome.getConfidenceLevel(), workItem.getStringId());

return Optional.of(this.newTransition("skip", workItem.getPhaseStatus(), outcome.getData()));
} else if (outcome.isPresent()) {
logger.debug("Prediction service is NOT certain (confidence level {}) on the outputs, setting recommended outputs on work item {}",
outcome.getConfidenceLevel(),
workItem.getStringId());
workItem.setOutputs(outcome.getData());
}
return Optional.empty();
}

public Optional<WorkItemTransition> completeWorkItemHandler(KogitoWorkItemManager manager, KogitoWorkItemHandler handler, KogitoWorkItem workItem, WorkItemTransition transition) {
// upon actual transition train the data if it's completion phase
predictionService.train(workItem, workItem.getParameters(), transition.data());
return Optional.empty();
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,11 @@
import java.util.concurrent.atomic.AtomicBoolean;

import org.drools.io.ClassPathResource;
import org.jbpm.process.instance.impl.humantask.HumanTaskWorkItemHandler;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.kie.kogito.Model;
import org.kie.kogito.auth.SecurityPolicy;
import org.kie.kogito.internal.process.workitem.Policy;
import org.kie.kogito.process.ProcessConfig;
import org.kie.kogito.process.ProcessInstance;
import org.kie.kogito.process.WorkItem;
Expand All @@ -38,7 +38,6 @@
import org.kie.kogito.process.impl.CachedWorkItemHandlerConfig;
import org.kie.kogito.process.impl.DefaultProcessEventListenerConfig;
import org.kie.kogito.process.impl.StaticProcessConfig;
import org.kie.kogito.process.workitem.Policy;
import org.kie.kogito.process.workitems.InternalKogitoWorkItem;
import org.kie.kogito.services.identity.StaticIdentityProvider;
import org.kie.kogito.services.uow.CollectingUnitOfWorkFactory;
Expand All @@ -50,7 +49,7 @@

public class PredictionAwareHumanTaskLifeCycleTest {

private Policy<?> securityPolicy = SecurityPolicy.of(new StaticIdentityProvider("john"));
private Policy securityPolicy = SecurityPolicy.of(new StaticIdentityProvider("john"));

private AtomicBoolean predictNow;
private List<String> trainedTasks;
Expand Down Expand Up @@ -88,7 +87,7 @@ public String getIdentifier() {
};

CachedWorkItemHandlerConfig wiConfig = new CachedWorkItemHandlerConfig();
wiConfig.register("Human Task", new HumanTaskWorkItemHandler(new PredictionAwareHumanTaskLifeCycle(predictionService)));
wiConfig.register("Human Task", new PredictionAwareHumanTaskWorkItemHandler(predictionService));
config = new StaticProcessConfig(wiConfig, new DefaultProcessEventListenerConfig(), new DefaultUnitOfWorkManager(new CollectingUnitOfWorkFactory()));
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@
import java.util.Set;

import org.kie.api.runtime.process.WorkItem;
import org.kie.kogito.internal.process.runtime.KogitoWorkItem;
import org.kie.kogito.internal.process.workitem.KogitoWorkItem;
import org.kie.kogito.prediction.api.PredictionOutcome;
import org.kie.kogito.prediction.api.PredictionService;
import org.slf4j.Logger;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,11 +23,9 @@
import java.util.Map;

import org.drools.io.ClassPathResource;
import org.jbpm.process.instance.impl.humantask.HumanTaskWorkItemHandler;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.kie.kogito.Model;
import org.kie.kogito.prediction.api.PredictionAwareHumanTaskLifeCycle;
import org.kie.kogito.prediction.api.PredictionService;
import org.kie.kogito.process.ProcessConfig;
import org.kie.kogito.process.ProcessInstance;
Expand Down Expand Up @@ -64,7 +62,7 @@ public void configure() {

predictionService = new SmileRandomForest(configuration);
CachedWorkItemHandlerConfig wiConfig = new CachedWorkItemHandlerConfig();
wiConfig.register("Human Task", new HumanTaskWorkItemHandler(new PredictionAwareHumanTaskLifeCycle(predictionService)));
// wiConfig.register("Human Task", new UserTaskKogitoWorkItemHandler(new PredictionAwareHumanTaskLifeCycle(predictionService)));
config = new StaticProcessConfig(wiConfig, new DefaultProcessEventListenerConfig(), new DefaultUnitOfWorkManager(new CollectingUnitOfWorkFactory()));

for (int i = 0; i < 10; i++) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
import org.junit.jupiter.api.Test;
import org.kie.kogito.auth.IdentityProviders;
import org.kie.kogito.auth.SecurityPolicy;
import org.kie.kogito.internal.process.workitem.Policy;
import org.kie.kogito.persistence.jdbc.JDBCProcessInstances;
import org.kie.kogito.process.ProcessInstance;
import org.kie.kogito.process.WorkItem;
Expand All @@ -56,7 +57,7 @@
abstract class AbstractProcessInstancesIT {

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

DataSource dataSource;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
*/
package org.kie.kogito.task.management.service;

import org.kie.kogito.process.workitem.Policy;
import org.kie.kogito.internal.process.workitem.Policy;

public interface TaskManagementOperations {

Expand All @@ -27,7 +27,7 @@ TaskInfo updateTask(String processId,
String taskId,
TaskInfo taskInfo,
boolean replace,
Policy<?>... policies);
Policy... policies);

TaskInfo getTask(String processId, String processInstanceId, String taskId, Policy<?>... policies);
TaskInfo getTask(String processId, String processInstanceId, String taskId, Policy... policies);
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,22 +18,22 @@
*/
package org.kie.kogito.task.management.service;

import java.util.Collections;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.function.BiConsumer;
import java.util.function.Consumer;
import java.util.function.Supplier;

import org.jbpm.process.instance.impl.humantask.HumanTaskHelper;
import org.jbpm.process.instance.impl.humantask.InternalHumanTaskWorkItem;
import org.kie.kogito.internal.process.runtime.KogitoWorkItem;
import org.kie.kogito.internal.process.workitem.KogitoWorkItem;
import org.kie.kogito.internal.process.workitem.Policy;
import org.kie.kogito.process.Process;
import org.kie.kogito.process.ProcessConfig;
import org.kie.kogito.process.ProcessInstance;
import org.kie.kogito.process.ProcessInstanceNotFoundException;
import org.kie.kogito.process.Processes;
import org.kie.kogito.process.workitem.HumanTaskWorkItem;
import org.kie.kogito.process.workitem.Policy;
import org.kie.kogito.process.WorkItem;
import org.kie.kogito.process.workitems.InternalKogitoWorkItem;
import org.kie.kogito.services.uow.UnitOfWorkExecutor;

public class TaskManagementService implements TaskManagementOperations {
Expand All @@ -52,24 +52,16 @@ public TaskInfo updateTask(String processId,
String taskId,
TaskInfo taskInfo,
boolean shouldReplace,
Policy<?>... policies) {
Policy... policies) {
ProcessInstance<?> pi = getProcessInstance(processId, processInstanceId, taskId);
KogitoWorkItem workItem = UnitOfWorkExecutor.executeInUnitOfWork(processConfig.unitOfWorkManager(),
() -> pi.updateWorkItem(taskId,
wi -> {
InternalHumanTaskWorkItem humanTask = HumanTaskHelper.asHumanTask(wi);
setField(humanTask::setAdminGroups, taskInfo::getAdminGroups, shouldReplace);
setField(humanTask::setAdminUsers, taskInfo::getAdminUsers, shouldReplace);
setField(humanTask::setExcludedUsers, taskInfo::getExcludedUsers, shouldReplace);
setField(humanTask::setPotentialUsers, taskInfo::getPotentialUsers, shouldReplace);
setField(humanTask::setPotentialGroups, taskInfo::getPotentialGroups, shouldReplace);
setField(humanTask::setTaskPriority, taskInfo::getPriority, shouldReplace);
setField(humanTask::setTaskDescription, taskInfo::getDescription, shouldReplace);
setMap(humanTask::setParameters, humanTask::setParameter, taskInfo.getInputParams(),
shouldReplace);
InternalKogitoWorkItem task = (InternalKogitoWorkItem) wi;
setMap(task::setParameters, task::setParameter, taskInfo.getInputParams(), shouldReplace);
return wi;
}, policies));
return convert((HumanTaskWorkItem) workItem);
return convert(workItem);
}

private void setMap(Consumer<Map<String, Object>> allConsumer,
Expand All @@ -87,25 +79,44 @@ private void setMap(Consumer<Map<String, Object>> allConsumer,
}
}

private <T> boolean setField(Consumer<T> consumer, Supplier<T> supplier, boolean shouldReplace) {
T value = supplier.get();
boolean result = shouldReplace || value != null;
if (result) {
consumer.accept(value);
}
return result;
@Override
public TaskInfo getTask(String processId, String processInstanceId, String taskId, Policy... policies) {
WorkItem workItem = getProcessInstance(processId, processInstanceId, taskId).workItem(taskId, policies);
return convert(workItem);
}

@Override
public TaskInfo getTask(String processId, String processInstanceId, String taskId, Policy<?>... policies) {
return convert(HumanTaskHelper.findTask(getProcessInstance(processId, processInstanceId, taskId), taskId,
policies));
private TaskInfo convert(WorkItem workItem) {
return new TaskInfo(
(String) workItem.getParameters().get("Description"),
(String) workItem.getParameters().get("Priority"),
toSet(workItem.getParameters().get("ActorId")),
toSet(workItem.getParameters().get("GroupId")),
toSet(workItem.getParameters().get("ExcludedUsersId")),
toSet(workItem.getParameters().get("BusinessAdministratorId")),
toSet(workItem.getParameters().get("BusinessGroupsId")),
workItem.getParameters());
}

private TaskInfo convert(KogitoWorkItem workItem) {
return new TaskInfo(
(String) workItem.getParameter("Description"),
(String) workItem.getParameter("Priority"),
toSet(workItem.getParameter("ActorId")),
toSet(workItem.getParameter("GroupId")),
toSet(workItem.getParameter("ExcludedUsersId")),
toSet(workItem.getParameter("BusinessAdministratorId")),
toSet(workItem.getParameter("BusinessGroupsId")),
workItem.getParameters());
}

private TaskInfo convert(HumanTaskWorkItem humanTask) {
return new TaskInfo(humanTask.getTaskDescription(), humanTask.getTaskPriority(), humanTask.getPotentialUsers(),
humanTask.getPotentialGroups(), humanTask.getExcludedUsers(), humanTask.getAdminUsers(),
humanTask.getAdminGroups(), humanTask.getParameters());
private Set<String> toSet(Object value) {
if (value == null) {
return Collections.emptySet();
}
if (value instanceof String string) {
return Set.of(string.split(","));
}
return Collections.emptySet();
}

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

}
Loading

0 comments on commit d31149a

Please sign in to comment.