You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@kie.apache.org by eg...@apache.org on 2024/11/18 13:09:50 UTC
(incubator-kie-kogito-runtimes) branch main updated: [incubator-kie-issues-1551] Deadlines for Human Task (#3752)
This is an automated email from the ASF dual-hosted git repository.
egonzalez 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 a3ac6e7408 [incubator-kie-issues-1551] Deadlines for Human Task (#3752)
a3ac6e7408 is described below
commit a3ac6e7408ccf1aa2c3a5bbaac8b03fca488a318
Author: Enrique <en...@ibm.com>
AuthorDate: Mon Nov 18 14:09:46 2024 +0100
[incubator-kie-issues-1551] Deadlines for Human Task (#3752)
---
.../jpa/mapper/AttachmentsEntityMapper.java | 4 +-
.../usertask/jpa/mapper/CommentsEntityMapper.java | 4 +-
.../org/jbpm/usertask/jpa/mapper/EntityMapper.java | 14 +-
.../jpa/mapper/TaskDeadlineEntityMapper.java | 136 ++++++++
.../jpa/mapper/TaskDeadlineTimerEntityMapper.java | 132 ++++++++
.../jpa/mapper/TaskInputsEntityMapper.java | 4 +-
.../jpa/mapper/TaskMetadataEntityMapper.java | 4 +-
.../jpa/mapper/TaskOutputsEntityMapper.java | 4 +-
.../jpa/mapper/TaskReassignmentEntityMapper.java | 137 ++++++++
.../mapper/TaskReassignmentTimerEntityMapper.java | 130 ++++++++
.../jpa/mapper/UserTaskInstanceEntityMapper.java | 32 +-
.../usertask/jpa/mapper/json/utils/JSONUtils.java | 20 +-
...TaskDataEntity.java => AbstractTaskEntity.java} | 37 +--
.../usertask/jpa/model/TaskDeadlineEntity.java | 78 +++++
.../jpa/model/TaskDeadlineTimerEntity.java | 74 +++++
.../jbpm/usertask/jpa/model/TaskDeadlineType.java | 12 +-
.../jbpm/usertask/jpa/model/TaskInputEntity.java | 11 +-
.../usertask/jpa/model/TaskMetadataEntity.java | 12 +-
...askDataEntity.java => TaskNamedDataEntity.java} | 47 +--
...ataEntityPK.java => TaskNamedDataEntityPK.java} | 16 +-
.../jbpm/usertask/jpa/model/TaskOutputEntity.java | 12 +-
.../usertask/jpa/model/TaskReassignmentEntity.java | 78 +++++
.../jpa/model/TaskReassignmentTimerEntity.java | 73 +++++
.../usertask/jpa/model/TaskReassignmentType.java | 12 +-
...kDataEntity.java => TaskTimerConfigEntity.java} | 62 ++--
...askDataEntity.java => TaskTimerDataEntity.java} | 53 +--
...ataEntityPK.java => TaskTimerDataEntityPK.java} | 32 +-
.../usertask/jpa/model/UserTaskInstanceEntity.java | 92 +++++-
...Repository.java => TaskDeadlineRepository.java} | 11 +-
...itory.java => TaskDeadlineTimerRepository.java} | 12 +-
.../jpa/repository/TaskInputRepository.java | 4 +-
.../jpa/repository/TaskMetadataRepository.java | 4 +-
.../jpa/repository/TaskOutputRepository.java | 4 +-
...sitory.java => TaskReassignmentRepository.java} | 11 +-
...y.java => TaskReassignmentTimerRepository.java} | 12 +-
.../h2/V1.0.1__jBPM_user_task_timers.sql | 71 ++++
.../postgresql/V1.0.1__jBPM_user_task_timers.sql | 72 ++++
.../usertask/jpa/JPAUserTaskInstancesTest.java | 17 +-
.../jpa/mapper/AttachmentsEntityMapperTest.java | 2 +-
.../mapper/UserTaskInstanceEntityMapperTest.java | 8 +-
.../jbpm/usertask/jpa/mapper/utils/TestUtils.java | 30 +-
.../kogito/jobs/api/JobCallbackResourceDef.java | 43 ++-
.../jobs/api/JobCallbackResourceDefTest.java | 4 +-
.../kogito/jobs/management/RestJobsService.java | 6 +-
.../jobs/management/RestJobsServiceTest.java | 17 +-
.../src/main/java/org/kie/kogito/StaticConfig.java | 27 +-
.../java/org/kie/kogito/jobs/JobDescription.java | 5 +
.../main/java/org/kie/kogito/jobs/JobsService.java | 12 +-
.../ProcessInstanceJobDescription.java | 18 +-
.../ProcessInstanceJobDescriptionBuilder.java | 4 +-
.../{ => descriptors}/ProcessJobDescription.java | 9 +-
.../UserTaskInstanceJobDescription.java | 69 ++++
.../UserTaskInstanceJobDescriptionBuilder.java | 80 +++++
.../java/org/kie/kogito/usertask/UserTask.java | 8 +-
.../org/kie/kogito/usertask/UserTaskInstance.java | 32 ++
.../usertask/lifecycle/UserTaskLifeCycle.java | 14 +-
.../model/{Reassignment.java => Notification.java} | 39 ++-
.../kie/kogito/usertask/model/Reassignment.java | 11 +
.../services/jobs/impl/InMemoryJobContext.java | 17 +-
.../services/jobs/impl/InMemoryJobService.java | 198 +++--------
.../impl/InMemoryProcessJobExecutorFactory.java | 189 +++++++++++
.../impl/InMemoryUserTaskJobExecutorFactory.java | 123 +++++++
.../services/jobs/impl/JobExecutorFactory.java | 23 +-
.../impl/LegacyInMemoryJobExecutorFactory.java | 136 ++++++++
.../jobs/impl/LegacyInMemoryJobService.java | 83 +----
.../services/jobs/impl/StaticJobService.java | 13 +-
.../services/uow/StaticUnitOfWorkManger.java | 15 +-
.../kogito/services/uow/UnitOfWorkExecutor.java | 1 -
.../org/jbpm/bpmn2/xml/AbstractNodeHandler.java | 4 +
.../org/kie/kogito/process/bpmn2/BpmnProcess.java | 6 +-
jbpm/jbpm-flow/pom.xml | 5 +
.../process/instance/AbstractProcessRuntime.java | 4 +-
.../jbpm/process/instance/LightProcessRuntime.java | 8 +-
.../workflow/core/node/AsyncEventNodeInstance.java | 6 +-
.../org/jbpm/workflow/core/node/HumanTaskNode.java | 2 +-
.../instance/impl/WorkflowProcessInstanceImpl.java | 6 +-
.../instance/node/StateBasedNodeInstance.java | 6 +-
.../workflow/instance/node/TimerNodeInstance.java | 6 +-
.../kie/kogito/process/impl/AbstractProcess.java | 4 +-
.../kogito/process/impl/AbstractProcessConfig.java | 7 +-
.../kogito/process/impl/StaticProcessConfig.java | 21 +-
.../src/test/java/org/jbpm/process/TimerTest.java | 159 ++++-----
.../jbpm/bpmn2/calendar/BusinessCalendarTest.java | 12 +-
.../org/jbpm/test/utils/ProcessTestHelper.java | 18 +-
.../handler/UserTaskKogitoWorkItemHandler.java | 16 +-
.../kie/kogito/usertask/impl/AbstractUserTask.java | 24 +-
.../usertask/impl/DefaultUserTaskConfig.java | 26 +-
.../usertask/impl/DefaultUserTaskInstance.java | 259 ++++++++++++++-
.../kie/kogito/usertask/impl/DefaultUserTasks.java | 2 +
.../usertask/impl/InMemoryUserTaskInstances.java | 3 +
.../kogito/usertask/impl/UserTaskServiceImpl.java | 16 +-
.../impl/lifecycle/DefaultUserTaskLifeCycle.java | 55 +++-
.../kogito/usertask/impl/model/DeadlineHelper.java | 17 +-
.../usertask/impl/model/DeadlineHelperTest.java | 66 ++--
.../codegen/core/ApplicationConfigGenerator.java | 22 +-
.../config/ApplicationConfigJavaTemplate.java | 2 +-
.../config/ApplicationConfigQuarkusTemplate.java | 5 +-
.../config/ApplicationConfigSpringTemplate.java | 5 +-
.../org/kie/kogito/codegen/tests/UserTaskIT.java | 361 +++++++++++++++++++++
.../usertask/UserTasksNotCompletedDeadline.bpmn2 | 124 +++++++
.../usertask/UserTasksNotCompletedReassign.bpmn2 | 124 +++++++
.../usertask/UserTasksNotStartedDeadline.bpmn2 | 129 ++++++++
.../usertask/UserTasksNotStartedReasssign.bpmn2 | 124 +++++++
.../kogito/codegen/usertask/UserTaskCodegen.java | 25 +-
.../usertask/UserTaskContainerGenerator.java | 6 +-
.../ProcessContainerJavaTemplate.java | 15 +
.../usertask/UserTasksContainerJavaTemplate.java | 13 +
.../UserTasksContainerQuarkusTemplate.java | 14 +
.../usertask/UserTasksContainerSpringTemplate.java | 14 +
.../StaticFluentWorkflowApplicationTest.java | 14 +
...r.java => QuarkusTaskDeadlineEntityMapper.java} | 14 +-
...a => QuarkusTaskDeadlineTimerEntityMapper.java} | 14 +-
...va => QuarkusTaskReassignmentEntityMapper.java} | 14 +-
... QuarkusTaskReassignmentTimerEntityMapper.java} | 14 +-
.../QuarkusUserTaskInstanceEntityMapper.java | 13 +-
.../repository/QuarkusTaskDeadlineRepository.java | 23 +-
.../QuarkusTaskDeadlineTimerRepository.java | 23 +-
.../QuarkusTaskReassignmentRepository.java | 23 +-
.../QuarkusTaskReassignmentTimerRepository.java | 23 +-
.../AbstractReactiveMessagingJobsService.java | 10 +-
.../AbstractReactiveMessagingJobsServiceTest.java | 25 +-
.../common/CallbackJobsServiceResource.java | 4 +-
.../jobs/management/quarkus/VertxJobsService.java | 11 +-
.../management/quarkus/VertxJobsServiceTest.java | 4 +-
.../quarkus/workflow/KogitoBeanProducer.java | 10 +-
...ava => SpringBootTaskDeadlineEntityMapper.java} | 14 +-
...> SpringBootTaskDeadlineTimerEntityMapper.java} | 14 +-
...=> SpringBootTaskReassignmentEntityMapper.java} | 14 +-
...ringBootTaskReassignmentTimerEntityMapper.java} | 14 +-
.../SpringBootUserTaskInstanceEntityMapper.java | 11 +-
.../SpringBootTaskDeadlineRepository.java} | 17 +-
.../SpringBootTaskDeadlineTimerRepository.java} | 17 +-
.../SpringBootTaskReassignmentRepository.java} | 17 +-
...SpringBootTaskReassignmentTimerRepository.java} | 17 +-
.../springboot/CallbackJobsServiceResource.java | 2 +-
.../springboot/SpringRestJobsService.java | 11 +-
.../springboot/SpringRestJobsServiceTest.java | 4 +-
.../.gitignore | 1 +
.../org/kie/kogito/process/KogitoBeanProducer.java | 16 +
139 files changed, 3909 insertions(+), 1016 deletions(-)
diff --git a/addons/common/jbpm-usertask-storage-jpa/src/main/java/org/jbpm/usertask/jpa/mapper/AttachmentsEntityMapper.java b/addons/common/jbpm-usertask-storage-jpa/src/main/java/org/jbpm/usertask/jpa/mapper/AttachmentsEntityMapper.java
index 210553ed85..96aee9ee70 100644
--- a/addons/common/jbpm-usertask-storage-jpa/src/main/java/org/jbpm/usertask/jpa/mapper/AttachmentsEntityMapper.java
+++ b/addons/common/jbpm-usertask-storage-jpa/src/main/java/org/jbpm/usertask/jpa/mapper/AttachmentsEntityMapper.java
@@ -33,13 +33,14 @@ import org.kie.kogito.usertask.model.Attachment;
import static java.util.stream.Collectors.toCollection;
-public class AttachmentsEntityMapper {
+public class AttachmentsEntityMapper implements EntityMapper {
private final AttachmentRepository repository;
public AttachmentsEntityMapper(AttachmentRepository repository) {
this.repository = repository;
}
+ @Override
public void mapInstanceToEntity(UserTaskInstance userTaskInstance, UserTaskInstanceEntity userTaskInstanceEntity) {
Collection<AttachmentEntity> toRemove = userTaskInstanceEntity.getAttachments()
.stream()
@@ -65,6 +66,7 @@ public class AttachmentsEntityMapper {
});
}
+ @Override
public void mapEntityToInstance(UserTaskInstanceEntity userTaskInstanceEntity, UserTaskInstance userTaskInstance) {
List<Attachment> attachments = userTaskInstanceEntity.getAttachments().stream().map(attachmentEntity -> {
diff --git a/addons/common/jbpm-usertask-storage-jpa/src/main/java/org/jbpm/usertask/jpa/mapper/CommentsEntityMapper.java b/addons/common/jbpm-usertask-storage-jpa/src/main/java/org/jbpm/usertask/jpa/mapper/CommentsEntityMapper.java
index b854ec3510..d705ef882e 100644
--- a/addons/common/jbpm-usertask-storage-jpa/src/main/java/org/jbpm/usertask/jpa/mapper/CommentsEntityMapper.java
+++ b/addons/common/jbpm-usertask-storage-jpa/src/main/java/org/jbpm/usertask/jpa/mapper/CommentsEntityMapper.java
@@ -32,7 +32,7 @@ import org.kie.kogito.usertask.model.Comment;
import static java.util.stream.Collectors.toCollection;
-public class CommentsEntityMapper {
+public class CommentsEntityMapper implements EntityMapper {
private final CommentRepository repository;
@@ -40,6 +40,7 @@ public class CommentsEntityMapper {
this.repository = repository;
}
+ @Override
public void mapInstanceToEntity(UserTaskInstance userTaskInstance, UserTaskInstanceEntity userTaskInstanceEntity) {
Collection<CommentEntity> toRemove = userTaskInstanceEntity.getComments()
.stream()
@@ -64,6 +65,7 @@ public class CommentsEntityMapper {
});
}
+ @Override
public void mapEntityToInstance(UserTaskInstanceEntity userTaskInstanceEntity, UserTaskInstance userTaskInstance) {
List<Comment> comments = userTaskInstanceEntity.getComments().stream().map(commentEntity -> {
Comment comment = new Comment(commentEntity.getId(), commentEntity.getUpdatedBy());
diff --git a/api/kogito-api/src/main/java/org/kie/kogito/jobs/JobDescription.java b/addons/common/jbpm-usertask-storage-jpa/src/main/java/org/jbpm/usertask/jpa/mapper/EntityMapper.java
similarity index 66%
copy from api/kogito-api/src/main/java/org/kie/kogito/jobs/JobDescription.java
copy to addons/common/jbpm-usertask-storage-jpa/src/main/java/org/jbpm/usertask/jpa/mapper/EntityMapper.java
index 5bbd520bfc..d9759d6e1a 100644
--- a/api/kogito-api/src/main/java/org/kie/kogito/jobs/JobDescription.java
+++ b/addons/common/jbpm-usertask-storage-jpa/src/main/java/org/jbpm/usertask/jpa/mapper/EntityMapper.java
@@ -16,13 +16,15 @@
* specific language governing permissions and limitations
* under the License.
*/
-package org.kie.kogito.jobs;
+package org.jbpm.usertask.jpa.mapper;
-public interface JobDescription {
+import org.jbpm.usertask.jpa.model.UserTaskInstanceEntity;
+import org.kie.kogito.usertask.UserTaskInstance;
- String id();
+public interface EntityMapper {
- ExpirationTime expirationTime();
+ void mapInstanceToEntity(UserTaskInstance userTaskInstance, UserTaskInstanceEntity userTaskInstanceEntity);
- Integer priority();
-}
+ void mapEntityToInstance(UserTaskInstanceEntity userTaskInstanceEntity, UserTaskInstance userTaskInstance);
+
+}
\ No newline at end of file
diff --git a/addons/common/jbpm-usertask-storage-jpa/src/main/java/org/jbpm/usertask/jpa/mapper/TaskDeadlineEntityMapper.java b/addons/common/jbpm-usertask-storage-jpa/src/main/java/org/jbpm/usertask/jpa/mapper/TaskDeadlineEntityMapper.java
new file mode 100644
index 0000000000..7d28bbdbda
--- /dev/null
+++ b/addons/common/jbpm-usertask-storage-jpa/src/main/java/org/jbpm/usertask/jpa/mapper/TaskDeadlineEntityMapper.java
@@ -0,0 +1,136 @@
+/*
+ * 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.jbpm.usertask.jpa.mapper;
+
+import java.nio.charset.StandardCharsets;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+import org.jbpm.usertask.jpa.mapper.json.utils.JSONUtils;
+import org.jbpm.usertask.jpa.model.TaskDeadlineEntity;
+import org.jbpm.usertask.jpa.model.TaskDeadlineType;
+import org.jbpm.usertask.jpa.model.UserTaskInstanceEntity;
+import org.jbpm.usertask.jpa.repository.TaskDeadlineRepository;
+import org.kie.kogito.usertask.UserTaskInstance;
+import org.kie.kogito.usertask.impl.DefaultUserTaskInstance;
+import org.kie.kogito.usertask.model.DeadlineInfo;
+import org.kie.kogito.usertask.model.Notification;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.fasterxml.jackson.databind.JavaType;
+
+public class TaskDeadlineEntityMapper implements EntityMapper {
+ private static final Logger LOG = LoggerFactory.getLogger(TaskDeadlineEntityMapper.class);
+
+ private final TaskDeadlineRepository repository;
+
+ public TaskDeadlineEntityMapper(TaskDeadlineRepository repository) {
+ this.repository = repository;
+ }
+
+ @Override
+ public void mapInstanceToEntity(UserTaskInstance userTaskInstance, UserTaskInstanceEntity userTaskInstanceEntity) {
+ if (userTaskInstanceEntity.getDeadlines() == null) {
+ userTaskInstanceEntity.setDeadlines(new ArrayList<>());
+ }
+
+ List<TaskDeadlineEntity> entities = new ArrayList<>();
+ List<DeadlineInfo<Notification>> notStartedNotifications = new ArrayList<>();
+ List<DeadlineInfo<Notification>> notCompletedNotifications = new ArrayList<>();
+ Iterator<TaskDeadlineEntity> iterator = userTaskInstanceEntity.getDeadlines().iterator();
+ while (iterator.hasNext()) {
+ TaskDeadlineEntity deadlineEntity = iterator.next();
+ DeadlineInfo<Notification> deadline = readNotification(deadlineEntity.getValue());
+ switch (deadlineEntity.getType()) {
+ case NotCompleted:
+ if (!userTaskInstance.getNotCompletedDeadlines().contains(deadline)) {
+ entities.add(deadlineEntity);
+ } else {
+ notCompletedNotifications.add(deadline);
+ }
+ break;
+ case NotStarted:
+ if (!userTaskInstance.getNotStartedDeadlines().contains(deadline)) {
+ entities.add(deadlineEntity);
+ } else {
+ notStartedNotifications.add(deadline);
+ }
+ break;
+ }
+ }
+
+ entities.forEach(e -> {
+ repository.remove(e);
+ userTaskInstanceEntity.getDeadlines().remove(e);
+ });
+ entities.clear();
+
+ for (DeadlineInfo<Notification> deadline : userTaskInstance.getNotStartedDeadlines()) {
+ if (!notStartedNotifications.contains(deadline)) {
+ entities.add(buildEntity(userTaskInstanceEntity, deadline, TaskDeadlineType.NotStarted));
+ }
+ }
+ for (DeadlineInfo<Notification> deadline : userTaskInstance.getNotCompletedDeadlines()) {
+ if (!notCompletedNotifications.contains(deadline)) {
+ entities.add(buildEntity(userTaskInstanceEntity, deadline, TaskDeadlineType.NotCompleted));
+ }
+ }
+ entities.forEach(e -> {
+ userTaskInstanceEntity.getDeadlines().add(e);
+ });
+ }
+
+ private TaskDeadlineEntity buildEntity(UserTaskInstanceEntity userTaskInstanceEntity, DeadlineInfo<Notification> deadline, TaskDeadlineType type) {
+ TaskDeadlineEntity entity = new TaskDeadlineEntity();
+ entity.setTaskInstance(userTaskInstanceEntity);
+ entity.setJavaType(DeadlineInfo.class.getName());
+ entity.setValue(JSONUtils.valueToString(deadline).getBytes(StandardCharsets.UTF_8));
+ entity.setType(type);
+ return entity;
+ }
+
+ @Override
+ public void mapEntityToInstance(UserTaskInstanceEntity userTaskInstanceEntity, UserTaskInstance userTaskInstance) {
+ List<DeadlineInfo<Notification>> notStarted = new ArrayList<>();
+ List<DeadlineInfo<Notification>> notCompleted = new ArrayList<>();
+
+ for (TaskDeadlineEntity entity : userTaskInstanceEntity.getDeadlines()) {
+ DeadlineInfo<Notification> deadline = readNotification(entity.getValue());
+ switch (entity.getType()) {
+ case NotCompleted:
+ notCompleted.add(deadline);
+ break;
+ case NotStarted:
+ notStarted.add(deadline);
+ break;
+ }
+ }
+
+ ((DefaultUserTaskInstance) userTaskInstance).setNotStartedDeadlines(notStarted);
+ ((DefaultUserTaskInstance) userTaskInstance).setNotCompletedDeadlines(notCompleted);
+ }
+
+ private DeadlineInfo<Notification> readNotification(byte[] value) {
+ JavaType javaType = JSONUtils.buildJavaType(DeadlineInfo.class, Notification.class);
+ return (DeadlineInfo<Notification>) JSONUtils.stringTreeToValue(new String(value), javaType);
+ }
+}
diff --git a/addons/common/jbpm-usertask-storage-jpa/src/main/java/org/jbpm/usertask/jpa/mapper/TaskDeadlineTimerEntityMapper.java b/addons/common/jbpm-usertask-storage-jpa/src/main/java/org/jbpm/usertask/jpa/mapper/TaskDeadlineTimerEntityMapper.java
new file mode 100644
index 0000000000..568cea2e6f
--- /dev/null
+++ b/addons/common/jbpm-usertask-storage-jpa/src/main/java/org/jbpm/usertask/jpa/mapper/TaskDeadlineTimerEntityMapper.java
@@ -0,0 +1,132 @@
+/*
+ * 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.jbpm.usertask.jpa.mapper;
+
+import java.nio.charset.StandardCharsets;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+import org.jbpm.usertask.jpa.mapper.json.utils.JSONUtils;
+import org.jbpm.usertask.jpa.model.TaskDeadlineTimerEntity;
+import org.jbpm.usertask.jpa.model.TaskDeadlineType;
+import org.jbpm.usertask.jpa.model.UserTaskInstanceEntity;
+import org.jbpm.usertask.jpa.repository.TaskDeadlineTimerRepository;
+import org.kie.kogito.usertask.UserTaskInstance;
+import org.kie.kogito.usertask.impl.DefaultUserTaskInstance;
+import org.kie.kogito.usertask.model.Notification;
+
+public class TaskDeadlineTimerEntityMapper implements EntityMapper {
+
+ private final TaskDeadlineTimerRepository repository;
+
+ public TaskDeadlineTimerEntityMapper(TaskDeadlineTimerRepository repository) {
+ this.repository = repository;
+ }
+
+ @Override
+ public void mapInstanceToEntity(UserTaskInstance instance, UserTaskInstanceEntity userTaskInstanceEntity) {
+ if (userTaskInstanceEntity.getDeadlineTimers() == null) {
+ userTaskInstanceEntity.setDeadlineTimers(new ArrayList<>());
+ }
+ DefaultUserTaskInstance userTaskInstance = (DefaultUserTaskInstance) instance;
+ List<String> notStartedNotifications = new ArrayList<>();
+ List<String> notCompletedNotifications = new ArrayList<>();
+
+ List<TaskDeadlineTimerEntity> entities = new ArrayList<>();
+ Iterator<TaskDeadlineTimerEntity> iterator = userTaskInstanceEntity.getDeadlineTimers().iterator();
+ while (iterator.hasNext()) {
+ TaskDeadlineTimerEntity deadlineEntity = iterator.next();
+ switch (deadlineEntity.getType()) {
+ case NotCompleted:
+ if (!userTaskInstance.getNotCompletedDeadlinesTimers().keySet().contains(deadlineEntity.getJobId())) {
+ entities.add(deadlineEntity);
+ } else {
+ notCompletedNotifications.add(deadlineEntity.getJobId());
+ }
+ break;
+ case NotStarted:
+ if (!userTaskInstance.getNotStartedDeadlinesTimers().keySet().contains(deadlineEntity.getJobId())) {
+ entities.add(deadlineEntity);
+ } else {
+ notStartedNotifications.add(deadlineEntity.getJobId());
+ }
+ break;
+ }
+ }
+
+ entities.forEach(e -> {
+ repository.remove(e);
+ userTaskInstanceEntity.getDeadlineTimers().remove(e);
+ });
+ entities.clear();
+
+ for (Map.Entry<String, Notification> timer : userTaskInstance.getNotStartedDeadlinesTimers().entrySet()) {
+ if (!notStartedNotifications.contains(timer.getKey())) {
+ TaskDeadlineTimerEntity entity = buildEntity(userTaskInstanceEntity, timer.getKey(), timer.getValue(), TaskDeadlineType.NotStarted);
+ entities.add(entity);
+ }
+ }
+
+ for (Map.Entry<String, Notification> timer : userTaskInstance.getNotCompletedDeadlinesTimers().entrySet()) {
+ if (!notCompletedNotifications.contains(timer.getKey())) {
+ TaskDeadlineTimerEntity entity = buildEntity(userTaskInstanceEntity, timer.getKey(), timer.getValue(), TaskDeadlineType.NotCompleted);
+ entities.add(entity);
+ }
+ }
+ entities.forEach(userTaskInstanceEntity.getDeadlineTimers()::add);
+ }
+
+ private TaskDeadlineTimerEntity buildEntity(UserTaskInstanceEntity userTaskInstanceEntity, String jobId, Notification deadline, TaskDeadlineType type) {
+ TaskDeadlineTimerEntity entity = new TaskDeadlineTimerEntity();
+ entity.setTaskInstance(userTaskInstanceEntity);
+ entity.setJobId(jobId);
+ entity.setJavaType(Notification.class.getName());
+ entity.setValue(JSONUtils.valueToString(deadline).getBytes(StandardCharsets.UTF_8));
+ entity.setType(type);
+ return entity;
+ }
+
+ @Override
+ public void mapEntityToInstance(UserTaskInstanceEntity userTaskInstanceEntity, UserTaskInstance userTaskInstance) {
+ Map<String, Notification> notStarted = new HashMap<>();
+ Map<String, Notification> notCompleted = new HashMap<>();
+ for (TaskDeadlineTimerEntity entity : userTaskInstanceEntity.getDeadlineTimers()) {
+ Notification notification = (Notification) JSONUtils.stringTreeToValue(new String(entity.getValue()), Notification.class.getName());
+ switch (entity.getType()) {
+ case NotCompleted:
+ notCompleted.put(entity.getJobId(), notification);
+ break;
+ case NotStarted:
+ notStarted.put(entity.getJobId(), notification);
+ break;
+ }
+ }
+
+ ((DefaultUserTaskInstance) userTaskInstance).setNotStartedDeadlinesTimers(notStarted);
+ ((DefaultUserTaskInstance) userTaskInstance).setNotCompletedDeadlinesTimers(notCompleted);
+ }
+
+ private Notification readNotification(byte[] value) {
+ return (Notification) JSONUtils.stringTreeToValue(new String(value), Notification.class.getName());
+ }
+}
diff --git a/addons/common/jbpm-usertask-storage-jpa/src/main/java/org/jbpm/usertask/jpa/mapper/TaskInputsEntityMapper.java b/addons/common/jbpm-usertask-storage-jpa/src/main/java/org/jbpm/usertask/jpa/mapper/TaskInputsEntityMapper.java
index 12a6c50f98..a61ffabcdd 100644
--- a/addons/common/jbpm-usertask-storage-jpa/src/main/java/org/jbpm/usertask/jpa/mapper/TaskInputsEntityMapper.java
+++ b/addons/common/jbpm-usertask-storage-jpa/src/main/java/org/jbpm/usertask/jpa/mapper/TaskInputsEntityMapper.java
@@ -32,7 +32,7 @@ import org.jbpm.usertask.jpa.repository.TaskInputRepository;
import org.kie.kogito.usertask.UserTaskInstance;
import org.kie.kogito.usertask.impl.DefaultUserTaskInstance;
-public class TaskInputsEntityMapper {
+public class TaskInputsEntityMapper implements EntityMapper {
private TaskInputRepository repository;
@@ -40,6 +40,7 @@ public class TaskInputsEntityMapper {
this.repository = repository;
}
+ @Override
public void mapInstanceToEntity(UserTaskInstance userTaskInstance, UserTaskInstanceEntity userTaskInstanceEntity) {
Collection<TaskInputEntity> toRemove = userTaskInstanceEntity.getInputs()
.stream()
@@ -66,6 +67,7 @@ public class TaskInputsEntityMapper {
});
}
+ @Override
public void mapEntityToInstance(UserTaskInstanceEntity userTaskInstanceEntity, UserTaskInstance userTaskInstance) {
Map<String, Object> inputs = new HashMap<>();
userTaskInstanceEntity.getInputs().forEach(taskInputEntity -> {
diff --git a/addons/common/jbpm-usertask-storage-jpa/src/main/java/org/jbpm/usertask/jpa/mapper/TaskMetadataEntityMapper.java b/addons/common/jbpm-usertask-storage-jpa/src/main/java/org/jbpm/usertask/jpa/mapper/TaskMetadataEntityMapper.java
index 999c735749..b4af4fc8a9 100644
--- a/addons/common/jbpm-usertask-storage-jpa/src/main/java/org/jbpm/usertask/jpa/mapper/TaskMetadataEntityMapper.java
+++ b/addons/common/jbpm-usertask-storage-jpa/src/main/java/org/jbpm/usertask/jpa/mapper/TaskMetadataEntityMapper.java
@@ -31,7 +31,7 @@ import org.jbpm.usertask.jpa.repository.TaskMetadataRepository;
import org.kie.kogito.usertask.UserTaskInstance;
import org.kie.kogito.usertask.impl.DefaultUserTaskInstance;
-public class TaskMetadataEntityMapper {
+public class TaskMetadataEntityMapper implements EntityMapper {
private final TaskMetadataRepository repository;
@@ -39,6 +39,7 @@ public class TaskMetadataEntityMapper {
this.repository = repository;
}
+ @Override
public void mapInstanceToEntity(UserTaskInstance userTaskInstance, UserTaskInstanceEntity userTaskInstanceEntity) {
Collection<TaskMetadataEntity> toRemove = userTaskInstanceEntity.getMetadata()
.stream()
@@ -64,6 +65,7 @@ public class TaskMetadataEntityMapper {
});
}
+ @Override
public void mapEntityToInstance(UserTaskInstanceEntity userTaskInstanceEntity, UserTaskInstance userTaskInstance) {
Map<String, Object> metadata = new HashMap<>();
userTaskInstanceEntity.getMetadata().forEach(metadataEntry -> {
diff --git a/addons/common/jbpm-usertask-storage-jpa/src/main/java/org/jbpm/usertask/jpa/mapper/TaskOutputsEntityMapper.java b/addons/common/jbpm-usertask-storage-jpa/src/main/java/org/jbpm/usertask/jpa/mapper/TaskOutputsEntityMapper.java
index 1fa7d4ae28..5f93dd53ee 100644
--- a/addons/common/jbpm-usertask-storage-jpa/src/main/java/org/jbpm/usertask/jpa/mapper/TaskOutputsEntityMapper.java
+++ b/addons/common/jbpm-usertask-storage-jpa/src/main/java/org/jbpm/usertask/jpa/mapper/TaskOutputsEntityMapper.java
@@ -32,7 +32,7 @@ import org.jbpm.usertask.jpa.repository.TaskOutputRepository;
import org.kie.kogito.usertask.UserTaskInstance;
import org.kie.kogito.usertask.impl.DefaultUserTaskInstance;
-public class TaskOutputsEntityMapper {
+public class TaskOutputsEntityMapper implements EntityMapper {
private final TaskOutputRepository repository;
@@ -40,6 +40,7 @@ public class TaskOutputsEntityMapper {
this.repository = repository;
}
+ @Override
public void mapInstanceToEntity(UserTaskInstance userTaskInstance, UserTaskInstanceEntity userTaskInstanceEntity) {
Collection<TaskOutputEntity> toRemove = userTaskInstanceEntity.getOutputs()
.stream()
@@ -66,6 +67,7 @@ public class TaskOutputsEntityMapper {
});
}
+ @Override
public void mapEntityToInstance(UserTaskInstanceEntity userTaskInstanceEntity, UserTaskInstance userTaskInstance) {
Map<String, Object> outputs = new HashMap<>();
userTaskInstanceEntity.getOutputs().forEach(taskOutputEntity -> {
diff --git a/addons/common/jbpm-usertask-storage-jpa/src/main/java/org/jbpm/usertask/jpa/mapper/TaskReassignmentEntityMapper.java b/addons/common/jbpm-usertask-storage-jpa/src/main/java/org/jbpm/usertask/jpa/mapper/TaskReassignmentEntityMapper.java
new file mode 100644
index 0000000000..84a4f78308
--- /dev/null
+++ b/addons/common/jbpm-usertask-storage-jpa/src/main/java/org/jbpm/usertask/jpa/mapper/TaskReassignmentEntityMapper.java
@@ -0,0 +1,137 @@
+/*
+ * 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.jbpm.usertask.jpa.mapper;
+
+import java.nio.charset.StandardCharsets;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+import org.jbpm.usertask.jpa.mapper.json.utils.JSONUtils;
+import org.jbpm.usertask.jpa.model.TaskReassignmentEntity;
+import org.jbpm.usertask.jpa.model.TaskReassignmentType;
+import org.jbpm.usertask.jpa.model.UserTaskInstanceEntity;
+import org.jbpm.usertask.jpa.repository.TaskReassignmentRepository;
+import org.kie.kogito.usertask.UserTaskInstance;
+import org.kie.kogito.usertask.impl.DefaultUserTaskInstance;
+import org.kie.kogito.usertask.model.DeadlineInfo;
+import org.kie.kogito.usertask.model.Reassignment;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.fasterxml.jackson.databind.JavaType;
+
+public class TaskReassignmentEntityMapper implements EntityMapper {
+
+ private static final Logger LOG = LoggerFactory.getLogger(TaskReassignmentEntityMapper.class);
+
+ private final TaskReassignmentRepository repository;
+
+ public TaskReassignmentEntityMapper(TaskReassignmentRepository repository) {
+ this.repository = repository;
+ }
+
+ @Override
+ public void mapInstanceToEntity(UserTaskInstance userTaskInstance, UserTaskInstanceEntity userTaskInstanceEntity) {
+ if (userTaskInstanceEntity.getReassignments() == null) {
+ userTaskInstanceEntity.setReassignments(new ArrayList<>());
+ }
+ List<TaskReassignmentEntity> entities = new ArrayList<>();
+ List<DeadlineInfo<Reassignment>> notStartedReassignments = new ArrayList<>();
+ List<DeadlineInfo<Reassignment>> notCompletedReassignments = new ArrayList<>();
+ Iterator<TaskReassignmentEntity> iterator = userTaskInstanceEntity.getReassignments().iterator();
+ while (iterator.hasNext()) {
+ TaskReassignmentEntity reassignmentEntity = iterator.next();
+ DeadlineInfo<Reassignment> deadline = readNotification(reassignmentEntity.getValue());
+ switch (reassignmentEntity.getType()) {
+ case NotCompleted:
+ if (!userTaskInstance.getNotCompletedReassignments().contains(deadline)) {
+ entities.add(reassignmentEntity);
+ } else {
+ notCompletedReassignments.add(deadline);
+ }
+ break;
+ case NotStarted:
+ if (!userTaskInstance.getNotStartedReassignments().contains(deadline)) {
+ entities.add(reassignmentEntity);
+ } else {
+ notStartedReassignments.add(deadline);
+ }
+ break;
+ }
+ }
+
+ entities.forEach(e -> {
+ repository.remove(e);
+ userTaskInstanceEntity.getReassignments().remove(e);
+ });
+ entities.clear();
+
+ for (DeadlineInfo<Reassignment> reassignment : userTaskInstance.getNotStartedReassignments()) {
+ if (!notStartedReassignments.contains(reassignment)) {
+ entities.add(buildEntity(userTaskInstanceEntity, reassignment, TaskReassignmentType.NotStarted));
+ }
+ }
+
+ for (DeadlineInfo<Reassignment> reassignment : userTaskInstance.getNotCompletedReassignments()) {
+ if (!notCompletedReassignments.contains(reassignment)) {
+ entities.add(buildEntity(userTaskInstanceEntity, reassignment, TaskReassignmentType.NotCompleted));
+ }
+ }
+ entities.forEach(e -> {
+ userTaskInstanceEntity.getReassignments().add(e);
+ });
+ }
+
+ private TaskReassignmentEntity buildEntity(UserTaskInstanceEntity userTaskInstanceEntity, DeadlineInfo<Reassignment> deadline, TaskReassignmentType type) {
+ TaskReassignmentEntity entity = new TaskReassignmentEntity();
+ entity.setTaskInstance(userTaskInstanceEntity);
+ entity.setJavaType(DeadlineInfo.class.getName());
+ entity.setValue(JSONUtils.valueToString(deadline).getBytes(StandardCharsets.UTF_8));
+ entity.setType(type);
+ return entity;
+ }
+
+ private DeadlineInfo<Reassignment> readNotification(byte[] value) {
+ JavaType javaType = JSONUtils.buildJavaType(DeadlineInfo.class, Reassignment.class);
+ return (DeadlineInfo<Reassignment>) JSONUtils.stringTreeToValue(new String(value), javaType);
+ }
+
+ @Override
+ public void mapEntityToInstance(UserTaskInstanceEntity userTaskInstanceEntity, UserTaskInstance userTaskInstance) {
+ List<DeadlineInfo<Reassignment>> notStarted = new ArrayList<>();
+ List<DeadlineInfo<Reassignment>> notCompleted = new ArrayList<>();
+ JavaType javaType = JSONUtils.buildJavaType(DeadlineInfo.class, Reassignment.class);
+ for (TaskReassignmentEntity entity : userTaskInstanceEntity.getReassignments()) {
+ DeadlineInfo<Reassignment> deadline = (DeadlineInfo<Reassignment>) JSONUtils.stringTreeToValue(new String(entity.getValue()), javaType);
+ switch (entity.getType()) {
+ case NotCompleted:
+ notCompleted.add(deadline);
+ break;
+ case NotStarted:
+ notStarted.add(deadline);
+ break;
+ }
+ }
+
+ ((DefaultUserTaskInstance) userTaskInstance).setNotStartedReassignments(notStarted);
+ ((DefaultUserTaskInstance) userTaskInstance).setNotCompletedReassignments(notCompleted);
+ }
+}
diff --git a/addons/common/jbpm-usertask-storage-jpa/src/main/java/org/jbpm/usertask/jpa/mapper/TaskReassignmentTimerEntityMapper.java b/addons/common/jbpm-usertask-storage-jpa/src/main/java/org/jbpm/usertask/jpa/mapper/TaskReassignmentTimerEntityMapper.java
new file mode 100644
index 0000000000..80366a07be
--- /dev/null
+++ b/addons/common/jbpm-usertask-storage-jpa/src/main/java/org/jbpm/usertask/jpa/mapper/TaskReassignmentTimerEntityMapper.java
@@ -0,0 +1,130 @@
+/*
+ * 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.jbpm.usertask.jpa.mapper;
+
+import java.nio.charset.StandardCharsets;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+import org.jbpm.usertask.jpa.mapper.json.utils.JSONUtils;
+import org.jbpm.usertask.jpa.model.TaskReassignmentTimerEntity;
+import org.jbpm.usertask.jpa.model.TaskReassignmentType;
+import org.jbpm.usertask.jpa.model.UserTaskInstanceEntity;
+import org.jbpm.usertask.jpa.repository.TaskReassignmentTimerRepository;
+import org.kie.kogito.usertask.UserTaskInstance;
+import org.kie.kogito.usertask.impl.DefaultUserTaskInstance;
+import org.kie.kogito.usertask.model.Reassignment;
+
+public class TaskReassignmentTimerEntityMapper implements EntityMapper {
+
+ private final TaskReassignmentTimerRepository repository;
+
+ public TaskReassignmentTimerEntityMapper(TaskReassignmentTimerRepository repository) {
+ this.repository = repository;
+ }
+
+ @Override
+ public void mapInstanceToEntity(UserTaskInstance instance, UserTaskInstanceEntity userTaskInstanceEntity) {
+ if (userTaskInstanceEntity.getReassignmentTimers() == null) {
+ userTaskInstanceEntity.setReassignmentTimers(new ArrayList<>());
+ }
+ DefaultUserTaskInstance userTaskInstance = (DefaultUserTaskInstance) instance;
+
+ List<TaskReassignmentTimerEntity> entities = new ArrayList<>();
+ List<String> notStartedReassignments = new ArrayList<>();
+ List<String> notCompletedReassignments = new ArrayList<>();
+
+ Iterator<TaskReassignmentTimerEntity> iterator = userTaskInstanceEntity.getReassignmentTimers().iterator();
+ while (iterator.hasNext()) {
+ TaskReassignmentTimerEntity deadlineEntity = iterator.next();
+ switch (deadlineEntity.getType()) {
+ case NotCompleted:
+ if (!userTaskInstance.getNotCompletedReassignmentsTimers().keySet().contains(deadlineEntity.getJobId())) {
+ entities.add(deadlineEntity);
+ } else {
+ notCompletedReassignments.add(deadlineEntity.getJobId());
+ }
+ break;
+ case NotStarted:
+ if (!userTaskInstance.getNotStartedReassignmentsTimers().keySet().contains(deadlineEntity.getJobId())) {
+ entities.add(deadlineEntity);
+ } else {
+ notStartedReassignments.add(deadlineEntity.getJobId());
+ }
+ break;
+ }
+ }
+
+ entities.forEach(e -> {
+ repository.remove(e);
+ userTaskInstanceEntity.getReassignmentTimers().remove(e);
+ });
+ entities.clear();
+
+ for (Map.Entry<String, Reassignment> timer : userTaskInstance.getNotStartedReassignmentsTimers().entrySet()) {
+ if (!notStartedReassignments.contains(timer.getKey())) {
+ TaskReassignmentTimerEntity entity = buildEntity(userTaskInstanceEntity, timer.getKey(), timer.getValue(), TaskReassignmentType.NotStarted);
+ entities.add(entity);
+ }
+ }
+
+ for (Map.Entry<String, Reassignment> timer : userTaskInstance.getNotCompletedReassignmentsTimers().entrySet()) {
+ if (!notCompletedReassignments.contains(timer.getKey())) {
+ TaskReassignmentTimerEntity entity = buildEntity(userTaskInstanceEntity, timer.getKey(), timer.getValue(), TaskReassignmentType.NotCompleted);
+ entities.add(entity);
+ }
+ }
+ entities.forEach(userTaskInstanceEntity.getReassignmentTimers()::add);
+ }
+
+ private TaskReassignmentTimerEntity buildEntity(UserTaskInstanceEntity userTaskInstanceEntity, String jobId, Reassignment reassignment, TaskReassignmentType type) {
+ TaskReassignmentTimerEntity entity = new TaskReassignmentTimerEntity();
+ entity.setJobId(jobId);
+ entity.setTaskInstance(userTaskInstanceEntity);
+ entity.setJavaType(Reassignment.class.getName());
+ entity.setValue(JSONUtils.valueToString(reassignment).getBytes(StandardCharsets.UTF_8));
+ entity.setType(type);
+ return entity;
+ }
+
+ @Override
+ public void mapEntityToInstance(UserTaskInstanceEntity userTaskInstanceEntity, UserTaskInstance userTaskInstance) {
+ Map<String, Reassignment> notStarted = new HashMap<>();
+ Map<String, Reassignment> notCompleted = new HashMap<>();
+ for (TaskReassignmentTimerEntity entity : userTaskInstanceEntity.getReassignmentTimers()) {
+ Reassignment notification = (Reassignment) JSONUtils.stringTreeToValue(new String(entity.getValue()), Reassignment.class.getName());
+ switch (entity.getType()) {
+ case NotCompleted:
+ notCompleted.put(entity.getJobId(), notification);
+ break;
+ case NotStarted:
+ notStarted.put(entity.getJobId(), notification);
+ break;
+ }
+ }
+
+ ((DefaultUserTaskInstance) userTaskInstance).setNotStartedReassignmentsTimers(notStarted);
+ ((DefaultUserTaskInstance) userTaskInstance).setNotCompletedReassignmentsTimers(notCompleted);
+ }
+
+}
diff --git a/addons/common/jbpm-usertask-storage-jpa/src/main/java/org/jbpm/usertask/jpa/mapper/UserTaskInstanceEntityMapper.java b/addons/common/jbpm-usertask-storage-jpa/src/main/java/org/jbpm/usertask/jpa/mapper/UserTaskInstanceEntityMapper.java
index e03125742b..c183ad0f22 100644
--- a/addons/common/jbpm-usertask-storage-jpa/src/main/java/org/jbpm/usertask/jpa/mapper/UserTaskInstanceEntityMapper.java
+++ b/addons/common/jbpm-usertask-storage-jpa/src/main/java/org/jbpm/usertask/jpa/mapper/UserTaskInstanceEntityMapper.java
@@ -19,6 +19,8 @@
package org.jbpm.usertask.jpa.mapper;
+import java.util.ArrayList;
+import java.util.List;
import java.util.Set;
import org.jbpm.usertask.jpa.model.UserTaskInstanceEntity;
@@ -28,19 +30,11 @@ import org.kie.kogito.usertask.lifecycle.UserTaskState;
public class UserTaskInstanceEntityMapper {
- private final AttachmentsEntityMapper attachmentsMapper;
- private final CommentsEntityMapper commentMapper;
- private final TaskInputsEntityMapper taskInputsMapper;
- private final TaskOutputsEntityMapper taskOutputsMapper;
- private final TaskMetadataEntityMapper taskMetadataMapper;
-
- public UserTaskInstanceEntityMapper(AttachmentsEntityMapper attachmentsMapper, CommentsEntityMapper commentsMapper, TaskMetadataEntityMapper taskMetadataMapper,
- TaskInputsEntityMapper taskInputsMapper, TaskOutputsEntityMapper taskOutputMapper) {
- this.attachmentsMapper = attachmentsMapper;
- this.commentMapper = commentsMapper;
- this.taskMetadataMapper = taskMetadataMapper;
- this.taskInputsMapper = taskInputsMapper;
- this.taskOutputsMapper = taskOutputMapper;
+ private List<EntityMapper> mappers;
+
+ public UserTaskInstanceEntityMapper(Iterable<EntityMapper> mappers) {
+ this.mappers = new ArrayList<>();
+ mappers.forEach(this.mappers::add);
}
public UserTaskInstanceEntity mapTaskInstanceToEntity(UserTaskInstance userTaskInstance, UserTaskInstanceEntity entity) {
@@ -60,11 +54,7 @@ public class UserTaskInstanceEntityMapper {
entity.setAdminGroups(Set.copyOf(userTaskInstance.getAdminGroups()));
entity.setExcludedUsers(Set.copyOf(userTaskInstance.getExcludedUsers()));
- attachmentsMapper.mapInstanceToEntity(userTaskInstance, entity);
- commentMapper.mapInstanceToEntity(userTaskInstance, entity);
- taskInputsMapper.mapInstanceToEntity(userTaskInstance, entity);
- taskOutputsMapper.mapInstanceToEntity(userTaskInstance, entity);
- taskMetadataMapper.mapInstanceToEntity(userTaskInstance, entity);
+ mappers.forEach(e -> e.mapInstanceToEntity(userTaskInstance, entity));
return entity;
}
@@ -90,11 +80,7 @@ public class UserTaskInstanceEntityMapper {
instance.setAdminGroups(Set.copyOf(entity.getAdminGroups()));
instance.setExcludedUsers(Set.copyOf(entity.getExcludedUsers()));
- attachmentsMapper.mapEntityToInstance(entity, instance);
- commentMapper.mapEntityToInstance(entity, instance);
- taskInputsMapper.mapEntityToInstance(entity, instance);
- taskOutputsMapper.mapEntityToInstance(entity, instance);
- taskMetadataMapper.mapEntityToInstance(entity, instance);
+ mappers.forEach(e -> e.mapEntityToInstance(entity, instance));
return instance;
}
diff --git a/addons/common/jbpm-usertask-storage-jpa/src/main/java/org/jbpm/usertask/jpa/mapper/json/utils/JSONUtils.java b/addons/common/jbpm-usertask-storage-jpa/src/main/java/org/jbpm/usertask/jpa/mapper/json/utils/JSONUtils.java
index b7e3358980..ab4d13f49d 100644
--- a/addons/common/jbpm-usertask-storage-jpa/src/main/java/org/jbpm/usertask/jpa/mapper/json/utils/JSONUtils.java
+++ b/addons/common/jbpm-usertask-storage-jpa/src/main/java/org/jbpm/usertask/jpa/mapper/json/utils/JSONUtils.java
@@ -22,9 +22,12 @@ package org.jbpm.usertask.jpa.mapper.json.utils;
import java.util.Objects;
import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
+import static java.lang.Thread.currentThread;
+
public class JSONUtils {
private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper();
@@ -33,6 +36,10 @@ public class JSONUtils {
OBJECT_MAPPER.registerModule(new JavaTimeModule());
}
+ public static JavaType buildJavaType(Class<?> clazz, Class<?> parameter) {
+ return OBJECT_MAPPER.getTypeFactory().constructParametricType(clazz, parameter);
+ }
+
public static String valueToString(Object value) {
try {
return OBJECT_MAPPER.writeValueAsString(value);
@@ -46,7 +53,18 @@ public class JSONUtils {
if (Objects.isNull(value) || Objects.isNull(javaType)) {
return null;
}
- return OBJECT_MAPPER.readValue(value, Class.forName(javaType));
+ return OBJECT_MAPPER.readValue(value, currentThread().getContextClassLoader().loadClass(javaType));
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ public static Object stringTreeToValue(String value, JavaType javaType) {
+ try {
+ if (Objects.isNull(value) || Objects.isNull(javaType)) {
+ return null;
+ }
+ return OBJECT_MAPPER.readValue(value, javaType);
} catch (Exception e) {
throw new RuntimeException(e);
}
diff --git a/addons/common/jbpm-usertask-storage-jpa/src/main/java/org/jbpm/usertask/jpa/model/TaskDataEntity.java b/addons/common/jbpm-usertask-storage-jpa/src/main/java/org/jbpm/usertask/jpa/model/AbstractTaskEntity.java
similarity index 60%
copy from addons/common/jbpm-usertask-storage-jpa/src/main/java/org/jbpm/usertask/jpa/model/TaskDataEntity.java
copy to addons/common/jbpm-usertask-storage-jpa/src/main/java/org/jbpm/usertask/jpa/model/AbstractTaskEntity.java
index 506f3bf925..9a1fed04b4 100644
--- a/addons/common/jbpm-usertask-storage-jpa/src/main/java/org/jbpm/usertask/jpa/model/TaskDataEntity.java
+++ b/addons/common/jbpm-usertask-storage-jpa/src/main/java/org/jbpm/usertask/jpa/model/AbstractTaskEntity.java
@@ -21,19 +21,11 @@ package org.jbpm.usertask.jpa.model;
import java.util.Objects;
-import jakarta.persistence.*;
+import jakarta.persistence.Column;
+import jakarta.persistence.MappedSuperclass;
@MappedSuperclass
-public abstract class TaskDataEntity<T> {
-
- @Id
- @Column(name = "name")
- protected String name;
-
- @Id
- @ManyToOne(optional = false)
- @JoinColumn(name = "task_id")
- protected UserTaskInstanceEntity taskInstance;
+public abstract class AbstractTaskEntity<T> {
@Column(name = "value")
protected T value;
@@ -41,22 +33,6 @@ public abstract class TaskDataEntity<T> {
@Column(name = "java_type")
protected String javaType;
- public String getName() {
- return name;
- }
-
- public void setName(String name) {
- this.name = name;
- }
-
- public UserTaskInstanceEntity getTaskInstance() {
- return taskInstance;
- }
-
- public void setTaskInstance(UserTaskInstanceEntity taskInstance) {
- this.taskInstance = taskInstance;
- }
-
public T getValue() {
return value;
}
@@ -79,13 +55,12 @@ public abstract class TaskDataEntity<T> {
return true;
if (o == null || getClass() != o.getClass())
return false;
- TaskDataEntity<?> that = (TaskDataEntity<?>) o;
- return Objects.equals(getName(), that.getName()) && Objects.equals(getTaskInstance(), that.getTaskInstance()) && Objects.equals(getValue(),
- that.getValue()) && Objects.equals(getJavaType(), that.getJavaType());
+ AbstractTaskEntity<?> that = (AbstractTaskEntity<?>) o;
+ return Objects.equals(getValue(), that.getValue()) && Objects.equals(getJavaType(), that.getJavaType());
}
@Override
public int hashCode() {
- return Objects.hash(getName(), getTaskInstance(), getValue(), getJavaType());
+ return Objects.hash(getValue(), getJavaType());
}
}
diff --git a/addons/common/jbpm-usertask-storage-jpa/src/main/java/org/jbpm/usertask/jpa/model/TaskDeadlineEntity.java b/addons/common/jbpm-usertask-storage-jpa/src/main/java/org/jbpm/usertask/jpa/model/TaskDeadlineEntity.java
new file mode 100644
index 0000000000..35f790adb1
--- /dev/null
+++ b/addons/common/jbpm-usertask-storage-jpa/src/main/java/org/jbpm/usertask/jpa/model/TaskDeadlineEntity.java
@@ -0,0 +1,78 @@
+/*
+ * 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.jbpm.usertask.jpa.model;
+
+import java.util.Objects;
+
+import jakarta.persistence.AssociationOverride;
+import jakarta.persistence.AttributeOverride;
+import jakarta.persistence.AttributeOverrides;
+import jakarta.persistence.Column;
+import jakarta.persistence.Entity;
+import jakarta.persistence.EnumType;
+import jakarta.persistence.Enumerated;
+import jakarta.persistence.ForeignKey;
+import jakarta.persistence.JoinColumn;
+import jakarta.persistence.Table;
+
+@Entity
+@Table(name = "jbpm_user_tasks_deadline")
+@AttributeOverrides({
+ @AttributeOverride(name = "value", column = @Column(name = "notification_value"))
+})
+@AssociationOverride(name = "taskInstance",
+ joinColumns = @JoinColumn(name = "task_id", foreignKey = @ForeignKey(name = "jbpm_user_tasks_deadline_tid")))
+public class TaskDeadlineEntity extends TaskTimerConfigEntity<byte[]> {
+
+ @Column(name = "notification_type")
+ @Enumerated(EnumType.STRING)
+ private TaskDeadlineType type;
+
+ public TaskDeadlineType getType() {
+ return type;
+ }
+
+ public void setType(TaskDeadlineType type) {
+ this.type = type;
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(value, javaType, type);
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj)
+ return true;
+ if (!super.equals(obj))
+ return false;
+ if (getClass() != obj.getClass())
+ return false;
+ TaskDeadlineEntity other = (TaskDeadlineEntity) obj;
+ return type == other.type && super.equals(obj);
+ }
+
+ @Override
+ public String toString() {
+ return "TaskDeadlineEntity [type=" + type + ", id=" + id + ", taskInstance=" + taskInstance.getId() + ", javaType=" + javaType + "]";
+ }
+
+}
diff --git a/addons/common/jbpm-usertask-storage-jpa/src/main/java/org/jbpm/usertask/jpa/model/TaskDeadlineTimerEntity.java b/addons/common/jbpm-usertask-storage-jpa/src/main/java/org/jbpm/usertask/jpa/model/TaskDeadlineTimerEntity.java
new file mode 100644
index 0000000000..0c3d762f22
--- /dev/null
+++ b/addons/common/jbpm-usertask-storage-jpa/src/main/java/org/jbpm/usertask/jpa/model/TaskDeadlineTimerEntity.java
@@ -0,0 +1,74 @@
+/*
+ * 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.jbpm.usertask.jpa.model;
+
+import java.util.Objects;
+
+import jakarta.persistence.AssociationOverride;
+import jakarta.persistence.AttributeOverride;
+import jakarta.persistence.AttributeOverrides;
+import jakarta.persistence.Column;
+import jakarta.persistence.Entity;
+import jakarta.persistence.EnumType;
+import jakarta.persistence.Enumerated;
+import jakarta.persistence.ForeignKey;
+import jakarta.persistence.JoinColumn;
+import jakarta.persistence.Table;
+
+@Entity
+@Table(name = "jbpm_user_tasks_deadline_timer")
+@AttributeOverrides({
+ @AttributeOverride(name = "jobId", column = @Column(name = "notification_job_id")),
+ @AttributeOverride(name = "value", column = @Column(name = "notification_value"))
+})
+@AssociationOverride(name = "taskInstance",
+ joinColumns = @JoinColumn(name = "task_id", foreignKey = @ForeignKey(name = "jbpm_user_tasks_deadline_timer_tid")))
+public class TaskDeadlineTimerEntity extends TaskTimerDataEntity<byte[]> {
+
+ @Column(name = "notification_type")
+ @Enumerated(EnumType.STRING)
+ private TaskDeadlineType type;
+
+ public TaskDeadlineType getType() {
+ return type;
+ }
+
+ public void setType(TaskDeadlineType type) {
+ this.type = type;
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(getJobId(), getValue(), getJavaType(), type);
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj)
+ return true;
+ if (!super.equals(obj))
+ return false;
+ if (getClass() != obj.getClass())
+ return false;
+ TaskDeadlineTimerEntity other = (TaskDeadlineTimerEntity) obj;
+ return super.equals(obj) && type == other.type;
+ }
+
+}
diff --git a/api/kogito-api/src/main/java/org/kie/kogito/jobs/JobDescription.java b/addons/common/jbpm-usertask-storage-jpa/src/main/java/org/jbpm/usertask/jpa/model/TaskDeadlineType.java
similarity index 84%
copy from api/kogito-api/src/main/java/org/kie/kogito/jobs/JobDescription.java
copy to addons/common/jbpm-usertask-storage-jpa/src/main/java/org/jbpm/usertask/jpa/model/TaskDeadlineType.java
index 5bbd520bfc..f388f935d6 100644
--- a/api/kogito-api/src/main/java/org/kie/kogito/jobs/JobDescription.java
+++ b/addons/common/jbpm-usertask-storage-jpa/src/main/java/org/jbpm/usertask/jpa/model/TaskDeadlineType.java
@@ -16,13 +16,9 @@
* specific language governing permissions and limitations
* under the License.
*/
-package org.kie.kogito.jobs;
+package org.jbpm.usertask.jpa.model;
-public interface JobDescription {
-
- String id();
-
- ExpirationTime expirationTime();
-
- Integer priority();
+public enum TaskDeadlineType {
+ NotStarted,
+ NotCompleted
}
diff --git a/addons/common/jbpm-usertask-storage-jpa/src/main/java/org/jbpm/usertask/jpa/model/TaskInputEntity.java b/addons/common/jbpm-usertask-storage-jpa/src/main/java/org/jbpm/usertask/jpa/model/TaskInputEntity.java
index 9c4351cfd2..3439ed45fd 100644
--- a/addons/common/jbpm-usertask-storage-jpa/src/main/java/org/jbpm/usertask/jpa/model/TaskInputEntity.java
+++ b/addons/common/jbpm-usertask-storage-jpa/src/main/java/org/jbpm/usertask/jpa/model/TaskInputEntity.java
@@ -19,7 +19,13 @@
package org.jbpm.usertask.jpa.model;
-import jakarta.persistence.*;
+import jakarta.persistence.AssociationOverride;
+import jakarta.persistence.AttributeOverride;
+import jakarta.persistence.AttributeOverrides;
+import jakarta.persistence.Column;
+import jakarta.persistence.Entity;
+import jakarta.persistence.ForeignKey;
+import jakarta.persistence.Table;
@Entity
@Table(name = "jbpm_user_tasks_inputs")
@@ -28,7 +34,6 @@ import jakarta.persistence.*;
@AttributeOverride(name = "value", column = @Column(name = "input_value"))
})
@AssociationOverride(name = "taskInstance", foreignKey = @ForeignKey(name = "jbpm_user_tasks_inputs_tid"))
-@IdClass(TaskDataEntityPK.class)
-public class TaskInputEntity extends TaskDataEntity<byte[]> {
+public class TaskInputEntity extends TaskNamedDataEntity<byte[]> {
}
diff --git a/addons/common/jbpm-usertask-storage-jpa/src/main/java/org/jbpm/usertask/jpa/model/TaskMetadataEntity.java b/addons/common/jbpm-usertask-storage-jpa/src/main/java/org/jbpm/usertask/jpa/model/TaskMetadataEntity.java
index 2729ee6871..b7d05701c8 100644
--- a/addons/common/jbpm-usertask-storage-jpa/src/main/java/org/jbpm/usertask/jpa/model/TaskMetadataEntity.java
+++ b/addons/common/jbpm-usertask-storage-jpa/src/main/java/org/jbpm/usertask/jpa/model/TaskMetadataEntity.java
@@ -19,7 +19,14 @@
package org.jbpm.usertask.jpa.model;
-import jakarta.persistence.*;
+import jakarta.persistence.AssociationOverride;
+import jakarta.persistence.AttributeOverride;
+import jakarta.persistence.AttributeOverrides;
+import jakarta.persistence.Column;
+import jakarta.persistence.Entity;
+import jakarta.persistence.ForeignKey;
+import jakarta.persistence.JoinColumn;
+import jakarta.persistence.Table;
@Entity
@Table(name = "jbpm_user_tasks_metadata")
@@ -29,7 +36,6 @@ import jakarta.persistence.*;
})
@AssociationOverride(name = "taskInstance",
joinColumns = @JoinColumn(name = "task_id", foreignKey = @ForeignKey(name = "jbpm_user_tasks_metadata_tid")))
-@IdClass(TaskDataEntityPK.class)
-public class TaskMetadataEntity extends TaskDataEntity<String> {
+public class TaskMetadataEntity extends TaskNamedDataEntity<String> {
}
diff --git a/addons/common/jbpm-usertask-storage-jpa/src/main/java/org/jbpm/usertask/jpa/model/TaskDataEntity.java b/addons/common/jbpm-usertask-storage-jpa/src/main/java/org/jbpm/usertask/jpa/model/TaskNamedDataEntity.java
similarity index 66%
copy from addons/common/jbpm-usertask-storage-jpa/src/main/java/org/jbpm/usertask/jpa/model/TaskDataEntity.java
copy to addons/common/jbpm-usertask-storage-jpa/src/main/java/org/jbpm/usertask/jpa/model/TaskNamedDataEntity.java
index 506f3bf925..45b1c9f601 100644
--- a/addons/common/jbpm-usertask-storage-jpa/src/main/java/org/jbpm/usertask/jpa/model/TaskDataEntity.java
+++ b/addons/common/jbpm-usertask-storage-jpa/src/main/java/org/jbpm/usertask/jpa/model/TaskNamedDataEntity.java
@@ -21,25 +21,25 @@ package org.jbpm.usertask.jpa.model;
import java.util.Objects;
-import jakarta.persistence.*;
+import jakarta.persistence.Column;
+import jakarta.persistence.Id;
+import jakarta.persistence.IdClass;
+import jakarta.persistence.JoinColumn;
+import jakarta.persistence.ManyToOne;
+import jakarta.persistence.MappedSuperclass;
@MappedSuperclass
-public abstract class TaskDataEntity<T> {
-
- @Id
- @Column(name = "name")
- protected String name;
+@IdClass(TaskNamedDataEntityPK.class)
+public abstract class TaskNamedDataEntity<T> extends AbstractTaskEntity<T> {
@Id
@ManyToOne(optional = false)
@JoinColumn(name = "task_id")
protected UserTaskInstanceEntity taskInstance;
- @Column(name = "value")
- protected T value;
-
- @Column(name = "java_type")
- protected String javaType;
+ @Id
+ @Column(name = "name")
+ protected String name;
public String getName() {
return name;
@@ -57,35 +57,20 @@ public abstract class TaskDataEntity<T> {
this.taskInstance = taskInstance;
}
- public T getValue() {
- return value;
- }
-
- public void setValue(T value) {
- this.value = value;
- }
-
- public String getJavaType() {
- return javaType;
- }
-
- public void setJavaType(String javaType) {
- this.javaType = javaType;
- }
-
@Override
public boolean equals(Object o) {
if (this == o)
return true;
if (o == null || getClass() != o.getClass())
return false;
- TaskDataEntity<?> that = (TaskDataEntity<?>) o;
- return Objects.equals(getName(), that.getName()) && Objects.equals(getTaskInstance(), that.getTaskInstance()) && Objects.equals(getValue(),
- that.getValue()) && Objects.equals(getJavaType(), that.getJavaType());
+ TaskNamedDataEntity<?> that = (TaskNamedDataEntity<?>) o;
+ return Objects.equals(getName(), that.getName()) &&
+ Objects.equals(getValue(), that.getValue()) &&
+ Objects.equals(getJavaType(), that.getJavaType());
}
@Override
public int hashCode() {
- return Objects.hash(getName(), getTaskInstance(), getValue(), getJavaType());
+ return Objects.hash(getName(), getValue(), getJavaType());
}
}
diff --git a/addons/common/jbpm-usertask-storage-jpa/src/main/java/org/jbpm/usertask/jpa/model/TaskDataEntityPK.java b/addons/common/jbpm-usertask-storage-jpa/src/main/java/org/jbpm/usertask/jpa/model/TaskNamedDataEntityPK.java
similarity index 78%
copy from addons/common/jbpm-usertask-storage-jpa/src/main/java/org/jbpm/usertask/jpa/model/TaskDataEntityPK.java
copy to addons/common/jbpm-usertask-storage-jpa/src/main/java/org/jbpm/usertask/jpa/model/TaskNamedDataEntityPK.java
index 4d0f1fab9e..1c8c4f5ce5 100644
--- a/addons/common/jbpm-usertask-storage-jpa/src/main/java/org/jbpm/usertask/jpa/model/TaskDataEntityPK.java
+++ b/addons/common/jbpm-usertask-storage-jpa/src/main/java/org/jbpm/usertask/jpa/model/TaskNamedDataEntityPK.java
@@ -22,15 +22,17 @@ package org.jbpm.usertask.jpa.model;
import java.io.Serializable;
import java.util.Objects;
-public class TaskDataEntityPK implements Serializable {
+public class TaskNamedDataEntityPK implements Serializable {
+
+ private static final long serialVersionUID = 5506586793841760884L;
private String name;
private UserTaskInstanceEntity taskInstance;
- public TaskDataEntityPK() {
+ public TaskNamedDataEntityPK() {
}
- public TaskDataEntityPK(String inputName, UserTaskInstanceEntity taskInstance) {
+ public TaskNamedDataEntityPK(String inputName, UserTaskInstanceEntity taskInstance) {
this.taskInstance = taskInstance;
this.name = inputName;
}
@@ -57,8 +59,8 @@ public class TaskDataEntityPK implements Serializable {
return true;
if (o == null || getClass() != o.getClass())
return false;
- TaskDataEntityPK that = (TaskDataEntityPK) o;
- return Objects.equals(getName(), that.getName()) && Objects.equals(getTaskInstance(), that.getTaskInstance());
+ TaskNamedDataEntityPK that = (TaskNamedDataEntityPK) o;
+ return Objects.equals(getName(), that.getName()) && Objects.equals(getTaskInstance().getId(), that.getTaskInstance().getId());
}
@Override
@@ -68,8 +70,8 @@ public class TaskDataEntityPK implements Serializable {
@Override
public String toString() {
- return "TaskInputEntityId{" +
- "taskInstance='" + taskInstance + '\'' +
+ return "TaskNamedDataEntityId {" +
+ "taskInstance='" + taskInstance.getId() + '\'' +
", name='" + name + '\'' +
'}';
}
diff --git a/addons/common/jbpm-usertask-storage-jpa/src/main/java/org/jbpm/usertask/jpa/model/TaskOutputEntity.java b/addons/common/jbpm-usertask-storage-jpa/src/main/java/org/jbpm/usertask/jpa/model/TaskOutputEntity.java
index bd7098f245..7961dcecc9 100644
--- a/addons/common/jbpm-usertask-storage-jpa/src/main/java/org/jbpm/usertask/jpa/model/TaskOutputEntity.java
+++ b/addons/common/jbpm-usertask-storage-jpa/src/main/java/org/jbpm/usertask/jpa/model/TaskOutputEntity.java
@@ -19,7 +19,14 @@
package org.jbpm.usertask.jpa.model;
-import jakarta.persistence.*;
+import jakarta.persistence.AssociationOverride;
+import jakarta.persistence.AttributeOverride;
+import jakarta.persistence.AttributeOverrides;
+import jakarta.persistence.Column;
+import jakarta.persistence.Entity;
+import jakarta.persistence.ForeignKey;
+import jakarta.persistence.JoinColumn;
+import jakarta.persistence.Table;
@Entity
@Table(name = "jbpm_user_tasks_outputs")
@@ -29,7 +36,6 @@ import jakarta.persistence.*;
})
@AssociationOverride(name = "taskInstance",
joinColumns = @JoinColumn(name = "task_id", foreignKey = @ForeignKey(name = "jbpm_user_tasks_outputs_tid")))
-@IdClass(TaskDataEntityPK.class)
-public class TaskOutputEntity extends TaskDataEntity<byte[]> {
+public class TaskOutputEntity extends TaskNamedDataEntity<byte[]> {
}
diff --git a/addons/common/jbpm-usertask-storage-jpa/src/main/java/org/jbpm/usertask/jpa/model/TaskReassignmentEntity.java b/addons/common/jbpm-usertask-storage-jpa/src/main/java/org/jbpm/usertask/jpa/model/TaskReassignmentEntity.java
new file mode 100644
index 0000000000..9bd409cd7d
--- /dev/null
+++ b/addons/common/jbpm-usertask-storage-jpa/src/main/java/org/jbpm/usertask/jpa/model/TaskReassignmentEntity.java
@@ -0,0 +1,78 @@
+/*
+ * 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.jbpm.usertask.jpa.model;
+
+import java.util.Objects;
+
+import jakarta.persistence.AssociationOverride;
+import jakarta.persistence.AttributeOverride;
+import jakarta.persistence.AttributeOverrides;
+import jakarta.persistence.Column;
+import jakarta.persistence.Entity;
+import jakarta.persistence.EnumType;
+import jakarta.persistence.Enumerated;
+import jakarta.persistence.ForeignKey;
+import jakarta.persistence.JoinColumn;
+import jakarta.persistence.Table;
+
+@Entity
+@Table(name = "jbpm_user_tasks_reassignment")
+@AttributeOverrides({
+ @AttributeOverride(name = "value", column = @Column(name = "reassignment_value"))
+})
+@AssociationOverride(name = "taskInstance",
+ joinColumns = @JoinColumn(name = "task_id", foreignKey = @ForeignKey(name = "jbpm_user_tasks_reassignment_tid")))
+public class TaskReassignmentEntity extends TaskTimerConfigEntity<byte[]> {
+
+ @Column(name = "reassignment_type")
+ @Enumerated(EnumType.STRING)
+ private TaskReassignmentType type;
+
+ public TaskReassignmentType getType() {
+ return type;
+ }
+
+ public void setType(TaskReassignmentType type) {
+ this.type = type;
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(value, javaType, type);
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj)
+ return true;
+ if (!super.equals(obj))
+ return false;
+ if (getClass() != obj.getClass())
+ return false;
+ TaskReassignmentEntity other = (TaskReassignmentEntity) obj;
+ return type == other.type && super.equals(obj);
+ }
+
+ @Override
+ public String toString() {
+ return "TaskReassignmentEntity [type=" + type + ", id=" + id + ", taskInstance=" + taskInstance.getId() + ", javaType=" + javaType + "]";
+ }
+
+}
diff --git a/addons/common/jbpm-usertask-storage-jpa/src/main/java/org/jbpm/usertask/jpa/model/TaskReassignmentTimerEntity.java b/addons/common/jbpm-usertask-storage-jpa/src/main/java/org/jbpm/usertask/jpa/model/TaskReassignmentTimerEntity.java
new file mode 100644
index 0000000000..8b735917c5
--- /dev/null
+++ b/addons/common/jbpm-usertask-storage-jpa/src/main/java/org/jbpm/usertask/jpa/model/TaskReassignmentTimerEntity.java
@@ -0,0 +1,73 @@
+/*
+ * 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.jbpm.usertask.jpa.model;
+
+import java.util.Objects;
+
+import jakarta.persistence.AssociationOverride;
+import jakarta.persistence.AttributeOverride;
+import jakarta.persistence.AttributeOverrides;
+import jakarta.persistence.Column;
+import jakarta.persistence.Entity;
+import jakarta.persistence.EnumType;
+import jakarta.persistence.Enumerated;
+import jakarta.persistence.ForeignKey;
+import jakarta.persistence.JoinColumn;
+import jakarta.persistence.Table;
+
+@Entity
+@Table(name = "jbpm_user_tasks_reassignment_timer")
+@AttributeOverrides({
+ @AttributeOverride(name = "jobId", column = @Column(name = "reassignment_job_id")),
+ @AttributeOverride(name = "value", column = @Column(name = "reassignment_value"))
+})
+@AssociationOverride(name = "taskInstance",
+ joinColumns = @JoinColumn(name = "task_id", foreignKey = @ForeignKey(name = "jbpm_user_tasks_reassignment_timer_tid")))
+public class TaskReassignmentTimerEntity extends TaskTimerDataEntity<byte[]> {
+
+ @Column(name = "reassignment_type")
+ @Enumerated(EnumType.STRING)
+ private TaskReassignmentType type;
+
+ public TaskReassignmentType getType() {
+ return type;
+ }
+
+ public void setType(TaskReassignmentType type) {
+ this.type = type;
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(getJobId(), getValue(), getJavaType(), type);
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj)
+ return true;
+ if (!super.equals(obj))
+ return false;
+ if (getClass() != obj.getClass())
+ return false;
+ TaskReassignmentTimerEntity other = (TaskReassignmentTimerEntity) obj;
+ return super.equals(obj) && type == other.type;
+ }
+}
diff --git a/api/kogito-api/src/main/java/org/kie/kogito/jobs/JobDescription.java b/addons/common/jbpm-usertask-storage-jpa/src/main/java/org/jbpm/usertask/jpa/model/TaskReassignmentType.java
similarity index 84%
copy from api/kogito-api/src/main/java/org/kie/kogito/jobs/JobDescription.java
copy to addons/common/jbpm-usertask-storage-jpa/src/main/java/org/jbpm/usertask/jpa/model/TaskReassignmentType.java
index 5bbd520bfc..bf4e2a8da2 100644
--- a/api/kogito-api/src/main/java/org/kie/kogito/jobs/JobDescription.java
+++ b/addons/common/jbpm-usertask-storage-jpa/src/main/java/org/jbpm/usertask/jpa/model/TaskReassignmentType.java
@@ -16,13 +16,9 @@
* specific language governing permissions and limitations
* under the License.
*/
-package org.kie.kogito.jobs;
+package org.jbpm.usertask.jpa.model;
-public interface JobDescription {
-
- String id();
-
- ExpirationTime expirationTime();
-
- Integer priority();
+public enum TaskReassignmentType {
+ NotStarted,
+ NotCompleted
}
diff --git a/addons/common/jbpm-usertask-storage-jpa/src/main/java/org/jbpm/usertask/jpa/model/TaskDataEntity.java b/addons/common/jbpm-usertask-storage-jpa/src/main/java/org/jbpm/usertask/jpa/model/TaskTimerConfigEntity.java
similarity index 54%
copy from addons/common/jbpm-usertask-storage-jpa/src/main/java/org/jbpm/usertask/jpa/model/TaskDataEntity.java
copy to addons/common/jbpm-usertask-storage-jpa/src/main/java/org/jbpm/usertask/jpa/model/TaskTimerConfigEntity.java
index 506f3bf925..1f59855a80 100644
--- a/addons/common/jbpm-usertask-storage-jpa/src/main/java/org/jbpm/usertask/jpa/model/TaskDataEntity.java
+++ b/addons/common/jbpm-usertask-storage-jpa/src/main/java/org/jbpm/usertask/jpa/model/TaskTimerConfigEntity.java
@@ -21,32 +21,30 @@ package org.jbpm.usertask.jpa.model;
import java.util.Objects;
-import jakarta.persistence.*;
+import jakarta.persistence.GeneratedValue;
+import jakarta.persistence.GenerationType;
+import jakarta.persistence.Id;
+import jakarta.persistence.JoinColumn;
+import jakarta.persistence.ManyToOne;
+import jakarta.persistence.MappedSuperclass;
@MappedSuperclass
-public abstract class TaskDataEntity<T> {
+public abstract class TaskTimerConfigEntity<T> extends AbstractTaskEntity<T> {
@Id
- @Column(name = "name")
- protected String name;
+ @GeneratedValue(strategy = GenerationType.AUTO)
+ protected Integer id;
- @Id
@ManyToOne(optional = false)
@JoinColumn(name = "task_id")
protected UserTaskInstanceEntity taskInstance;
- @Column(name = "value")
- protected T value;
-
- @Column(name = "java_type")
- protected String javaType;
-
- public String getName() {
- return name;
+ public Integer getId() {
+ return id;
}
- public void setName(String name) {
- this.name = name;
+ public void setId(Integer id) {
+ this.id = id;
}
public UserTaskInstanceEntity getTaskInstance() {
@@ -57,35 +55,21 @@ public abstract class TaskDataEntity<T> {
this.taskInstance = taskInstance;
}
- public T getValue() {
- return value;
- }
-
- public void setValue(T value) {
- this.value = value;
- }
-
- public String getJavaType() {
- return javaType;
- }
-
- public void setJavaType(String javaType) {
- this.javaType = javaType;
+ @Override
+ public int hashCode() {
+ return Objects.hash(value, javaType, id, taskInstance.getId());
}
@Override
- public boolean equals(Object o) {
- if (this == o)
+ public boolean equals(Object obj) {
+ if (this == obj)
return true;
- if (o == null || getClass() != o.getClass())
+ if (!super.equals(obj))
+ return false;
+ if (getClass() != obj.getClass())
return false;
- TaskDataEntity<?> that = (TaskDataEntity<?>) o;
- return Objects.equals(getName(), that.getName()) && Objects.equals(getTaskInstance(), that.getTaskInstance()) && Objects.equals(getValue(),
- that.getValue()) && Objects.equals(getJavaType(), that.getJavaType());
+ TaskTimerConfigEntity other = (TaskTimerConfigEntity) obj;
+ return super.equals(obj) && Objects.equals(id, other.id) && Objects.equals(taskInstance.getId(), other.taskInstance.getId());
}
- @Override
- public int hashCode() {
- return Objects.hash(getName(), getTaskInstance(), getValue(), getJavaType());
- }
}
diff --git a/addons/common/jbpm-usertask-storage-jpa/src/main/java/org/jbpm/usertask/jpa/model/TaskDataEntity.java b/addons/common/jbpm-usertask-storage-jpa/src/main/java/org/jbpm/usertask/jpa/model/TaskTimerDataEntity.java
similarity index 59%
rename from addons/common/jbpm-usertask-storage-jpa/src/main/java/org/jbpm/usertask/jpa/model/TaskDataEntity.java
rename to addons/common/jbpm-usertask-storage-jpa/src/main/java/org/jbpm/usertask/jpa/model/TaskTimerDataEntity.java
index 506f3bf925..67b7e21729 100644
--- a/addons/common/jbpm-usertask-storage-jpa/src/main/java/org/jbpm/usertask/jpa/model/TaskDataEntity.java
+++ b/addons/common/jbpm-usertask-storage-jpa/src/main/java/org/jbpm/usertask/jpa/model/TaskTimerDataEntity.java
@@ -21,32 +21,32 @@ package org.jbpm.usertask.jpa.model;
import java.util.Objects;
-import jakarta.persistence.*;
+import jakarta.persistence.Column;
+import jakarta.persistence.Id;
+import jakarta.persistence.IdClass;
+import jakarta.persistence.JoinColumn;
+import jakarta.persistence.ManyToOne;
+import jakarta.persistence.MappedSuperclass;
@MappedSuperclass
-public abstract class TaskDataEntity<T> {
-
- @Id
- @Column(name = "name")
- protected String name;
+@IdClass(TaskTimerDataEntityPK.class)
+public abstract class TaskTimerDataEntity<T> extends AbstractTaskEntity<T> {
@Id
@ManyToOne(optional = false)
@JoinColumn(name = "task_id")
protected UserTaskInstanceEntity taskInstance;
- @Column(name = "value")
- protected T value;
-
- @Column(name = "java_type")
- protected String javaType;
+ @Id
+ @Column(name = "jobId")
+ protected String jobId;
- public String getName() {
- return name;
+ public String getJobId() {
+ return jobId;
}
- public void setName(String name) {
- this.name = name;
+ public void setJobId(String jobId) {
+ this.jobId = jobId;
}
public UserTaskInstanceEntity getTaskInstance() {
@@ -57,35 +57,18 @@ public abstract class TaskDataEntity<T> {
this.taskInstance = taskInstance;
}
- public T getValue() {
- return value;
- }
-
- public void setValue(T value) {
- this.value = value;
- }
-
- public String getJavaType() {
- return javaType;
- }
-
- public void setJavaType(String javaType) {
- this.javaType = javaType;
- }
-
@Override
public boolean equals(Object o) {
if (this == o)
return true;
if (o == null || getClass() != o.getClass())
return false;
- TaskDataEntity<?> that = (TaskDataEntity<?>) o;
- return Objects.equals(getName(), that.getName()) && Objects.equals(getTaskInstance(), that.getTaskInstance()) && Objects.equals(getValue(),
- that.getValue()) && Objects.equals(getJavaType(), that.getJavaType());
+ TaskTimerDataEntity<?> that = (TaskTimerDataEntity<?>) o;
+ return Objects.equals(getJobId(), that.getJobId()) && super.equals(o);
}
@Override
public int hashCode() {
- return Objects.hash(getName(), getTaskInstance(), getValue(), getJavaType());
+ return Objects.hash(getJobId(), getValue(), getJavaType());
}
}
diff --git a/addons/common/jbpm-usertask-storage-jpa/src/main/java/org/jbpm/usertask/jpa/model/TaskDataEntityPK.java b/addons/common/jbpm-usertask-storage-jpa/src/main/java/org/jbpm/usertask/jpa/model/TaskTimerDataEntityPK.java
similarity index 64%
rename from addons/common/jbpm-usertask-storage-jpa/src/main/java/org/jbpm/usertask/jpa/model/TaskDataEntityPK.java
rename to addons/common/jbpm-usertask-storage-jpa/src/main/java/org/jbpm/usertask/jpa/model/TaskTimerDataEntityPK.java
index 4d0f1fab9e..d4c1c06ea6 100644
--- a/addons/common/jbpm-usertask-storage-jpa/src/main/java/org/jbpm/usertask/jpa/model/TaskDataEntityPK.java
+++ b/addons/common/jbpm-usertask-storage-jpa/src/main/java/org/jbpm/usertask/jpa/model/TaskTimerDataEntityPK.java
@@ -22,17 +22,19 @@ package org.jbpm.usertask.jpa.model;
import java.io.Serializable;
import java.util.Objects;
-public class TaskDataEntityPK implements Serializable {
+public class TaskTimerDataEntityPK implements Serializable {
- private String name;
+ private static final long serialVersionUID = 5506586793841760884L;
+
+ private String jobId;
private UserTaskInstanceEntity taskInstance;
- public TaskDataEntityPK() {
+ public TaskTimerDataEntityPK() {
}
- public TaskDataEntityPK(String inputName, UserTaskInstanceEntity taskInstance) {
+ public TaskTimerDataEntityPK(String jobId, UserTaskInstanceEntity taskInstance) {
this.taskInstance = taskInstance;
- this.name = inputName;
+ this.jobId = jobId;
}
public UserTaskInstanceEntity getTaskInstance() {
@@ -43,12 +45,12 @@ public class TaskDataEntityPK implements Serializable {
this.taskInstance = taskInstance;
}
- public String getName() {
- return name;
+ public String getJobId() {
+ return jobId;
}
- public void setName(String name) {
- this.name = name;
+ public void setJobId(String jobId) {
+ this.jobId = jobId;
}
@Override
@@ -57,20 +59,20 @@ public class TaskDataEntityPK implements Serializable {
return true;
if (o == null || getClass() != o.getClass())
return false;
- TaskDataEntityPK that = (TaskDataEntityPK) o;
- return Objects.equals(getName(), that.getName()) && Objects.equals(getTaskInstance(), that.getTaskInstance());
+ TaskTimerDataEntityPK that = (TaskTimerDataEntityPK) o;
+ return Objects.equals(getJobId(), that.getJobId()) && Objects.equals(getTaskInstance().getId(), that.getTaskInstance().getId());
}
@Override
public int hashCode() {
- return Objects.hash(getName(), getTaskInstance());
+ return Objects.hash(getJobId(), getTaskInstance());
}
@Override
public String toString() {
- return "TaskInputEntityId{" +
- "taskInstance='" + taskInstance + '\'' +
- ", name='" + name + '\'' +
+ return "TaskTimerDataEntityId {" +
+ "taskInstance='" + taskInstance.getId() + '\'' +
+ ", name='" + jobId + '\'' +
'}';
}
}
diff --git a/addons/common/jbpm-usertask-storage-jpa/src/main/java/org/jbpm/usertask/jpa/model/UserTaskInstanceEntity.java b/addons/common/jbpm-usertask-storage-jpa/src/main/java/org/jbpm/usertask/jpa/model/UserTaskInstanceEntity.java
index 8b3cfca028..b721f0ce3f 100644
--- a/addons/common/jbpm-usertask-storage-jpa/src/main/java/org/jbpm/usertask/jpa/model/UserTaskInstanceEntity.java
+++ b/addons/common/jbpm-usertask-storage-jpa/src/main/java/org/jbpm/usertask/jpa/model/UserTaskInstanceEntity.java
@@ -19,9 +19,25 @@
package org.jbpm.usertask.jpa.model;
-import java.util.*;
-
-import jakarta.persistence.*;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Objects;
+import java.util.Set;
+
+import jakarta.persistence.CascadeType;
+import jakarta.persistence.CollectionTable;
+import jakarta.persistence.Column;
+import jakarta.persistence.ElementCollection;
+import jakarta.persistence.Entity;
+import jakarta.persistence.FetchType;
+import jakarta.persistence.ForeignKey;
+import jakarta.persistence.Id;
+import jakarta.persistence.JoinColumn;
+import jakarta.persistence.NamedQuery;
+import jakarta.persistence.OneToMany;
+import jakarta.persistence.Table;
@Entity
@NamedQuery(name = UserTaskInstanceEntity.GET_INSTANCES_BY_IDENTITY,
@@ -105,6 +121,18 @@ public class UserTaskInstanceEntity {
@OneToMany(mappedBy = "taskInstance", cascade = CascadeType.ALL, orphanRemoval = true, fetch = FetchType.LAZY)
private List<TaskMetadataEntity> metadata = new ArrayList<>();
+ @OneToMany(mappedBy = "taskInstance", cascade = CascadeType.ALL, orphanRemoval = true, fetch = FetchType.LAZY)
+ private List<TaskDeadlineEntity> deadlines;
+
+ @OneToMany(mappedBy = "taskInstance", cascade = CascadeType.ALL, orphanRemoval = true, fetch = FetchType.LAZY)
+ private List<TaskDeadlineTimerEntity> deadlineTimers;
+
+ @OneToMany(mappedBy = "taskInstance", cascade = CascadeType.ALL, orphanRemoval = true, fetch = FetchType.LAZY)
+ private List<TaskReassignmentEntity> reassignments;
+
+ @OneToMany(mappedBy = "taskInstance", cascade = CascadeType.ALL, orphanRemoval = true, fetch = FetchType.LAZY)
+ private List<TaskReassignmentTimerEntity> reassignmentTimers;
+
public String getId() {
return id;
}
@@ -331,4 +359,62 @@ public class UserTaskInstanceEntity {
public String getTerminationType() {
return terminationType;
}
+
+ public List<TaskDeadlineEntity> getDeadlines() {
+ return deadlines;
+ }
+
+ public void setDeadlines(List<TaskDeadlineEntity> deadlines) {
+ this.deadlines = deadlines;
+ }
+
+ public List<TaskReassignmentEntity> getReassignments() {
+ return reassignments;
+ }
+
+ public void setReassignments(List<TaskReassignmentEntity> reassignments) {
+ this.reassignments = reassignments;
+ }
+
+ public List<TaskDeadlineTimerEntity> getDeadlineTimers() {
+ return deadlineTimers;
+ }
+
+ public void setDeadlineTimers(List<TaskDeadlineTimerEntity> deadlineTimers) {
+ this.deadlineTimers = deadlineTimers;
+ }
+
+ public List<TaskReassignmentTimerEntity> getReassignmentTimers() {
+ return reassignmentTimers;
+ }
+
+ public void setReassignmentTimers(List<TaskReassignmentTimerEntity> reassignmentTimers) {
+ this.reassignmentTimers = reassignmentTimers;
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(actualOwner, adminGroups, adminUsers, attachments, comments, deadlineTimers, deadlines, excludedUsers, externalReferenceId, id, inputs, metadata, outputs, potentialGroups,
+ potentialUsers, reassignmentTimers, reassignments, status, taskDescription, taskName, taskPriority, terminationType, userTaskId);
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj)
+ return true;
+ if (obj == null)
+ return false;
+ if (getClass() != obj.getClass())
+ return false;
+ UserTaskInstanceEntity other = (UserTaskInstanceEntity) obj;
+ return Objects.equals(actualOwner, other.actualOwner) && Objects.equals(adminGroups, other.adminGroups) && Objects.equals(adminUsers, other.adminUsers)
+ && Objects.equals(attachments, other.attachments) && Objects.equals(comments, other.comments) && Objects.equals(deadlineTimers, other.deadlineTimers)
+ && Objects.equals(deadlines, other.deadlines) && Objects.equals(excludedUsers, other.excludedUsers) && Objects.equals(externalReferenceId, other.externalReferenceId)
+ && Objects.equals(id, other.id) && Objects.equals(inputs, other.inputs) && Objects.equals(metadata, other.metadata) && Objects.equals(outputs, other.outputs)
+ && Objects.equals(potentialGroups, other.potentialGroups) && Objects.equals(potentialUsers, other.potentialUsers) && Objects.equals(reassignmentTimers, other.reassignmentTimers)
+ && Objects.equals(reassignments, other.reassignments) && Objects.equals(status, other.status) && Objects.equals(taskDescription, other.taskDescription)
+ && Objects.equals(taskName, other.taskName) && Objects.equals(taskPriority, other.taskPriority) && Objects.equals(terminationType, other.terminationType)
+ && Objects.equals(userTaskId, other.userTaskId);
+ }
+
}
diff --git a/addons/common/jbpm-usertask-storage-jpa/src/main/java/org/jbpm/usertask/jpa/repository/TaskInputRepository.java b/addons/common/jbpm-usertask-storage-jpa/src/main/java/org/jbpm/usertask/jpa/repository/TaskDeadlineRepository.java
similarity index 72%
copy from addons/common/jbpm-usertask-storage-jpa/src/main/java/org/jbpm/usertask/jpa/repository/TaskInputRepository.java
copy to addons/common/jbpm-usertask-storage-jpa/src/main/java/org/jbpm/usertask/jpa/repository/TaskDeadlineRepository.java
index 6e85081ff7..2fc7cedc95 100644
--- a/addons/common/jbpm-usertask-storage-jpa/src/main/java/org/jbpm/usertask/jpa/repository/TaskInputRepository.java
+++ b/addons/common/jbpm-usertask-storage-jpa/src/main/java/org/jbpm/usertask/jpa/repository/TaskDeadlineRepository.java
@@ -19,17 +19,16 @@
package org.jbpm.usertask.jpa.repository;
-import org.jbpm.usertask.jpa.model.TaskDataEntityPK;
-import org.jbpm.usertask.jpa.model.TaskInputEntity;
+import org.jbpm.usertask.jpa.model.TaskDeadlineEntity;
-public class TaskInputRepository extends BaseRepository<TaskInputEntity, TaskDataEntityPK> {
+public class TaskDeadlineRepository extends BaseRepository<TaskDeadlineEntity, Integer> {
- public TaskInputRepository(UserTaskJPAContext context) {
+ public TaskDeadlineRepository(UserTaskJPAContext context) {
super(context);
}
@Override
- public Class<TaskInputEntity> getEntityClass() {
- return TaskInputEntity.class;
+ public Class<TaskDeadlineEntity> getEntityClass() {
+ return TaskDeadlineEntity.class;
}
}
diff --git a/addons/common/jbpm-usertask-storage-jpa/src/main/java/org/jbpm/usertask/jpa/repository/TaskInputRepository.java b/addons/common/jbpm-usertask-storage-jpa/src/main/java/org/jbpm/usertask/jpa/repository/TaskDeadlineTimerRepository.java
similarity index 68%
copy from addons/common/jbpm-usertask-storage-jpa/src/main/java/org/jbpm/usertask/jpa/repository/TaskInputRepository.java
copy to addons/common/jbpm-usertask-storage-jpa/src/main/java/org/jbpm/usertask/jpa/repository/TaskDeadlineTimerRepository.java
index 6e85081ff7..370f9e3591 100644
--- a/addons/common/jbpm-usertask-storage-jpa/src/main/java/org/jbpm/usertask/jpa/repository/TaskInputRepository.java
+++ b/addons/common/jbpm-usertask-storage-jpa/src/main/java/org/jbpm/usertask/jpa/repository/TaskDeadlineTimerRepository.java
@@ -19,17 +19,17 @@
package org.jbpm.usertask.jpa.repository;
-import org.jbpm.usertask.jpa.model.TaskDataEntityPK;
-import org.jbpm.usertask.jpa.model.TaskInputEntity;
+import org.jbpm.usertask.jpa.model.TaskDeadlineTimerEntity;
+import org.jbpm.usertask.jpa.model.TaskTimerDataEntityPK;
-public class TaskInputRepository extends BaseRepository<TaskInputEntity, TaskDataEntityPK> {
+public class TaskDeadlineTimerRepository extends BaseRepository<TaskDeadlineTimerEntity, TaskTimerDataEntityPK> {
- public TaskInputRepository(UserTaskJPAContext context) {
+ public TaskDeadlineTimerRepository(UserTaskJPAContext context) {
super(context);
}
@Override
- public Class<TaskInputEntity> getEntityClass() {
- return TaskInputEntity.class;
+ public Class<TaskDeadlineTimerEntity> getEntityClass() {
+ return TaskDeadlineTimerEntity.class;
}
}
diff --git a/addons/common/jbpm-usertask-storage-jpa/src/main/java/org/jbpm/usertask/jpa/repository/TaskInputRepository.java b/addons/common/jbpm-usertask-storage-jpa/src/main/java/org/jbpm/usertask/jpa/repository/TaskInputRepository.java
index 6e85081ff7..344fbba90a 100644
--- a/addons/common/jbpm-usertask-storage-jpa/src/main/java/org/jbpm/usertask/jpa/repository/TaskInputRepository.java
+++ b/addons/common/jbpm-usertask-storage-jpa/src/main/java/org/jbpm/usertask/jpa/repository/TaskInputRepository.java
@@ -19,10 +19,10 @@
package org.jbpm.usertask.jpa.repository;
-import org.jbpm.usertask.jpa.model.TaskDataEntityPK;
import org.jbpm.usertask.jpa.model.TaskInputEntity;
+import org.jbpm.usertask.jpa.model.TaskNamedDataEntityPK;
-public class TaskInputRepository extends BaseRepository<TaskInputEntity, TaskDataEntityPK> {
+public class TaskInputRepository extends BaseRepository<TaskInputEntity, TaskNamedDataEntityPK> {
public TaskInputRepository(UserTaskJPAContext context) {
super(context);
diff --git a/addons/common/jbpm-usertask-storage-jpa/src/main/java/org/jbpm/usertask/jpa/repository/TaskMetadataRepository.java b/addons/common/jbpm-usertask-storage-jpa/src/main/java/org/jbpm/usertask/jpa/repository/TaskMetadataRepository.java
index 26796bb38a..836fa5dd07 100644
--- a/addons/common/jbpm-usertask-storage-jpa/src/main/java/org/jbpm/usertask/jpa/repository/TaskMetadataRepository.java
+++ b/addons/common/jbpm-usertask-storage-jpa/src/main/java/org/jbpm/usertask/jpa/repository/TaskMetadataRepository.java
@@ -19,10 +19,10 @@
package org.jbpm.usertask.jpa.repository;
-import org.jbpm.usertask.jpa.model.TaskDataEntityPK;
import org.jbpm.usertask.jpa.model.TaskMetadataEntity;
+import org.jbpm.usertask.jpa.model.TaskNamedDataEntityPK;
-public class TaskMetadataRepository extends BaseRepository<TaskMetadataEntity, TaskDataEntityPK> {
+public class TaskMetadataRepository extends BaseRepository<TaskMetadataEntity, TaskNamedDataEntityPK> {
public TaskMetadataRepository(UserTaskJPAContext context) {
super(context);
diff --git a/addons/common/jbpm-usertask-storage-jpa/src/main/java/org/jbpm/usertask/jpa/repository/TaskOutputRepository.java b/addons/common/jbpm-usertask-storage-jpa/src/main/java/org/jbpm/usertask/jpa/repository/TaskOutputRepository.java
index 2b39b8f1bb..610cde606d 100644
--- a/addons/common/jbpm-usertask-storage-jpa/src/main/java/org/jbpm/usertask/jpa/repository/TaskOutputRepository.java
+++ b/addons/common/jbpm-usertask-storage-jpa/src/main/java/org/jbpm/usertask/jpa/repository/TaskOutputRepository.java
@@ -19,10 +19,10 @@
package org.jbpm.usertask.jpa.repository;
-import org.jbpm.usertask.jpa.model.TaskDataEntityPK;
+import org.jbpm.usertask.jpa.model.TaskNamedDataEntityPK;
import org.jbpm.usertask.jpa.model.TaskOutputEntity;
-public class TaskOutputRepository extends BaseRepository<TaskOutputEntity, TaskDataEntityPK> {
+public class TaskOutputRepository extends BaseRepository<TaskOutputEntity, TaskNamedDataEntityPK> {
public TaskOutputRepository(UserTaskJPAContext context) {
super(context);
diff --git a/addons/common/jbpm-usertask-storage-jpa/src/main/java/org/jbpm/usertask/jpa/repository/TaskInputRepository.java b/addons/common/jbpm-usertask-storage-jpa/src/main/java/org/jbpm/usertask/jpa/repository/TaskReassignmentRepository.java
similarity index 72%
copy from addons/common/jbpm-usertask-storage-jpa/src/main/java/org/jbpm/usertask/jpa/repository/TaskInputRepository.java
copy to addons/common/jbpm-usertask-storage-jpa/src/main/java/org/jbpm/usertask/jpa/repository/TaskReassignmentRepository.java
index 6e85081ff7..ae01f0fd44 100644
--- a/addons/common/jbpm-usertask-storage-jpa/src/main/java/org/jbpm/usertask/jpa/repository/TaskInputRepository.java
+++ b/addons/common/jbpm-usertask-storage-jpa/src/main/java/org/jbpm/usertask/jpa/repository/TaskReassignmentRepository.java
@@ -19,17 +19,16 @@
package org.jbpm.usertask.jpa.repository;
-import org.jbpm.usertask.jpa.model.TaskDataEntityPK;
-import org.jbpm.usertask.jpa.model.TaskInputEntity;
+import org.jbpm.usertask.jpa.model.TaskReassignmentEntity;
-public class TaskInputRepository extends BaseRepository<TaskInputEntity, TaskDataEntityPK> {
+public class TaskReassignmentRepository extends BaseRepository<TaskReassignmentEntity, Integer> {
- public TaskInputRepository(UserTaskJPAContext context) {
+ public TaskReassignmentRepository(UserTaskJPAContext context) {
super(context);
}
@Override
- public Class<TaskInputEntity> getEntityClass() {
- return TaskInputEntity.class;
+ public Class<TaskReassignmentEntity> getEntityClass() {
+ return TaskReassignmentEntity.class;
}
}
diff --git a/addons/common/jbpm-usertask-storage-jpa/src/main/java/org/jbpm/usertask/jpa/repository/TaskInputRepository.java b/addons/common/jbpm-usertask-storage-jpa/src/main/java/org/jbpm/usertask/jpa/repository/TaskReassignmentTimerRepository.java
similarity index 67%
copy from addons/common/jbpm-usertask-storage-jpa/src/main/java/org/jbpm/usertask/jpa/repository/TaskInputRepository.java
copy to addons/common/jbpm-usertask-storage-jpa/src/main/java/org/jbpm/usertask/jpa/repository/TaskReassignmentTimerRepository.java
index 6e85081ff7..f9124609db 100644
--- a/addons/common/jbpm-usertask-storage-jpa/src/main/java/org/jbpm/usertask/jpa/repository/TaskInputRepository.java
+++ b/addons/common/jbpm-usertask-storage-jpa/src/main/java/org/jbpm/usertask/jpa/repository/TaskReassignmentTimerRepository.java
@@ -19,17 +19,17 @@
package org.jbpm.usertask.jpa.repository;
-import org.jbpm.usertask.jpa.model.TaskDataEntityPK;
-import org.jbpm.usertask.jpa.model.TaskInputEntity;
+import org.jbpm.usertask.jpa.model.TaskReassignmentTimerEntity;
+import org.jbpm.usertask.jpa.model.TaskTimerDataEntityPK;
-public class TaskInputRepository extends BaseRepository<TaskInputEntity, TaskDataEntityPK> {
+public class TaskReassignmentTimerRepository extends BaseRepository<TaskReassignmentTimerEntity, TaskTimerDataEntityPK> {
- public TaskInputRepository(UserTaskJPAContext context) {
+ public TaskReassignmentTimerRepository(UserTaskJPAContext context) {
super(context);
}
@Override
- public Class<TaskInputEntity> getEntityClass() {
- return TaskInputEntity.class;
+ public Class<TaskReassignmentTimerEntity> getEntityClass() {
+ return TaskReassignmentTimerEntity.class;
}
}
diff --git a/addons/common/jbpm-usertask-storage-jpa/src/main/resources/kie-flyway/db/user-tasks/h2/V1.0.1__jBPM_user_task_timers.sql b/addons/common/jbpm-usertask-storage-jpa/src/main/resources/kie-flyway/db/user-tasks/h2/V1.0.1__jBPM_user_task_timers.sql
new file mode 100644
index 0000000000..80154790b0
--- /dev/null
+++ b/addons/common/jbpm-usertask-storage-jpa/src/main/resources/kie-flyway/db/user-tasks/h2/V1.0.1__jBPM_user_task_timers.sql
@@ -0,0 +1,71 @@
+/*
+ * 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.
+ */
+create table jbpm_user_tasks_deadline (
+ id int,
+ task_id varchar(50) not null,
+ notification_type varchar(255) not null,
+ notification_value varbinary(max),
+ java_type varchar(255),
+ primary key (id)
+);
+
+
+create table jbpm_user_tasks_reassignment (
+ id int,
+ task_id varchar(50) not null,
+ reassignment_type varchar(255) not null,
+ reassignment_value varbinary(max),
+ java_type varchar(255),
+ primary key (id)
+);
+
+
+create table jbpm_user_tasks_deadline_timer (
+ task_id varchar(50) not null,
+ notification_job_id varchar(255) not null,
+ notification_type varchar(255) not null,
+ notification_value varbinary(max),
+ java_type varchar(255),
+ primary key (task_id, notification_job_id)
+);
+
+create table jbpm_user_tasks_reassignment_timer (
+ task_id varchar(50) not null,
+ reassignment_job_id varchar(255) not null,
+ reassignment_type varchar(255) not null,
+ reassignment_value varbinary(max),
+ java_type varchar(255),
+ primary key (task_id, reassignment_job_id)
+);
+
+CREATE SEQUENCE jbpm_user_tasks_deadline_seq INCREMENT BY 50;
+CREATE SEQUENCE jbpm_user_tasks_reassignment_seq INCREMENT BY 50;
+
+alter table if exists jbpm_user_tasks_deadline
+add constraint fk_jbpm_user_tasks_deadline_tid foreign key (task_id) references jbpm_user_tasks(id) on delete cascade;
+
+alter table if exists jbpm_user_tasks_reassignment
+add constraint fk_jbpm_user_tasks_reassignment_tid foreign key (task_id) references jbpm_user_tasks(id) on delete cascade;
+
+alter table if exists jbpm_user_tasks_deadline_timer
+add constraint fk_jbpm_user_tasks_deadline_timer_tid foreign key (task_id) references jbpm_user_tasks(id) on delete cascade;
+
+
+alter table if exists jbpm_user_tasks_reassignment_timer
+add constraint fk_jbpm_user_tasks_reassignment_timer_tid foreign key (task_id) references jbpm_user_tasks(id) on delete cascade;
diff --git a/addons/common/jbpm-usertask-storage-jpa/src/main/resources/kie-flyway/db/user-tasks/postgresql/V1.0.1__jBPM_user_task_timers.sql b/addons/common/jbpm-usertask-storage-jpa/src/main/resources/kie-flyway/db/user-tasks/postgresql/V1.0.1__jBPM_user_task_timers.sql
new file mode 100644
index 0000000000..e54054517d
--- /dev/null
+++ b/addons/common/jbpm-usertask-storage-jpa/src/main/resources/kie-flyway/db/user-tasks/postgresql/V1.0.1__jBPM_user_task_timers.sql
@@ -0,0 +1,72 @@
+/*
+ * 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.
+ */
+create table jbpm_user_tasks_deadline (
+ id int,
+ task_id varchar(50) not null,
+ notification_type varchar(255) not null,
+ notification_value bytea,
+ java_type varchar(255),
+ primary key (id)
+);
+
+
+create table jbpm_user_tasks_reassignment (
+ id int,
+ task_id varchar(50) not null,
+ reassignment_type varchar(255) not null,
+ reassignment_value bytea,
+ java_type varchar(255),
+ primary key (id)
+);
+
+
+create table jbpm_user_tasks_deadline_timer (
+ task_id varchar(50) not null,
+ notification_job_id varchar(255) not null,
+ notification_type varchar(255) not null,
+ notification_value bytea,
+ java_type varchar(255),
+ primary key (task_id, notification_job_id)
+);
+
+
+
+create table jbpm_user_tasks_reassignment_timer (
+ task_id varchar(50) not null,
+ reassignment_job_id varchar(255) not null,
+ reassignment_type varchar(255) not null,
+ reassignment_value bytea,
+ java_type varchar(255),
+ primary key (task_id, reassignment_job_id)
+);
+
+CREATE SEQUENCE jbpm_user_tasks_deadline_seq INCREMENT BY 50 OWNED BY jbpm_user_tasks_deadline.id;
+CREATE SEQUENCE jbpm_user_tasks_reassignment_seq INCREMENT BY 50 OWNED BY jbpm_user_tasks_reassignment.id;
+
+alter table if exists jbpm_user_tasks_deadline
+add constraint fk_jbpm_user_tasks_deadline_tid foreign key (task_id) references jbpm_user_tasks(id) on delete cascade;
+
+alter table if exists jbpm_user_tasks_reassignment
+add constraint fk_jbpm_user_tasks_reassignment_tid foreign key (task_id) references jbpm_user_tasks(id) on delete cascade;
+
+alter table if exists jbpm_user_tasks_deadline_timer
+add constraint fk_jbpm_user_tasks_deadline_timer_tid foreign key (task_id) references jbpm_user_tasks(id) on delete cascade;
+
+alter table if exists jbpm_user_tasks_reassignment_timer
+add constraint fk_jbpm_user_tasks_reassignment_timer_tid foreign key (task_id) references jbpm_user_tasks(id) on delete cascade;
diff --git a/addons/common/jbpm-usertask-storage-jpa/src/test/java/org/jbpm/usertask/jpa/JPAUserTaskInstancesTest.java b/addons/common/jbpm-usertask-storage-jpa/src/test/java/org/jbpm/usertask/jpa/JPAUserTaskInstancesTest.java
index d0ca49f114..b93b54e51e 100644
--- a/addons/common/jbpm-usertask-storage-jpa/src/test/java/org/jbpm/usertask/jpa/JPAUserTaskInstancesTest.java
+++ b/addons/common/jbpm-usertask-storage-jpa/src/test/java/org/jbpm/usertask/jpa/JPAUserTaskInstancesTest.java
@@ -24,7 +24,12 @@ import java.util.Optional;
import java.util.function.Function;
import org.assertj.core.api.Assertions;
-import org.jbpm.usertask.jpa.mapper.*;
+import org.jbpm.usertask.jpa.mapper.CommentsEntityMapper;
+import org.jbpm.usertask.jpa.mapper.EntityMapper;
+import org.jbpm.usertask.jpa.mapper.TaskInputsEntityMapper;
+import org.jbpm.usertask.jpa.mapper.TaskMetadataEntityMapper;
+import org.jbpm.usertask.jpa.mapper.TaskOutputsEntityMapper;
+import org.jbpm.usertask.jpa.mapper.UserTaskInstanceEntityMapper;
import org.jbpm.usertask.jpa.mapper.utils.TestUtils;
import org.jbpm.usertask.jpa.model.UserTaskInstanceEntity;
import org.jbpm.usertask.jpa.repository.UserTaskInstanceRepository;
@@ -37,7 +42,11 @@ import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;
import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.Mockito.*;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
@ExtendWith(MockitoExtension.class)
public class JPAUserTaskInstancesTest {
@@ -46,7 +55,7 @@ public class JPAUserTaskInstancesTest {
private UserTaskInstanceRepository userTaskInstanceRepository;
@Mock
- private AttachmentsEntityMapper attachmentsEntityMapper;
+ private EntityMapper attachmentsEntityMapper;
@Mock
private CommentsEntityMapper commentsEntityMapper;
@Mock
@@ -66,7 +75,7 @@ public class JPAUserTaskInstancesTest {
@BeforeEach
public void setup() {
- userTaskInstanceEntityMapper = spy(new UserTaskInstanceEntityMapper(attachmentsEntityMapper, commentsEntityMapper, metadataEntityMapper, inputsEntityMapper, outputsEntityMapper));
+ userTaskInstanceEntityMapper = spy(new UserTaskInstanceEntityMapper(List.of(attachmentsEntityMapper, commentsEntityMapper, metadataEntityMapper, inputsEntityMapper, outputsEntityMapper)));
jpaUserTaskInstances = new JPAUserTaskInstances(userTaskInstanceRepository, userTaskInstanceEntityMapper);
jpaUserTaskInstances.setReconnectUserTaskInstance(reconnectUserTaskInstance);
jpaUserTaskInstances.setDisconnectUserTaskInstance(disconnectUserTaskInstance);
diff --git a/addons/common/jbpm-usertask-storage-jpa/src/test/java/org/jbpm/usertask/jpa/mapper/AttachmentsEntityMapperTest.java b/addons/common/jbpm-usertask-storage-jpa/src/test/java/org/jbpm/usertask/jpa/mapper/AttachmentsEntityMapperTest.java
index cafdb8e166..904dd0c619 100644
--- a/addons/common/jbpm-usertask-storage-jpa/src/test/java/org/jbpm/usertask/jpa/mapper/AttachmentsEntityMapperTest.java
+++ b/addons/common/jbpm-usertask-storage-jpa/src/test/java/org/jbpm/usertask/jpa/mapper/AttachmentsEntityMapperTest.java
@@ -42,7 +42,7 @@ public class AttachmentsEntityMapperTest {
@Mock
private AttachmentRepository repository;
- private AttachmentsEntityMapper mapper;
+ private EntityMapper mapper;
@BeforeEach
public void setup() {
diff --git a/addons/common/jbpm-usertask-storage-jpa/src/test/java/org/jbpm/usertask/jpa/mapper/UserTaskInstanceEntityMapperTest.java b/addons/common/jbpm-usertask-storage-jpa/src/test/java/org/jbpm/usertask/jpa/mapper/UserTaskInstanceEntityMapperTest.java
index 3b49d9b445..2cdf057b5d 100644
--- a/addons/common/jbpm-usertask-storage-jpa/src/test/java/org/jbpm/usertask/jpa/mapper/UserTaskInstanceEntityMapperTest.java
+++ b/addons/common/jbpm-usertask-storage-jpa/src/test/java/org/jbpm/usertask/jpa/mapper/UserTaskInstanceEntityMapperTest.java
@@ -19,6 +19,8 @@
package org.jbpm.usertask.jpa.mapper;
+import java.util.List;
+
import org.jbpm.usertask.jpa.mapper.utils.TestUtils;
import org.jbpm.usertask.jpa.model.UserTaskInstanceEntity;
import org.junit.jupiter.api.BeforeEach;
@@ -28,7 +30,9 @@ import org.kie.kogito.usertask.UserTaskInstance;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;
-import static org.mockito.Mockito.*;
+import static org.mockito.ArgumentMatchers.same;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
@ExtendWith(MockitoExtension.class)
public class UserTaskInstanceEntityMapperTest {
@@ -48,7 +52,7 @@ public class UserTaskInstanceEntityMapperTest {
@BeforeEach
public void setUp() {
- this.userTaskInstanceEntityMapper = new UserTaskInstanceEntityMapper(attachmentsEntityMapper, commentsEntityMapper, metadataEntityMapper, inputsEntityMapper, outputsEntityMapper);
+ this.userTaskInstanceEntityMapper = new UserTaskInstanceEntityMapper(List.of(attachmentsEntityMapper, commentsEntityMapper, metadataEntityMapper, inputsEntityMapper, outputsEntityMapper));
}
@Test
diff --git a/addons/common/jbpm-usertask-storage-jpa/src/test/java/org/jbpm/usertask/jpa/mapper/utils/TestUtils.java b/addons/common/jbpm-usertask-storage-jpa/src/test/java/org/jbpm/usertask/jpa/mapper/utils/TestUtils.java
index b1b4373f36..0d501f1478 100644
--- a/addons/common/jbpm-usertask-storage-jpa/src/test/java/org/jbpm/usertask/jpa/mapper/utils/TestUtils.java
+++ b/addons/common/jbpm-usertask-storage-jpa/src/test/java/org/jbpm/usertask/jpa/mapper/utils/TestUtils.java
@@ -19,13 +19,21 @@
package org.jbpm.usertask.jpa.mapper.utils;
-import java.util.*;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Objects;
+import java.util.Optional;
+import java.util.Set;
+import java.util.UUID;
import org.assertj.core.api.Assertions;
import org.jbpm.usertask.jpa.mapper.models.Person;
import org.jbpm.usertask.jpa.model.AttachmentEntity;
import org.jbpm.usertask.jpa.model.CommentEntity;
-import org.jbpm.usertask.jpa.model.TaskDataEntity;
+import org.jbpm.usertask.jpa.model.TaskNamedDataEntity;
import org.jbpm.usertask.jpa.model.UserTaskInstanceEntity;
import org.kie.kogito.usertask.UserTaskInstance;
import org.kie.kogito.usertask.impl.DefaultUserTaskInstance;
@@ -203,7 +211,7 @@ public class TestUtils {
assertUserTaskEntityMapData(userTaskInstanceEntity.getMetadata(), userTaskInstance.getMetadata());
}
- private static void assertUserTaskEntityMapData(Collection<? extends TaskDataEntity> entityData, Map<String, Object> instanceData) {
+ private static void assertUserTaskEntityMapData(Collection<? extends TaskNamedDataEntity> entityData, Map<String, Object> instanceData) {
Assertions.assertThat(entityData.size())
.isEqualTo(instanceData.size());
@@ -228,18 +236,18 @@ public class TestUtils {
assertUserTaskInstanceMapData(userTaskInstance.getMetadata(), userTaskInstanceEntity.getMetadata());
}
- private static void assertUserTaskInstanceMapData(Map<String, Object> instanceData, Collection<? extends TaskDataEntity> entityData) {
+ private static void assertUserTaskInstanceMapData(Map<String, Object> instanceData, Collection<? extends TaskNamedDataEntity> entityData) {
Assertions.assertThat(instanceData.size())
.isEqualTo(entityData.size());
instanceData.forEach((key, value) -> {
- Optional<? extends TaskDataEntity> optional = entityData.stream().filter(data -> data.getName().equals(key)).findFirst();
+ Optional<? extends TaskNamedDataEntity> optional = entityData.stream().filter(data -> data.getName().equals(key)).findFirst();
Assertions.assertThat(optional)
.isPresent();
if (Objects.nonNull(value)) {
- TaskDataEntity data = optional.get();
+ TaskNamedDataEntity data = optional.get();
Assertions.assertThat(value.getClass().getName())
.isEqualTo(data.getJavaType());
}
@@ -262,6 +270,16 @@ public class TestUtils {
instance.setAdminGroups(Set.of("Administrators", "Managers"));
instance.setExcludedUsers(Set.of("Ned", "Bart"));
+ instance.setNotStartedDeadlines(new ArrayList<>());
+ instance.setNotStartedDeadlinesTimers(new HashMap<>());
+ instance.setNotCompletedDeadlines(new ArrayList<>());
+ instance.setNotCompletedDeadlinesTimers(new HashMap<>());
+
+ instance.setNotStartedReassignments(new ArrayList<>());
+ instance.setNotStartedReassignmentsTimers(new HashMap<>());
+ instance.setNotCompletedReassignments(new ArrayList<>());
+ instance.setNotCompletedReassignmentsTimers(new HashMap<>());
+
instance.setExternalReferenceId("external-reference-id");
instance.setMetadata("ProcessId", "process-id");
diff --git a/addons/common/jobs/api/src/main/java/org/kie/kogito/jobs/api/JobCallbackResourceDef.java b/addons/common/jobs/api/src/main/java/org/kie/kogito/jobs/api/JobCallbackResourceDef.java
index ba5cfd6ac0..3bb36df752 100644
--- a/addons/common/jobs/api/src/main/java/org/kie/kogito/jobs/api/JobCallbackResourceDef.java
+++ b/addons/common/jobs/api/src/main/java/org/kie/kogito/jobs/api/JobCallbackResourceDef.java
@@ -20,7 +20,8 @@ package org.kie.kogito.jobs.api;
import java.time.temporal.ChronoUnit;
-import org.kie.kogito.jobs.ProcessInstanceJobDescription;
+import org.kie.kogito.jobs.JobDescription;
+import org.kie.kogito.jobs.descriptors.ProcessInstanceJobDescription;
import org.kie.kogito.jobs.service.api.TemporalUnit;
import org.kie.kogito.jobs.service.api.recipient.http.HttpRecipient;
import org.kie.kogito.jobs.service.api.recipient.http.HttpRecipientJsonPayloadData;
@@ -53,25 +54,16 @@ public class JobCallbackResourceDef {
public static final String LIMIT_DEFAULT_VALUE = "0";
- public static final String JOBS_CALLBACK_URI = "/management/jobs";
-
public static final String JOBS_CALLBACK_POST_URI = "{" + PROCESS_ID + "}/instances/{" + PROCESS_INSTANCE_ID + "}/timers/{" + TIMER_ID + "}";
private JobCallbackResourceDef() {
}
- public static String buildCallbackURI(ProcessInstanceJobDescription description, String jobsCallbackEndpoint) {
- return URIBuilder.toURI(jobsCallbackEndpoint
- + JOBS_CALLBACK_URI + "/"
- + description.processId()
- + "/instances/"
- + description.processInstanceId()
- + "/timers/"
- + description.timerId())
- .toString();
+ public static String buildCallbackURI(JobDescription description, String jobsCallbackEndpoint) {
+ return URIBuilder.toURI(jobsCallbackEndpoint + description.path()).toString();
}
- public static org.kie.kogito.jobs.service.api.Job buildCallbackPatternJob(ProcessInstanceJobDescription description,
+ public static org.kie.kogito.jobs.service.api.Job buildCallbackPatternJob(JobDescription description,
String callback, ObjectMapper objectMapper) {
return org.kie.kogito.jobs.service.api.Job.builder()
.id(description.id())
@@ -81,25 +73,28 @@ public class JobCallbackResourceDef {
.build();
}
- private static HttpRecipient<HttpRecipientJsonPayloadData> buildRecipient(ProcessInstanceJobDescription description, String callback, ObjectMapper objectMapper) {
- return HttpRecipient.builder()
+ private static HttpRecipient<HttpRecipientJsonPayloadData> buildRecipient(JobDescription description, String callback, ObjectMapper objectMapper) {
+ HttpRecipient.Builder<HttpRecipientJsonPayloadData> selector = HttpRecipient.builder()
.forJsonPayload()
.payload(HttpRecipientJsonPayloadData.from(buildPayload(description, objectMapper)))
.url(callback)
- .header(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON)
- .header(PROCESS_ID, description.processId())
- .header(PROCESS_INSTANCE_ID, description.processInstanceId())
- .header(ROOT_PROCESS_ID, description.rootProcessId())
- .header(ROOT_PROCESS_INSTANCE_ID, description.rootProcessInstanceId())
- .header(NODE_INSTANCE_ID, description.nodeInstanceId())
- .build();
+ .header(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON);
+
+ if (description instanceof ProcessInstanceJobDescription processInstanceJobDescription) {
+ selector.header(PROCESS_ID, processInstanceJobDescription.processId())
+ .header(PROCESS_INSTANCE_ID, processInstanceJobDescription.processInstanceId())
+ .header(ROOT_PROCESS_ID, processInstanceJobDescription.rootProcessId())
+ .header(ROOT_PROCESS_INSTANCE_ID, processInstanceJobDescription.rootProcessInstanceId())
+ .header(NODE_INSTANCE_ID, processInstanceJobDescription.nodeInstanceId());
+ }
+ return selector.build();
}
- private static JsonNode buildPayload(ProcessInstanceJobDescription description, ObjectMapper objectMapper) {
+ private static JsonNode buildPayload(JobDescription description, ObjectMapper objectMapper) {
return objectMapper.valueToTree(new JobCallbackPayload(description.id()));
}
- public static TimerSchedule buildSchedule(ProcessInstanceJobDescription description) {
+ public static TimerSchedule buildSchedule(JobDescription description) {
return TimerSchedule.builder()
.startTime(description.expirationTime().get().toOffsetDateTime().truncatedTo(ChronoUnit.MILLIS))
.repeatCount(translateLimit(description.expirationTime().repeatLimit()))
diff --git a/addons/common/jobs/api/src/test/java/org/kie/kogito/jobs/api/JobCallbackResourceDefTest.java b/addons/common/jobs/api/src/test/java/org/kie/kogito/jobs/api/JobCallbackResourceDefTest.java
index ee9b7aec67..060a0470b8 100644
--- a/addons/common/jobs/api/src/test/java/org/kie/kogito/jobs/api/JobCallbackResourceDefTest.java
+++ b/addons/common/jobs/api/src/test/java/org/kie/kogito/jobs/api/JobCallbackResourceDefTest.java
@@ -23,7 +23,7 @@ import java.net.URI;
import org.junit.jupiter.api.Test;
import org.kie.kogito.jobs.ExactExpirationTime;
import org.kie.kogito.jobs.ExpirationTime;
-import org.kie.kogito.jobs.ProcessInstanceJobDescription;
+import org.kie.kogito.jobs.descriptors.ProcessInstanceJobDescription;
import org.kie.kogito.jobs.service.api.recipient.http.HttpRecipient;
import org.kie.kogito.jobs.service.api.schedule.timer.TimerSchedule;
import org.kie.kogito.jobs.service.api.serlialization.SerializationUtils;
@@ -91,7 +91,7 @@ class JobCallbackResourceDefTest {
}
private ProcessInstanceJobDescription mockProcessInstanceJobDescription() {
- return ProcessInstanceJobDescription.builder()
+ return ProcessInstanceJobDescription.newProcessInstanceJobDescriptionBuilder()
.id(JOB_ID)
.timerId(TIMER_ID)
.expirationTime(EXPIRATION_TIME)
diff --git a/addons/common/jobs/management-common/src/main/java/org/kie/kogito/jobs/management/RestJobsService.java b/addons/common/jobs/management-common/src/main/java/org/kie/kogito/jobs/management/RestJobsService.java
index a503015d3b..615b40b5cd 100644
--- a/addons/common/jobs/management-common/src/main/java/org/kie/kogito/jobs/management/RestJobsService.java
+++ b/addons/common/jobs/management-common/src/main/java/org/kie/kogito/jobs/management/RestJobsService.java
@@ -21,8 +21,8 @@ package org.kie.kogito.jobs.management;
import java.net.URI;
import java.util.Objects;
+import org.kie.kogito.jobs.JobDescription;
import org.kie.kogito.jobs.JobsService;
-import org.kie.kogito.jobs.ProcessInstanceJobDescription;
import org.kie.kogito.jobs.api.URIBuilder;
import org.kie.kogito.jobs.service.api.Job;
@@ -46,7 +46,7 @@ public abstract class RestJobsService implements JobsService {
this.objectMapper = objectMapper;
}
- public String getCallbackEndpoint(ProcessInstanceJobDescription description) {
+ public String getCallbackEndpoint(JobDescription description) {
return buildCallbackURI(description, callbackEndpoint);
}
@@ -58,7 +58,7 @@ public abstract class RestJobsService implements JobsService {
return jobsServiceUri;
}
- public Job buildJob(ProcessInstanceJobDescription description, String callback) {
+ public Job buildJob(JobDescription description, String callback) {
return buildCallbackPatternJob(description, callback, objectMapper);
}
}
diff --git a/addons/common/jobs/management-common/src/test/java/org/kie/kogito/jobs/management/RestJobsServiceTest.java b/addons/common/jobs/management-common/src/test/java/org/kie/kogito/jobs/management/RestJobsServiceTest.java
index 193ceb92a1..0f0b2d3f5d 100644
--- a/addons/common/jobs/management-common/src/test/java/org/kie/kogito/jobs/management/RestJobsServiceTest.java
+++ b/addons/common/jobs/management-common/src/test/java/org/kie/kogito/jobs/management/RestJobsServiceTest.java
@@ -25,9 +25,8 @@ import java.time.temporal.ChronoUnit;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.kie.kogito.jobs.ExactExpirationTime;
-import org.kie.kogito.jobs.ProcessInstanceJobDescription;
-import org.kie.kogito.jobs.ProcessJobDescription;
import org.kie.kogito.jobs.api.JobCallbackPayload;
+import org.kie.kogito.jobs.descriptors.ProcessInstanceJobDescription;
import org.kie.kogito.jobs.service.api.Job;
import org.kie.kogito.jobs.service.api.recipient.http.HttpRecipient;
import org.kie.kogito.jobs.service.api.recipient.http.HttpRecipientJsonPayloadData;
@@ -37,7 +36,6 @@ import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import static org.assertj.core.api.Assertions.assertThat;
-import static org.assertj.core.api.Assertions.assertThatThrownBy;
public abstract class RestJobsServiceTest<T extends RestJobsService> {
@@ -64,7 +62,7 @@ public abstract class RestJobsServiceTest<T extends RestJobsService> {
@Test
void testGetCallbackEndpoint() {
- ProcessInstanceJobDescription description = ProcessInstanceJobDescription.builder()
+ ProcessInstanceJobDescription description = ProcessInstanceJobDescription.newProcessInstanceJobDescriptionBuilder()
.id(JOB_ID)
.timerId(TIMER_ID)
.expirationTime(ExactExpirationTime.now())
@@ -86,17 +84,8 @@ public abstract class RestJobsServiceTest<T extends RestJobsService> {
assertThat(jobsServiceUri).hasToString(JOB_SERVICE_URL + "/v2/jobs");
}
- @Test
- void testScheduleProcessJob() {
- ProcessJobDescription processJobDescription = ProcessJobDescription.of(ExactExpirationTime.of(EXPIRATION_TIME),
- 1,
- PROCESS_ID);
- assertThatThrownBy(() -> tested.scheduleProcessJob(processJobDescription))
- .isInstanceOf(UnsupportedOperationException.class);
- }
-
protected ProcessInstanceJobDescription buildProcessInstanceJobDescription() {
- return ProcessInstanceJobDescription.builder()
+ return ProcessInstanceJobDescription.newProcessInstanceJobDescriptionBuilder()
.id(JOB_ID)
.timerId(TIMER_ID)
.expirationTime(ExactExpirationTime.of(EXPIRATION_TIME))
diff --git a/api/kogito-api/src/main/java/org/kie/kogito/StaticConfig.java b/api/kogito-api/src/main/java/org/kie/kogito/StaticConfig.java
index cbfbe80afa..dd67a4cc19 100644
--- a/api/kogito-api/src/main/java/org/kie/kogito/StaticConfig.java
+++ b/api/kogito-api/src/main/java/org/kie/kogito/StaticConfig.java
@@ -18,22 +18,33 @@
*/
package org.kie.kogito;
-import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
+import static java.util.Arrays.asList;
+
public class StaticConfig implements Config {
- private final Addons addons;
- private final Map<Class<? extends KogitoConfig>, KogitoConfig> configMap = new HashMap<>();
+ private Addons addons;
+ private Map<Class<? extends KogitoConfig>, KogitoConfig> configMap = new HashMap<>();
+
+ public StaticConfig() {
+ addons = Addons.EMTPY;
+ }
+
+ public StaticConfig(Addons addons, KogitoConfig... configs) {
+ init(addons, configs);
+ }
+
+ protected StaticConfig(Addons addons, Iterable<KogitoConfig> configs) {
+ init(addons, configs);
+ }
- public StaticConfig(Addons addons,
- KogitoConfig... configs) {
- this(addons, Arrays.asList(configs));
+ protected void init(Addons addons, KogitoConfig... configs) {
+ init(addons, asList(configs));
}
- protected StaticConfig(Addons addons,
- Iterable<KogitoConfig> configs) {
+ protected void init(Addons addons, Iterable<KogitoConfig> configs) {
this.addons = addons;
configs.forEach(this::loadConfig);
}
diff --git a/api/kogito-api/src/main/java/org/kie/kogito/jobs/JobDescription.java b/api/kogito-api/src/main/java/org/kie/kogito/jobs/JobDescription.java
index 5bbd520bfc..f69c74e6c2 100644
--- a/api/kogito-api/src/main/java/org/kie/kogito/jobs/JobDescription.java
+++ b/api/kogito-api/src/main/java/org/kie/kogito/jobs/JobDescription.java
@@ -20,9 +20,14 @@ package org.kie.kogito.jobs;
public interface JobDescription {
+ static final String JOBS_CALLBACK_URI = "/management/jobs";
+
String id();
ExpirationTime expirationTime();
Integer priority();
+
+ String path();
+
}
diff --git a/api/kogito-api/src/main/java/org/kie/kogito/jobs/JobsService.java b/api/kogito-api/src/main/java/org/kie/kogito/jobs/JobsService.java
index a9e5230c40..f953c9a79b 100644
--- a/api/kogito-api/src/main/java/org/kie/kogito/jobs/JobsService.java
+++ b/api/kogito-api/src/main/java/org/kie/kogito/jobs/JobsService.java
@@ -29,19 +29,11 @@ public interface JobsService {
* Schedules process job that is responsible for starting new process instances
* based on the given description.
*
+ * @param context of the job
* @param description defines what kind of process should be started upon expiration time
* @return returns unique id of the job
*/
- String scheduleProcessJob(ProcessJobDescription description);
-
- /**
- * Schedules process instance related job that will signal exact same process instance
- * upon expiration time.
- *
- * @param description defines the context of the process instance that should be signaled
- * @return returns unique id of the job
- */
- String scheduleProcessInstanceJob(ProcessInstanceJobDescription description);
+ String scheduleJob(JobDescription description);
/**
* Cancels given job
diff --git a/api/kogito-api/src/main/java/org/kie/kogito/jobs/ProcessInstanceJobDescription.java b/api/kogito-api/src/main/java/org/kie/kogito/jobs/descriptors/ProcessInstanceJobDescription.java
similarity index 88%
rename from api/kogito-api/src/main/java/org/kie/kogito/jobs/ProcessInstanceJobDescription.java
rename to api/kogito-api/src/main/java/org/kie/kogito/jobs/descriptors/ProcessInstanceJobDescription.java
index 086bfac244..3f0becb82e 100644
--- a/api/kogito-api/src/main/java/org/kie/kogito/jobs/ProcessInstanceJobDescription.java
+++ b/api/kogito-api/src/main/java/org/kie/kogito/jobs/descriptors/ProcessInstanceJobDescription.java
@@ -16,7 +16,10 @@
* specific language governing permissions and limitations
* under the License.
*/
-package org.kie.kogito.jobs;
+package org.kie.kogito.jobs.descriptors;
+
+import org.kie.kogito.jobs.ExpirationTime;
+import org.kie.kogito.jobs.JobDescription;
import static java.util.Objects.requireNonNull;
@@ -93,10 +96,21 @@ public class ProcessInstanceJobDescription implements JobDescription {
return nodeInstanceId;
}
- public static ProcessInstanceJobDescriptionBuilder builder() {
+ public static ProcessInstanceJobDescriptionBuilder newProcessInstanceJobDescriptionBuilder() {
return new ProcessInstanceJobDescriptionBuilder();
}
+ @Override
+ public String path() {
+ return JOBS_CALLBACK_URI + "/"
+ + processId()
+ + "/instances/"
+ + processInstanceId()
+ + "/timers/"
+ + timerId();
+
+ }
+
@Override
public String toString() {
return "ProcessInstanceJobDescription{" +
diff --git a/api/kogito-api/src/main/java/org/kie/kogito/jobs/ProcessInstanceJobDescriptionBuilder.java b/api/kogito-api/src/main/java/org/kie/kogito/jobs/descriptors/ProcessInstanceJobDescriptionBuilder.java
similarity index 97%
rename from api/kogito-api/src/main/java/org/kie/kogito/jobs/ProcessInstanceJobDescriptionBuilder.java
rename to api/kogito-api/src/main/java/org/kie/kogito/jobs/descriptors/ProcessInstanceJobDescriptionBuilder.java
index 73e491aefe..0c9c203442 100644
--- a/api/kogito-api/src/main/java/org/kie/kogito/jobs/ProcessInstanceJobDescriptionBuilder.java
+++ b/api/kogito-api/src/main/java/org/kie/kogito/jobs/descriptors/ProcessInstanceJobDescriptionBuilder.java
@@ -16,10 +16,12 @@
* specific language governing permissions and limitations
* under the License.
*/
-package org.kie.kogito.jobs;
+package org.kie.kogito.jobs.descriptors;
import java.util.UUID;
+import org.kie.kogito.jobs.ExpirationTime;
+
public class ProcessInstanceJobDescriptionBuilder {
private String id;
diff --git a/api/kogito-api/src/main/java/org/kie/kogito/jobs/ProcessJobDescription.java b/api/kogito-api/src/main/java/org/kie/kogito/jobs/descriptors/ProcessJobDescription.java
similarity index 93%
rename from api/kogito-api/src/main/java/org/kie/kogito/jobs/ProcessJobDescription.java
rename to api/kogito-api/src/main/java/org/kie/kogito/jobs/descriptors/ProcessJobDescription.java
index d3f3d8d177..e8ab6baf01 100644
--- a/api/kogito-api/src/main/java/org/kie/kogito/jobs/ProcessJobDescription.java
+++ b/api/kogito-api/src/main/java/org/kie/kogito/jobs/descriptors/ProcessJobDescription.java
@@ -16,10 +16,12 @@
* specific language governing permissions and limitations
* under the License.
*/
-package org.kie.kogito.jobs;
+package org.kie.kogito.jobs.descriptors;
import java.util.UUID;
+import org.kie.kogito.jobs.ExpirationTime;
+import org.kie.kogito.jobs.JobDescription;
import org.kie.kogito.process.Process;
import static java.util.Objects.requireNonNull;
@@ -87,4 +89,9 @@ public class ProcessJobDescription implements JobDescription {
public Process<?> process() {
return process;
}
+
+ @Override
+ public String path() {
+ return "";
+ }
}
diff --git a/api/kogito-api/src/main/java/org/kie/kogito/jobs/descriptors/UserTaskInstanceJobDescription.java b/api/kogito-api/src/main/java/org/kie/kogito/jobs/descriptors/UserTaskInstanceJobDescription.java
new file mode 100644
index 0000000000..5fbe5f29ed
--- /dev/null
+++ b/api/kogito-api/src/main/java/org/kie/kogito/jobs/descriptors/UserTaskInstanceJobDescription.java
@@ -0,0 +1,69 @@
+/*
+ * 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.jobs.descriptors;
+
+import org.kie.kogito.jobs.ExpirationTime;
+import org.kie.kogito.jobs.JobDescription;
+
+public class UserTaskInstanceJobDescription implements JobDescription {
+
+ private String id;
+ private ExpirationTime expirationTime;
+ private Integer priority = ProcessInstanceJobDescription.DEFAULT_PRIORITY;
+ private String userTaskInstanceId;
+
+ public UserTaskInstanceJobDescription() {
+ // do nothing
+ }
+
+ public UserTaskInstanceJobDescription(String id, ExpirationTime expirationTime, Integer priority, String userTaskInstanceId) {
+ this.id = id;
+ this.expirationTime = expirationTime;
+ this.priority = priority;
+ this.userTaskInstanceId = userTaskInstanceId;
+ }
+
+ @Override
+ public String id() {
+ return id;
+ }
+
+ @Override
+ public ExpirationTime expirationTime() {
+ return expirationTime;
+ }
+
+ @Override
+ public Integer priority() {
+ return priority;
+ }
+
+ @Override
+ public String path() {
+ return null;
+ }
+
+ public String getUserTaskInstanceId() {
+ return userTaskInstanceId;
+ }
+
+ public static UserTaskInstanceJobDescriptionBuilder newUserTaskInstanceJobDescriptionBuilder() {
+ return new UserTaskInstanceJobDescriptionBuilder();
+ }
+}
diff --git a/api/kogito-api/src/main/java/org/kie/kogito/jobs/descriptors/UserTaskInstanceJobDescriptionBuilder.java b/api/kogito-api/src/main/java/org/kie/kogito/jobs/descriptors/UserTaskInstanceJobDescriptionBuilder.java
new file mode 100644
index 0000000000..ad8a4bfba2
--- /dev/null
+++ b/api/kogito-api/src/main/java/org/kie/kogito/jobs/descriptors/UserTaskInstanceJobDescriptionBuilder.java
@@ -0,0 +1,80 @@
+/*
+ * 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.jobs.descriptors;
+
+import java.util.UUID;
+
+import org.kie.kogito.jobs.ExpirationTime;
+import org.kie.kogito.jobs.JobDescription;
+
+public class UserTaskInstanceJobDescriptionBuilder implements JobDescription {
+
+ private String id;
+ private ExpirationTime expirationTime;
+ private Integer priority = ProcessInstanceJobDescription.DEFAULT_PRIORITY;
+ private String userTaskInstanceId;
+
+ @Override
+ public String id() {
+ return id;
+ }
+
+ @Override
+ public ExpirationTime expirationTime() {
+ return expirationTime;
+ }
+
+ @Override
+ public Integer priority() {
+ return priority;
+ }
+
+ @Override
+ public String path() {
+ return null;
+ }
+
+ public UserTaskInstanceJobDescriptionBuilder id(String id) {
+ this.id = id;
+ return this;
+ }
+
+ public UserTaskInstanceJobDescriptionBuilder generateId() {
+ return id(UUID.randomUUID().toString());
+ }
+
+ public UserTaskInstanceJobDescriptionBuilder expirationTime(ExpirationTime expirationTime) {
+ this.expirationTime = expirationTime;
+ return this;
+ }
+
+ public UserTaskInstanceJobDescriptionBuilder priority(Integer priority) {
+ this.priority = priority;
+ return this;
+ }
+
+ public UserTaskInstanceJobDescriptionBuilder userTaskInstanceId(String userTaskInstanceId) {
+ this.userTaskInstanceId = userTaskInstanceId;
+ return this;
+ }
+
+ public UserTaskInstanceJobDescription build() {
+ return new UserTaskInstanceJobDescription(id, expirationTime, priority, userTaskInstanceId);
+ }
+}
diff --git a/api/kogito-api/src/main/java/org/kie/kogito/usertask/UserTask.java b/api/kogito-api/src/main/java/org/kie/kogito/usertask/UserTask.java
index b07df5f2f3..1a8b8f80b8 100644
--- a/api/kogito-api/src/main/java/org/kie/kogito/usertask/UserTask.java
+++ b/api/kogito-api/src/main/java/org/kie/kogito/usertask/UserTask.java
@@ -19,10 +19,10 @@
package org.kie.kogito.usertask;
import java.util.Collection;
-import java.util.Map;
import java.util.Set;
import org.kie.kogito.usertask.model.DeadlineInfo;
+import org.kie.kogito.usertask.model.Notification;
import org.kie.kogito.usertask.model.Reassignment;
/**
@@ -101,13 +101,13 @@ public interface UserTask {
*/
Set<String> getExcludedUsers();
- Collection<DeadlineInfo<Map<String, Object>>> getNotStartedDeadlines();
+ Collection<DeadlineInfo<Notification>> getNotStartedDeadlines();
- Collection<DeadlineInfo<Map<String, Object>>> getNotCompletedDeadlines();
+ Collection<DeadlineInfo<Notification>> getNotCompletedDeadlines();
Collection<DeadlineInfo<Reassignment>> getNotStartedReassignments();
- Collection<DeadlineInfo<Reassignment>> getNotCompletedReassigments();
+ Collection<DeadlineInfo<Reassignment>> getNotCompletedReassignments();
UserTaskAssignmentStrategy getAssignmentStrategy();
diff --git a/api/kogito-api/src/main/java/org/kie/kogito/usertask/UserTaskInstance.java b/api/kogito-api/src/main/java/org/kie/kogito/usertask/UserTaskInstance.java
index e28e23befe..6fcdd84c6f 100644
--- a/api/kogito-api/src/main/java/org/kie/kogito/usertask/UserTaskInstance.java
+++ b/api/kogito-api/src/main/java/org/kie/kogito/usertask/UserTaskInstance.java
@@ -23,9 +23,13 @@ import java.util.Map;
import java.util.Set;
import org.kie.kogito.auth.IdentityProvider;
+import org.kie.kogito.jobs.descriptors.UserTaskInstanceJobDescription;
import org.kie.kogito.usertask.lifecycle.UserTaskState;
import org.kie.kogito.usertask.model.Attachment;
import org.kie.kogito.usertask.model.Comment;
+import org.kie.kogito.usertask.model.DeadlineInfo;
+import org.kie.kogito.usertask.model.Notification;
+import org.kie.kogito.usertask.model.Reassignment;
public interface UserTaskInstance {
@@ -43,6 +47,8 @@ public interface UserTaskInstance {
String getActualOwner();
+ void initialize(Map<String, Object> data, IdentityProvider identity);
+
void transition(String transitionId, Map<String, Object> data, IdentityProvider identityProvider);
String getExternalReferenceId();
@@ -118,4 +124,30 @@ public interface UserTaskInstance {
Collection<Comment> getComments();
+ void trigger(UserTaskInstanceJobDescription userTaskInstanceJobDescription);
+
+ Collection<DeadlineInfo<Notification>> getNotStartedDeadlines();
+
+ Collection<DeadlineInfo<Notification>> getNotCompletedDeadlines();
+
+ Collection<DeadlineInfo<Reassignment>> getNotStartedReassignments();
+
+ Collection<DeadlineInfo<Reassignment>> getNotCompletedReassignments();
+
+ void startNotStartedDeadlines();
+
+ void startNotCompletedDeadlines();
+
+ void startNotStartedReassignments();
+
+ void startNotCompletedReassignments();
+
+ void stopNotStartedDeadlines();
+
+ void stopNotStartedReassignments();
+
+ void stopNotCompletedDeadlines();
+
+ void stopNotCompletedReassignments();
+
}
diff --git a/api/kogito-api/src/main/java/org/kie/kogito/usertask/lifecycle/UserTaskLifeCycle.java b/api/kogito-api/src/main/java/org/kie/kogito/usertask/lifecycle/UserTaskLifeCycle.java
index 09170f4d1c..43b8b66950 100644
--- a/api/kogito-api/src/main/java/org/kie/kogito/usertask/lifecycle/UserTaskLifeCycle.java
+++ b/api/kogito-api/src/main/java/org/kie/kogito/usertask/lifecycle/UserTaskLifeCycle.java
@@ -28,13 +28,23 @@ import org.kie.kogito.usertask.UserTaskInstance;
public interface UserTaskLifeCycle {
+ final String ACTIVATE = "activate";
+
+ default String startTransition() {
+ return ACTIVATE;
+ }
+
Optional<UserTaskTransitionToken> transition(UserTaskInstance userTaskInstance, UserTaskTransitionToken transition, IdentityProvider identity);
UserTaskTransitionToken newTransitionToken(String transitionId, UserTaskInstance userTaskInstance, Map<String, Object> data);
- UserTaskTransitionToken newCompleteTransitionToken(UserTaskInstance userTaskInstance, Map<String, Object> emptyMap);
+ default Optional<UserTaskTransitionToken> newReassignmentTransitionToken(UserTaskInstance defaultUserTaskInstance, Map<String, Object> data) {
+ return Optional.empty();
+ }
+
+ UserTaskTransitionToken newCompleteTransitionToken(UserTaskInstance userTaskInstance, Map<String, Object> data);
- UserTaskTransitionToken newAbortTransitionToken(UserTaskInstance userTaskInstance, Map<String, Object> emptyMap);
+ UserTaskTransitionToken newAbortTransitionToken(UserTaskInstance userTaskInstance, Map<String, Object> data);
List<UserTaskTransition> allowedTransitions(UserTaskInstance ut);
diff --git a/api/kogito-api/src/main/java/org/kie/kogito/usertask/model/Reassignment.java b/api/kogito-api/src/main/java/org/kie/kogito/usertask/model/Notification.java
similarity index 56%
copy from api/kogito-api/src/main/java/org/kie/kogito/usertask/model/Reassignment.java
copy to api/kogito-api/src/main/java/org/kie/kogito/usertask/model/Notification.java
index 024532fcf1..0146d3cd70 100644
--- a/api/kogito-api/src/main/java/org/kie/kogito/usertask/model/Reassignment.java
+++ b/api/kogito-api/src/main/java/org/kie/kogito/usertask/model/Notification.java
@@ -18,45 +18,50 @@
*/
package org.kie.kogito.usertask.model;
+import java.util.HashMap;
+import java.util.Map;
import java.util.Objects;
-import java.util.Set;
-public class Reassignment {
+public class Notification {
- private Set<String> potentialUsers;
- private Set<String> potentialGroups;
+ private Map<String, Object> data;
- public Reassignment(Set<String> potentialUsers, Set<String> potentialGroups) {
- this.potentialUsers = potentialUsers;
- this.potentialGroups = potentialGroups;
+ public Notification() {
+ data = new HashMap<>();
}
- public Set<String> getPotentialUsers() {
- return potentialUsers;
+ public Notification(Map<String, Object> data) {
+ this.data = data;
}
- public Set<String> getPotentialGroups() {
- return potentialGroups;
+ public Map<String, Object> getData() {
+ return data;
+ }
+
+ public void setData(Map<String, Object> data) {
+ this.data = data;
}
@Override
public String toString() {
- return "Reassigment [potentialUsers=" + potentialUsers + ", potentialGroups=" + potentialGroups + "]";
+ return "Notification [data=" + data + "]";
}
@Override
public int hashCode() {
- return Objects.hash(potentialGroups, potentialUsers);
+ return Objects.hash(data);
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
- if (!(obj instanceof Reassignment))
+ if (obj == null)
return false;
- Reassignment other = (Reassignment) obj;
- return Objects.equals(potentialGroups, other.potentialGroups) && Objects.equals(potentialUsers,
- other.potentialUsers);
+ if (getClass() != obj.getClass())
+ return false;
+ Notification other = (Notification) obj;
+ return Objects.equals(data, other.data);
}
+
}
diff --git a/api/kogito-api/src/main/java/org/kie/kogito/usertask/model/Reassignment.java b/api/kogito-api/src/main/java/org/kie/kogito/usertask/model/Reassignment.java
index 024532fcf1..89bda5921f 100644
--- a/api/kogito-api/src/main/java/org/kie/kogito/usertask/model/Reassignment.java
+++ b/api/kogito-api/src/main/java/org/kie/kogito/usertask/model/Reassignment.java
@@ -26,6 +26,17 @@ public class Reassignment {
private Set<String> potentialUsers;
private Set<String> potentialGroups;
+ public Reassignment() {
+ }
+
+ public void setPotentialGroups(Set<String> potentialGroups) {
+ this.potentialGroups = potentialGroups;
+ }
+
+ public void setPotentialUsers(Set<String> potentialUsers) {
+ this.potentialUsers = potentialUsers;
+ }
+
public Reassignment(Set<String> potentialUsers, Set<String> potentialGroups) {
this.potentialUsers = potentialUsers;
this.potentialGroups = potentialGroups;
diff --git a/kogito-codegen-modules/kogito-codegen-core/src/main/resources/class-templates/config/ApplicationConfigSpringTemplate.java b/api/kogito-services/src/main/java/org/kie/kogito/services/jobs/impl/InMemoryJobContext.java
similarity index 67%
copy from kogito-codegen-modules/kogito-codegen-core/src/main/resources/class-templates/config/ApplicationConfigSpringTemplate.java
copy to api/kogito-services/src/main/java/org/kie/kogito/services/jobs/impl/InMemoryJobContext.java
index 74e3c06683..ed98f33dda 100644
--- a/kogito-codegen-modules/kogito-codegen-core/src/main/resources/class-templates/config/ApplicationConfigSpringTemplate.java
+++ b/api/kogito-services/src/main/java/org/kie/kogito/services/jobs/impl/InMemoryJobContext.java
@@ -16,16 +16,13 @@
* specific language governing permissions and limitations
* under the License.
*/
-package $Package$;
+package org.kie.kogito.services.jobs.impl;
-import java.util.Collection;
+import org.kie.kogito.internal.process.runtime.KogitoProcessRuntime;
+import org.kie.kogito.process.Processes;
+import org.kie.kogito.uow.UnitOfWorkManager;
+import org.kie.kogito.usertask.UserTasks;
-@org.springframework.stereotype.Component
-public class ApplicationConfig extends org.kie.kogito.StaticConfig {
+public record InMemoryJobContext(KogitoProcessRuntime runtime, UnitOfWorkManager unitOfWorkManager, Processes processes, UserTasks userTasks) {
- @org.springframework.beans.factory.annotation.Autowired
- public ApplicationConfig(
- Collection<org.kie.kogito.KogitoConfig> configs) {
- super($Addons$, configs);
- }
-}
+}
\ No newline at end of file
diff --git a/api/kogito-services/src/main/java/org/kie/kogito/services/jobs/impl/InMemoryJobService.java b/api/kogito-services/src/main/java/org/kie/kogito/services/jobs/impl/InMemoryJobService.java
index c3ea0ad7f8..f48f8b9c2b 100644
--- a/api/kogito-services/src/main/java/org/kie/kogito/services/jobs/impl/InMemoryJobService.java
+++ b/api/kogito-services/src/main/java/org/kie/kogito/services/jobs/impl/InMemoryJobService.java
@@ -20,7 +20,9 @@ package org.kie.kogito.services.jobs.impl;
import java.time.Duration;
import java.time.ZonedDateTime;
-import java.util.Objects;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
import java.util.Optional;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ScheduledExecutorService;
@@ -28,16 +30,8 @@ import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
-import org.kie.kogito.Model;
import org.kie.kogito.jobs.JobDescription;
import org.kie.kogito.jobs.JobsService;
-import org.kie.kogito.jobs.ProcessInstanceJobDescription;
-import org.kie.kogito.jobs.ProcessJobDescription;
-import org.kie.kogito.process.Process;
-import org.kie.kogito.process.ProcessInstanceOptimisticLockingException;
-import org.kie.kogito.process.Processes;
-import org.kie.kogito.services.uow.UnitOfWorkExecutor;
-import org.kie.kogito.uow.UnitOfWorkManager;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -45,74 +39,59 @@ public class InMemoryJobService implements JobsService, AutoCloseable {
public static final String IN_MEMORY_JOB_SERVICE_POOL_SIZE_PROPERTY = "kogito.in-memory.job-service.pool-size";
private static final Logger LOGGER = LoggerFactory.getLogger(InMemoryJobService.class);
- protected static final String TRIGGER = "timer";
- protected final ScheduledExecutorService scheduler;
- protected final UnitOfWorkManager unitOfWorkManager;
+ protected ScheduledExecutorService scheduler;
- protected ConcurrentHashMap<String, ScheduledFuture<?>> scheduledJobs = new ConcurrentHashMap<>();
- private final Processes processes;
+ protected ConcurrentHashMap<String, ScheduledFuture<?>> scheduledJobs;
+ protected List<JobExecutorFactory> jobExecutorFactories;
- private static final ConcurrentHashMap<Integer, InMemoryJobService> INSTANCE = new ConcurrentHashMap<>();
-
- protected InMemoryJobService(Processes processes, UnitOfWorkManager unitOfWorkManager) {
- this(processes, unitOfWorkManager, new ScheduledThreadPoolExecutor(Integer.parseInt(System.getProperty(IN_MEMORY_JOB_SERVICE_POOL_SIZE_PROPERTY, "10"))));
+ public InMemoryJobService() {
+ this(new ScheduledThreadPoolExecutor(Integer.parseInt(System.getProperty(IN_MEMORY_JOB_SERVICE_POOL_SIZE_PROPERTY, "10"))));
}
- protected InMemoryJobService(Processes processes, UnitOfWorkManager unitOfWorkManager, ScheduledExecutorService scheduler) {
- this.processes = processes;
- this.unitOfWorkManager = unitOfWorkManager;
+ public InMemoryJobService(ScheduledExecutorService scheduler) {
+ this.scheduledJobs = new ConcurrentHashMap<>();
+ this.jobExecutorFactories = new ArrayList<>();
this.scheduler = scheduler;
}
- public static InMemoryJobService get(Processes processes, UnitOfWorkManager unitOfWorkManager) {
- Objects.requireNonNull(processes);
- Objects.requireNonNull(unitOfWorkManager);
- return INSTANCE.computeIfAbsent(processes.hashCode() + 7 * unitOfWorkManager.hashCode(), k -> new InMemoryJobService(processes, unitOfWorkManager));
- }
-
- public static InMemoryJobService get(Processes processes, UnitOfWorkManager unitOfWorkManager, ScheduledExecutorService scheduler) {
- Objects.requireNonNull(processes);
- Objects.requireNonNull(unitOfWorkManager);
- Objects.requireNonNull(scheduler);
- return INSTANCE.computeIfAbsent(processes.hashCode() + 7 * unitOfWorkManager.hashCode(), k -> new InMemoryJobService(processes, unitOfWorkManager, scheduler));
+ public InMemoryJobService registerJobExecutorFactory(JobExecutorFactory jobExecutorFactory) {
+ Iterator<JobExecutorFactory> iterator = this.jobExecutorFactories.iterator();
+ while (iterator.hasNext()) {
+ JobExecutorFactory factory = iterator.next();
+ if (factory.types().containsAll(jobExecutorFactory.types())) {
+ iterator.remove();
+ }
+ }
+ this.jobExecutorFactories.add(jobExecutorFactory);
+ return this;
}
@Override
- public String scheduleProcessJob(ProcessJobDescription description) {
- LOGGER.debug("ScheduleProcessJob: {}", description);
+ public String scheduleJob(JobDescription jobDescription) {
+ LOGGER.debug("ScheduleProcessJob: {}", jobDescription);
ScheduledFuture<?> future;
- if (description.expirationTime().repeatInterval() != null) {
- future = scheduler.scheduleAtFixedRate(repeatableProcessJobByDescription(description), calculateDelay(description), description.expirationTime().repeatInterval(), TimeUnit.MILLISECONDS);
- } else {
- future = scheduler.schedule(processJobByDescription(description), calculateDelay(description), TimeUnit.MILLISECONDS);
+ long delay = calculateDelay(jobDescription);
+ Long interval = jobDescription.expirationTime().repeatInterval();
+ Optional<JobExecutorFactory> jobExecutorFactoryFound = findJobExecutorFactory(jobDescription);
+
+ if (jobExecutorFactoryFound.isEmpty()) {
+ throw new IllegalArgumentException("Could not schedule " + jobDescription + ". No job executor factory provided");
}
- scheduledJobs.put(description.id(), future);
- return description.id();
- }
- @Override
- public String scheduleProcessInstanceJob(ProcessInstanceJobDescription description) {
- ScheduledFuture<?> future;
- if (description.expirationTime().repeatInterval() != null) {
- future = scheduler.scheduleAtFixedRate(
- getSignalProcessInstanceCommand(description, false, description.expirationTime().repeatLimit()),
- calculateDelay(description), description.expirationTime().repeatInterval(), TimeUnit.MILLISECONDS);
+ JobExecutorFactory jobExecutorFactory = jobExecutorFactoryFound.get();
+
+ if (interval != null) {
+ future = scheduler.scheduleAtFixedRate(jobExecutorFactory.createNewRepeteableRunnable(this, jobDescription), delay, interval, TimeUnit.MILLISECONDS);
} else {
- future = scheduler.schedule(getSignalProcessInstanceCommand(description, true, 1), calculateDelay(description),
- TimeUnit.MILLISECONDS);
+ future = scheduler.schedule(jobExecutorFactory.createNewRunnable(this, jobDescription), delay, TimeUnit.MILLISECONDS);
}
- scheduledJobs.put(description.id(), future);
- return description.id();
+ scheduledJobs.put(jobDescription.id(), future);
+ return jobDescription.id();
}
- public Runnable getSignalProcessInstanceCommand(ProcessInstanceJobDescription description, boolean remove, int limit) {
- return new SignalProcessInstanceOnExpiredTimer(
- description.id(),
- description.timerId(),
- description.processInstanceId(),
- remove,
- limit);
+ private Optional<JobExecutorFactory> findJobExecutorFactory(JobDescription jobDescription) {
+ return jobExecutorFactories.stream().filter(factory -> factory.accept(jobDescription)).findFirst();
}
@Override
@@ -139,102 +118,15 @@ public class InMemoryJobService implements JobsService, AutoCloseable {
return delay;
}
- protected Runnable processJobByDescription(ProcessJobDescription description) {
- return new StartProcessOnExpiredTimer(description.id(), description.process(), true, -1);
- }
-
- protected Runnable repeatableProcessJobByDescription(ProcessJobDescription description) {
- return new StartProcessOnExpiredTimer(description.id(), description.process(), false, description.expirationTime().repeatLimit());
- }
-
- private class SignalProcessInstanceOnExpiredTimer implements Runnable {
-
- private final String id;
- private final String timerId;
- private boolean removeAtExecution;
- private String processInstanceId;
- private Integer limit;
-
- private SignalProcessInstanceOnExpiredTimer(String id, String timerId, String processInstanceId, boolean removeAtExecution, Integer limit) {
- this.id = id;
- this.timerId = timerId;
- this.processInstanceId = processInstanceId;
- this.removeAtExecution = removeAtExecution;
- this.limit = limit;
- }
-
- @Override
- public void run() {
- try {
- Optional<Process<? extends Model>> process = processes.processByProcessInstanceId(processInstanceId);
- if (process.isEmpty()) {
- LOGGER.info("Skipping Job {}. There is no process for pid {} ", id, processInstanceId);
- return;
- }
- LOGGER.info("Job {} started", id);
- limit--;
- boolean executed = new TriggerJobCommand(processInstanceId, id, timerId, limit, process.get(), unitOfWorkManager).execute();
- if (limit == 0 || !executed) {
- cancelJob(id, false);
- }
- LOGGER.debug("Job {} completed", id);
- } catch (ProcessInstanceOptimisticLockingException ex) {
- LOGGER.info("Retrying Job {} due to: {}", id, ex.getMessage());
- limit++;
- run();
- } finally {
- if (removeAtExecution) {
- cancelJob(id, false);
- }
- }
- }
- }
-
- private class StartProcessOnExpiredTimer implements Runnable {
-
- private final String id;
-
- private boolean removeAtExecution;
- @SuppressWarnings("rawtypes")
- private org.kie.kogito.process.Process process;
-
- private Integer limit;
-
- private StartProcessOnExpiredTimer(String id, org.kie.kogito.process.Process<?> process, boolean removeAtExecution, Integer limit) {
- this.id = id;
- this.process = process;
- this.removeAtExecution = removeAtExecution;
- this.limit = limit;
- }
-
- @SuppressWarnings("unchecked")
- @Override
- public void run() {
- try {
- LOGGER.debug("Job {} started", id);
- UnitOfWorkExecutor.executeInUnitOfWork(unitOfWorkManager, () -> {
- org.kie.kogito.process.ProcessInstance<?> pi = process.createInstance(process.createModel());
- if (pi != null) {
- pi.start(TRIGGER, null);
- }
- return null;
- });
- limit--;
- if (limit == 0) {
- cancelJob(id, true);
- }
- LOGGER.debug("Job {} completed", id);
- } finally {
- if (removeAtExecution) {
- cancelJob(id, false);
- }
- }
- }
- }
-
@Override
public void close() throws Exception {
+ LOGGER.info("closing in memory job service");
scheduledJobs.clear();
- scheduler.shutdown();
+ scheduledJobs.forEach((k, v) -> v.cancel(true));
+ scheduler.shutdownNow();
+ }
+
+ public void clearJobExecutorFactories() {
+ jobExecutorFactories.clear();
}
}
diff --git a/api/kogito-services/src/main/java/org/kie/kogito/services/jobs/impl/InMemoryProcessJobExecutorFactory.java b/api/kogito-services/src/main/java/org/kie/kogito/services/jobs/impl/InMemoryProcessJobExecutorFactory.java
new file mode 100644
index 0000000000..00ed9f8f49
--- /dev/null
+++ b/api/kogito-services/src/main/java/org/kie/kogito/services/jobs/impl/InMemoryProcessJobExecutorFactory.java
@@ -0,0 +1,189 @@
+/*
+ * 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.services.jobs.impl;
+
+import java.util.Optional;
+import java.util.Set;
+
+import org.kie.kogito.Model;
+import org.kie.kogito.jobs.JobDescription;
+import org.kie.kogito.jobs.JobsService;
+import org.kie.kogito.jobs.descriptors.ProcessInstanceJobDescription;
+import org.kie.kogito.jobs.descriptors.ProcessJobDescription;
+import org.kie.kogito.process.Process;
+import org.kie.kogito.process.ProcessInstanceOptimisticLockingException;
+import org.kie.kogito.services.uow.UnitOfWorkExecutor;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class InMemoryProcessJobExecutorFactory implements JobExecutorFactory {
+
+ private InMemoryJobContext jobsConfiguration;
+
+ public InMemoryProcessJobExecutorFactory(InMemoryJobContext jobsConfiguration) {
+ this.jobsConfiguration = jobsConfiguration;
+ }
+
+ @Override
+ public Set<Class<? extends JobDescription>> types() {
+ return Set.of(ProcessInstanceJobDescription.class, ProcessJobDescription.class);
+ }
+
+ @Override
+ public Runnable createNewRunnable(JobsService jobService, JobDescription jobDescription) {
+ if (jobDescription instanceof ProcessInstanceJobDescription processInstanceJobDescription) {
+ return processInstanceJobDescription(jobService, jobsConfiguration, processInstanceJobDescription, true, 1);
+ } else if (jobDescription instanceof ProcessJobDescription processJobDescription) {
+ return processJobByDescription(jobService, jobsConfiguration, processJobDescription);
+ }
+ throw new IllegalArgumentException("single job description not supported for " + jobDescription);
+ }
+
+ @Override
+ public Runnable createNewRepeteableRunnable(JobsService jobService, JobDescription jobDescription) {
+ if (jobDescription instanceof ProcessInstanceJobDescription processInstanceJobDescription) {
+ return processInstanceJobDescription(jobService, jobsConfiguration, processInstanceJobDescription, false, processInstanceJobDescription.expirationTime().repeatLimit());
+ } else if (jobDescription instanceof ProcessJobDescription processJobDescription) {
+ return repeatableJobByDescription(jobService, jobsConfiguration, processJobDescription);
+ }
+ throw new IllegalArgumentException("repeteable job description not supported for " + jobDescription);
+ }
+
+ protected Runnable processInstanceJobDescription(JobsService jobService, InMemoryJobContext jobsConfiguration, ProcessInstanceJobDescription description, boolean remove, int limit) {
+ return new SignalProcessInstanceOnExpiredTimer(
+ jobService,
+ jobsConfiguration,
+ description.id(),
+ description.timerId(),
+ description.processInstanceId(),
+ remove,
+ limit);
+ }
+
+ protected Runnable processJobByDescription(JobsService jobService, InMemoryJobContext jobsConfiguration, ProcessJobDescription description) {
+ return new StartProcessOnExpiredTimer(jobService, jobsConfiguration, description.id(), description.process(), true, -1);
+ }
+
+ protected Runnable repeatableJobByDescription(JobsService jobService, InMemoryJobContext jobsConfiguration, ProcessJobDescription description) {
+ return new StartProcessOnExpiredTimer(jobService, jobsConfiguration, description.id(), description.process(), false, description.expirationTime().repeatLimit());
+ }
+
+}
+
+class SignalProcessInstanceOnExpiredTimer implements Runnable {
+
+ private static Logger LOGGER = LoggerFactory.getLogger(SignalProcessInstanceOnExpiredTimer.class);
+
+ private final String id;
+ private final String timerId;
+ private boolean removeAtExecution;
+ private String processInstanceId;
+ private Integer limit;
+ private JobsService jobService;
+
+ private InMemoryJobContext jobsConfiguration;
+
+ public SignalProcessInstanceOnExpiredTimer(JobsService jobService, InMemoryJobContext jobsConfiguration, String id, String timerId, String processInstanceId, boolean removeAtExecution,
+ Integer limit) {
+ this.id = id;
+ this.timerId = timerId;
+ this.processInstanceId = processInstanceId;
+ this.removeAtExecution = removeAtExecution;
+ this.limit = limit;
+ this.jobsConfiguration = jobsConfiguration;
+ this.jobService = jobService;
+ }
+
+ @Override
+ public void run() {
+ try {
+ Optional<Process<? extends Model>> process = jobsConfiguration.processes().processByProcessInstanceId(processInstanceId);
+ if (process.isEmpty()) {
+ LOGGER.info("Skipping Job {}. There is no process for pid {} ", id, processInstanceId);
+ return;
+ }
+ LOGGER.info("Job {} started", id);
+ limit--;
+ boolean executed = new TriggerJobCommand(processInstanceId, id, timerId, limit, process.get(), jobsConfiguration.unitOfWorkManager()).execute();
+ if (limit == 0 || !executed) {
+ jobService.cancelJob(id);
+ }
+ LOGGER.debug("Job {} completed", id);
+ } catch (ProcessInstanceOptimisticLockingException ex) {
+ LOGGER.info("Retrying Job {} due to: {}", id, ex.getMessage());
+ limit++;
+ run();
+ } finally {
+ if (removeAtExecution) {
+ jobService.cancelJob(id);
+ }
+ }
+ }
+}
+
+class StartProcessOnExpiredTimer implements Runnable {
+
+ private static Logger LOGGER = LoggerFactory.getLogger(StartProcessOnExpiredTimer.class);
+
+ private static final String TRIGGER = "timer";
+
+ private final String id;
+
+ private boolean removeAtExecution;
+ @SuppressWarnings("rawtypes")
+ private org.kie.kogito.process.Process process;
+
+ private Integer limit;
+
+ private JobsService jobService;
+ private InMemoryJobContext jobsConfiguration;
+
+ public StartProcessOnExpiredTimer(JobsService jobService, InMemoryJobContext jobsConfiguration, String id, org.kie.kogito.process.Process<?> process, boolean removeAtExecution, Integer limit) {
+ this.id = id;
+ this.process = process;
+ this.removeAtExecution = removeAtExecution;
+ this.limit = limit;
+ this.jobsConfiguration = jobsConfiguration;
+ this.jobService = jobService;
+ }
+
+ @SuppressWarnings("unchecked")
+ @Override
+ public void run() {
+ try {
+ LOGGER.debug("Job {} started", id);
+ UnitOfWorkExecutor.executeInUnitOfWork(jobsConfiguration.unitOfWorkManager(), () -> {
+ org.kie.kogito.process.ProcessInstance<?> pi = process.createInstance(process.createModel());
+ if (pi != null) {
+ pi.start(TRIGGER, null);
+ }
+ return null;
+ });
+ limit--;
+ if (limit == 0) {
+ jobService.cancelJob(id);
+ }
+ LOGGER.debug("Job {} completed", id);
+ } finally {
+ if (removeAtExecution) {
+ jobService.cancelJob(id);
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/api/kogito-services/src/main/java/org/kie/kogito/services/jobs/impl/InMemoryUserTaskJobExecutorFactory.java b/api/kogito-services/src/main/java/org/kie/kogito/services/jobs/impl/InMemoryUserTaskJobExecutorFactory.java
new file mode 100644
index 0000000000..1381928eba
--- /dev/null
+++ b/api/kogito-services/src/main/java/org/kie/kogito/services/jobs/impl/InMemoryUserTaskJobExecutorFactory.java
@@ -0,0 +1,123 @@
+/*
+ * 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.services.jobs.impl;
+
+import java.util.Optional;
+import java.util.Set;
+
+import org.kie.kogito.jobs.JobDescription;
+import org.kie.kogito.jobs.JobsService;
+import org.kie.kogito.jobs.descriptors.UserTaskInstanceJobDescription;
+import org.kie.kogito.process.ProcessInstanceOptimisticLockingException;
+import org.kie.kogito.usertask.UserTaskInstance;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import static org.kie.kogito.services.uow.UnitOfWorkExecutor.executeInUnitOfWork;
+
+public class InMemoryUserTaskJobExecutorFactory implements JobExecutorFactory {
+
+ private InMemoryJobContext jobsConfiguration;
+
+ public InMemoryUserTaskJobExecutorFactory(InMemoryJobContext jobsConfiguration) {
+ this.jobsConfiguration = jobsConfiguration;
+ }
+
+ @Override
+ public Set<Class<? extends JobDescription>> types() {
+ return Set.of(UserTaskInstanceJobDescription.class);
+ }
+
+ @Override
+ public Runnable createNewRunnable(JobsService jobService, JobDescription jobDescription) {
+ if (jobDescription instanceof UserTaskInstanceJobDescription userTaskInstanceJobDescription) {
+ return userTaskJobDescription(jobService, jobsConfiguration, userTaskInstanceJobDescription);
+ }
+ throw new IllegalArgumentException("single job description not supported for " + jobDescription);
+ }
+
+ @Override
+ public Runnable createNewRepeteableRunnable(JobsService jobService, JobDescription jobDescription) {
+ if (jobDescription instanceof UserTaskInstanceJobDescription userTaskInstanceJobDescription) {
+ return repetableUserTaskJobDescription(jobService, jobsConfiguration, userTaskInstanceJobDescription);
+ }
+ throw new IllegalArgumentException("repeteable job description not supported for " + jobDescription);
+ }
+
+ private Runnable userTaskJobDescription(JobsService jobService, InMemoryJobContext jobsConfiguration, UserTaskInstanceJobDescription userTaskInstanceJobDescription) {
+ return new SignalUserTaskInstanceOnExpiredTimer(jobService, jobsConfiguration, userTaskInstanceJobDescription, true, -1);
+ }
+
+ private Runnable repetableUserTaskJobDescription(JobsService jobService, InMemoryJobContext jobsConfiguration, UserTaskInstanceJobDescription userTaskInstanceJobDescription) {
+ return new SignalUserTaskInstanceOnExpiredTimer(jobService, jobsConfiguration, userTaskInstanceJobDescription, false, userTaskInstanceJobDescription.expirationTime().repeatLimit());
+ }
+
+}
+
+class SignalUserTaskInstanceOnExpiredTimer implements Runnable {
+
+ private static Logger LOGGER = LoggerFactory.getLogger(SignalUserTaskInstanceOnExpiredTimer.class);
+
+ private boolean removeAtExecution;
+ private Integer limit;
+ private JobsService jobService;
+
+ private InMemoryJobContext jobsConfiguration;
+
+ private UserTaskInstanceJobDescription userTaskInstanceJobDescription;
+
+ public SignalUserTaskInstanceOnExpiredTimer(JobsService jobService, InMemoryJobContext jobsConfiguration, UserTaskInstanceJobDescription userTaskInstanceJobDescription, boolean removeAtExecution,
+ Integer limit) {
+ this.userTaskInstanceJobDescription = userTaskInstanceJobDescription;
+ this.removeAtExecution = removeAtExecution;
+ this.limit = limit;
+ this.jobsConfiguration = jobsConfiguration;
+ this.jobService = jobService;
+ }
+
+ @Override
+ public void run() {
+ String jobId = userTaskInstanceJobDescription.id();
+ String userTaskInstanceId = userTaskInstanceJobDescription.getUserTaskInstanceId();
+ try {
+ Optional<UserTaskInstance> userTaskInstance = jobsConfiguration.userTasks().instances().findById(userTaskInstanceId);
+ if (userTaskInstance.isEmpty()) {
+ LOGGER.info("Skipping Job {}. There is no user task instance of id {} ", jobId, userTaskInstanceId);
+ return;
+ }
+ limit--;
+ executeInUnitOfWork(jobsConfiguration.unitOfWorkManager(), () -> {
+ userTaskInstance.get().trigger(userTaskInstanceJobDescription);
+ return null;
+ });
+ if (limit == 0) {
+ jobService.cancelJob(jobId);
+ }
+ LOGGER.debug("Job {} completed", jobId);
+ } catch (ProcessInstanceOptimisticLockingException ex) {
+ LOGGER.info("Retrying Job {} due to: {}", jobId, ex.getMessage());
+ limit++;
+ run();
+ } finally {
+ if (removeAtExecution) {
+ jobService.cancelJob(jobId);
+ }
+ }
+ }
+}
diff --git a/addons/common/jbpm-usertask-storage-jpa/src/main/java/org/jbpm/usertask/jpa/repository/TaskInputRepository.java b/api/kogito-services/src/main/java/org/kie/kogito/services/jobs/impl/JobExecutorFactory.java
similarity index 60%
copy from addons/common/jbpm-usertask-storage-jpa/src/main/java/org/jbpm/usertask/jpa/repository/TaskInputRepository.java
copy to api/kogito-services/src/main/java/org/kie/kogito/services/jobs/impl/JobExecutorFactory.java
index 6e85081ff7..f689e12577 100644
--- a/addons/common/jbpm-usertask-storage-jpa/src/main/java/org/jbpm/usertask/jpa/repository/TaskInputRepository.java
+++ b/api/kogito-services/src/main/java/org/kie/kogito/services/jobs/impl/JobExecutorFactory.java
@@ -16,20 +16,23 @@
* specific language governing permissions and limitations
* under the License.
*/
+package org.kie.kogito.services.jobs.impl;
-package org.jbpm.usertask.jpa.repository;
+import java.util.Set;
-import org.jbpm.usertask.jpa.model.TaskDataEntityPK;
-import org.jbpm.usertask.jpa.model.TaskInputEntity;
+import org.kie.kogito.jobs.JobDescription;
+import org.kie.kogito.jobs.JobsService;
-public class TaskInputRepository extends BaseRepository<TaskInputEntity, TaskDataEntityPK> {
+public interface JobExecutorFactory {
- public TaskInputRepository(UserTaskJPAContext context) {
- super(context);
- }
+ Set<Class<? extends JobDescription>> types();
- @Override
- public Class<TaskInputEntity> getEntityClass() {
- return TaskInputEntity.class;
+ default boolean accept(JobDescription jobDescription) {
+ return types().contains(jobDescription.getClass());
}
+
+ Runnable createNewRunnable(JobsService jobService, JobDescription jobDescription);
+
+ Runnable createNewRepeteableRunnable(JobsService jobService, JobDescription jobDescription);
+
}
diff --git a/api/kogito-services/src/main/java/org/kie/kogito/services/jobs/impl/LegacyInMemoryJobExecutorFactory.java b/api/kogito-services/src/main/java/org/kie/kogito/services/jobs/impl/LegacyInMemoryJobExecutorFactory.java
new file mode 100644
index 0000000000..0700b59528
--- /dev/null
+++ b/api/kogito-services/src/main/java/org/kie/kogito/services/jobs/impl/LegacyInMemoryJobExecutorFactory.java
@@ -0,0 +1,136 @@
+/*
+ * 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.services.jobs.impl;
+
+import java.util.Set;
+import java.util.concurrent.atomic.AtomicInteger;
+
+import org.kie.api.runtime.process.ProcessInstance;
+import org.kie.kogito.internal.process.runtime.KogitoProcessInstance;
+import org.kie.kogito.jobs.JobDescription;
+import org.kie.kogito.jobs.JobsService;
+import org.kie.kogito.jobs.descriptors.ProcessInstanceJobDescription;
+import org.kie.kogito.jobs.descriptors.ProcessJobDescription;
+import org.kie.kogito.services.uow.UnitOfWorkExecutor;
+import org.kie.kogito.timer.TimerInstance;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import static org.kie.kogito.services.jobs.impl.TriggerJobCommand.SIGNAL;
+
+public class LegacyInMemoryJobExecutorFactory implements JobExecutorFactory {
+
+ private static final String TRIGGER = "timer";
+
+ private static Logger LOGGER = LoggerFactory.getLogger(LegacyInMemoryJobExecutorFactory.class);
+
+ private InMemoryJobContext jobsConfiguration;
+
+ public LegacyInMemoryJobExecutorFactory(InMemoryJobContext jobsConfiguration) {
+ this.jobsConfiguration = jobsConfiguration;
+ }
+
+ @Override
+ public Set<Class<? extends JobDescription>> types() {
+ return Set.of(ProcessInstanceJobDescription.class, ProcessJobDescription.class);
+ }
+
+ @Override
+ public Runnable createNewRunnable(JobsService jobService, JobDescription jobDescription) {
+ if (jobDescription instanceof ProcessInstanceJobDescription processInstanceJobDescription) {
+ return processInstanceJobDescription(jobService, jobsConfiguration, processInstanceJobDescription, true, 1);
+ } else if (jobDescription instanceof ProcessJobDescription processJobDescription) {
+ return processJobByDescription(jobService, jobsConfiguration, processJobDescription);
+ }
+ throw new IllegalArgumentException("single job description not supported for " + jobDescription);
+ }
+
+ @Override
+ public Runnable createNewRepeteableRunnable(JobsService jobService, JobDescription jobDescription) {
+ if (jobDescription instanceof ProcessInstanceJobDescription processInstanceJobDescription) {
+ return processInstanceJobDescription(jobService, jobsConfiguration, processInstanceJobDescription, false, processInstanceJobDescription.expirationTime().repeatLimit());
+ } else if (jobDescription instanceof ProcessJobDescription processJobDescription) {
+ return repeatableJobByDescription(jobService, jobsConfiguration, processJobDescription);
+ }
+ throw new IllegalArgumentException("multiple job description not supported for " + jobDescription);
+ }
+
+ protected Runnable processInstanceJobDescription(JobsService jobService, InMemoryJobContext jobsConfiguration, ProcessInstanceJobDescription description, boolean remove, int limit) {
+ String id = description.id();
+ AtomicInteger counter = new AtomicInteger(limit);
+ return () -> {
+ try {
+ UnitOfWorkExecutor.executeInUnitOfWork(jobsConfiguration.unitOfWorkManager(), () -> {
+ ProcessInstance pi = jobsConfiguration.runtime().getProcessInstance(description.processInstanceId());
+ if (pi != null) {
+ pi.signalEvent(SIGNAL, TimerInstance.with(description.id(), description.timerId(), counter.decrementAndGet()));
+ if (counter.get() == 0) {
+ jobService.cancelJob(id);
+ }
+ } else {
+ // since owning process instance does not exist cancel timers
+ jobService.cancelJob(id);
+ }
+ return null;
+ });
+ LOGGER.debug("Job {} completed", id);
+ } finally {
+ if (remove) {
+ jobService.cancelJob(id);
+ }
+ }
+ };
+ }
+
+ protected Runnable processJobByDescription(JobsService jobService, InMemoryJobContext jobsConfiguration, ProcessJobDescription description) {
+ return processCommand(jobService, jobsConfiguration, description, true);
+ }
+
+ protected Runnable repeatableJobByDescription(JobsService jobService, InMemoryJobContext jobsConfiguration, ProcessJobDescription description) {
+ return processCommand(jobService, jobsConfiguration, description, false);
+ }
+
+ private Runnable processCommand(JobsService jobService, InMemoryJobContext jobsConfiguration, ProcessJobDescription description, boolean remove) {
+
+ String id = description.id();
+ AtomicInteger counter = new AtomicInteger(description.expirationTime().repeatLimit());
+ String processId = description.processId();
+ return () -> {
+ try {
+ LOGGER.debug("Job {} started", id);
+ UnitOfWorkExecutor.executeInUnitOfWork(jobsConfiguration.unitOfWorkManager(), () -> {
+ KogitoProcessInstance pi = jobsConfiguration.runtime().createProcessInstance(processId, null);
+ if (pi != null) {
+ jobsConfiguration.runtime().startProcessInstance(pi.getStringId(), TRIGGER);
+ }
+ return null;
+ });
+ if (counter.decrementAndGet() == 0) {
+ jobService.cancelJob(id);
+ }
+ LOGGER.debug("Job {} completed", id);
+ } finally {
+ if (remove) {
+ jobService.cancelJob(id);
+ }
+ }
+ };
+ }
+
+}
diff --git a/api/kogito-services/src/main/java/org/kie/kogito/services/jobs/impl/LegacyInMemoryJobService.java b/api/kogito-services/src/main/java/org/kie/kogito/services/jobs/impl/LegacyInMemoryJobService.java
index 9ef2adcf86..960b96624b 100644
--- a/api/kogito-services/src/main/java/org/kie/kogito/services/jobs/impl/LegacyInMemoryJobService.java
+++ b/api/kogito-services/src/main/java/org/kie/kogito/services/jobs/impl/LegacyInMemoryJobService.java
@@ -18,92 +18,13 @@
*/
package org.kie.kogito.services.jobs.impl;
-import java.util.concurrent.atomic.AtomicInteger;
-
-import org.kie.api.runtime.process.ProcessInstance;
-import org.kie.kogito.internal.process.runtime.KogitoProcessInstance;
import org.kie.kogito.internal.process.runtime.KogitoProcessRuntime;
-import org.kie.kogito.jobs.ProcessInstanceJobDescription;
-import org.kie.kogito.jobs.ProcessJobDescription;
-import org.kie.kogito.services.uow.UnitOfWorkExecutor;
-import org.kie.kogito.timer.TimerInstance;
import org.kie.kogito.uow.UnitOfWorkManager;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import static org.kie.kogito.services.jobs.impl.TriggerJobCommand.SIGNAL;
public class LegacyInMemoryJobService extends InMemoryJobService {
- private static final Logger LOGGER = LoggerFactory.getLogger(LegacyInMemoryJobService.class);
- private KogitoProcessRuntime processRuntime;
-
- public LegacyInMemoryJobService(KogitoProcessRuntime processRuntime, UnitOfWorkManager unitOfWorkManager) {
- super(null, unitOfWorkManager);
- this.processRuntime = processRuntime;
- }
-
- @Override
- public Runnable getSignalProcessInstanceCommand(ProcessInstanceJobDescription description, boolean remove, int limit) {
- String id = description.id();
- AtomicInteger counter = new AtomicInteger(limit);
- return () -> {
- try {
- UnitOfWorkExecutor.executeInUnitOfWork(unitOfWorkManager, () -> {
- ProcessInstance pi = processRuntime.getProcessInstance(description.processInstanceId());
- if (pi != null) {
- pi.signalEvent(SIGNAL, TimerInstance.with(description.id(), description.timerId(), counter.decrementAndGet()));
- if (counter.get() == 0) {
- cancelJob(id, false);
- }
- } else {
- // since owning process instance does not exist cancel timers
- cancelJob(id, false);
- }
- return null;
- });
- LOGGER.debug("Job {} completed", id);
- } finally {
- if (remove) {
- cancelJob(id);
- }
- }
- };
+ public LegacyInMemoryJobService(KogitoProcessRuntime runtime, UnitOfWorkManager unitOfWorkManager) {
+ registerJobExecutorFactory(new LegacyInMemoryJobExecutorFactory(new InMemoryJobContext(runtime, unitOfWorkManager, null, null)));
}
- @Override
- protected Runnable processJobByDescription(ProcessJobDescription description) {
- return processCommand(description, true);
- }
-
- private Runnable processCommand(ProcessJobDescription description, boolean remove) {
- String id = description.id();
- AtomicInteger counter = new AtomicInteger(description.expirationTime().repeatLimit());
- String processId = description.processId();
- return () -> {
- try {
- LOGGER.debug("Job {} started", id);
- UnitOfWorkExecutor.executeInUnitOfWork(unitOfWorkManager, () -> {
- KogitoProcessInstance pi = processRuntime.createProcessInstance(processId, null);
- if (pi != null) {
- processRuntime.startProcessInstance(pi.getStringId(), TRIGGER);
- }
- return null;
- });
- if (counter.decrementAndGet() == 0) {
- cancelJob(id, false);
- }
- LOGGER.debug("Job {} completed", id);
- } finally {
- if (remove) {
- cancelJob(id);
- }
- }
- };
- }
-
- @Override
- protected Runnable repeatableProcessJobByDescription(ProcessJobDescription description) {
- return processCommand(description, false);
- }
}
diff --git a/kogito-codegen-modules/kogito-codegen-core/src/main/resources/class-templates/config/ApplicationConfigJavaTemplate.java b/api/kogito-services/src/main/java/org/kie/kogito/services/jobs/impl/StaticJobService.java
similarity index 73%
copy from kogito-codegen-modules/kogito-codegen-core/src/main/resources/class-templates/config/ApplicationConfigJavaTemplate.java
copy to api/kogito-services/src/main/java/org/kie/kogito/services/jobs/impl/StaticJobService.java
index 64cea466d1..94c8027a34 100644
--- a/kogito-codegen-modules/kogito-codegen-core/src/main/resources/class-templates/config/ApplicationConfigJavaTemplate.java
+++ b/api/kogito-services/src/main/java/org/kie/kogito/services/jobs/impl/StaticJobService.java
@@ -16,11 +16,16 @@
* specific language governing permissions and limitations
* under the License.
*/
-package $Package$;
+package org.kie.kogito.services.jobs.impl;
-public class ApplicationConfig extends org.kie.kogito.StaticConfig {
+public class StaticJobService {
- public ApplicationConfig() {
- super($Addons$ /* additional values provided during codegen */);
+ private static InMemoryJobService INSTANCE;
+
+ public static InMemoryJobService staticJobService() {
+ if (INSTANCE == null) {
+ INSTANCE = new InMemoryJobService();
+ }
+ return INSTANCE;
}
}
diff --git a/kogito-codegen-modules/kogito-codegen-processes/src/main/resources/class-templates/usertask/UserTasksContainerJavaTemplate.java b/api/kogito-services/src/main/java/org/kie/kogito/services/uow/StaticUnitOfWorkManger.java
similarity index 71%
copy from kogito-codegen-modules/kogito-codegen-processes/src/main/resources/class-templates/usertask/UserTasksContainerJavaTemplate.java
copy to api/kogito-services/src/main/java/org/kie/kogito/services/uow/StaticUnitOfWorkManger.java
index 3b5293ac0e..0d4b4b9665 100644
--- a/kogito-codegen-modules/kogito-codegen-processes/src/main/resources/class-templates/usertask/UserTasksContainerJavaTemplate.java
+++ b/api/kogito-services/src/main/java/org/kie/kogito/services/uow/StaticUnitOfWorkManger.java
@@ -16,14 +16,15 @@
* specific language governing permissions and limitations
* under the License.
*/
-package org.kie.kogito.usertask.impl;
+package org.kie.kogito.services.uow;
-import org.kie.kogito.usertask.impl.DefaultUserTasks;
+import org.kie.kogito.uow.UnitOfWorkManager;
-public class UserTasks extends DefaultUserTasks {
+public class StaticUnitOfWorkManger {
- public UserTasks(Application application) {
- super(application);
- }
+ private static final UnitOfWorkManager SINGLETON = new DefaultUnitOfWorkManager(new CollectingUnitOfWorkFactory());
-}
\ No newline at end of file
+ public static UnitOfWorkManager staticUnitOfWorkManager() {
+ return SINGLETON;
+ }
+}
diff --git a/api/kogito-services/src/main/java/org/kie/kogito/services/uow/UnitOfWorkExecutor.java b/api/kogito-services/src/main/java/org/kie/kogito/services/uow/UnitOfWorkExecutor.java
index b9a81aea33..12f792fbee 100644
--- a/api/kogito-services/src/main/java/org/kie/kogito/services/uow/UnitOfWorkExecutor.java
+++ b/api/kogito-services/src/main/java/org/kie/kogito/services/uow/UnitOfWorkExecutor.java
@@ -43,7 +43,6 @@ public class UnitOfWorkExecutor {
return result;
} catch (ProcessInstanceExecutionException e) {
uow.end();
-
throw e;
} catch (Exception e) {
uow.abort();
diff --git a/jbpm/jbpm-bpmn2/src/main/java/org/jbpm/bpmn2/xml/AbstractNodeHandler.java b/jbpm/jbpm-bpmn2/src/main/java/org/jbpm/bpmn2/xml/AbstractNodeHandler.java
index 50eb0f0f9e..e0cea66062 100755
--- a/jbpm/jbpm-bpmn2/src/main/java/org/jbpm/bpmn2/xml/AbstractNodeHandler.java
+++ b/jbpm/jbpm-bpmn2/src/main/java/org/jbpm/bpmn2/xml/AbstractNodeHandler.java
@@ -634,6 +634,10 @@ public abstract class AbstractNodeHandler extends BaseAbstractHandler implements
}
private String cleanUp(String expression) {
+ // this is for user task expressions (they should be set as it is)
+ if (expression.startsWith("[")) {
+ return expression;
+ }
Matcher matcher = PatternConstants.PARAMETER_MATCHER.matcher(expression);
String temp = expression;
if (matcher.find()) {
diff --git a/jbpm/jbpm-bpmn2/src/main/java/org/kie/kogito/process/bpmn2/BpmnProcess.java b/jbpm/jbpm-bpmn2/src/main/java/org/kie/kogito/process/bpmn2/BpmnProcess.java
index df188e2b2e..bb61669e9b 100644
--- a/jbpm/jbpm-bpmn2/src/main/java/org/kie/kogito/process/bpmn2/BpmnProcess.java
+++ b/jbpm/jbpm-bpmn2/src/main/java/org/kie/kogito/process/bpmn2/BpmnProcess.java
@@ -37,8 +37,8 @@ import org.kie.kogito.process.impl.AbstractProcess;
import org.kie.kogito.process.impl.DefaultProcessEventListenerConfig;
import org.kie.kogito.process.impl.DefaultWorkItemHandlerConfig;
import org.kie.kogito.process.impl.StaticProcessConfig;
-import org.kie.kogito.services.uow.CollectingUnitOfWorkFactory;
-import org.kie.kogito.services.uow.DefaultUnitOfWorkManager;
+
+import static org.kie.kogito.services.uow.StaticUnitOfWorkManger.staticUnitOfWorkManager;
public class BpmnProcess extends AbstractProcess<BpmnVariables> {
@@ -127,7 +127,7 @@ public class BpmnProcess extends AbstractProcess<BpmnVariables> {
}
public static List<BpmnProcess> from(WorkItemHandlerConfig config, Resource... resource) {
- return from(new StaticProcessConfig(config, new DefaultProcessEventListenerConfig(), new DefaultUnitOfWorkManager(new CollectingUnitOfWorkFactory())), resource);
+ return from(new StaticProcessConfig(config, new DefaultProcessEventListenerConfig(), staticUnitOfWorkManager()), resource);
}
public static List<BpmnProcess> from(ProcessConfig config, Resource... resources) {
diff --git a/jbpm/jbpm-flow/pom.xml b/jbpm/jbpm-flow/pom.xml
index d0fc15edb2..0da528e8e2 100755
--- a/jbpm/jbpm-flow/pom.xml
+++ b/jbpm/jbpm-flow/pom.xml
@@ -152,6 +152,11 @@
<artifactId>assertj-core</artifactId>
<scope>test</scope>
</dependency>
+ <dependency>
+ <groupId>org.awaitility</groupId>
+ <artifactId>awaitility</artifactId>
+ <scope>test</scope>
+ </dependency>
</dependencies>
<profiles>
diff --git a/jbpm/jbpm-flow/src/main/java/org/jbpm/process/instance/AbstractProcessRuntime.java b/jbpm/jbpm-flow/src/main/java/org/jbpm/process/instance/AbstractProcessRuntime.java
index cb388bb361..2223cd5687 100644
--- a/jbpm/jbpm-flow/src/main/java/org/jbpm/process/instance/AbstractProcessRuntime.java
+++ b/jbpm/jbpm-flow/src/main/java/org/jbpm/process/instance/AbstractProcessRuntime.java
@@ -42,7 +42,7 @@ import org.kie.kogito.jobs.DurationExpirationTime;
import org.kie.kogito.jobs.ExactExpirationTime;
import org.kie.kogito.jobs.ExpirationTime;
import org.kie.kogito.jobs.JobsService;
-import org.kie.kogito.jobs.ProcessJobDescription;
+import org.kie.kogito.jobs.descriptors.ProcessJobDescription;
import org.kie.kogito.signal.SignalManager;
import static org.jbpm.process.core.constants.CalendarConstants.BUSINESS_CALENDAR_ENVIRONMENT_KEY;
@@ -100,7 +100,7 @@ public abstract class AbstractProcessRuntime implements InternalProcessRuntime {
if (startNodes != null && !startNodes.isEmpty()) {
for (StartNode startNode : startNodes) {
if (startNode != null && startNode.getTimer() != null) {
- jobService.scheduleProcessJob(ProcessJobDescription.of(createTimerInstance(startNode.getTimer(), kruntime), p.getId()));
+ jobService.scheduleJob(ProcessJobDescription.of(createTimerInstance(startNode.getTimer(), kruntime), p.getId()));
}
}
}
diff --git a/jbpm/jbpm-flow/src/main/java/org/jbpm/process/instance/LightProcessRuntime.java b/jbpm/jbpm-flow/src/main/java/org/jbpm/process/instance/LightProcessRuntime.java
index a972d72daf..7c1a43e5c8 100755
--- a/jbpm/jbpm-flow/src/main/java/org/jbpm/process/instance/LightProcessRuntime.java
+++ b/jbpm/jbpm-flow/src/main/java/org/jbpm/process/instance/LightProcessRuntime.java
@@ -51,8 +51,6 @@ import org.kie.kogito.Application;
import org.kie.kogito.internal.process.runtime.KogitoProcessInstance;
import org.kie.kogito.internal.process.workitem.KogitoWorkItemManager;
import org.kie.kogito.jobs.JobsService;
-import org.kie.kogito.process.Processes;
-import org.kie.kogito.services.jobs.impl.InMemoryJobService;
import org.kie.kogito.signal.SignalManager;
import org.kie.kogito.uow.UnitOfWorkManager;
@@ -81,7 +79,7 @@ public class LightProcessRuntime extends AbstractProcessRuntime {
this.runtimeContext = runtimeContext;
this.processInstanceManager = services.getProcessInstanceManager();
this.signalManager = services.getSignalManager();
- this.jobService = services.getJobsService() == null ? InMemoryJobService.get(application.get(Processes.class), this.unitOfWorkManager) : services.getJobsService();
+ this.jobService = services.getJobsService();
this.processEventSupport = services.getEventSupport();
this.workItemManager = services.getKogitoWorkItemManager();
if (isActive()) {
@@ -144,9 +142,7 @@ public class LightProcessRuntime extends AbstractProcessRuntime {
@Override
public KogitoProcessInstance createProcessInstance(String processId, CorrelationKey correlationKey, Map<String, Object> parameters) {
return createProcessInstance(
- runtimeContext.findProcess(processId)
- .orElseThrow(() -> new IllegalArgumentException(
- "Unknown process ID: " + processId)),
+ runtimeContext.findProcess(processId).orElseThrow(() -> new IllegalArgumentException("Unknown process ID: " + processId)),
correlationKey, parameters);
}
diff --git a/jbpm/jbpm-flow/src/main/java/org/jbpm/workflow/core/node/AsyncEventNodeInstance.java b/jbpm/jbpm-flow/src/main/java/org/jbpm/workflow/core/node/AsyncEventNodeInstance.java
index f96f9476ad..59cc4263c8 100644
--- a/jbpm/jbpm-flow/src/main/java/org/jbpm/workflow/core/node/AsyncEventNodeInstance.java
+++ b/jbpm/jbpm-flow/src/main/java/org/jbpm/workflow/core/node/AsyncEventNodeInstance.java
@@ -33,7 +33,7 @@ import org.kie.kogito.internal.process.runtime.KogitoNodeInstance;
import org.kie.kogito.jobs.ExactExpirationTime;
import org.kie.kogito.jobs.ExpirationTime;
import org.kie.kogito.jobs.JobsService;
-import org.kie.kogito.jobs.ProcessInstanceJobDescription;
+import org.kie.kogito.jobs.descriptors.ProcessInstanceJobDescription;
import org.kie.kogito.process.ProcessInstance;
import org.kie.kogito.services.uow.BaseWorkUnit;
import org.kie.kogito.timer.TimerInstance;
@@ -99,7 +99,7 @@ public class AsyncEventNodeInstance extends EventNodeInstance {
new BaseWorkUnit<>(this, instance -> {
ExpirationTime expirationTime = ExactExpirationTime.of(ZonedDateTime.now().plus(1, ChronoUnit.MILLIS));
ProcessInstanceJobDescription jobDescription =
- ProcessInstanceJobDescription.builder()
+ ProcessInstanceJobDescription.newProcessInstanceJobDescriptionBuilder()
.id(getJobId())
.timerId("-1")
.expirationTime(expirationTime)
@@ -110,7 +110,7 @@ public class AsyncEventNodeInstance extends EventNodeInstance {
.nodeInstanceId(Optional.ofNullable(from).map(KogitoNodeInstance::getStringId).orElse(null))
.build();
JobsService jobService = processRuntime.getJobsService();
- String jobId = jobService.scheduleProcessInstanceJob(jobDescription);
+ String jobId = jobService.scheduleJob(jobDescription);
setJobId(jobId);
}, i -> {
}, WorkUnit.LOW_PRIORITY));
diff --git a/jbpm/jbpm-flow/src/main/java/org/jbpm/workflow/core/node/HumanTaskNode.java b/jbpm/jbpm-flow/src/main/java/org/jbpm/workflow/core/node/HumanTaskNode.java
index 872276850a..1632732093 100755
--- a/jbpm/jbpm-flow/src/main/java/org/jbpm/workflow/core/node/HumanTaskNode.java
+++ b/jbpm/jbpm-flow/src/main/java/org/jbpm/workflow/core/node/HumanTaskNode.java
@@ -38,9 +38,9 @@ public class HumanTaskNode extends WorkItemNode {
"TaskName",
"NodeName",
"NotStartedNotify",
+ "NotStartedReassign",
"NotCompletedNotify",
"NotCompletedReassign",
- "NotStartedReassign",
"Description",
"Comment",
"ActorId",
diff --git a/jbpm/jbpm-flow/src/main/java/org/jbpm/workflow/instance/impl/WorkflowProcessInstanceImpl.java b/jbpm/jbpm-flow/src/main/java/org/jbpm/workflow/instance/impl/WorkflowProcessInstanceImpl.java
index 27a67f296e..aa68a09c33 100755
--- a/jbpm/jbpm-flow/src/main/java/org/jbpm/workflow/instance/impl/WorkflowProcessInstanceImpl.java
+++ b/jbpm/jbpm-flow/src/main/java/org/jbpm/workflow/instance/impl/WorkflowProcessInstanceImpl.java
@@ -95,7 +95,7 @@ import org.kie.kogito.internal.process.runtime.KogitoWorkflowProcess;
import org.kie.kogito.internal.process.runtime.MessageException;
import org.kie.kogito.jobs.DurationExpirationTime;
import org.kie.kogito.jobs.JobsService;
-import org.kie.kogito.jobs.ProcessInstanceJobDescription;
+import org.kie.kogito.jobs.descriptors.ProcessInstanceJobDescription;
import org.kie.kogito.process.BaseEventDescription;
import org.kie.kogito.process.EventDescription;
import org.kie.kogito.process.NamedDataType;
@@ -599,7 +599,7 @@ public abstract class WorkflowProcessInstanceImpl extends ProcessInstanceImpl im
private TimerInstance registerTimer(TimerInstance timerInstance) {
ProcessInstanceJobDescription description =
- ProcessInstanceJobDescription.builder()
+ ProcessInstanceJobDescription.newProcessInstanceJobDescriptionBuilder()
.id(timerInstance.getId())
.timerId(timerInstance.getTimerId())
.expirationTime(DurationExpirationTime.after(timerInstance.getDelay()))
@@ -607,7 +607,7 @@ public abstract class WorkflowProcessInstanceImpl extends ProcessInstanceImpl im
.processId(getProcessId())
.build();
JobsService jobsService = InternalProcessRuntime.asKogitoProcessRuntime(getKnowledgeRuntime().getProcessRuntime()).getJobsService();
- jobsService.scheduleProcessInstanceJob(description);
+ jobsService.scheduleJob(description);
return timerInstance;
}
diff --git a/jbpm/jbpm-flow/src/main/java/org/jbpm/workflow/instance/node/StateBasedNodeInstance.java b/jbpm/jbpm-flow/src/main/java/org/jbpm/workflow/instance/node/StateBasedNodeInstance.java
index 2b0517718c..c03ce5c437 100755
--- a/jbpm/jbpm-flow/src/main/java/org/jbpm/workflow/instance/node/StateBasedNodeInstance.java
+++ b/jbpm/jbpm-flow/src/main/java/org/jbpm/workflow/instance/node/StateBasedNodeInstance.java
@@ -52,7 +52,7 @@ import org.kie.kogito.jobs.DurationExpirationTime;
import org.kie.kogito.jobs.ExactExpirationTime;
import org.kie.kogito.jobs.ExpirationTime;
import org.kie.kogito.jobs.JobsService;
-import org.kie.kogito.jobs.ProcessInstanceJobDescription;
+import org.kie.kogito.jobs.descriptors.ProcessInstanceJobDescription;
import org.kie.kogito.process.expr.Expression;
import org.kie.kogito.process.expr.ExpressionHandlerFactory;
import org.kie.kogito.timer.TimerInstance;
@@ -95,7 +95,7 @@ public abstract class StateBasedNodeInstance extends ExtendedNodeInstanceImpl im
JobsService jobService = ((KogitoProcessRuntime.Provider) getProcessInstance().getKnowledgeRuntime().getProcessRuntime()).getKogitoProcessRuntime().getJobsService();
for (Timer timer : timers.keySet()) {
ProcessInstanceJobDescription jobDescription =
- ProcessInstanceJobDescription.builder()
+ ProcessInstanceJobDescription.newProcessInstanceJobDescriptionBuilder()
.generateId()
.timerId(Long.toString(timer.getId()))
.expirationTime(createTimerInstance(timer))
@@ -105,7 +105,7 @@ public abstract class StateBasedNodeInstance extends ExtendedNodeInstanceImpl im
.processInstanceId(getProcessInstance().getStringId())
.nodeInstanceId(this.getId())
.build();
- String jobId = jobService.scheduleProcessInstanceJob(jobDescription);
+ String jobId = jobService.scheduleJob(jobDescription);
timerInstances.add(jobId);
timerInstancesReference.put(jobId, Long.toString(timer.getId()));
}
diff --git a/jbpm/jbpm-flow/src/main/java/org/jbpm/workflow/instance/node/TimerNodeInstance.java b/jbpm/jbpm-flow/src/main/java/org/jbpm/workflow/instance/node/TimerNodeInstance.java
index 452e978528..5ca0c76a28 100755
--- a/jbpm/jbpm-flow/src/main/java/org/jbpm/workflow/instance/node/TimerNodeInstance.java
+++ b/jbpm/jbpm-flow/src/main/java/org/jbpm/workflow/instance/node/TimerNodeInstance.java
@@ -36,7 +36,7 @@ import org.kie.kogito.internal.process.runtime.KogitoNodeInstance;
import org.kie.kogito.internal.process.workitem.WorkItemExecutionException;
import org.kie.kogito.jobs.ExpirationTime;
import org.kie.kogito.jobs.JobsService;
-import org.kie.kogito.jobs.ProcessInstanceJobDescription;
+import org.kie.kogito.jobs.descriptors.ProcessInstanceJobDescription;
import org.kie.kogito.process.BaseEventDescription;
import org.kie.kogito.process.EventDescription;
import org.kie.kogito.services.uow.BaseWorkUnit;
@@ -82,7 +82,7 @@ public class TimerNodeInstance extends StateBasedNodeInstance implements EventLi
processRuntime.getUnitOfWorkManager().currentUnitOfWork().intercept(
new BaseWorkUnit<>(this, instance -> {
ProcessInstanceJobDescription jobDescription =
- ProcessInstanceJobDescription.builder()
+ ProcessInstanceJobDescription.newProcessInstanceJobDescriptionBuilder()
.id(getTimerId())
.timerId("-1")
.expirationTime(expirationTime)
@@ -93,7 +93,7 @@ public class TimerNodeInstance extends StateBasedNodeInstance implements EventLi
.nodeInstanceId(this.getId())
.build();
JobsService jobService = processRuntime.getJobsService();
- String jobId = jobService.scheduleProcessInstanceJob(jobDescription);
+ String jobId = jobService.scheduleJob(jobDescription);
internalSetTimerId(jobId);
}, i -> {
}, WorkUnit.LOW_PRIORITY));
diff --git a/jbpm/jbpm-flow/src/main/java/org/kie/kogito/process/impl/AbstractProcess.java b/jbpm/jbpm-flow/src/main/java/org/kie/kogito/process/impl/AbstractProcess.java
index 96ec9a0e65..89e3193c79 100644
--- a/jbpm/jbpm-flow/src/main/java/org/kie/kogito/process/impl/AbstractProcess.java
+++ b/jbpm/jbpm-flow/src/main/java/org/kie/kogito/process/impl/AbstractProcess.java
@@ -57,7 +57,7 @@ import org.kie.kogito.internal.utils.ConversionUtils;
import org.kie.kogito.jobs.DurationExpirationTime;
import org.kie.kogito.jobs.ExactExpirationTime;
import org.kie.kogito.jobs.ExpirationTime;
-import org.kie.kogito.jobs.ProcessJobDescription;
+import org.kie.kogito.jobs.descriptors.ProcessJobDescription;
import org.kie.kogito.process.MutableProcessInstances;
import org.kie.kogito.process.Process;
import org.kie.kogito.process.ProcessConfig;
@@ -227,7 +227,7 @@ public abstract class AbstractProcess<T extends Model> implements Process<T>, Pr
if (startNodes != null && !startNodes.isEmpty()) {
for (StartNode startNode : startNodes) {
if (startNode != null && startNode.getTimer() != null) {
- String timerId = processRuntime.getJobsService().scheduleProcessJob(ProcessJobDescription.of(configureTimerInstance(startNode.getTimer()), this));
+ String timerId = processRuntime.getJobsService().scheduleJob(ProcessJobDescription.of(configureTimerInstance(startNode.getTimer()), this));
startTimerInstances.add(timerId);
}
}
diff --git a/jbpm/jbpm-flow/src/main/java/org/kie/kogito/process/impl/AbstractProcessConfig.java b/jbpm/jbpm-flow/src/main/java/org/kie/kogito/process/impl/AbstractProcessConfig.java
index ac13e65942..826efc66d4 100644
--- a/jbpm/jbpm-flow/src/main/java/org/kie/kogito/process/impl/AbstractProcessConfig.java
+++ b/jbpm/jbpm-flow/src/main/java/org/kie/kogito/process/impl/AbstractProcessConfig.java
@@ -36,6 +36,7 @@ import org.kie.kogito.process.ProcessEventListenerConfig;
import org.kie.kogito.process.ProcessVersionResolver;
import org.kie.kogito.process.WorkItemHandlerConfig;
import org.kie.kogito.services.identity.NoOpIdentityProvider;
+import org.kie.kogito.services.jobs.impl.StaticJobService;
import org.kie.kogito.services.signal.DefaultSignalManagerHub;
import org.kie.kogito.services.uow.CollectingUnitOfWorkFactory;
import org.kie.kogito.services.uow.DefaultUnitOfWorkManager;
@@ -69,10 +70,8 @@ public abstract class AbstractProcessConfig implements ProcessConfig {
this.workItemHandlerConfig = mergeWorkItemHandler(workItemHandlerConfig, DefaultWorkItemHandlerConfig::new);
this.processEventListenerConfig = merge(processEventListenerConfigs, processEventListeners);
- this.unitOfWorkManager = orDefault(unitOfWorkManager,
- () -> new DefaultUnitOfWorkManager(
- new CollectingUnitOfWorkFactory()));
- this.jobsService = orDefault(jobsService, () -> null);
+ this.unitOfWorkManager = orDefault(unitOfWorkManager, () -> new DefaultUnitOfWorkManager(new CollectingUnitOfWorkFactory()));
+ this.jobsService = orDefault(jobsService, StaticJobService::staticJobService);
this.versionResolver = orDefault(versionResolver, () -> null);
this.identityProvider = orDefault(identityProvider, NoOpIdentityProvider::new);
this.businessCalendar = orDefault(businessCalendar, () -> null);
diff --git a/jbpm/jbpm-flow/src/main/java/org/kie/kogito/process/impl/StaticProcessConfig.java b/jbpm/jbpm-flow/src/main/java/org/kie/kogito/process/impl/StaticProcessConfig.java
index 343f232a04..55f688757b 100644
--- a/jbpm/jbpm-flow/src/main/java/org/kie/kogito/process/impl/StaticProcessConfig.java
+++ b/jbpm/jbpm-flow/src/main/java/org/kie/kogito/process/impl/StaticProcessConfig.java
@@ -27,11 +27,12 @@ import org.kie.kogito.process.ProcessVersionResolver;
import org.kie.kogito.process.WorkItemHandlerConfig;
import org.kie.kogito.services.identity.NoOpIdentityProvider;
import org.kie.kogito.services.signal.DefaultSignalManagerHub;
-import org.kie.kogito.services.uow.CollectingUnitOfWorkFactory;
-import org.kie.kogito.services.uow.DefaultUnitOfWorkManager;
import org.kie.kogito.signal.SignalManagerHub;
import org.kie.kogito.uow.UnitOfWorkManager;
+import static org.kie.kogito.services.jobs.impl.StaticJobService.staticJobService;
+import static org.kie.kogito.services.uow.StaticUnitOfWorkManger.staticUnitOfWorkManager;
+
public class StaticProcessConfig implements ProcessConfig {
private final WorkItemHandlerConfig workItemHandlerConfig;
@@ -44,11 +45,21 @@ public class StaticProcessConfig implements ProcessConfig {
private final IdentityProvider identityProvider;
private final BusinessCalendar businessCalendar;
+ public StaticProcessConfig(JobsService jobService) {
+ this(new DefaultWorkItemHandlerConfig(),
+ new DefaultProcessEventListenerConfig(),
+ staticUnitOfWorkManager(),
+ jobService,
+ null,
+ new NoOpIdentityProvider(),
+ null);
+ }
+
public StaticProcessConfig(
WorkItemHandlerConfig workItemHandlerConfig,
ProcessEventListenerConfig processEventListenerConfig,
UnitOfWorkManager unitOfWorkManager) {
- this(workItemHandlerConfig, processEventListenerConfig, unitOfWorkManager, null, null, new NoOpIdentityProvider(), null);
+ this(workItemHandlerConfig, processEventListenerConfig, unitOfWorkManager, staticJobService(), null, new NoOpIdentityProvider(), null);
}
public StaticProcessConfig(
@@ -72,8 +83,8 @@ public class StaticProcessConfig implements ProcessConfig {
public StaticProcessConfig() {
this(new DefaultWorkItemHandlerConfig(),
new DefaultProcessEventListenerConfig(),
- new DefaultUnitOfWorkManager(new CollectingUnitOfWorkFactory()),
- null,
+ staticUnitOfWorkManager(),
+ staticJobService(),
null,
new NoOpIdentityProvider(),
null);
diff --git a/jbpm/jbpm-flow/src/test/java/org/jbpm/process/TimerTest.java b/jbpm/jbpm-flow/src/test/java/org/jbpm/process/TimerTest.java
index 67f835b37a..93f0279d81 100755
--- a/jbpm/jbpm-flow/src/test/java/org/jbpm/process/TimerTest.java
+++ b/jbpm/jbpm-flow/src/test/java/org/jbpm/process/TimerTest.java
@@ -18,6 +18,7 @@
*/
package org.jbpm.process;
+import java.time.Duration;
import java.util.concurrent.TimeUnit;
import org.drools.core.common.InternalWorkingMemory;
@@ -26,21 +27,19 @@ import org.jbpm.process.instance.InternalProcessRuntime;
import org.jbpm.process.instance.ProcessRuntimeFactoryServiceImpl;
import org.jbpm.ruleflow.instance.RuleFlowProcessInstance;
import org.jbpm.test.util.AbstractBaseTest;
-import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.Timeout;
import org.kie.kogito.internal.process.runtime.KogitoProcessRuntime;
import org.kie.kogito.jobs.DurationExpirationTime;
import org.kie.kogito.jobs.ExactExpirationTime;
-import org.kie.kogito.jobs.JobsService;
-import org.kie.kogito.jobs.ProcessInstanceJobDescription;
+import org.kie.kogito.jobs.descriptors.ProcessInstanceJobDescription;
import org.kie.kogito.services.jobs.impl.LegacyInMemoryJobService;
-import org.kie.kogito.services.uow.CollectingUnitOfWorkFactory;
-import org.kie.kogito.services.uow.DefaultUnitOfWorkManager;
+import org.kie.kogito.services.uow.StaticUnitOfWorkManger;
import org.kie.kogito.timer.TimerInstance;
import org.slf4j.LoggerFactory;
import static org.assertj.core.api.Assertions.assertThat;
+import static org.awaitility.Awaitility.await;
import static org.jbpm.workflow.instance.node.TimerNodeInstance.TIMER_TRIGGERED_EVENT;
public class TimerTest extends AbstractBaseTest {
@@ -57,95 +56,75 @@ public class TimerTest extends AbstractBaseTest {
@Test
@Timeout(value = 10L, unit = TimeUnit.SECONDS)
- @Disabled
- public void testTimer() {
+ public void testTimer() throws Exception {
KogitoProcessRuntime kruntime = createKogitoProcessRuntime();
-
- RuleFlowProcessInstance processInstance = new RuleFlowProcessInstance() {
- private static final long serialVersionUID = 510l;
-
- public void signalEvent(String type, Object event) {
- if (TIMER_TRIGGERED_EVENT.equals(type)) {
- TimerInstance timer = (TimerInstance) event;
- logger.info("Timer {} triggered", timer.getId());
- counter++;
+ try (LegacyInMemoryJobService jobService = new LegacyInMemoryJobService(kruntime, StaticUnitOfWorkManger.staticUnitOfWorkManager());) {
+ RuleFlowProcessInstance processInstance = new RuleFlowProcessInstance() {
+ private static final long serialVersionUID = 510l;
+
+ public void signalEvent(String type, Object event) {
+ if (TIMER_TRIGGERED_EVENT.equals(type)) {
+ TimerInstance timer = (TimerInstance) event;
+ logger.info("Timer {} triggered", timer.getId());
+ counter++;
+ }
}
- }
- };
- processInstance.setKnowledgeRuntime(((InternalWorkingMemory) kruntime.getKieSession()).getKnowledgeRuntime());
- processInstance.setId("1234");
- InternalProcessRuntime processRuntime = ((InternalProcessRuntime) ((InternalWorkingMemory) kruntime.getKieSession()).getProcessRuntime());
- processRuntime.getProcessInstanceManager().internalAddProcessInstance(processInstance);
-
- new Thread(() -> kruntime.getKieSession().fireUntilHalt()).start();
- JobsService jobService = new LegacyInMemoryJobService(kruntime, new DefaultUnitOfWorkManager(new CollectingUnitOfWorkFactory()));
-
- ProcessInstanceJobDescription desc = ProcessInstanceJobDescription.builder()
- .expirationTime(ExactExpirationTime.now())
- .processInstanceId(processInstance.getStringId())
- .processId("test")
- .id("job1")
- .timerId("timer1")
- .build();
- jobService.scheduleProcessInstanceJob(desc);
-
- try {
- Thread.sleep(1000);
- } catch (InterruptedException e) {
- // do nothing
- }
- assertThat(counter).isEqualTo(1);
-
- counter = 0;
- desc = ProcessInstanceJobDescription.builder()
- .expirationTime(DurationExpirationTime.after(500))
- .processInstanceId(processInstance.getStringId())
- .processId("test")
- .id("job2")
- .timerId("timer2")
- .build();
- jobService.scheduleProcessInstanceJob(desc);
- assertThat(counter).isZero();
- try {
- Thread.sleep(1000);
- } catch (InterruptedException e) {
- // do nothing
- }
- assertThat(counter).isEqualTo(1);
-
- counter = 0;
- desc = ProcessInstanceJobDescription.builder()
- .expirationTime(DurationExpirationTime.repeat(500, 300L))
- .processInstanceId(processInstance.getStringId())
- .processId("test")
- .id("job3")
- .timerId("timer3")
- .build();
- String jobId = jobService.scheduleProcessInstanceJob(desc);
- assertThat(counter).isZero();
- try {
- Thread.sleep(700);
- } catch (InterruptedException e) {
- // do nothing
- }
- assertThat(counter).isEqualTo(1);
+ };
+ processInstance.setKnowledgeRuntime(((InternalWorkingMemory) kruntime.getKieSession()).getKnowledgeRuntime());
+ processInstance.setId("1234");
+ InternalProcessRuntime processRuntime = ((InternalProcessRuntime) ((InternalWorkingMemory) kruntime.getKieSession()).getProcessRuntime());
+ processRuntime.getProcessInstanceManager().internalAddProcessInstance(processInstance);
+
+ new Thread(() -> kruntime.getKieSession().fireUntilHalt()).start();
+
+ ProcessInstanceJobDescription desc = ProcessInstanceJobDescription.newProcessInstanceJobDescriptionBuilder()
+ .expirationTime(ExactExpirationTime.now())
+ .processInstanceId(processInstance.getStringId())
+ .processId("test")
+ .id("job1")
+ .timerId("timer1")
+ .build();
+ jobService.scheduleJob(desc);
+
+ await().atMost(Duration.ofSeconds(5L)).until(() -> counter == 1);
+ assertThat(counter).isEqualTo(1);
+
+ counter = 0;
+ desc = ProcessInstanceJobDescription.newProcessInstanceJobDescriptionBuilder()
+ .expirationTime(DurationExpirationTime.after(500))
+ .processInstanceId(processInstance.getStringId())
+ .processId("test")
+ .id("job2")
+ .timerId("timer2")
+ .build();
+ jobService.scheduleJob(desc);
+ assertThat(counter).isZero();
+ await().atMost(Duration.ofSeconds(5L)).until(() -> counter == 1);
+ assertThat(counter).isEqualTo(1);
+
+ counter = 0;
+ desc = ProcessInstanceJobDescription.newProcessInstanceJobDescriptionBuilder()
+ .expirationTime(DurationExpirationTime.repeat(500, 300L))
+ .processInstanceId(processInstance.getStringId())
+ .processId("test")
+ .id("job3")
+ .timerId("timer3")
+ .build();
+ String jobId = jobService.scheduleJob(desc);
+ assertThat(counter).isZero();
+
+ await().atMost(Duration.ofSeconds(5L)).until(() -> counter == 1);
+ assertThat(counter).isEqualTo(1);
+
+ await().atMost(Duration.ofSeconds(5L)).until(() -> counter == 4);
+ assertThat(counter).isEqualTo(4);
+
+ jobService.cancelJob(jobId);
+ int lastCount = counter;
+ // value is preserved
+ await().during(Duration.ofSeconds(2L)).until(() -> counter == lastCount);
- try {
- Thread.sleep(1000);
- } catch (InterruptedException e) {
- // do nothing
- }
- // we can't know exactly how many times this will fire as timers are not precise, but should be at least 4
- assertThat(counter >= 4).isTrue();
-
- jobService.cancelJob(jobId);
- int lastCount = counter;
- try {
- Thread.sleep(1000);
- } catch (InterruptedException e) {
- // do nothing
}
- assertThat(counter).isEqualTo(lastCount);
}
}
diff --git a/jbpm/jbpm-tests/src/test/java/org/jbpm/bpmn2/calendar/BusinessCalendarTest.java b/jbpm/jbpm-tests/src/test/java/org/jbpm/bpmn2/calendar/BusinessCalendarTest.java
index c89cc7a824..0ca0a9bde8 100644
--- a/jbpm/jbpm-tests/src/test/java/org/jbpm/bpmn2/calendar/BusinessCalendarTest.java
+++ b/jbpm/jbpm-tests/src/test/java/org/jbpm/bpmn2/calendar/BusinessCalendarTest.java
@@ -32,12 +32,8 @@ import org.jbpm.test.utils.ProcessTestHelper;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
import org.kie.kogito.Application;
-import org.kie.kogito.StaticApplication;
-import org.kie.kogito.StaticConfig;
import org.kie.kogito.calendar.BusinessCalendar;
-import org.kie.kogito.process.ProcessConfig;
import org.kie.kogito.process.ProcessInstance;
-import org.kie.kogito.process.bpmn2.BpmnProcesses;
import org.kie.kogito.process.impl.AbstractProcessConfig;
import static org.assertj.core.api.Assertions.assertThat;
@@ -55,9 +51,7 @@ public class BusinessCalendarTest {
@Test
public void testTimerWithWorkingDayCalendar() throws InterruptedException {
- BpmnProcesses bpmnProcesses = new BpmnProcesses();
- ProcessConfig config = new MockProcessConfig(workingDayCalendar);
- Application app = new StaticApplication(new StaticConfig(null, config), bpmnProcesses);
+ Application app = ProcessTestHelper.newApplication(new MockProcessConfig(workingDayCalendar));
TestWorkItemHandler workItemHandler = new TestWorkItemHandler();
ProcessTestHelper.registerHandler(app, "Human Task", workItemHandler);
org.kie.kogito.process.Process<BusinessCalendarTimerModel> processDefinition = BusinessCalendarTimerProcess.newProcess(app);
@@ -71,9 +65,7 @@ public class BusinessCalendarTest {
@Test
public void testTimerWithNotWorkingDayCalendar() throws InterruptedException {
- BpmnProcesses bpmnProcesses = new BpmnProcesses();
- ProcessConfig config = new MockProcessConfig(notWorkingDayCalendar);
- Application app = new StaticApplication(new StaticConfig(null, config), bpmnProcesses);
+ Application app = ProcessTestHelper.newApplication(new MockProcessConfig(notWorkingDayCalendar));
TestWorkItemHandler workItemHandler = new TestWorkItemHandler();
ProcessTestHelper.registerHandler(app, "Human Task", workItemHandler);
org.kie.kogito.process.Process<BusinessCalendarTimerModel> processDefinition = BusinessCalendarTimerProcess.newProcess(app);
diff --git a/jbpm/jbpm-tests/src/test/java/org/jbpm/test/utils/ProcessTestHelper.java b/jbpm/jbpm-tests/src/test/java/org/jbpm/test/utils/ProcessTestHelper.java
index 1c111d88d9..9da2d64e30 100644
--- a/jbpm/jbpm-tests/src/test/java/org/jbpm/test/utils/ProcessTestHelper.java
+++ b/jbpm/jbpm-tests/src/test/java/org/jbpm/test/utils/ProcessTestHelper.java
@@ -30,6 +30,7 @@ import org.jbpm.bpmn2.intermediate.IntermediateCatchEventTimerDurationWithErrorP
import org.kie.api.event.process.ProcessNodeEvent;
import org.kie.api.event.process.ProcessNodeLeftEvent;
import org.kie.api.event.process.ProcessNodeTriggeredEvent;
+import org.kie.kogito.Addons;
import org.kie.kogito.Application;
import org.kie.kogito.Model;
import org.kie.kogito.StaticApplication;
@@ -45,22 +46,29 @@ import org.kie.kogito.process.bpmn2.BpmnProcesses;
import org.kie.kogito.process.impl.DefaultProcessEventListenerConfig;
import org.kie.kogito.process.impl.DefaultWorkItemHandlerConfig;
import org.kie.kogito.process.impl.StaticProcessConfig;
-import org.kie.kogito.services.uow.CollectingUnitOfWorkFactory;
-import org.kie.kogito.services.uow.DefaultUnitOfWorkManager;
+import org.kie.kogito.services.jobs.impl.InMemoryJobContext;
+import org.kie.kogito.services.jobs.impl.InMemoryProcessJobExecutorFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import static java.util.Collections.emptyList;
+import static org.kie.kogito.services.jobs.impl.StaticJobService.staticJobService;
+import static org.kie.kogito.services.uow.StaticUnitOfWorkManger.staticUnitOfWorkManager;
public class ProcessTestHelper {
private static Logger LOGGER = LoggerFactory.getLogger(ProcessTestHelper.class);
public static Application newApplication() {
+ return newApplication(new StaticProcessConfig());
+ }
+
+ public static Application newApplication(ProcessConfig staticConfig) {
BpmnProcesses bpmnProcesses = new BpmnProcesses();
- StaticProcessConfig staticConfig =
- new StaticProcessConfig(new DefaultWorkItemHandlerConfig(), new DefaultProcessEventListenerConfig(), new DefaultUnitOfWorkManager(new CollectingUnitOfWorkFactory()));
- return new StaticApplication(new StaticConfig(null, staticConfig), bpmnProcesses);
+ InMemoryJobContext context = new InMemoryJobContext(null, staticUnitOfWorkManager(), bpmnProcesses, null);
+ staticJobService().clearJobExecutorFactories();
+ staticJobService().registerJobExecutorFactory(new InMemoryProcessJobExecutorFactory(context));
+ return new StaticApplication(new StaticConfig(Addons.EMTPY, staticConfig), bpmnProcesses);
}
public static void registerProcessEventListener(Application app, KogitoProcessEventListener kogitoProcessEventListener) {
diff --git a/jbpm/jbpm-usertask-workitem/src/main/java/org/kie/kogito/jbpm/usertask/handler/UserTaskKogitoWorkItemHandler.java b/jbpm/jbpm-usertask-workitem/src/main/java/org/kie/kogito/jbpm/usertask/handler/UserTaskKogitoWorkItemHandler.java
index cf30b7ed2b..000e78a2d2 100644
--- a/jbpm/jbpm-usertask-workitem/src/main/java/org/kie/kogito/jbpm/usertask/handler/UserTaskKogitoWorkItemHandler.java
+++ b/jbpm/jbpm-usertask-workitem/src/main/java/org/kie/kogito/jbpm/usertask/handler/UserTaskKogitoWorkItemHandler.java
@@ -35,6 +35,7 @@ import org.kie.kogito.usertask.UserTask;
import org.kie.kogito.usertask.UserTasks;
import org.kie.kogito.usertask.impl.DefaultUserTaskInstance;
import org.kie.kogito.usertask.impl.lifecycle.DefaultUserTaskLifeCycle;
+import org.kie.kogito.usertask.impl.model.DeadlineHelper;
import static java.util.Collections.emptyMap;
import static java.util.Optional.ofNullable;
@@ -51,12 +52,18 @@ public class UserTaskKogitoWorkItemHandler extends DefaultKogitoWorkItemHandler
private static final String DESCRIPTION = "Description";
private static final String PRIORITY = "Priority";
private static final String TASK_NAME = "TaskName";
+ private static final String NODE_NAME = "NodeName";
private static final String ACTOR_ID = "ActorId";
private static final String GROUP_ID = "GroupId";
private static final String BUSINESSADMINISTRATOR_ID = "BusinessAdministratorId";
private static final String BUSINESSADMINISTRATOR_GROUP_ID = "BusinessAdministratorGroupId";
private static final String EXCLUDED_OWNER_ID = "ExcludedOwnerId";
+ private static final String NOT_STARTED_NOTIFY = "NotStartedNotify";
+ private static final String NOT_STARTED_REASSIGN = "NotStartedReassign";
+ private static final String NOT_COMPLETED_NOTIFY = "NotCompletedNotify";
+ private static final String NOT_COMPLETED_REASSIGN = "NotCompletedReassign";
+
public UserTaskKogitoWorkItemHandler() {
super();
}
@@ -78,7 +85,7 @@ public class UserTaskKogitoWorkItemHandler extends DefaultKogitoWorkItemHandler
userTask.instances().create(instance);
- instance.setTaskName((String) workItem.getParameter(TASK_NAME));
+ instance.setTaskName(ofNullable((String) workItem.getParameter(TASK_NAME)).orElse((String) workItem.getParameter(NODE_NAME)));
instance.setTaskDescription((String) workItem.getParameter(DESCRIPTION));
instance.setTaskPriority(priority != null ? priority.toString() : null);
@@ -100,7 +107,12 @@ public class UserTaskKogitoWorkItemHandler extends DefaultKogitoWorkItemHandler
ofNullable(workItem.getParameters().get(BUSINESSADMINISTRATOR_GROUP_ID)).map(String.class::cast).map(this::toSet).ifPresent(instance::setAdminGroups);
ofNullable(workItem.getParameters().get(EXCLUDED_OWNER_ID)).map(String.class::cast).map(this::toSet).ifPresent(instance::setExcludedUsers);
- instance.transition(DefaultUserTaskLifeCycle.ACTIVATE, emptyMap(), IdentityProviders.of(WORKFLOW_ENGINE_USER));
+ ofNullable(workItem.getParameters().get(NOT_STARTED_NOTIFY)).map(String.class::cast).map(DeadlineHelper::parseDeadlines).ifPresent(instance::setNotStartedDeadlines);
+ ofNullable(workItem.getParameters().get(NOT_STARTED_REASSIGN)).map(String.class::cast).map(DeadlineHelper::parseReassignments).ifPresent(instance::setNotStartedReassignments);
+ ofNullable(workItem.getParameters().get(NOT_COMPLETED_NOTIFY)).map(String.class::cast).map(DeadlineHelper::parseDeadlines).ifPresent(instance::setNotCompletedDeadlines);
+ ofNullable(workItem.getParameters().get(NOT_COMPLETED_REASSIGN)).map(String.class::cast).map(DeadlineHelper::parseReassignments).ifPresent(instance::setNotCompletedReassignments);
+
+ instance.initialize(emptyMap(), IdentityProviders.of(WORKFLOW_ENGINE_USER));
if (workItem instanceof InternalKogitoWorkItem ikw) {
ikw.setExternalReferenceId(instance.getId());
diff --git a/jbpm/jbpm-usertask/src/main/java/org/kie/kogito/usertask/impl/AbstractUserTask.java b/jbpm/jbpm-usertask/src/main/java/org/kie/kogito/usertask/impl/AbstractUserTask.java
index 795c0f25e9..8fb214c0b1 100644
--- a/jbpm/jbpm-usertask/src/main/java/org/kie/kogito/usertask/impl/AbstractUserTask.java
+++ b/jbpm/jbpm-usertask/src/main/java/org/kie/kogito/usertask/impl/AbstractUserTask.java
@@ -20,13 +20,13 @@ package org.kie.kogito.usertask.impl;
import java.util.Collection;
import java.util.HashSet;
-import java.util.Map;
import java.util.Set;
import org.kie.kogito.usertask.UserTask;
import org.kie.kogito.usertask.UserTaskInstance;
import org.kie.kogito.usertask.impl.model.DeadlineHelper;
import org.kie.kogito.usertask.model.DeadlineInfo;
+import org.kie.kogito.usertask.model.Notification;
import org.kie.kogito.usertask.model.Reassignment;
public abstract class AbstractUserTask implements UserTask {
@@ -44,10 +44,10 @@ public abstract class AbstractUserTask implements UserTask {
private Set<String> adminUsers;
private Set<String> adminGroups;
private Set<String> excludedUsers;
- private Collection<DeadlineInfo<Map<String, Object>>> startDeadlines;
- private Collection<DeadlineInfo<Map<String, Object>>> endDeadlines;
+ private Collection<DeadlineInfo<Notification>> startDeadlines;
+ private Collection<DeadlineInfo<Notification>> endDeadlines;
private Collection<DeadlineInfo<Reassignment>> startReassigments;
- private Collection<DeadlineInfo<Reassignment>> endReassigments;
+ private Collection<DeadlineInfo<Reassignment>> endReassignments;
public AbstractUserTask(String id, String name) {
this.id = id;
@@ -61,7 +61,7 @@ public abstract class AbstractUserTask implements UserTask {
this.startDeadlines = new HashSet<>();
this.endDeadlines = new HashSet<>();
this.startReassigments = new HashSet<>();
- this.endReassigments = new HashSet<>();
+ this.endReassignments = new HashSet<>();
}
@Override
@@ -77,6 +77,10 @@ public abstract class AbstractUserTask implements UserTask {
instance.setAdminGroups(getAdminGroups());
instance.setExcludedUsers(getExcludedUsers());
instance.setInstances(this.instances());
+ instance.setNotCompletedDeadlines(this.getNotCompletedDeadlines());
+ instance.setNotCompletedReassignments(this.getNotCompletedReassignments());
+ instance.setNotStartedDeadlines(this.getNotStartedDeadlines());
+ instance.setNotStartedReassignments(this.getNotStartedReassignments());
return instance;
}
@@ -200,7 +204,7 @@ public abstract class AbstractUserTask implements UserTask {
}
@Override
- public Collection<DeadlineInfo<Map<String, Object>>> getNotStartedDeadlines() {
+ public Collection<DeadlineInfo<Notification>> getNotStartedDeadlines() {
return startDeadlines;
}
@@ -209,7 +213,7 @@ public abstract class AbstractUserTask implements UserTask {
}
@Override
- public Collection<DeadlineInfo<Map<String, Object>>> getNotCompletedDeadlines() {
+ public Collection<DeadlineInfo<Notification>> getNotCompletedDeadlines() {
return endDeadlines;
}
@@ -227,12 +231,12 @@ public abstract class AbstractUserTask implements UserTask {
}
@Override
- public Collection<DeadlineInfo<Reassignment>> getNotCompletedReassigments() {
- return endReassigments;
+ public Collection<DeadlineInfo<Reassignment>> getNotCompletedReassignments() {
+ return endReassignments;
}
public void setNotCompletedReassigments(String reassignments) {
- this.endReassigments = DeadlineHelper.parseReassignments(reassignments);
+ this.endReassignments = DeadlineHelper.parseReassignments(reassignments);
}
protected Set<String> toSet(String value) {
diff --git a/jbpm/jbpm-usertask/src/main/java/org/kie/kogito/usertask/impl/DefaultUserTaskConfig.java b/jbpm/jbpm-usertask/src/main/java/org/kie/kogito/usertask/impl/DefaultUserTaskConfig.java
index 7282ce7253..88ce68e6b9 100644
--- a/jbpm/jbpm-usertask/src/main/java/org/kie/kogito/usertask/impl/DefaultUserTaskConfig.java
+++ b/jbpm/jbpm-usertask/src/main/java/org/kie/kogito/usertask/impl/DefaultUserTaskConfig.java
@@ -24,8 +24,10 @@ import java.util.function.Supplier;
import org.kie.kogito.auth.IdentityProvider;
import org.kie.kogito.jobs.JobsService;
import org.kie.kogito.services.identity.NoOpIdentityProvider;
+import org.kie.kogito.services.jobs.impl.StaticJobService;
import org.kie.kogito.services.uow.CollectingUnitOfWorkFactory;
import org.kie.kogito.services.uow.DefaultUnitOfWorkManager;
+import org.kie.kogito.services.uow.StaticUnitOfWorkManger;
import org.kie.kogito.uow.UnitOfWorkManager;
import org.kie.kogito.usertask.UserTaskAssignmentStrategyConfig;
import org.kie.kogito.usertask.UserTaskConfig;
@@ -33,9 +35,15 @@ import org.kie.kogito.usertask.UserTaskEventListenerConfig;
import org.kie.kogito.usertask.UserTaskInstances;
import org.kie.kogito.usertask.impl.lifecycle.DefaultUserTaskLifeCycle;
import org.kie.kogito.usertask.lifecycle.UserTaskLifeCycle;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import static org.kie.kogito.services.jobs.impl.StaticJobService.staticJobService;
public class DefaultUserTaskConfig implements UserTaskConfig {
+ private static final Logger LOG = LoggerFactory.getLogger(DefaultUserTaskConfig.class);
+
private UserTaskEventListenerConfig userTaskEventListeners;
private UnitOfWorkManager unitOfWorkManager;
private JobsService jobService;
@@ -47,7 +55,7 @@ public class DefaultUserTaskConfig implements UserTaskConfig {
public DefaultUserTaskConfig() {
this(new DefaultUserTaskEventListenerConfig(),
new DefaultUnitOfWorkManager(new CollectingUnitOfWorkFactory()),
- null,
+ staticJobService(),
new NoOpIdentityProvider(),
new DefaultUserTaskLifeCycle(),
new DefaultUserTaskAssignmentStrategyConfig(),
@@ -64,8 +72,8 @@ public class DefaultUserTaskConfig implements UserTaskConfig {
Iterable<UserTaskInstances> userTaskInstances) {
this.userTaskEventListeners = singleton(userTaskEventListenerConfig, DefaultUserTaskEventListenerConfig::new);
- this.unitOfWorkManager = singleton(unitOfWorkManager, () -> new DefaultUnitOfWorkManager(new CollectingUnitOfWorkFactory()));
- this.jobService = singleton(jobService, () -> null);
+ this.unitOfWorkManager = singleton(unitOfWorkManager, StaticUnitOfWorkManger::staticUnitOfWorkManager);
+ this.jobService = singleton(jobService, StaticJobService::staticJobService);
this.identityProvider = singleton(identityProvider, NoOpIdentityProvider::new);
this.userTaskLifeCycle = singleton(userTaskLifeCycle, DefaultUserTaskLifeCycle::new);
this.userTaskAssignmentStrategyConfig = singleton(userTaskAssignmentStrategyConfig, DefaultUserTaskAssignmentStrategyConfig::new);
@@ -73,12 +81,16 @@ public class DefaultUserTaskConfig implements UserTaskConfig {
}
- private <T> T singleton(Iterable<T> value, Supplier<T> defaultValue) {
- Iterator<T> iterator = value.iterator();
+ private <T> T singleton(Iterable<T> values, Supplier<T> defaultValue) {
+ Iterator<T> iterator = values.iterator();
+ T value = null;
if (iterator.hasNext()) {
- return iterator.next();
+ value = iterator.next();
+ } else {
+ value = defaultValue.get();
}
- return defaultValue.get();
+ LOG.debug("UserTask config element {}", value);
+ return value;
}
public DefaultUserTaskConfig(
diff --git a/jbpm/jbpm-usertask/src/main/java/org/kie/kogito/usertask/impl/DefaultUserTaskInstance.java b/jbpm/jbpm-usertask/src/main/java/org/kie/kogito/usertask/impl/DefaultUserTaskInstance.java
index 757bf30ede..15e2477fc1 100644
--- a/jbpm/jbpm-usertask/src/main/java/org/kie/kogito/usertask/impl/DefaultUserTaskInstance.java
+++ b/jbpm/jbpm-usertask/src/main/java/org/kie/kogito/usertask/impl/DefaultUserTaskInstance.java
@@ -18,24 +18,53 @@
*/
package org.kie.kogito.usertask.impl;
-import java.util.*;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+import java.util.Optional;
+import java.util.Set;
+import java.util.UUID;
+import java.util.function.Consumer;
import org.kie.kogito.auth.IdentityProvider;
+import org.kie.kogito.auth.IdentityProviders;
import org.kie.kogito.internal.usertask.event.KogitoUserTaskEventSupport;
import org.kie.kogito.internal.usertask.event.KogitoUserTaskEventSupport.AssignmentType;
+import org.kie.kogito.jobs.ExpirationTime;
+import org.kie.kogito.jobs.JobDescription;
+import org.kie.kogito.jobs.JobsService;
+import org.kie.kogito.jobs.descriptors.UserTaskInstanceJobDescription;
import org.kie.kogito.usertask.UserTask;
import org.kie.kogito.usertask.UserTaskInstance;
import org.kie.kogito.usertask.UserTaskInstances;
+import org.kie.kogito.usertask.impl.model.DeadlineHelper;
import org.kie.kogito.usertask.lifecycle.UserTaskLifeCycle;
import org.kie.kogito.usertask.lifecycle.UserTaskState;
import org.kie.kogito.usertask.lifecycle.UserTaskTransitionToken;
import org.kie.kogito.usertask.model.Attachment;
import org.kie.kogito.usertask.model.Comment;
+import org.kie.kogito.usertask.model.DeadlineInfo;
+import org.kie.kogito.usertask.model.Notification;
+import org.kie.kogito.usertask.model.Reassignment;
+import org.kie.kogito.usertask.model.ScheduleInfo;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
import com.fasterxml.jackson.annotation.JsonIgnore;
+import static java.util.Collections.emptyMap;
+import static org.kie.kogito.jobs.descriptors.UserTaskInstanceJobDescription.newUserTaskInstanceJobDescriptionBuilder;
+import static org.kie.kogito.usertask.impl.lifecycle.DefaultUserTaskLifeCycle.WORKFLOW_ENGINE_USER;
+
public class DefaultUserTaskInstance implements UserTaskInstance {
+ private static Logger LOG = LoggerFactory.getLogger(DefaultUserTaskInstance.class);
+
private String id;
private String userTaskId;
@@ -67,6 +96,24 @@ public class DefaultUserTaskInstance implements UserTaskInstance {
private KogitoUserTaskEventSupport userTaskEventSupport;
@JsonIgnore
private UserTaskLifeCycle userTaskLifeCycle;
+ @JsonIgnore
+ private JobsService jobsService;
+
+ private Collection<DeadlineInfo<Notification>> notStartedDeadlines;
+
+ private Collection<DeadlineInfo<Notification>> notCompletedDeadlines;
+
+ private Collection<DeadlineInfo<Reassignment>> notStartedReassignments;
+
+ private Collection<DeadlineInfo<Reassignment>> notCompletedReassigments;
+
+ private Map<String, Notification> notStartedDeadlinesTimers;
+
+ private Map<String, Notification> notCompletedDeadlinesTimers;
+
+ private Map<String, Reassignment> notStartedReassignmentsTimers;
+
+ private Map<String, Reassignment> notCompletedReassignmentsTimers;
public DefaultUserTaskInstance() {
this.inputs = new HashMap<>();
@@ -80,6 +127,10 @@ public class DefaultUserTaskInstance implements UserTaskInstance {
this.adminUsers = new HashSet<>();
this.adminGroups = new HashSet<>();
this.excludedUsers = new HashSet<>();
+ this.notStartedDeadlinesTimers = new HashMap<>();
+ this.notCompletedDeadlinesTimers = new HashMap<>();
+ this.notStartedReassignmentsTimers = new HashMap<>();
+ this.notCompletedReassignmentsTimers = new HashMap<>();
}
public DefaultUserTaskInstance(UserTask userTask) {
@@ -88,6 +139,38 @@ public class DefaultUserTaskInstance implements UserTaskInstance {
this.userTask = userTask;
}
+ public Map<String, Notification> getNotCompletedDeadlinesTimers() {
+ return notCompletedDeadlinesTimers;
+ }
+
+ public void setNotCompletedDeadlinesTimers(Map<String, Notification> notCompletedDeadlinesTimers) {
+ this.notCompletedDeadlinesTimers = notCompletedDeadlinesTimers;
+ }
+
+ public Map<String, Reassignment> getNotCompletedReassignmentsTimers() {
+ return notCompletedReassignmentsTimers;
+ }
+
+ public void setNotCompletedReassignmentsTimers(Map<String, Reassignment> notCompletedReassignmentsTimers) {
+ this.notCompletedReassignmentsTimers = notCompletedReassignmentsTimers;
+ }
+
+ public Map<String, Notification> getNotStartedDeadlinesTimers() {
+ return notStartedDeadlinesTimers;
+ }
+
+ public void setNotStartedDeadlinesTimers(Map<String, Notification> notStartedDeadlinesTimers) {
+ this.notStartedDeadlinesTimers = notStartedDeadlinesTimers;
+ }
+
+ public Map<String, Reassignment> getNotStartedReassignmentsTimers() {
+ return notStartedReassignmentsTimers;
+ }
+
+ public void setNotStartedReassignmentsTimers(Map<String, Reassignment> notStartedReassignmentsTimers) {
+ this.notStartedReassignmentsTimers = notStartedReassignmentsTimers;
+ }
+
public void setUserTaskEventSupport(KogitoUserTaskEventSupport userTaskEventSupport) {
this.userTaskEventSupport = userTaskEventSupport;
}
@@ -96,6 +179,10 @@ public class DefaultUserTaskInstance implements UserTaskInstance {
this.userTaskLifeCycle = userTaskLifeCycle;
}
+ public UserTaskLifeCycle getUserTaskLifeCycle() {
+ return userTaskLifeCycle;
+ }
+
public void setInstances(UserTaskInstances instances) {
this.instances = instances;
}
@@ -155,6 +242,11 @@ public class DefaultUserTaskInstance implements UserTaskInstance {
this.externalReferenceId = externalReferenceId;
}
+ @Override
+ public void initialize(Map<String, Object> data, IdentityProvider identity) {
+ transition(this.userTaskLifeCycle.startTransition(), data, identity);
+ }
+
@Override
public void transition(String transitionId, Map<String, Object> data, IdentityProvider identity) {
Optional<UserTaskTransitionToken> next = Optional.of(this.userTaskLifeCycle.newTransitionToken(transitionId, this, data));
@@ -522,6 +614,171 @@ public class DefaultUserTaskInstance implements UserTaskInstance {
return this.comments.stream().filter(e -> e.getId().equals(commentId)).findAny().orElse(null);
}
+ @Override
+ public Collection<DeadlineInfo<Notification>> getNotStartedDeadlines() {
+ return notStartedDeadlines;
+ }
+
+ public void setNotStartedDeadlines(Collection<DeadlineInfo<Notification>> notStartedDeadlines) {
+ this.notStartedDeadlines = notStartedDeadlines;
+ }
+
+ @Override
+ public Collection<DeadlineInfo<Notification>> getNotCompletedDeadlines() {
+ return notCompletedDeadlines;
+ }
+
+ public void setNotCompletedDeadlines(Collection<DeadlineInfo<Notification>> notCompletedDeadlines) {
+ this.notCompletedDeadlines = notCompletedDeadlines;
+ }
+
+ @Override
+ public Collection<DeadlineInfo<Reassignment>> getNotStartedReassignments() {
+ return notStartedReassignments;
+ }
+
+ public void setNotStartedReassignments(Collection<DeadlineInfo<Reassignment>> notStartedReassignments) {
+ this.notStartedReassignments = notStartedReassignments;
+ }
+
+ @Override
+ public Collection<DeadlineInfo<Reassignment>> getNotCompletedReassignments() {
+ return notCompletedReassigments;
+ }
+
+ public void setNotCompletedReassignments(Collection<DeadlineInfo<Reassignment>> notCompletedReassigments) {
+ this.notCompletedReassigments = notCompletedReassigments;
+ }
+
+ public void setJobsService(JobsService jobsService) {
+ this.jobsService = jobsService;
+ }
+
+ private <T> void initTimers(Map<String, T> timers, Collection<DeadlineInfo<T>> deadlines) {
+ for (DeadlineInfo<T> deadline : deadlines) {
+ for (JobDescription jobDescription : toJobDescription(deadline)) {
+ timers.put(jobDescription.id(), deadline.getNotification());
+ this.jobsService.scheduleJob(jobDescription);
+ }
+ }
+ this.updatePersistence();
+ }
+
+ private <T> void stopTimers(Map<String, T> timers) {
+ timers.keySet().stream().filter(Objects::nonNull).forEach(this.jobsService::cancelJob);
+ timers.clear();
+ this.updatePersistence();
+ }
+
+ private List<JobDescription> toJobDescription(DeadlineInfo<?> deadline) {
+ List<JobDescription> jobs = new ArrayList<>();
+ for (ScheduleInfo info : deadline.getScheduleInfo()) {
+ ExpirationTime expirationTime = DeadlineHelper.getExpirationTime(info);
+ jobs.add(newUserTaskInstanceJobDescriptionBuilder()
+ .generateId()
+ .expirationTime(expirationTime)
+ .userTaskInstanceId(this.id)
+ .build());
+ }
+ return jobs;
+ }
+
+ @Override
+ public void startNotStartedDeadlines() {
+ initTimers(this.notStartedDeadlinesTimers, getNotStartedDeadlines());
+ }
+
+ @Override
+ public void startNotStartedReassignments() {
+ initTimers(this.notStartedReassignmentsTimers, getNotStartedReassignments());
+ }
+
+ @Override
+ public void startNotCompletedDeadlines() {
+ initTimers(this.notCompletedDeadlinesTimers, getNotCompletedDeadlines());
+ }
+
+ @Override
+ public void startNotCompletedReassignments() {
+ initTimers(this.notCompletedReassignmentsTimers, getNotCompletedReassignments());
+ }
+
+ @Override
+ public void stopNotStartedDeadlines() {
+ stopTimers(this.notStartedDeadlinesTimers);
+ }
+
+ @Override
+ public void stopNotStartedReassignments() {
+ stopTimers(this.notStartedReassignmentsTimers);
+ }
+
+ @Override
+ public void stopNotCompletedDeadlines() {
+ stopTimers(this.notCompletedDeadlinesTimers);
+ }
+
+ @Override
+ public void stopNotCompletedReassignments() {
+ stopTimers(this.notCompletedReassignmentsTimers);
+ }
+
+ public void trigger(UserTaskInstanceJobDescription jobDescription) {
+ LOG.trace("trigger timer in user tasks {} and job {}", this, jobDescription);
+ checkAndSendNotitication(jobDescription, notStartedDeadlinesTimers, this::startNotification);
+ checkAndSendNotitication(jobDescription, notCompletedDeadlinesTimers, this::endNotification);
+ checkAndReassign(jobDescription, notStartedReassignmentsTimers);
+ checkAndReassign(jobDescription, notCompletedReassignmentsTimers);
+ this.updatePersistence();
+ }
+
+ private void checkAndSendNotitication(UserTaskInstanceJobDescription timerInstance, Map<String, Notification> timers, Consumer<Notification> publisher) {
+ Notification notification = timers.get(timerInstance.id());
+ if (notification == null) {
+ return;
+ }
+
+ if (timerInstance.expirationTime().repeatLimit() <= 0) {
+ timers.remove(timerInstance.id());
+ }
+ publisher.accept(notification);
+
+ }
+
+ private void startNotification(Notification notification) {
+ if (this.userTaskEventSupport != null) {
+ this.userTaskEventSupport.fireOnUserTaskNotStartedDeadline(this, notification.getData());
+ }
+ }
+
+ private void endNotification(Notification notification) {
+ if (this.userTaskEventSupport != null) {
+ this.userTaskEventSupport.fireOnUserTaskNotCompletedDeadline(this, notification.getData());
+ }
+ }
+
+ private void checkAndReassign(UserTaskInstanceJobDescription timerInstance, Map<String, Reassignment> timers) {
+ Reassignment reassignment = timers.remove(timerInstance.id());
+
+ if (reassignment == null) {
+ return;
+ }
+ reassign(reassignment);
+ }
+
+ private void reassign(Reassignment reassignment) {
+ if (!reassignment.getPotentialUsers().isEmpty()) {
+ setPotentialUsers(reassignment.getPotentialUsers());
+ }
+ if (!reassignment.getPotentialGroups().isEmpty()) {
+ setPotentialGroups(reassignment.getPotentialGroups());
+ }
+
+ this.userTaskLifeCycle.newReassignmentTransitionToken(this, emptyMap()).ifPresent(token -> {
+ this.userTaskLifeCycle.transition(this, token, IdentityProviders.of(WORKFLOW_ENGINE_USER));
+ });
+ }
+
@Override
public String toString() {
return "DefaultUserTaskInstance [id=" + id + ", status=" + status + ", actualOwner=" + actualOwner + ", taskName=" + taskName + ", taskDescription=" + taskDescription + ", taskPriority="
diff --git a/jbpm/jbpm-usertask/src/main/java/org/kie/kogito/usertask/impl/DefaultUserTasks.java b/jbpm/jbpm-usertask/src/main/java/org/kie/kogito/usertask/impl/DefaultUserTasks.java
index e291867332..40b616f5c8 100644
--- a/jbpm/jbpm-usertask/src/main/java/org/kie/kogito/usertask/impl/DefaultUserTasks.java
+++ b/jbpm/jbpm-usertask/src/main/java/org/kie/kogito/usertask/impl/DefaultUserTasks.java
@@ -80,6 +80,7 @@ public class DefaultUserTasks implements UserTasks {
instance.setUserTaskEventSupport(null);
instance.setUserTaskLifeCycle(null);
instance.setInstances(null);
+ instance.setJobsService(null);
return instance;
}
@@ -93,6 +94,7 @@ public class DefaultUserTasks implements UserTasks {
instance.setUserTaskEventSupport(impl);
instance.setUserTaskLifeCycle(userTaskConfig.userTaskLifeCycle());
instance.setInstances(userTaskInstances);
+ instance.setJobsService(userTaskConfig.jobsService());
return instance;
}
}
diff --git a/jbpm/jbpm-usertask/src/main/java/org/kie/kogito/usertask/impl/InMemoryUserTaskInstances.java b/jbpm/jbpm-usertask/src/main/java/org/kie/kogito/usertask/impl/InMemoryUserTaskInstances.java
index 256144c484..113228f185 100644
--- a/jbpm/jbpm-usertask/src/main/java/org/kie/kogito/usertask/impl/InMemoryUserTaskInstances.java
+++ b/jbpm/jbpm-usertask/src/main/java/org/kie/kogito/usertask/impl/InMemoryUserTaskInstances.java
@@ -139,6 +139,7 @@ public class InMemoryUserTaskInstances implements UserTaskInstances {
@Override
public UserTaskInstance create(UserTaskInstance userTaskInstance) {
try {
+ LOG.trace("create {}", userTaskInstance);
byte[] data = mapper.writeValueAsBytes(userTaskInstance);
userTaskInstances.put(userTaskInstance.getId(), data);
return reconnectUserTaskInstance.apply(userTaskInstance);
@@ -151,6 +152,7 @@ public class InMemoryUserTaskInstances implements UserTaskInstances {
@Override
public UserTaskInstance update(UserTaskInstance userTaskInstance) {
try {
+ LOG.trace("update {}", userTaskInstance);
byte[] data = mapper.writeValueAsBytes(userTaskInstance);
userTaskInstances.put(userTaskInstance.getId(), data);
return userTaskInstance;
@@ -166,6 +168,7 @@ public class InMemoryUserTaskInstances implements UserTaskInstances {
if (!userTaskInstances.containsKey(userTaskInstance.getId())) {
return null;
}
+ LOG.trace("remove {}", userTaskInstance);
userTaskInstances.remove(userTaskInstance.getId());
return disconnectUserTaskInstance.apply(userTaskInstance);
} catch (Exception e) {
diff --git a/jbpm/jbpm-usertask/src/main/java/org/kie/kogito/usertask/impl/UserTaskServiceImpl.java b/jbpm/jbpm-usertask/src/main/java/org/kie/kogito/usertask/impl/UserTaskServiceImpl.java
index 3f1009245e..a2da034e93 100644
--- a/jbpm/jbpm-usertask/src/main/java/org/kie/kogito/usertask/impl/UserTaskServiceImpl.java
+++ b/jbpm/jbpm-usertask/src/main/java/org/kie/kogito/usertask/impl/UserTaskServiceImpl.java
@@ -79,15 +79,13 @@ public class UserTaskServiceImpl implements UserTaskService {
@Override
public Optional<UserTaskView> transition(String taskId, String transitionId, Map<String, Object> data, IdentityProvider identity) {
- return UnitOfWorkExecutor.executeInUnitOfWork(application.unitOfWorkManager(), () -> {
- Optional<UserTaskInstance> userTaskInstance = application.get(UserTasks.class).instances().findById(taskId);
- if (userTaskInstance.isEmpty()) {
- return Optional.empty();
- }
- UserTaskInstance ut = userTaskInstance.get();
- ut.transition(transitionId, data, identity);
- return Optional.of(toUserTaskView(ut));
- });
+ Optional<UserTaskInstance> userTaskInstance = application.get(UserTasks.class).instances().findById(taskId);
+ if (userTaskInstance.isEmpty()) {
+ return Optional.empty();
+ }
+ UserTaskInstance ut = userTaskInstance.get();
+ ut.transition(transitionId, data, identity);
+ return Optional.of(toUserTaskView(ut));
}
@Override
diff --git a/jbpm/jbpm-usertask/src/main/java/org/kie/kogito/usertask/impl/lifecycle/DefaultUserTaskLifeCycle.java b/jbpm/jbpm-usertask/src/main/java/org/kie/kogito/usertask/impl/lifecycle/DefaultUserTaskLifeCycle.java
index 6af8a612fc..5b871d2a8f 100644
--- a/jbpm/jbpm-usertask/src/main/java/org/kie/kogito/usertask/impl/lifecycle/DefaultUserTaskLifeCycle.java
+++ b/jbpm/jbpm-usertask/src/main/java/org/kie/kogito/usertask/impl/lifecycle/DefaultUserTaskLifeCycle.java
@@ -49,6 +49,7 @@ public class DefaultUserTaskLifeCycle implements UserTaskLifeCycle {
public static final String COMPLETE = "complete";
public static final String SKIP = "skip";
public static final String FAIL = "fail";
+ public static final String REASSIGN = "reassign";
public static final UserTaskState INACTIVE = UserTaskState.initalized();
public static final UserTaskState ACTIVE = UserTaskState.of("Ready");
@@ -66,6 +67,9 @@ public class DefaultUserTaskLifeCycle implements UserTaskLifeCycle {
private final UserTaskTransition T_RESERVED_SKIPPED = new DefaultUserTransition(SKIP, RESERVED, OBSOLETE, this::skip);
private final UserTaskTransition T_RESERVED_ERROR = new DefaultUserTransition(FAIL, RESERVED, ERROR, this::fail);
+ private final UserTaskTransition T_RESERVED_ACTIVE_R = new DefaultUserTransition(REASSIGN, RESERVED, ACTIVE, this::reassign);
+ private final UserTaskTransition T_ACTIVE_ACTIVE_R = new DefaultUserTransition(REASSIGN, ACTIVE, ACTIVE, this::reassign);
+
private List<UserTaskTransition> transitions;
public DefaultUserTaskLifeCycle() {
@@ -77,7 +81,9 @@ public class DefaultUserTaskLifeCycle implements UserTaskLifeCycle {
T_RESERVED_ACTIVE,
T_RESERVED_COMPLETED,
T_RESERVED_SKIPPED,
- T_RESERVED_ERROR);
+ T_RESERVED_ERROR,
+ T_RESERVED_ACTIVE_R,
+ T_ACTIVE_ACTIVE_R);
}
@Override
@@ -95,6 +101,15 @@ public class DefaultUserTaskLifeCycle implements UserTaskLifeCycle {
return transition.executor().execute(userTaskInstance, userTaskTransitionToken, identityProvider);
}
+ @Override
+ public Optional<UserTaskTransitionToken> newReassignmentTransitionToken(UserTaskInstance userTaskInstance, Map<String, Object> data) {
+ try {
+ return Optional.of(newTransitionToken(REASSIGN, userTaskInstance.getStatus(), data));
+ } catch (UserTaskTransitionException e) {
+ return Optional.empty();
+ }
+ }
+
@Override
public UserTaskTransitionToken newCompleteTransitionToken(UserTaskInstance userTaskInstance, Map<String, Object> data) {
return newTransitionToken(COMPLETE, userTaskInstance.getStatus(), data);
@@ -116,11 +131,35 @@ public class DefaultUserTaskLifeCycle implements UserTaskLifeCycle {
return new DefaultUserTaskTransitionToken(transition.id(), transition.source(), transition.target(), data);
}
+ public Optional<UserTaskTransitionToken> reassign(UserTaskInstance userTaskInstance, UserTaskTransitionToken token, IdentityProvider identityProvider) {
+ userTaskInstance.stopNotStartedDeadlines();
+ userTaskInstance.stopNotStartedReassignments();
+ userTaskInstance.stopNotCompletedDeadlines();
+ userTaskInstance.stopNotCompletedReassignments();
+
+ // restart the timers
+ userTaskInstance.startNotCompletedDeadlines();
+ userTaskInstance.startNotCompletedReassignments();
+
+ String user = assignStrategy(userTaskInstance, identityProvider);
+ if (user != null) {
+ return Optional.of(newTransitionToken(CLAIM, ACTIVE, Map.of(PARAMETER_USER, user)));
+ }
+ userTaskInstance.startNotStartedDeadlines();
+ userTaskInstance.startNotStartedReassignments();
+ return Optional.empty();
+ }
+
public Optional<UserTaskTransitionToken> activate(UserTaskInstance userTaskInstance, UserTaskTransitionToken token, IdentityProvider identityProvider) {
+ userTaskInstance.startNotCompletedDeadlines();
+ userTaskInstance.startNotCompletedReassignments();
+
String user = assignStrategy(userTaskInstance, identityProvider);
if (user != null) {
return Optional.of(newTransitionToken(CLAIM, ACTIVE, Map.of(PARAMETER_USER, user)));
}
+ userTaskInstance.startNotStartedDeadlines();
+ userTaskInstance.startNotStartedReassignments();
return Optional.empty();
}
@@ -132,6 +171,8 @@ public class DefaultUserTaskLifeCycle implements UserTaskLifeCycle {
defaultUserTaskInstance.setActualOwner(identityProvider.getName());
}
}
+ userTaskInstance.stopNotStartedDeadlines();
+ userTaskInstance.stopNotStartedReassignments();
return Optional.empty();
}
@@ -144,6 +185,10 @@ public class DefaultUserTaskLifeCycle implements UserTaskLifeCycle {
public Optional<UserTaskTransitionToken> complete(UserTaskInstance userTaskInstance, UserTaskTransitionToken token, IdentityProvider identityProvider) {
token.data().forEach(userTaskInstance::setOutput);
+ userTaskInstance.stopNotStartedDeadlines();
+ userTaskInstance.stopNotStartedReassignments();
+ userTaskInstance.stopNotCompletedDeadlines();
+ userTaskInstance.stopNotCompletedReassignments();
return Optional.empty();
}
@@ -151,6 +196,10 @@ public class DefaultUserTaskLifeCycle implements UserTaskLifeCycle {
if (token.data().containsKey(PARAMETER_NOTIFY)) {
userTaskInstance.getMetadata().put(PARAMETER_NOTIFY, token.data().get(PARAMETER_NOTIFY));
}
+ userTaskInstance.stopNotStartedDeadlines();
+ userTaskInstance.stopNotStartedReassignments();
+ userTaskInstance.stopNotCompletedDeadlines();
+ userTaskInstance.stopNotCompletedReassignments();
return Optional.empty();
}
@@ -158,6 +207,10 @@ public class DefaultUserTaskLifeCycle implements UserTaskLifeCycle {
if (token.data().containsKey(PARAMETER_NOTIFY)) {
userTaskInstance.getMetadata().put(PARAMETER_NOTIFY, token.data().get(PARAMETER_NOTIFY));
}
+ userTaskInstance.stopNotStartedDeadlines();
+ userTaskInstance.stopNotStartedReassignments();
+ userTaskInstance.stopNotCompletedDeadlines();
+ userTaskInstance.stopNotCompletedReassignments();
return Optional.empty();
}
diff --git a/jbpm/jbpm-usertask/src/main/java/org/kie/kogito/usertask/impl/model/DeadlineHelper.java b/jbpm/jbpm-usertask/src/main/java/org/kie/kogito/usertask/impl/model/DeadlineHelper.java
index cb541a9c7e..3e0793830b 100644
--- a/jbpm/jbpm-usertask/src/main/java/org/kie/kogito/usertask/impl/model/DeadlineHelper.java
+++ b/jbpm/jbpm-usertask/src/main/java/org/kie/kogito/usertask/impl/model/DeadlineHelper.java
@@ -38,6 +38,7 @@ import org.kie.kogito.jobs.DurationExpirationTime;
import org.kie.kogito.jobs.ExactExpirationTime;
import org.kie.kogito.jobs.ExpirationTime;
import org.kie.kogito.usertask.model.DeadlineInfo;
+import org.kie.kogito.usertask.model.Notification;
import org.kie.kogito.usertask.model.Reassignment;
import org.kie.kogito.usertask.model.ScheduleInfo;
import org.slf4j.Logger;
@@ -89,11 +90,17 @@ public class DeadlineHelper {
}
public static Collection<DeadlineInfo<Reassignment>> parseReassignments(Object text) {
+ if (text instanceof String textString && textString.isBlank()) {
+ return Collections.emptyList();
+ }
return parseDeadlines(text, DeadlineHelper::parseReassigment, DeadlineHelper::getReassignmentSchedule);
}
- public static Collection<DeadlineInfo<Map<String, Object>>> parseDeadlines(Object text) {
- return parseDeadlines(text, DeadlineHelper::asMap, DeadlineHelper::getSchedulesInfo);
+ public static Collection<DeadlineInfo<Notification>> parseDeadlines(Object text) {
+ if (text instanceof String textString && textString.isBlank()) {
+ return Collections.emptyList();
+ }
+ return parseDeadlines(text, DeadlineHelper::asNotification, DeadlineHelper::getSchedulesInfo);
}
private static <T> Collection<DeadlineInfo<T>> parseDeadlines(Object text,
@@ -116,7 +123,7 @@ public class DeadlineHelper {
deadline.setScheduleInfo(scheduleFunction.apply(text.substring(indexOf + 3, text.length() - 1).trim()));
return deadline;
}
- throw new IllegalArgumentException("Invalid formar for dead line expression " + text);
+ throw new IllegalArgumentException("Invalid format for dead line expression " + text);
}
private static Collection<ScheduleInfo> getReassignmentSchedule(String timeStr) {
@@ -198,6 +205,10 @@ public class DeadlineHelper {
return repetitionStr.length() > 1 ? Integer.parseInt(repetitionStr.substring(1)) : -1;
}
+ private static Notification asNotification(String text) {
+ return new Notification(asMap(text));
+ }
+
private static Map<String, Object> asMap(String text) {
Map<String, Object> result = new HashMap<>();
for (String str : text.split("\\|")) {
diff --git a/jbpm/jbpm-usertask/src/test/java/org/kie/kogito/usertask/impl/model/DeadlineHelperTest.java b/jbpm/jbpm-usertask/src/test/java/org/kie/kogito/usertask/impl/model/DeadlineHelperTest.java
index 0bf241c43b..2c022d7672 100644
--- a/jbpm/jbpm-usertask/src/test/java/org/kie/kogito/usertask/impl/model/DeadlineHelperTest.java
+++ b/jbpm/jbpm-usertask/src/test/java/org/kie/kogito/usertask/impl/model/DeadlineHelperTest.java
@@ -23,11 +23,11 @@ import java.time.Period;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Collection;
-import java.util.Map;
import org.junit.jupiter.api.Test;
import org.kie.kogito.jobs.ExpirationTime;
import org.kie.kogito.usertask.model.DeadlineInfo;
+import org.kie.kogito.usertask.model.Notification;
import org.kie.kogito.usertask.model.Reassignment;
import org.kie.kogito.usertask.model.ScheduleInfo;
@@ -38,12 +38,12 @@ public class DeadlineHelperTest {
@Test
public void testRepetition() {
- Collection<DeadlineInfo<Map<String, Object>>> deadlines = DeadlineHelper.parseDeadlines(
+ Collection<DeadlineInfo<Notification>> deadlines = DeadlineHelper.parseDeadlines(
"[subject:5secs|body:NotCompleted repeated notification every 5secs]@[R/PT5S]");
assertThat(deadlines).hasSize(1);
- DeadlineInfo<Map<String, Object>> deadlineInfo = deadlines.iterator().next();
- assertThat(deadlineInfo.getNotification()).containsEntry("subject", "5secs");
- assertThat(deadlineInfo.getNotification()).containsEntry("body", "NotCompleted repeated notification every 5secs");
+ DeadlineInfo<Notification> deadlineInfo = deadlines.iterator().next();
+ assertThat(deadlineInfo.getNotification().getData()).containsEntry("subject", "5secs");
+ assertThat(deadlineInfo.getNotification().getData()).containsEntry("body", "NotCompleted repeated notification every 5secs");
Collection<ScheduleInfo> scheduling = deadlineInfo.getScheduleInfo();
assertThat(scheduling).hasSize(1);
ScheduleInfo scheduleInfo = scheduling.iterator().next();
@@ -61,11 +61,11 @@ public class DeadlineHelperTest {
@Test
public void testRepetitionWithEndDate() {
ZonedDateTime future = ZonedDateTime.now().plus(Duration.ofMinutes(2)).plus(Duration.ofSeconds(2));
- Collection<DeadlineInfo<Map<String, Object>>> deadlines = DeadlineHelper.parseDeadlines(
+ Collection<DeadlineInfo<Notification>> deadlines = DeadlineHelper.parseDeadlines(
"[subject:5secs]@[R/PT5S/" + future.format(DateTimeFormatter.ISO_OFFSET_DATE_TIME) + "]");
assertThat(deadlines).hasSize(1);
- DeadlineInfo<Map<String, Object>> deadlineInfo = deadlines.iterator().next();
- assertThat(deadlineInfo.getNotification()).containsEntry("subject", "5secs");
+ DeadlineInfo<Notification> deadlineInfo = deadlines.iterator().next();
+ assertThat(deadlineInfo.getNotification().getData()).containsEntry("subject", "5secs");
Collection<ScheduleInfo> scheduling = deadlineInfo.getScheduleInfo();
assertThat(scheduling).hasSize(1);
ScheduleInfo scheduleInfo = scheduling.iterator().next();
@@ -82,11 +82,11 @@ public class DeadlineHelperTest {
@Test
public void testRepetitionWithEndDateCornerCase() {
ZonedDateTime future = ZonedDateTime.now().plus(Duration.ofSeconds(5));
- Collection<DeadlineInfo<Map<String, Object>>> deadlines = DeadlineHelper.parseDeadlines(
+ Collection<DeadlineInfo<Notification>> deadlines = DeadlineHelper.parseDeadlines(
"[subject:5secs]@[R/PT5S/" + future.format(DateTimeFormatter.ISO_OFFSET_DATE_TIME) + "]");
assertThat(deadlines).hasSize(1);
- DeadlineInfo<Map<String, Object>> deadlineInfo = deadlines.iterator().next();
- assertThat(deadlineInfo.getNotification()).containsEntry("subject", "5secs");
+ DeadlineInfo<Notification> deadlineInfo = deadlines.iterator().next();
+ assertThat(deadlineInfo.getNotification().getData()).containsEntry("subject", "5secs");
Collection<ScheduleInfo> scheduling = deadlineInfo.getScheduleInfo();
assertThat(scheduling).hasSize(1);
ScheduleInfo scheduleInfo = scheduling.iterator().next();
@@ -103,11 +103,11 @@ public class DeadlineHelperTest {
@Test
public void testRepetitionWithEndDateAndLimit() {
- Collection<DeadlineInfo<Map<String, Object>>> deadlines = DeadlineHelper.parseDeadlines(
+ Collection<DeadlineInfo<Notification>> deadlines = DeadlineHelper.parseDeadlines(
"[subject:5secs]@[R2/PT5S/2021-03-18T18:55:01+01:00]");
assertThat(deadlines).hasSize(1);
- DeadlineInfo<Map<String, Object>> deadlineInfo = deadlines.iterator().next();
- assertThat(deadlineInfo.getNotification()).containsEntry("subject", "5secs");
+ DeadlineInfo<Notification> deadlineInfo = deadlines.iterator().next();
+ assertThat(deadlineInfo.getNotification().getData()).containsEntry("subject", "5secs");
Collection<ScheduleInfo> scheduling = deadlineInfo.getScheduleInfo();
assertThat(scheduling).hasSize(1);
ScheduleInfo scheduleInfo = scheduling.iterator().next();
@@ -124,11 +124,11 @@ public class DeadlineHelperTest {
@Test
public void testRepetitionStartEndDate() {
- Collection<DeadlineInfo<Map<String, Object>>> deadlines = DeadlineHelper.parseDeadlines(
+ Collection<DeadlineInfo<Notification>> deadlines = DeadlineHelper.parseDeadlines(
"[subject:5secs]@[R1/2021-03-18T18:55:01+01:00/2021-03-18T18:55:06+01:00]");
assertThat(deadlines).hasSize(1);
- DeadlineInfo<Map<String, Object>> deadlineInfo = deadlines.iterator().next();
- assertThat(deadlineInfo.getNotification()).containsEntry("subject", "5secs");
+ DeadlineInfo<Notification> deadlineInfo = deadlines.iterator().next();
+ assertThat(deadlineInfo.getNotification().getData()).containsEntry("subject", "5secs");
Collection<ScheduleInfo> scheduling = deadlineInfo.getScheduleInfo();
assertThat(scheduling).hasSize(1);
ScheduleInfo scheduleInfo = scheduling.iterator().next();
@@ -145,11 +145,11 @@ public class DeadlineHelperTest {
@Test
public void testRepetitionWithStartDate() {
- Collection<DeadlineInfo<Map<String, Object>>> deadlines = DeadlineHelper.parseDeadlines(
+ Collection<DeadlineInfo<Notification>> deadlines = DeadlineHelper.parseDeadlines(
"[subject:5secs]@[R26/2021-03-18T18:55:01+01:00/PT2M]");
assertThat(deadlines).hasSize(1);
- DeadlineInfo<Map<String, Object>> deadlineInfo = deadlines.iterator().next();
- assertThat(deadlineInfo.getNotification()).containsEntry("subject", "5secs");
+ DeadlineInfo<Notification> deadlineInfo = deadlines.iterator().next();
+ assertThat(deadlineInfo.getNotification().getData()).containsEntry("subject", "5secs");
Collection<ScheduleInfo> scheduling = deadlineInfo.getScheduleInfo();
assertThat(scheduling).hasSize(1);
ScheduleInfo scheduleInfo = scheduling.iterator().next();
@@ -166,11 +166,11 @@ public class DeadlineHelperTest {
@Test
public void testExactDate() {
- Collection<DeadlineInfo<Map<String, Object>>> deadlines = DeadlineHelper.parseDeadlines(
+ Collection<DeadlineInfo<Notification>> deadlines = DeadlineHelper.parseDeadlines(
"[subject:exact date]@[2021-03-18T18:55:01+01:00]");
assertThat(deadlines).hasSize(1);
- DeadlineInfo<Map<String, Object>> deadlineInfo = deadlines.iterator().next();
- assertThat(deadlineInfo.getNotification()).containsEntry("subject", "exact date");
+ DeadlineInfo<Notification> deadlineInfo = deadlines.iterator().next();
+ assertThat(deadlineInfo.getNotification().getData()).containsEntry("subject", "exact date");
Collection<ScheduleInfo> scheduling = deadlineInfo.getScheduleInfo();
assertThat(scheduling).hasSize(1);
ScheduleInfo scheduleInfo = scheduling.iterator().next();
@@ -187,11 +187,11 @@ public class DeadlineHelperTest {
@Test
public void testLargeRepetition() {
- Collection<DeadlineInfo<Map<String, Object>>> deadlines = DeadlineHelper.parseDeadlines(
+ Collection<DeadlineInfo<Notification>> deadlines = DeadlineHelper.parseDeadlines(
"[subject:more than 1 year]@[R/P1Y3WT1H]");
assertThat(deadlines).hasSize(1);
- DeadlineInfo<Map<String, Object>> deadlineInfo = deadlines.iterator().next();
- assertThat(deadlineInfo.getNotification()).containsEntry("subject", "more than 1 year");
+ DeadlineInfo<Notification> deadlineInfo = deadlines.iterator().next();
+ assertThat(deadlineInfo.getNotification().getData()).containsEntry("subject", "more than 1 year");
Collection<ScheduleInfo> scheduling = deadlineInfo.getScheduleInfo();
assertThat(scheduling).hasSize(1);
ScheduleInfo scheduleInfo = scheduling.iterator().next();
@@ -209,11 +209,11 @@ public class DeadlineHelperTest {
@Test
public void testMultipleDuration() {
- Collection<DeadlineInfo<Map<String, Object>>> deadlines = DeadlineHelper.parseDeadlines(
+ Collection<DeadlineInfo<Notification>> deadlines = DeadlineHelper.parseDeadlines(
"[subject:1 and 4 hour]@[PT1H,PT4H]");
assertThat(deadlines).hasSize(1);
- DeadlineInfo<Map<String, Object>> deadlineInfo = deadlines.iterator().next();
- assertThat(deadlineInfo.getNotification()).containsEntry("subject", "1 and 4 hour");
+ DeadlineInfo<Notification> deadlineInfo = deadlines.iterator().next();
+ assertThat(deadlineInfo.getNotification().getData()).containsEntry("subject", "1 and 4 hour");
Collection<ScheduleInfo> scheduling = deadlineInfo.getScheduleInfo();
assertThat(scheduling).hasSize(2);
assertThat(scheduling.stream().filter(s -> s.getDuration().equals(Duration.ofHours(1)) || s.getDuration()
@@ -222,14 +222,14 @@ public class DeadlineHelperTest {
@Test
public void testMultipleNotification() {
- Collection<DeadlineInfo<Map<String, Object>>> deadlines = DeadlineHelper.parseDeadlines(
+ Collection<DeadlineInfo<Notification>> deadlines = DeadlineHelper.parseDeadlines(
"[subject:1 hour]@[PT1H]^[subject:4 hour]@[PT4H]");
assertThat(deadlines).hasSize(2);
- for (DeadlineInfo<Map<String, Object>> deadline : deadlines) {
- if ("1 hour".equals(deadline.getNotification().get("subject"))) {
+ for (DeadlineInfo<Notification> deadline : deadlines) {
+ if ("1 hour".equals(deadline.getNotification().getData().get("subject"))) {
assertThat(deadline.getScheduleInfo().iterator().next().getDuration()).isEqualTo(Duration.ofHours(1));
- } else if ("4 hour".equals(deadline.getNotification().get("subject"))) {
+ } else if ("4 hour".equals(deadline.getNotification().getData().get("subject"))) {
assertThat(deadline.getScheduleInfo().iterator().next().getDuration()).isEqualTo(Duration.ofHours(4));
} else {
fail("Unexpected subject value");
diff --git a/kogito-codegen-modules/kogito-codegen-core/src/main/java/org/kie/kogito/codegen/core/ApplicationConfigGenerator.java b/kogito-codegen-modules/kogito-codegen-core/src/main/java/org/kie/kogito/codegen/core/ApplicationConfigGenerator.java
index 7e54343178..5cec2c94a1 100644
--- a/kogito-codegen-modules/kogito-codegen-core/src/main/java/org/kie/kogito/codegen/core/ApplicationConfigGenerator.java
+++ b/kogito-codegen-modules/kogito-codegen-core/src/main/java/org/kie/kogito/codegen/core/ApplicationConfigGenerator.java
@@ -34,11 +34,12 @@ import org.kie.kogito.codegen.api.template.TemplatedGenerator;
import com.github.javaparser.ast.CompilationUnit;
import com.github.javaparser.ast.body.ClassOrInterfaceDeclaration;
+import com.github.javaparser.ast.body.ConstructorDeclaration;
import com.github.javaparser.ast.expr.MethodCallExpr;
import com.github.javaparser.ast.expr.NameExpr;
import com.github.javaparser.ast.expr.ObjectCreationExpr;
import com.github.javaparser.ast.expr.StringLiteralExpr;
-import com.github.javaparser.ast.stmt.ExplicitConstructorInvocationStmt;
+import com.github.javaparser.ast.stmt.BlockStmt;
import static org.kie.kogito.codegen.core.CodegenUtils.newObject;
@@ -102,7 +103,7 @@ public class ApplicationConfigGenerator {
templatedGenerator,
"Compilation unit doesn't contain a class or interface declaration!"));
- initConfigs(getSuperStatement(cls), configClassNames);
+ initConfigs(getInitStatement(cls), configClassNames);
}
return new GeneratedFile(ConfigGenerator.APPLICATION_CONFIG_TYPE,
@@ -138,8 +139,8 @@ public class ApplicationConfigGenerator {
this.addons = addons;
}
- private ExplicitConstructorInvocationStmt getSuperStatement(ClassOrInterfaceDeclaration cls) {
- return cls.findFirst(ExplicitConstructorInvocationStmt.class)
+ private BlockStmt getInitStatement(ClassOrInterfaceDeclaration cls) {
+ return cls.findFirst(ConstructorDeclaration.class).map(ConstructorDeclaration::getBody)
.orElseThrow(() -> new InvalidTemplateException(
templatedGenerator,
"Impossible to find super invocation"));
@@ -154,10 +155,13 @@ public class ApplicationConfigGenerator {
* @param superInvocation
* @param configClassNames
*/
- private void initConfigs(ExplicitConstructorInvocationStmt superInvocation, Collection<String> configClassNames) {
- configClassNames.stream()
- .map(config -> new ObjectCreationExpr()
- .setType(config))
- .forEach(superInvocation::addArgument);
+ private void initConfigs(BlockStmt initInvocation, Collection<String> configClassNames) {
+ initInvocation.findFirst(MethodCallExpr.class).ifPresent(call -> {
+ configClassNames
+ .stream()
+ .map(config -> new ObjectCreationExpr().setType(config))
+ .forEach(call::addArgument);
+ });
+
}
}
diff --git a/kogito-codegen-modules/kogito-codegen-core/src/main/resources/class-templates/config/ApplicationConfigJavaTemplate.java b/kogito-codegen-modules/kogito-codegen-core/src/main/resources/class-templates/config/ApplicationConfigJavaTemplate.java
index 64cea466d1..1d872f1d2f 100644
--- a/kogito-codegen-modules/kogito-codegen-core/src/main/resources/class-templates/config/ApplicationConfigJavaTemplate.java
+++ b/kogito-codegen-modules/kogito-codegen-core/src/main/resources/class-templates/config/ApplicationConfigJavaTemplate.java
@@ -21,6 +21,6 @@ package $Package$;
public class ApplicationConfig extends org.kie.kogito.StaticConfig {
public ApplicationConfig() {
- super($Addons$ /* additional values provided during codegen */);
+ init($Addons$ /* additional values provided during codegen */);
}
}
diff --git a/kogito-codegen-modules/kogito-codegen-core/src/main/resources/class-templates/config/ApplicationConfigQuarkusTemplate.java b/kogito-codegen-modules/kogito-codegen-core/src/main/resources/class-templates/config/ApplicationConfigQuarkusTemplate.java
index a329586e4b..b09fc59ae9 100644
--- a/kogito-codegen-modules/kogito-codegen-core/src/main/resources/class-templates/config/ApplicationConfigQuarkusTemplate.java
+++ b/kogito-codegen-modules/kogito-codegen-core/src/main/resources/class-templates/config/ApplicationConfigQuarkusTemplate.java
@@ -24,8 +24,7 @@ import jakarta.enterprise.inject.Instance;
public class ApplicationConfig extends org.kie.kogito.StaticConfig {
@jakarta.inject.Inject
- public ApplicationConfig(
- Instance<org.kie.kogito.KogitoConfig> configs) {
- super($Addons$, configs);
+ public ApplicationConfig(Instance<org.kie.kogito.KogitoConfig> configs) {
+ init($Addons$, configs);
}
}
\ No newline at end of file
diff --git a/kogito-codegen-modules/kogito-codegen-core/src/main/resources/class-templates/config/ApplicationConfigSpringTemplate.java b/kogito-codegen-modules/kogito-codegen-core/src/main/resources/class-templates/config/ApplicationConfigSpringTemplate.java
index 74e3c06683..3b403429d6 100644
--- a/kogito-codegen-modules/kogito-codegen-core/src/main/resources/class-templates/config/ApplicationConfigSpringTemplate.java
+++ b/kogito-codegen-modules/kogito-codegen-core/src/main/resources/class-templates/config/ApplicationConfigSpringTemplate.java
@@ -24,8 +24,7 @@ import java.util.Collection;
public class ApplicationConfig extends org.kie.kogito.StaticConfig {
@org.springframework.beans.factory.annotation.Autowired
- public ApplicationConfig(
- Collection<org.kie.kogito.KogitoConfig> configs) {
- super($Addons$, configs);
+ public ApplicationConfig(Collection<org.kie.kogito.KogitoConfig> configs) {
+ init($Addons$, configs);
}
}
diff --git a/kogito-codegen-modules/kogito-codegen-processes-integration-tests/src/test/java/org/kie/kogito/codegen/tests/UserTaskIT.java b/kogito-codegen-modules/kogito-codegen-processes-integration-tests/src/test/java/org/kie/kogito/codegen/tests/UserTaskIT.java
index 150c3d62ba..4a6182d0e1 100644
--- a/kogito-codegen-modules/kogito-codegen-processes-integration-tests/src/test/java/org/kie/kogito/codegen/tests/UserTaskIT.java
+++ b/kogito-codegen-modules/kogito-codegen-processes-integration-tests/src/test/java/org/kie/kogito/codegen/tests/UserTaskIT.java
@@ -20,11 +20,14 @@ package org.kie.kogito.codegen.tests;
import java.lang.reflect.Field;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
import org.junit.jupiter.api.Test;
import org.kie.kogito.Application;
@@ -48,9 +51,13 @@ import org.kie.kogito.process.Processes;
import org.kie.kogito.process.VariableViolationException;
import org.kie.kogito.process.WorkItem;
import org.kie.kogito.usertask.UserTaskConfig;
+import org.kie.kogito.usertask.UserTaskEventListener;
import org.kie.kogito.usertask.UserTaskInstance;
import org.kie.kogito.usertask.UserTaskInstanceNotAuthorizedException;
import org.kie.kogito.usertask.UserTasks;
+import org.kie.kogito.usertask.events.UserTaskAssignmentEvent;
+import org.kie.kogito.usertask.events.UserTaskDeadlineEvent;
+import org.kie.kogito.usertask.events.UserTaskDeadlineEvent.DeadlineType;
import org.kie.kogito.usertask.impl.lifecycle.DefaultUserTaskLifeCycle;
import static java.util.Collections.emptyList;
@@ -59,6 +66,7 @@ import static java.util.Collections.singletonList;
import static java.util.Collections.singletonMap;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
+import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.kie.kogito.usertask.impl.lifecycle.DefaultUserTaskLifeCycle.CLAIM;
import static org.kie.kogito.usertask.impl.lifecycle.DefaultUserTaskLifeCycle.COMPLETE;
import static org.kie.kogito.usertask.impl.lifecycle.DefaultUserTaskLifeCycle.RELEASE;
@@ -953,4 +961,357 @@ public class UserTaskIT extends AbstractCodegenIT {
assertThat(otherProcessInstance.id()).isNotEqualTo(processInstance.id());
assertThat(otherProcessInstance.businessKey()).isEqualTo(processInstance.businessKey()).isEqualTo(businessKey);
}
+
+ @Test
+ public void testUserTaskNotStartedDeadlineWithExpressionReplacement() throws Exception {
+ CountDownLatch latch = new CountDownLatch(2);
+ Application app = generateCodeProcessesOnly("usertask/UserTasksNotStartedDeadline.bpmn2");
+ assertThat(app).isNotNull();
+ List<String> subjects = new ArrayList<>();
+ List<String> bodies = new ArrayList<>();
+ List<UserTaskDeadlineEvent.DeadlineType> types = new ArrayList<>();
+
+ app.config().get(UserTaskConfig.class).userTaskEventListeners().listeners().add(new UserTaskEventListener() {
+ @Override
+ public void onUserTaskDeadline(UserTaskDeadlineEvent event) {
+ subjects.add((String) event.getNotification().get("subject"));
+ bodies.add((String) event.getNotification().get("body"));
+ types.add(event.getType());
+ latch.countDown();
+ }
+
+ });
+ Process<? extends Model> p = app.get(Processes.class).processById("UserTasksDeadline");
+
+ Model m = p.createModel();
+ Map<String, Object> parameters = new HashMap<>();
+ parameters.put("subject", "this is my subject");
+ parameters.put("body", "this is my body");
+ m.fromMap(parameters);
+
+ // assign custom business key for process instance
+ String businessKey = "business key";
+ ProcessInstance<?> processInstance = p.createInstance(businessKey, m);
+ processInstance.start();
+
+ assertThat(processInstance.status()).isEqualTo(ProcessInstance.STATE_ACTIVE);
+ // verify that custom business key is assigned properly
+ assertThat(processInstance.businessKey()).isEqualTo(businessKey);
+
+ // start another process instance with assigned duplicated business key of already active instance
+ ProcessInstance<? extends Model> otherProcessInstance = p.createInstance(businessKey, m);
+ assertThat(otherProcessInstance.id()).isNotEqualTo(processInstance.id());
+ assertThat(otherProcessInstance.businessKey()).isEqualTo(processInstance.businessKey()).isEqualTo(businessKey);
+ latch.await(5L, TimeUnit.SECONDS);
+ String subject = "Task is ready for ${owners[0].id}";
+ String body = "<html>\n"
+ + " <body>\n"
+ + " Reason this is my subject<br/>\n"
+ + " body of notification this is my body\n"
+ + " </body>\n"
+ + " </html>";
+ assertThat(subjects).containsExactly(subject, subject);
+ assertThat(bodies).containsExactly(body, body);
+ assertThat(types).containsExactly(DeadlineType.Started, DeadlineType.Started);
+ }
+
+ @Test
+ public void testUserTaskNotStartedDeadlineWithExpressionReplacementStopTimer() throws Exception {
+ CountDownLatch latch = new CountDownLatch(2);
+ Application app = generateCodeProcessesOnly("usertask/UserTasksNotStartedDeadline.bpmn2");
+ assertThat(app).isNotNull();
+
+ app.config().get(UserTaskConfig.class).userTaskEventListeners().listeners().add(new UserTaskEventListener() {
+ @Override
+ public void onUserTaskDeadline(UserTaskDeadlineEvent event) {
+ latch.countDown();
+ }
+
+ });
+ Process<? extends Model> p = app.get(Processes.class).processById("UserTasksDeadline");
+
+ Model m = p.createModel();
+ Map<String, Object> parameters = new HashMap<>();
+ parameters.put("subject", "this is my subject");
+ parameters.put("body", "this is my body");
+ m.fromMap(parameters);
+
+ // assign custom business key for process instance
+ String businessKey = "business key";
+ ProcessInstance<?> processInstance = p.createInstance(businessKey, m);
+ processInstance.start();
+
+ assertThat(processInstance.status()).isEqualTo(ProcessInstance.STATE_ACTIVE);
+ // verify that custom business key is assigned properly
+ assertThat(processInstance.businessKey()).isEqualTo(businessKey);
+ IdentityProvider mary = IdentityProviders.of("mary");
+ List<UserTaskInstance> userTaskInstances = app.get(UserTasks.class).instances().findByIdentity(mary);
+ userTaskInstances.forEach(e -> e.transition(DefaultUserTaskLifeCycle.CLAIM, Collections.emptyMap(), mary));
+
+ // start another process instance with assigned duplicated business key of already active instance
+ ProcessInstance<? extends Model> otherProcessInstance = p.createInstance(businessKey, m);
+ assertThat(otherProcessInstance.id()).isNotEqualTo(processInstance.id());
+ assertThat(otherProcessInstance.businessKey()).isEqualTo(processInstance.businessKey()).isEqualTo(businessKey);
+ assertThat(latch.await(5L, TimeUnit.SECONDS)).isFalse();
+
+ }
+
+ @Test
+ public void testUserTaskNotStartedReassign() throws Exception {
+ CountDownLatch latch = new CountDownLatch(1);
+ Application app = generateCodeProcessesOnly("usertask/UserTasksNotStartedReasssign.bpmn2");
+ assertThat(app).isNotNull();
+
+ app.config().get(UserTaskConfig.class).userTaskEventListeners().listeners().add(new UserTaskEventListener() {
+ @Override
+ public void onUserTaskAssignment(UserTaskAssignmentEvent event) {
+ List<String> users = Arrays.asList(event.getNewUsersId());
+ if (users.size() == 1 && users.contains("mike")) {
+ latch.countDown();
+ }
+ }
+ });
+ Process<? extends Model> p = app.get(Processes.class).processById("UserTasksDeadline");
+
+ Model m = p.createModel();
+ Map<String, Object> parameters = new HashMap<>();
+ parameters.put("subject", "this is my subject");
+ parameters.put("body", "this is my body");
+ m.fromMap(parameters);
+
+ // assign custom business key for process instance
+ String businessKey = "business key";
+ ProcessInstance<?> processInstance = p.createInstance(businessKey, m);
+ processInstance.start();
+
+ assertThat(processInstance.status()).isEqualTo(ProcessInstance.STATE_ACTIVE);
+ // verify that custom business key is assigned properly
+ assertThat(processInstance.businessKey()).isEqualTo(businessKey);
+
+ // start another process instance with assigned duplicated business key of already active instance
+ ProcessInstance<? extends Model> otherProcessInstance = p.createInstance(businessKey, m);
+ assertThat(otherProcessInstance.id()).isNotEqualTo(processInstance.id());
+ assertThat(otherProcessInstance.businessKey()).isEqualTo(processInstance.businessKey()).isEqualTo(businessKey);
+ assertThat(latch.await(5L, TimeUnit.SECONDS)).isTrue();
+ }
+
+ @Test
+ public void testUserTaskNotStartedReassignStopTimers() throws Exception {
+ CountDownLatch latch = new CountDownLatch(1);
+ Application app = generateCodeProcessesOnly("usertask/UserTasksNotStartedReasssign.bpmn2");
+ assertThat(app).isNotNull();
+
+ app.config().get(UserTaskConfig.class).userTaskEventListeners().listeners().add(new UserTaskEventListener() {
+ @Override
+ public void onUserTaskAssignment(UserTaskAssignmentEvent event) {
+ List<String> users = Arrays.asList(event.getNewUsersId());
+ if (users.size() == 1 && users.contains("mike")) {
+ latch.countDown();
+ }
+ }
+ });
+ Process<? extends Model> p = app.get(Processes.class).processById("UserTasksDeadline");
+
+ Model m = p.createModel();
+ Map<String, Object> parameters = new HashMap<>();
+ parameters.put("subject", "this is my subject");
+ parameters.put("body", "this is my body");
+ m.fromMap(parameters);
+
+ // assign custom business key for process instance
+ String businessKey = "business key";
+ ProcessInstance<?> processInstance = p.createInstance(businessKey, m);
+ processInstance.start();
+
+ assertThat(processInstance.status()).isEqualTo(ProcessInstance.STATE_ACTIVE);
+
+ // verify that custom business key is assigned properly
+ assertThat(processInstance.businessKey()).isEqualTo(businessKey);
+ IdentityProvider mary = IdentityProviders.of("mary");
+ List<UserTaskInstance> userTaskInstances = app.get(UserTasks.class).instances().findByIdentity(mary);
+ userTaskInstances.forEach(e -> e.transition(DefaultUserTaskLifeCycle.CLAIM, Collections.emptyMap(), mary));
+
+ // start another process instance with assigned duplicated business key of already active instance
+ ProcessInstance<? extends Model> otherProcessInstance = p.createInstance(businessKey, m);
+ assertThat(otherProcessInstance.id()).isNotEqualTo(processInstance.id());
+ assertThat(otherProcessInstance.businessKey()).isEqualTo(processInstance.businessKey()).isEqualTo(businessKey);
+ assertThat(latch.await(2L, TimeUnit.SECONDS)).isFalse();
+ }
+
+ @Test
+ public void testUserTaskNotCompletedDeadlineWithReplacement() throws Exception {
+ CountDownLatch latch = new CountDownLatch(1);
+ Application app = generateCodeProcessesOnly("usertask/UserTasksNotCompletedDeadline.bpmn2");
+ assertThat(app).isNotNull();
+
+ List<String> subjects = new ArrayList<>();
+ List<String> bodies = new ArrayList<>();
+ List<UserTaskDeadlineEvent.DeadlineType> types = new ArrayList<>();
+ app.config().get(UserTaskConfig.class).userTaskEventListeners().listeners().add(new UserTaskEventListener() {
+ @Override
+ public void onUserTaskDeadline(UserTaskDeadlineEvent event) {
+ subjects.add((String) event.getNotification().get("subject"));
+ bodies.add((String) event.getNotification().get("body"));
+ types.add(event.getType());
+ latch.countDown();
+ }
+ });
+ Process<? extends Model> p = app.get(Processes.class).processById("UserTasksDeadline");
+
+ Model m = p.createModel();
+ Map<String, Object> parameters = new HashMap<>();
+ parameters.put("body", "my body!!!");
+ m.fromMap(parameters);
+
+ // assign custom business key for process instance
+ String businessKey = "business key";
+ ProcessInstance<?> processInstance = p.createInstance(businessKey, m);
+ processInstance.start();
+
+ assertThat(processInstance.status()).isEqualTo(ProcessInstance.STATE_ACTIVE);
+ // verify that custom business key is assigned properly
+ assertThat(processInstance.businessKey()).isEqualTo(businessKey);
+
+ // start another process instance with assigned duplicated business key of already active instance
+ ProcessInstance<? extends Model> otherProcessInstance = p.createInstance(businessKey, m);
+ assertThat(otherProcessInstance.id()).isNotEqualTo(processInstance.id());
+ assertThat(otherProcessInstance.businessKey()).isEqualTo(processInstance.businessKey()).isEqualTo(businessKey);
+ assertTrue(latch.await(5L, TimeUnit.SECONDS));
+ latch.await(5L, TimeUnit.SECONDS);
+ String subject = "Not completedTask is ready for ${owners[0].id}";
+ String body = "my body!!!";
+ assertThat(subjects).containsExactly(subject);
+ assertThat(bodies).containsExactly(body);
+ assertThat(types).containsExactly(DeadlineType.Completed);
+ }
+
+ @Test
+ public void testUserTaskNotCompletedDeadlineWithReplacementStopTimer() throws Exception {
+ CountDownLatch latch = new CountDownLatch(2);
+ Application app = generateCodeProcessesOnly("usertask/UserTasksNotCompletedDeadline.bpmn2");
+ assertThat(app).isNotNull();
+
+ app.config().get(UserTaskConfig.class).userTaskEventListeners().listeners().add(new UserTaskEventListener() {
+ @Override
+ public void onUserTaskDeadline(UserTaskDeadlineEvent event) {
+ latch.countDown();
+ }
+
+ });
+ Process<? extends Model> p = app.get(Processes.class).processById("UserTasksDeadline");
+
+ Model m = p.createModel();
+ Map<String, Object> parameters = new HashMap<>();
+ parameters.put("subject", "this is my subject");
+ parameters.put("body", "this is my body");
+ m.fromMap(parameters);
+
+ // assign custom business key for process instance
+ String businessKey = "business key";
+ ProcessInstance<?> processInstance = p.createInstance(businessKey, m);
+ processInstance.start();
+
+ assertThat(processInstance.status()).isEqualTo(ProcessInstance.STATE_ACTIVE);
+ // verify that custom business key is assigned properly
+ assertThat(processInstance.businessKey()).isEqualTo(businessKey);
+ IdentityProvider mary = IdentityProviders.of("mary");
+ List<UserTaskInstance> userTaskInstances = app.get(UserTasks.class).instances().findByIdentity(mary);
+ userTaskInstances.forEach(e -> {
+ e.transition(DefaultUserTaskLifeCycle.CLAIM, emptyMap(), mary);
+ e.transition(DefaultUserTaskLifeCycle.COMPLETE, emptyMap(), mary);
+ });
+
+ // start another process instance with assigned duplicated business key of already active instance
+ ProcessInstance<? extends Model> otherProcessInstance = p.createInstance(businessKey, m);
+ assertThat(otherProcessInstance.id()).isNotEqualTo(processInstance.id());
+ assertThat(otherProcessInstance.businessKey()).isEqualTo(processInstance.businessKey()).isEqualTo(businessKey);
+ assertThat(latch.await(5L, TimeUnit.SECONDS)).isFalse();
+
+ }
+
+ @Test
+ public void testUserTaskNotCompletedReassign() throws Exception {
+ CountDownLatch latch = new CountDownLatch(1);
+ Application app = generateCodeProcessesOnly("usertask/UserTasksNotCompletedReassign.bpmn2");
+ assertThat(app).isNotNull();
+
+ app.config().get(UserTaskConfig.class).userTaskEventListeners().listeners().add(new UserTaskEventListener() {
+ @Override
+ public void onUserTaskAssignment(UserTaskAssignmentEvent event) {
+ List<String> users = Arrays.asList(event.getNewUsersId());
+ if (users.size() == 1 && users.contains("mike")) {
+ latch.countDown();
+ }
+ }
+ });
+ Process<? extends Model> p = app.get(Processes.class).processById("UserTasksDeadline");
+
+ Model m = p.createModel();
+ Map<String, Object> parameters = new HashMap<>();
+ parameters.put("body", "my body!!!");
+ m.fromMap(parameters);
+
+ // assign custom business key for process instance
+ String businessKey = "business key";
+ ProcessInstance<?> processInstance = p.createInstance(businessKey, m);
+ processInstance.start();
+
+ assertThat(processInstance.status()).isEqualTo(ProcessInstance.STATE_ACTIVE);
+ // verify that custom business key is assigned properly
+ assertThat(processInstance.businessKey()).isEqualTo(businessKey);
+
+ // start another process instance with assigned duplicated business key of already active instance
+ ProcessInstance<? extends Model> otherProcessInstance = p.createInstance(businessKey, m);
+ assertThat(otherProcessInstance.id()).isNotEqualTo(processInstance.id());
+ assertThat(otherProcessInstance.businessKey()).isEqualTo(processInstance.businessKey()).isEqualTo(businessKey);
+ assertTrue(latch.await(5L, TimeUnit.SECONDS));
+
+ }
+
+ @Test
+ public void testUserTaskNotCompletedReassignStopTimer() throws Exception {
+ CountDownLatch latch = new CountDownLatch(1);
+ Application app = generateCodeProcessesOnly("usertask/UserTasksNotCompletedReassign.bpmn2");
+ assertThat(app).isNotNull();
+
+ app.config().get(UserTaskConfig.class).userTaskEventListeners().listeners().add(new UserTaskEventListener() {
+ @Override
+ public void onUserTaskAssignment(UserTaskAssignmentEvent event) {
+ List<String> users = Arrays.asList(event.getNewUsersId());
+ if (users.size() == 1 && users.contains("mike")) {
+ latch.countDown();
+ }
+ }
+
+ });
+ Process<? extends Model> p = app.get(Processes.class).processById("UserTasksDeadline");
+
+ Model m = p.createModel();
+ Map<String, Object> parameters = new HashMap<>();
+ parameters.put("subject", "this is my subject");
+ parameters.put("body", "this is my body");
+ m.fromMap(parameters);
+
+ // assign custom business key for process instance
+ String businessKey = "business key";
+ ProcessInstance<?> processInstance = p.createInstance(businessKey, m);
+ processInstance.start();
+
+ assertThat(processInstance.status()).isEqualTo(ProcessInstance.STATE_ACTIVE);
+ // verify that custom business key is assigned properly
+ assertThat(processInstance.businessKey()).isEqualTo(businessKey);
+ IdentityProvider mary = IdentityProviders.of("mary");
+ List<UserTaskInstance> userTaskInstances = app.get(UserTasks.class).instances().findByIdentity(mary);
+ userTaskInstances.forEach(e -> {
+ e.transition(DefaultUserTaskLifeCycle.CLAIM, emptyMap(), mary);
+ e.transition(DefaultUserTaskLifeCycle.COMPLETE, emptyMap(), mary);
+ });
+
+ // start another process instance with assigned duplicated business key of already active instance
+ ProcessInstance<? extends Model> otherProcessInstance = p.createInstance(businessKey, m);
+ assertThat(otherProcessInstance.id()).isNotEqualTo(processInstance.id());
+ assertThat(otherProcessInstance.businessKey()).isEqualTo(processInstance.businessKey()).isEqualTo(businessKey);
+ assertThat(latch.await(2L, TimeUnit.SECONDS)).isFalse();
+
+ }
}
diff --git a/kogito-codegen-modules/kogito-codegen-processes-integration-tests/src/test/resources/usertask/UserTasksNotCompletedDeadline.bpmn2 b/kogito-codegen-modules/kogito-codegen-processes-integration-tests/src/test/resources/usertask/UserTasksNotCompletedDeadline.bpmn2
new file mode 100644
index 0000000000..1c7eb2d169
--- /dev/null
+++ b/kogito-codegen-modules/kogito-codegen-processes-integration-tests/src/test/resources/usertask/UserTasksNotCompletedDeadline.bpmn2
@@ -0,0 +1,124 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<definitions id="Definition"
+ targetNamespace="http://www.example.org/MinimalExample"
+ typeLanguage="http://www.java.com/javaTypes"
+ expressionLanguage="http://www.mvel.org/2.0"
+ xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://www.omg.org/spec/BPMN/20100524/MODEL BPMN20.xsd"
+ xmlns:g="http://www.jboss.org/drools/flow/gpd"
+ xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI"
+ xmlns:dc="http://www.omg.org/spec/DD/20100524/DC"
+ xmlns:di="http://www.omg.org/spec/DD/20100524/DI"
+ xmlns:tns="http://www.jboss.org/drools">
+
+ <itemDefinition id="_sItem" structureRef="String"/>
+
+ <process processType="Private" isExecutable="true" id="UserTasksDeadline" name="User Task Deadline" >
+
+ <!-- process variables -->
+ <property id="s" itemSubjectRef="_sItem"/>
+ <property id="subject" itemSubjectRef="_sItem"/>
+ <property id="body" itemSubjectRef="_sItem"/>
+
+ <!-- nodes -->
+ <startEvent id="_1" name="StartProcess" />
+ <userTask id="_2" name="Hello" >
+ <ioSpecification>
+ <dataInput id="_2_NotCompletedNotifyInput" name="NotCompletedNotify" />
+ <dataInput id="_2_NotStartedNotifyInput" name="NotStartedNotify" />
+ <dataInput id="_2_CommentInput" name="Comment" />
+ <dataInput id="_2_NotCompletedReassignInput" name="NotCompletedReassign" />
+ <dataInput id="_2_SkippableInput" name="Skippable" />
+ <dataInput id="_2_NotStartedReassignInput" name="NotStartedReassign" />
+ <dataInput id="_2_TaskNameInput" name="TaskName" />
+ <dataInput id="_2_GroupIdInput" name="GroupId" />
+ <dataInput id="_2_PriorityInput" name="Priority" />
+ <inputSet>
+ <dataInputRefs>_2_NotCompletedNotifyInput</dataInputRefs>
+ <dataInputRefs>_2_NotStartedNotifyInput</dataInputRefs>
+ <dataInputRefs>_2_CommentInput</dataInputRefs>
+ <dataInputRefs>_2_NotCompletedReassignInput</dataInputRefs>
+ <dataInputRefs>_2_SkippableInput</dataInputRefs>
+ <dataInputRefs>_2_NotStartedReassignInput</dataInputRefs>
+ <dataInputRefs>_2_TaskNameInput</dataInputRefs>
+ <dataInputRefs>_2_GroupIdInput</dataInputRefs>
+ <dataInputRefs>_2_PriorityInput</dataInputRefs>
+ </inputSet>
+ <outputSet>
+ </outputSet>
+ </ioSpecification>
+ <dataInputAssociation>
+ <targetRef>_2_NotCompletedNotifyInput</targetRef>
+ <assignment>
+ <from xsi:type="tFormalExpression">[tousers:mike|subject:Not completedTask is ready for ${owners[0].id}|body:#{body}]@[PT2S]</from>
+ <to xsi:type="tFormalExpression">_2_NotCompletedNotifyInput</to>
+ </assignment>
+ </dataInputAssociation>
+ <dataInputAssociation>
+ <targetRef>_2_SkippableInput</targetRef>
+ <assignment>
+ <from xsi:type="tFormalExpression">false</from>
+ <to xsi:type="tFormalExpression">_2_SkippableInput</to>
+ </assignment>
+ </dataInputAssociation>
+ <dataInputAssociation>
+ <targetRef>_2_TaskNameInput</targetRef>
+ <assignment>
+ <from xsi:type="tFormalExpression"></from>
+ <to xsi:type="tFormalExpression">_2_TaskNameInput</to>
+ </assignment>
+ </dataInputAssociation>
+ <dataInputAssociation>
+ <targetRef>_2_GroupIdInput</targetRef>
+ <assignment>
+ <from xsi:type="tFormalExpression"></from>
+ <to xsi:type="tFormalExpression">_2_GroupIdInput</to>
+ </assignment>
+ </dataInputAssociation>
+ <dataInputAssociation>
+ <targetRef>_2_PriorityInput</targetRef>
+ <assignment>
+ <from xsi:type="tFormalExpression"></from>
+ <to xsi:type="tFormalExpression">_2_PriorityInput</to>
+ </assignment>
+ </dataInputAssociation>
+ <potentialOwner>
+ <resourceAssignmentExpression>
+ <formalExpression>john,mary</formalExpression>
+ </resourceAssignmentExpression>
+ </potentialOwner>
+ </userTask>
+ <endEvent id="_3" name="EndProcess" >
+ <terminateEventDefinition/>
+ </endEvent>
+
+ <!-- connections -->
+ <sequenceFlow id="_1-_2" sourceRef="_1" targetRef="_2" />
+ <sequenceFlow id="_2-_3" sourceRef="_2" targetRef="_3" />
+
+ </process>
+
+ <bpmndi:BPMNDiagram>
+ <bpmndi:BPMNPlane bpmnElement="UserTask" >
+ <bpmndi:BPMNShape bpmnElement="_1" >
+ <dc:Bounds x="16" y="16" width="48" height="48" />
+ </bpmndi:BPMNShape>
+ <bpmndi:BPMNShape bpmnElement="_2" >
+ <dc:Bounds x="96" y="16" width="100" height="48" />
+ </bpmndi:BPMNShape>
+ <bpmndi:BPMNShape bpmnElement="_3" >
+ <dc:Bounds x="228" y="16" width="48" height="48" />
+ </bpmndi:BPMNShape>
+ <bpmndi:BPMNEdge bpmnElement="_1-_2" >
+ <di:waypoint x="40" y="40" />
+ <di:waypoint x="146" y="40" />
+ </bpmndi:BPMNEdge>
+ <bpmndi:BPMNEdge bpmnElement="_2-_3" >
+ <di:waypoint x="146" y="40" />
+ <di:waypoint x="252" y="40" />
+ </bpmndi:BPMNEdge>
+ </bpmndi:BPMNPlane>
+ </bpmndi:BPMNDiagram>
+
+</definitions>
\ No newline at end of file
diff --git a/kogito-codegen-modules/kogito-codegen-processes-integration-tests/src/test/resources/usertask/UserTasksNotCompletedReassign.bpmn2 b/kogito-codegen-modules/kogito-codegen-processes-integration-tests/src/test/resources/usertask/UserTasksNotCompletedReassign.bpmn2
new file mode 100644
index 0000000000..c0f0b33eb8
--- /dev/null
+++ b/kogito-codegen-modules/kogito-codegen-processes-integration-tests/src/test/resources/usertask/UserTasksNotCompletedReassign.bpmn2
@@ -0,0 +1,124 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<definitions id="Definition"
+ targetNamespace="http://www.example.org/MinimalExample"
+ typeLanguage="http://www.java.com/javaTypes"
+ expressionLanguage="http://www.mvel.org/2.0"
+ xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://www.omg.org/spec/BPMN/20100524/MODEL BPMN20.xsd"
+ xmlns:g="http://www.jboss.org/drools/flow/gpd"
+ xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI"
+ xmlns:dc="http://www.omg.org/spec/DD/20100524/DC"
+ xmlns:di="http://www.omg.org/spec/DD/20100524/DI"
+ xmlns:tns="http://www.jboss.org/drools">
+
+ <itemDefinition id="_sItem" structureRef="String"/>
+
+ <process processType="Private" isExecutable="true" id="UserTasksDeadline" name="User Task Deadline" >
+
+ <!-- process variables -->
+ <property id="s" itemSubjectRef="_sItem"/>
+ <property id="subject" itemSubjectRef="_sItem"/>
+ <property id="body" itemSubjectRef="_sItem"/>
+
+ <!-- nodes -->
+ <startEvent id="_1" name="StartProcess" />
+ <userTask id="_2" name="Hello" >
+ <ioSpecification>
+ <dataInput id="_2_NotCompletedNotifyInput" name="NotCompletedNotify" />
+ <dataInput id="_2_NotStartedNotifyInput" name="NotStartedNotify" />
+ <dataInput id="_2_CommentInput" name="Comment" />
+ <dataInput id="_2_NotCompletedReassignInput" name="NotCompletedReassign" />
+ <dataInput id="_2_SkippableInput" name="Skippable" />
+ <dataInput id="_2_NotStartedReassignInput" name="NotStartedReassign" />
+ <dataInput id="_2_TaskNameInput" name="TaskName" />
+ <dataInput id="_2_GroupIdInput" name="GroupId" />
+ <dataInput id="_2_PriorityInput" name="Priority" />
+ <inputSet>
+ <dataInputRefs>_2_NotCompletedNotifyInput</dataInputRefs>
+ <dataInputRefs>_2_NotStartedNotifyInput</dataInputRefs>
+ <dataInputRefs>_2_CommentInput</dataInputRefs>
+ <dataInputRefs>_2_NotCompletedReassignInput</dataInputRefs>
+ <dataInputRefs>_2_SkippableInput</dataInputRefs>
+ <dataInputRefs>_2_NotStartedReassignInput</dataInputRefs>
+ <dataInputRefs>_2_TaskNameInput</dataInputRefs>
+ <dataInputRefs>_2_GroupIdInput</dataInputRefs>
+ <dataInputRefs>_2_PriorityInput</dataInputRefs>
+ </inputSet>
+ <outputSet>
+ </outputSet>
+ </ioSpecification>
+ <dataInputAssociation>
+ <targetRef>_2_NotCompletedReassignInput</targetRef>
+ <assignment>
+ <from xsi:type="tFormalExpression">[users:mike]@[2s]</from>
+ <to xsi:type="tFormalExpression">_2_NotCompletedReassignInput</to>
+ </assignment>
+ </dataInputAssociation>
+ <dataInputAssociation>
+ <targetRef>_2_SkippableInput</targetRef>
+ <assignment>
+ <from xsi:type="tFormalExpression">false</from>
+ <to xsi:type="tFormalExpression">_2_SkippableInput</to>
+ </assignment>
+ </dataInputAssociation>
+ <dataInputAssociation>
+ <targetRef>_2_TaskNameInput</targetRef>
+ <assignment>
+ <from xsi:type="tFormalExpression"></from>
+ <to xsi:type="tFormalExpression">_2_TaskNameInput</to>
+ </assignment>
+ </dataInputAssociation>
+ <dataInputAssociation>
+ <targetRef>_2_GroupIdInput</targetRef>
+ <assignment>
+ <from xsi:type="tFormalExpression"></from>
+ <to xsi:type="tFormalExpression">_2_GroupIdInput</to>
+ </assignment>
+ </dataInputAssociation>
+ <dataInputAssociation>
+ <targetRef>_2_PriorityInput</targetRef>
+ <assignment>
+ <from xsi:type="tFormalExpression"></from>
+ <to xsi:type="tFormalExpression">_2_PriorityInput</to>
+ </assignment>
+ </dataInputAssociation>
+ <potentialOwner>
+ <resourceAssignmentExpression>
+ <formalExpression>john,mary</formalExpression>
+ </resourceAssignmentExpression>
+ </potentialOwner>
+ </userTask>
+ <endEvent id="_3" name="EndProcess" >
+ <terminateEventDefinition/>
+ </endEvent>
+
+ <!-- connections -->
+ <sequenceFlow id="_1-_2" sourceRef="_1" targetRef="_2" />
+ <sequenceFlow id="_2-_3" sourceRef="_2" targetRef="_3" />
+
+ </process>
+
+ <bpmndi:BPMNDiagram>
+ <bpmndi:BPMNPlane bpmnElement="UserTask" >
+ <bpmndi:BPMNShape bpmnElement="_1" >
+ <dc:Bounds x="16" y="16" width="48" height="48" />
+ </bpmndi:BPMNShape>
+ <bpmndi:BPMNShape bpmnElement="_2" >
+ <dc:Bounds x="96" y="16" width="100" height="48" />
+ </bpmndi:BPMNShape>
+ <bpmndi:BPMNShape bpmnElement="_3" >
+ <dc:Bounds x="228" y="16" width="48" height="48" />
+ </bpmndi:BPMNShape>
+ <bpmndi:BPMNEdge bpmnElement="_1-_2" >
+ <di:waypoint x="40" y="40" />
+ <di:waypoint x="146" y="40" />
+ </bpmndi:BPMNEdge>
+ <bpmndi:BPMNEdge bpmnElement="_2-_3" >
+ <di:waypoint x="146" y="40" />
+ <di:waypoint x="252" y="40" />
+ </bpmndi:BPMNEdge>
+ </bpmndi:BPMNPlane>
+ </bpmndi:BPMNDiagram>
+
+</definitions>
\ No newline at end of file
diff --git a/kogito-codegen-modules/kogito-codegen-processes-integration-tests/src/test/resources/usertask/UserTasksNotStartedDeadline.bpmn2 b/kogito-codegen-modules/kogito-codegen-processes-integration-tests/src/test/resources/usertask/UserTasksNotStartedDeadline.bpmn2
new file mode 100644
index 0000000000..d05098a7bf
--- /dev/null
+++ b/kogito-codegen-modules/kogito-codegen-processes-integration-tests/src/test/resources/usertask/UserTasksNotStartedDeadline.bpmn2
@@ -0,0 +1,129 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<definitions id="Definition"
+ targetNamespace="http://www.example.org/MinimalExample"
+ typeLanguage="http://www.java.com/javaTypes"
+ expressionLanguage="http://www.mvel.org/2.0"
+ xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://www.omg.org/spec/BPMN/20100524/MODEL BPMN20.xsd"
+ xmlns:g="http://www.jboss.org/drools/flow/gpd"
+ xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI"
+ xmlns:dc="http://www.omg.org/spec/DD/20100524/DC"
+ xmlns:di="http://www.omg.org/spec/DD/20100524/DI"
+ xmlns:tns="http://www.jboss.org/drools">
+
+ <itemDefinition id="_sItem" structureRef="String"/>
+
+ <process processType="Private" isExecutable="true" id="UserTasksDeadline" name="User Task Deadline" >
+
+ <!-- process variables -->
+ <property id="s" itemSubjectRef="_sItem"/>
+ <property id="subject" itemSubjectRef="_sItem"/>
+ <property id="body" itemSubjectRef="_sItem"/>
+
+ <!-- nodes -->
+ <startEvent id="_1" name="StartProcess" />
+ <userTask id="_2" name="Hello" >
+ <ioSpecification>
+ <dataInput id="_2_NotCompletedNotifyInput" name="NotCompletedNotify" />
+ <dataInput id="_2_NotStartedNotifyInput" name="NotStartedNotify" />
+ <dataInput id="_2_CommentInput" name="Comment" />
+ <dataInput id="_2_NotCompletedReassignInput" name="NotCompletedReassign" />
+ <dataInput id="_2_SkippableInput" name="Skippable" />
+ <dataInput id="_2_NotStartedReassignInput" name="NotStartedReassign" />
+ <dataInput id="_2_TaskNameInput" name="TaskName" />
+ <dataInput id="_2_GroupIdInput" name="GroupId" />
+ <dataInput id="_2_PriorityInput" name="Priority" />
+ <inputSet>
+ <dataInputRefs>_2_NotCompletedNotifyInput</dataInputRefs>
+ <dataInputRefs>_2_NotStartedNotifyInput</dataInputRefs>
+ <dataInputRefs>_2_CommentInput</dataInputRefs>
+ <dataInputRefs>_2_NotCompletedReassignInput</dataInputRefs>
+ <dataInputRefs>_2_SkippableInput</dataInputRefs>
+ <dataInputRefs>_2_NotStartedReassignInput</dataInputRefs>
+ <dataInputRefs>_2_TaskNameInput</dataInputRefs>
+ <dataInputRefs>_2_GroupIdInput</dataInputRefs>
+ <dataInputRefs>_2_PriorityInput</dataInputRefs>
+ </inputSet>
+ <outputSet>
+ </outputSet>
+ </ioSpecification>
+ <dataInputAssociation>
+ <targetRef>_2_NotStartedNotifyInput</targetRef>
+ <assignment>
+ <from xsi:type="tFormalExpression">[tousers:mike|subject:Task is ready for ${owners[0].id}|body:<html>
+ <body>
+ Reason #{subject}<br/>
+ body of notification #{body}
+ </body>
+ </html>]@[PT2S,PT4S]</from>
+ <to xsi:type="tFormalExpression">_2_NotStartedNotifyInput</to>
+ </assignment>
+ </dataInputAssociation>
+ <dataInputAssociation>
+ <targetRef>_2_SkippableInput</targetRef>
+ <assignment>
+ <from xsi:type="tFormalExpression">false</from>
+ <to xsi:type="tFormalExpression">_2_SkippableInput</to>
+ </assignment>
+ </dataInputAssociation>
+ <dataInputAssociation>
+ <targetRef>_2_TaskNameInput</targetRef>
+ <assignment>
+ <from xsi:type="tFormalExpression"></from>
+ <to xsi:type="tFormalExpression">_2_TaskNameInput</to>
+ </assignment>
+ </dataInputAssociation>
+ <dataInputAssociation>
+ <targetRef>_2_GroupIdInput</targetRef>
+ <assignment>
+ <from xsi:type="tFormalExpression"></from>
+ <to xsi:type="tFormalExpression">_2_GroupIdInput</to>
+ </assignment>
+ </dataInputAssociation>
+ <dataInputAssociation>
+ <targetRef>_2_PriorityInput</targetRef>
+ <assignment>
+ <from xsi:type="tFormalExpression"></from>
+ <to xsi:type="tFormalExpression">_2_PriorityInput</to>
+ </assignment>
+ </dataInputAssociation>
+ <potentialOwner>
+ <resourceAssignmentExpression>
+ <formalExpression>john,mary</formalExpression>
+ </resourceAssignmentExpression>
+ </potentialOwner>
+ </userTask>
+ <endEvent id="_3" name="EndProcess" >
+ <terminateEventDefinition/>
+ </endEvent>
+
+ <!-- connections -->
+ <sequenceFlow id="_1-_2" sourceRef="_1" targetRef="_2" />
+ <sequenceFlow id="_2-_3" sourceRef="_2" targetRef="_3" />
+
+ </process>
+
+ <bpmndi:BPMNDiagram>
+ <bpmndi:BPMNPlane bpmnElement="UserTask" >
+ <bpmndi:BPMNShape bpmnElement="_1" >
+ <dc:Bounds x="16" y="16" width="48" height="48" />
+ </bpmndi:BPMNShape>
+ <bpmndi:BPMNShape bpmnElement="_2" >
+ <dc:Bounds x="96" y="16" width="100" height="48" />
+ </bpmndi:BPMNShape>
+ <bpmndi:BPMNShape bpmnElement="_3" >
+ <dc:Bounds x="228" y="16" width="48" height="48" />
+ </bpmndi:BPMNShape>
+ <bpmndi:BPMNEdge bpmnElement="_1-_2" >
+ <di:waypoint x="40" y="40" />
+ <di:waypoint x="146" y="40" />
+ </bpmndi:BPMNEdge>
+ <bpmndi:BPMNEdge bpmnElement="_2-_3" >
+ <di:waypoint x="146" y="40" />
+ <di:waypoint x="252" y="40" />
+ </bpmndi:BPMNEdge>
+ </bpmndi:BPMNPlane>
+ </bpmndi:BPMNDiagram>
+
+</definitions>
\ No newline at end of file
diff --git a/kogito-codegen-modules/kogito-codegen-processes-integration-tests/src/test/resources/usertask/UserTasksNotStartedReasssign.bpmn2 b/kogito-codegen-modules/kogito-codegen-processes-integration-tests/src/test/resources/usertask/UserTasksNotStartedReasssign.bpmn2
new file mode 100644
index 0000000000..c2f69199e3
--- /dev/null
+++ b/kogito-codegen-modules/kogito-codegen-processes-integration-tests/src/test/resources/usertask/UserTasksNotStartedReasssign.bpmn2
@@ -0,0 +1,124 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<definitions id="Definition"
+ targetNamespace="http://www.example.org/MinimalExample"
+ typeLanguage="http://www.java.com/javaTypes"
+ expressionLanguage="http://www.mvel.org/2.0"
+ xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://www.omg.org/spec/BPMN/20100524/MODEL BPMN20.xsd"
+ xmlns:g="http://www.jboss.org/drools/flow/gpd"
+ xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI"
+ xmlns:dc="http://www.omg.org/spec/DD/20100524/DC"
+ xmlns:di="http://www.omg.org/spec/DD/20100524/DI"
+ xmlns:tns="http://www.jboss.org/drools">
+
+ <itemDefinition id="_sItem" structureRef="String"/>
+
+ <process processType="Private" isExecutable="true" id="UserTasksDeadline" name="User Task Deadline" >
+
+ <!-- process variables -->
+ <property id="s" itemSubjectRef="_sItem"/>
+ <property id="subject" itemSubjectRef="_sItem"/>
+ <property id="body" itemSubjectRef="_sItem"/>
+
+ <!-- nodes -->
+ <startEvent id="_1" name="StartProcess" />
+ <userTask id="_2" name="Hello" >
+ <ioSpecification>
+ <dataInput id="_2_NotCompletedNotifyInput" name="NotCompletedNotify" />
+ <dataInput id="_2_NotStartedNotifyInput" name="NotStartedNotify" />
+ <dataInput id="_2_CommentInput" name="Comment" />
+ <dataInput id="_2_NotCompletedReassignInput" name="NotCompletedReassign" />
+ <dataInput id="_2_SkippableInput" name="Skippable" />
+ <dataInput id="_2_NotStartedReassignInput" name="NotStartedReassign" />
+ <dataInput id="_2_TaskNameInput" name="TaskName" />
+ <dataInput id="_2_GroupIdInput" name="GroupId" />
+ <dataInput id="_2_PriorityInput" name="Priority" />
+ <inputSet>
+ <dataInputRefs>_2_NotCompletedNotifyInput</dataInputRefs>
+ <dataInputRefs>_2_NotStartedNotifyInput</dataInputRefs>
+ <dataInputRefs>_2_CommentInput</dataInputRefs>
+ <dataInputRefs>_2_NotCompletedReassignInput</dataInputRefs>
+ <dataInputRefs>_2_SkippableInput</dataInputRefs>
+ <dataInputRefs>_2_NotStartedReassignInput</dataInputRefs>
+ <dataInputRefs>_2_TaskNameInput</dataInputRefs>
+ <dataInputRefs>_2_GroupIdInput</dataInputRefs>
+ <dataInputRefs>_2_PriorityInput</dataInputRefs>
+ </inputSet>
+ <outputSet>
+ </outputSet>
+ </ioSpecification>
+ <dataInputAssociation>
+ <targetRef>_2_NotStartedReassignInput</targetRef>
+ <assignment>
+ <from xsi:type="tFormalExpression">[users:mike]@[PT1S]</from>
+ <to xsi:type="tFormalExpression">_2_NotStartedReassignInput</to>
+ </assignment>
+ </dataInputAssociation>
+ <dataInputAssociation>
+ <targetRef>_2_SkippableInput</targetRef>
+ <assignment>
+ <from xsi:type="tFormalExpression">false</from>
+ <to xsi:type="tFormalExpression">_2_SkippableInput</to>
+ </assignment>
+ </dataInputAssociation>
+ <dataInputAssociation>
+ <targetRef>_2_TaskNameInput</targetRef>
+ <assignment>
+ <from xsi:type="tFormalExpression"></from>
+ <to xsi:type="tFormalExpression">_2_TaskNameInput</to>
+ </assignment>
+ </dataInputAssociation>
+ <dataInputAssociation>
+ <targetRef>_2_GroupIdInput</targetRef>
+ <assignment>
+ <from xsi:type="tFormalExpression"></from>
+ <to xsi:type="tFormalExpression">_2_GroupIdInput</to>
+ </assignment>
+ </dataInputAssociation>
+ <dataInputAssociation>
+ <targetRef>_2_PriorityInput</targetRef>
+ <assignment>
+ <from xsi:type="tFormalExpression"></from>
+ <to xsi:type="tFormalExpression">_2_PriorityInput</to>
+ </assignment>
+ </dataInputAssociation>
+ <potentialOwner>
+ <resourceAssignmentExpression>
+ <formalExpression>john,mary</formalExpression>
+ </resourceAssignmentExpression>
+ </potentialOwner>
+ </userTask>
+ <endEvent id="_3" name="EndProcess" >
+ <terminateEventDefinition/>
+ </endEvent>
+
+ <!-- connections -->
+ <sequenceFlow id="_1-_2" sourceRef="_1" targetRef="_2" />
+ <sequenceFlow id="_2-_3" sourceRef="_2" targetRef="_3" />
+
+ </process>
+
+ <bpmndi:BPMNDiagram>
+ <bpmndi:BPMNPlane bpmnElement="UserTask" >
+ <bpmndi:BPMNShape bpmnElement="_1" >
+ <dc:Bounds x="16" y="16" width="48" height="48" />
+ </bpmndi:BPMNShape>
+ <bpmndi:BPMNShape bpmnElement="_2" >
+ <dc:Bounds x="96" y="16" width="100" height="48" />
+ </bpmndi:BPMNShape>
+ <bpmndi:BPMNShape bpmnElement="_3" >
+ <dc:Bounds x="228" y="16" width="48" height="48" />
+ </bpmndi:BPMNShape>
+ <bpmndi:BPMNEdge bpmnElement="_1-_2" >
+ <di:waypoint x="40" y="40" />
+ <di:waypoint x="146" y="40" />
+ </bpmndi:BPMNEdge>
+ <bpmndi:BPMNEdge bpmnElement="_2-_3" >
+ <di:waypoint x="146" y="40" />
+ <di:waypoint x="252" y="40" />
+ </bpmndi:BPMNEdge>
+ </bpmndi:BPMNPlane>
+ </bpmndi:BPMNDiagram>
+
+</definitions>
\ No newline at end of file
diff --git a/kogito-codegen-modules/kogito-codegen-processes/src/main/java/org/kie/kogito/codegen/usertask/UserTaskCodegen.java b/kogito-codegen-modules/kogito-codegen-processes/src/main/java/org/kie/kogito/codegen/usertask/UserTaskCodegen.java
index 81965e0c4e..9f4e1abb8d 100644
--- a/kogito-codegen-modules/kogito-codegen-processes/src/main/java/org/kie/kogito/codegen/usertask/UserTaskCodegen.java
+++ b/kogito-codegen-modules/kogito-codegen-processes/src/main/java/org/kie/kogito/codegen/usertask/UserTaskCodegen.java
@@ -55,6 +55,9 @@ import org.kie.kogito.internal.SupportedExtensions;
import org.kie.kogito.internal.process.runtime.KogitoWorkflowProcess;
import org.kie.kogito.process.validation.ValidationException;
import org.kie.kogito.process.validation.ValidationLogDecorator;
+import org.kie.kogito.usertask.impl.model.DeadlineHelper;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
import org.xml.sax.SAXException;
import com.github.javaparser.StaticJavaParser;
@@ -78,6 +81,8 @@ import static org.kie.kogito.serverless.workflow.utils.ServerlessWorkflowUtils.F
public class UserTaskCodegen extends AbstractGenerator {
+ private static Logger LOG = LoggerFactory.getLogger(UserTaskCodegen.class);
+
private static final String NODE_NAME = "NodeName";
private static final String DESCRIPTION = "Description";
private static final String PRIORITY = "Priority";
@@ -219,16 +224,28 @@ public class UserTaskCodegen extends AbstractGenerator {
block.addStatement(new MethodCallExpr(new ThisExpr(), "setReferenceName", NodeList.nodeList(toStringExpression(info.getParameter(NODE_NAME)))));
block.addStatement(new MethodCallExpr(new ThisExpr(), "setSkippable", NodeList.nodeList(toStringExpression(info.getParameter("Skippable")))));
- block.addStatement(new MethodCallExpr(new ThisExpr(), "setNotStartedDeadLines", NodeList.nodeList(toStringExpression(info.getParameter("NotStartedNotify")))));
- block.addStatement(new MethodCallExpr(new ThisExpr(), "setNotCompletedDeadlines", NodeList.nodeList(toStringExpression(info.getParameter("NotCompletedNotify")))));
- block.addStatement(new MethodCallExpr(new ThisExpr(), "setNotStartedReassignments", NodeList.nodeList(toStringExpression(info.getParameter("NotCompletedReassign")))));
- block.addStatement(new MethodCallExpr(new ThisExpr(), "setNotCompletedReassigments", NodeList.nodeList(toStringExpression(info.getParameter("NotStartedReassign")))));
+ block.addStatement(new MethodCallExpr(new ThisExpr(), "setNotStartedDeadLines", NodeList.nodeList(toDeadlineExpression(info.getParameter("NotStartedNotify")))));
+ block.addStatement(new MethodCallExpr(new ThisExpr(), "setNotCompletedDeadlines", NodeList.nodeList(toDeadlineExpression(info.getParameter("NotCompletedNotify")))));
+ block.addStatement(new MethodCallExpr(new ThisExpr(), "setNotStartedReassignments", NodeList.nodeList(toDeadlineExpression(info.getParameter("NotStartedReassign")))));
+ block.addStatement(new MethodCallExpr(new ThisExpr(), "setNotCompletedReassigments", NodeList.nodeList(toDeadlineExpression(info.getParameter("NotCompletedReassign")))));
generatedFiles.add(new GeneratedFile(GeneratedFileType.SOURCE, UserTaskCodegenHelper.path(info).resolve(className + ".java"), unit.toString()));
}
return generatedFiles;
}
+ private Expression toDeadlineExpression(Object parameter) {
+ if (parameter instanceof String stringParam) {
+ try {
+ DeadlineHelper.parseDeadlines(stringParam);
+ return toStringExpression(stringParam);
+ } catch (Exception e) {
+ LOG.debug("to deadline calculation failure. {} it is not a proper expression");
+ }
+ }
+ return new CastExpr(StaticJavaParser.parseType(String.class.getName()), new NullLiteralExpr());
+ }
+
private Expression toStringExpression(Object value) {
if (value == null) {
return new CastExpr(StaticJavaParser.parseType(String.class.getName()), new NullLiteralExpr());
diff --git a/kogito-codegen-modules/kogito-codegen-processes/src/main/java/org/kie/kogito/codegen/usertask/UserTaskContainerGenerator.java b/kogito-codegen-modules/kogito-codegen-processes/src/main/java/org/kie/kogito/codegen/usertask/UserTaskContainerGenerator.java
index 364ecf0383..1b05ea184f 100644
--- a/kogito-codegen-modules/kogito-codegen-processes/src/main/java/org/kie/kogito/codegen/usertask/UserTaskContainerGenerator.java
+++ b/kogito-codegen-modules/kogito-codegen-processes/src/main/java/org/kie/kogito/codegen/usertask/UserTaskContainerGenerator.java
@@ -62,17 +62,15 @@ public class UserTaskContainerGenerator extends AbstractApplicationSection {
ClassOrInterfaceDeclaration clazzUnit = unit.findFirst(ClassOrInterfaceDeclaration.class).get();
ConstructorDeclaration constructor = clazzUnit.findFirst(ConstructorDeclaration.class).get();
-
- BlockStmt block = new BlockStmt();
+ BlockStmt block = constructor.getBody();
NodeList<Expression> arguments = new NodeList<>();
arguments.add(new NameExpr("application"));
for (Work descriptor : descriptors) {
String fqn = UserTaskCodegenHelper.fqnClassName(descriptor);
arguments.add(new ObjectCreationExpr().setType(StaticJavaParser.parseClassOrInterfaceType(fqn)).setArguments(nodeList(new NameExpr("application"))));
}
- block.addStatement(new ExplicitConstructorInvocationStmt().setThis(false).setArguments(arguments));
+ block.findFirst(ExplicitConstructorInvocationStmt.class).ifPresent(e -> e.setArguments(arguments));
constructor.setBody(block);
-
return unit;
}
diff --git a/kogito-codegen-modules/kogito-codegen-processes/src/main/resources/class-templates/ProcessContainerJavaTemplate.java b/kogito-codegen-modules/kogito-codegen-processes/src/main/resources/class-templates/ProcessContainerJavaTemplate.java
index 341baa98a8..40c9fa3486 100644
--- a/kogito-codegen-modules/kogito-codegen-processes/src/main/resources/class-templates/ProcessContainerJavaTemplate.java
+++ b/kogito-codegen-modules/kogito-codegen-processes/src/main/resources/class-templates/ProcessContainerJavaTemplate.java
@@ -18,6 +18,14 @@
*/
package $Package$;
+import org.kie.kogito.jobs.JobsService;
+import org.kie.kogito.process.ProcessConfig;
+import org.kie.kogito.process.impl.StaticProcessConfig;
+import org.kie.kogito.services.jobs.impl.InMemoryProcessJobExecutorFactory;
+import org.kie.kogito.services.jobs.impl.InMemoryJobService;
+import org.kie.kogito.services.jobs.impl.InMemoryJobContext;
+import org.kie.kogito.uow.UnitOfWorkManager;
+
public class Processes implements org.kie.kogito.process.Processes {
private final Application application;
@@ -25,6 +33,13 @@ public class Processes implements org.kie.kogito.process.Processes {
public Processes(Application application) {
this.application = application;
+ JobsService jobsService = this.application.config().get(ProcessConfig.class).jobsService();
+ UnitOfWorkManager unitOfWorkManager = this.application.config().get(ProcessConfig.class).unitOfWorkManager();
+ if (jobsService instanceof InMemoryJobService) {
+ InMemoryJobService inMemoryJobService = (InMemoryJobService) jobsService;
+ InMemoryJobContext context = new InMemoryJobContext(null, unitOfWorkManager, this, null);
+ inMemoryJobService.registerJobExecutorFactory(new InMemoryProcessJobExecutorFactory(context));
+ }
}
public org.kie.kogito.process.Process<? extends org.kie.kogito.Model> processById(String processId) {
diff --git a/kogito-codegen-modules/kogito-codegen-processes/src/main/resources/class-templates/usertask/UserTasksContainerJavaTemplate.java b/kogito-codegen-modules/kogito-codegen-processes/src/main/resources/class-templates/usertask/UserTasksContainerJavaTemplate.java
index 3b5293ac0e..846b9a88b2 100644
--- a/kogito-codegen-modules/kogito-codegen-processes/src/main/resources/class-templates/usertask/UserTasksContainerJavaTemplate.java
+++ b/kogito-codegen-modules/kogito-codegen-processes/src/main/resources/class-templates/usertask/UserTasksContainerJavaTemplate.java
@@ -18,12 +18,25 @@
*/
package org.kie.kogito.usertask.impl;
+import org.kie.kogito.jobs.JobsService;
+import org.kie.kogito.usertask.UserTaskConfig;
+import org.kie.kogito.services.jobs.impl.InMemoryJobContext;
+import org.kie.kogito.services.jobs.impl.InMemoryJobService;
+import org.kie.kogito.services.jobs.impl.InMemoryUserTaskJobExecutorFactory;
+import org.kie.kogito.uow.UnitOfWorkManager;
import org.kie.kogito.usertask.impl.DefaultUserTasks;
public class UserTasks extends DefaultUserTasks {
public UserTasks(Application application) {
super(application);
+ JobsService jobsService = application.config().get(UserTaskConfig.class).jobsService();
+ UnitOfWorkManager unitOfWorkManager = application.config().get(UserTaskConfig.class).unitOfWorkManager();
+ if (jobsService instanceof InMemoryJobService) {
+ InMemoryJobService inMemoryJobService = (InMemoryJobService) jobsService;
+ InMemoryJobContext context = new InMemoryJobContext(null, unitOfWorkManager, null, this);
+ inMemoryJobService.registerJobExecutorFactory(new InMemoryUserTaskJobExecutorFactory(context));
+ }
}
}
\ No newline at end of file
diff --git a/kogito-codegen-modules/kogito-codegen-processes/src/main/resources/class-templates/usertask/UserTasksContainerQuarkusTemplate.java b/kogito-codegen-modules/kogito-codegen-processes/src/main/resources/class-templates/usertask/UserTasksContainerQuarkusTemplate.java
index 8e98179784..7b341ab3bb 100644
--- a/kogito-codegen-modules/kogito-codegen-processes/src/main/resources/class-templates/usertask/UserTasksContainerQuarkusTemplate.java
+++ b/kogito-codegen-modules/kogito-codegen-processes/src/main/resources/class-templates/usertask/UserTasksContainerQuarkusTemplate.java
@@ -23,6 +23,11 @@ import java.util.HashMap;
import java.util.Map;
import java.util.List;
+import org.kie.kogito.jobs.JobsService;
+import org.kie.kogito.services.jobs.impl.InMemoryJobContext;
+import org.kie.kogito.services.jobs.impl.InMemoryJobService;
+import org.kie.kogito.services.jobs.impl.InMemoryUserTaskJobExecutorFactory;
+import org.kie.kogito.uow.UnitOfWorkManager;
import org.kie.kogito.uow.events.UnitOfWorkUserTaskEventListener;
import org.kie.kogito.usertask.impl.DefaultUserTaskInstance;
import org.kie.kogito.usertask.impl.KogitoUserTaskEventSupportImpl;
@@ -57,6 +62,13 @@ public class UserTasks implements org.kie.kogito.usertask.UserTasks {
mappedUserTask.put(userTask.id(), userTask);
LOG.info("Registering user task {} with task name {}", userTask.id(), userTask.getTaskName());
}
+ JobsService jobsService = application.config().get(UserTaskConfig.class).jobsService();
+ UnitOfWorkManager unitOfWorkManager = application.config().get(UserTaskConfig.class).unitOfWorkManager();
+ if (jobsService instanceof InMemoryJobService) {
+ InMemoryJobService inMemoryJobService = (InMemoryJobService) jobsService;
+ InMemoryJobContext context = new InMemoryJobContext(null, unitOfWorkManager, null, this);
+ inMemoryJobService.registerJobExecutorFactory(new InMemoryUserTaskJobExecutorFactory(context));
+ }
}
public UserTask userTaskById(String userTaskId) {
@@ -78,6 +90,7 @@ public class UserTasks implements org.kie.kogito.usertask.UserTasks {
instance.setUserTaskEventSupport(null);
instance.setUserTaskLifeCycle(null);
instance.setInstances(null);
+ instance.setJobsService(null);
return instance;
}
@@ -91,6 +104,7 @@ public class UserTasks implements org.kie.kogito.usertask.UserTasks {
instance.setUserTaskEventSupport(impl);
instance.setUserTaskLifeCycle(userTaskConfig.userTaskLifeCycle());
instance.setInstances(application.config().get(UserTaskConfig.class).userTaskInstances());
+ instance.setJobsService(userTaskConfig.jobsService());
return instance;
}
}
\ No newline at end of file
diff --git a/kogito-codegen-modules/kogito-codegen-processes/src/main/resources/class-templates/usertask/UserTasksContainerSpringTemplate.java b/kogito-codegen-modules/kogito-codegen-processes/src/main/resources/class-templates/usertask/UserTasksContainerSpringTemplate.java
index 9785b44d7c..0d17584686 100644
--- a/kogito-codegen-modules/kogito-codegen-processes/src/main/resources/class-templates/usertask/UserTasksContainerSpringTemplate.java
+++ b/kogito-codegen-modules/kogito-codegen-processes/src/main/resources/class-templates/usertask/UserTasksContainerSpringTemplate.java
@@ -24,6 +24,11 @@ import java.util.Map;
import java.util.List;
import org.kie.kogito.Application;
+import org.kie.kogito.jobs.JobsService;
+import org.kie.kogito.services.jobs.impl.InMemoryJobContext;
+import org.kie.kogito.services.jobs.impl.InMemoryJobService;
+import org.kie.kogito.services.jobs.impl.InMemoryUserTaskJobExecutorFactory;
+import org.kie.kogito.uow.UnitOfWorkManager;
import org.kie.kogito.uow.events.UnitOfWorkUserTaskEventListener;
import org.kie.kogito.usertask.impl.DefaultUserTaskInstance;
import org.kie.kogito.usertask.impl.KogitoUserTaskEventSupportImpl;
@@ -58,6 +63,13 @@ public class UserTasks implements org.kie.kogito.usertask.UserTasks {
mappedUserTask.put(userTask.id(), userTask);
LOG.info("Registering user task {} with task name {}", userTask.id(), userTask.getTaskName());
}
+ JobsService jobsService = application.config().get(UserTaskConfig.class).jobsService();
+ UnitOfWorkManager unitOfWorkManager = application.config().get(UserTaskConfig.class).unitOfWorkManager();
+ if (jobsService instanceof InMemoryJobService) {
+ InMemoryJobService inMemoryJobService = (InMemoryJobService) jobsService;
+ InMemoryJobContext context = new InMemoryJobContext(null, unitOfWorkManager, null, this);
+ inMemoryJobService.registerJobExecutorFactory(new InMemoryUserTaskJobExecutorFactory(context));
+ }
}
public UserTask userTaskById(String userTaskId) {
@@ -79,6 +91,7 @@ public class UserTasks implements org.kie.kogito.usertask.UserTasks {
instance.setUserTaskEventSupport(null);
instance.setUserTaskLifeCycle(null);
instance.setInstances(null);
+ instance.setJobsService(null);
return instance;
}
@@ -92,6 +105,7 @@ public class UserTasks implements org.kie.kogito.usertask.UserTasks {
instance.setUserTaskEventSupport(impl);
instance.setUserTaskLifeCycle(userTaskConfig.userTaskLifeCycle());
instance.setInstances(application.config().get(UserTaskConfig.class).userTaskInstances());
+ instance.setJobsService(userTaskConfig.jobsService());
return instance;
}
}
\ No newline at end of file
diff --git a/kogito-serverless-workflow/kogito-serverless-workflow-executor-core/src/test/java/org/kie/kogito/serverless/workflow/executor/StaticFluentWorkflowApplicationTest.java b/kogito-serverless-workflow/kogito-serverless-workflow-executor-core/src/test/java/org/kie/kogito/serverless/workflow/executor/StaticFluentWorkflowApplicationTest.java
index 5cf827f291..dfc9d750d3 100644
--- a/kogito-serverless-workflow/kogito-serverless-workflow-executor-core/src/test/java/org/kie/kogito/serverless/workflow/executor/StaticFluentWorkflowApplicationTest.java
+++ b/kogito-serverless-workflow/kogito-serverless-workflow-executor-core/src/test/java/org/kie/kogito/serverless/workflow/executor/StaticFluentWorkflowApplicationTest.java
@@ -28,7 +28,10 @@ import java.util.concurrent.atomic.AtomicBoolean;
import org.junit.jupiter.api.Test;
import org.kie.api.event.process.ProcessCompletedEvent;
import org.kie.kogito.internal.process.event.DefaultKogitoProcessEventListener;
+import org.kie.kogito.jobs.JobsService;
import org.kie.kogito.process.Process;
+import org.kie.kogito.process.ProcessConfig;
+import org.kie.kogito.process.Processes;
import org.kie.kogito.process.validation.ValidationException;
import org.kie.kogito.serverless.workflow.actions.SysoutAction;
import org.kie.kogito.serverless.workflow.actions.WorkflowLogLevel;
@@ -38,6 +41,10 @@ import org.kie.kogito.serverless.workflow.models.JsonNodeModel;
import org.kie.kogito.serverless.workflow.parser.types.SysOutTypeHandler;
import org.kie.kogito.serverless.workflow.utils.ExpressionHandlerUtils;
import org.kie.kogito.serverless.workflow.utils.KogitoProcessContextResolver;
+import org.kie.kogito.services.jobs.impl.InMemoryJobContext;
+import org.kie.kogito.services.jobs.impl.InMemoryJobService;
+import org.kie.kogito.services.jobs.impl.InMemoryProcessJobExecutorFactory;
+import org.kie.kogito.uow.UnitOfWorkManager;
import org.slf4j.LoggerFactory;
import com.fasterxml.jackson.databind.JsonNode;
@@ -141,6 +148,13 @@ public class StaticFluentWorkflowApplicationTest {
OperationStateBuilder sleepState = operation().action(call(expr("inc", ".count=.count+1")).sleepAfter(Duration.ofSeconds(1)));
try (StaticWorkflowApplication application = StaticWorkflowApplication.create()) {
+ ProcessConfig processConfig = application.config().get(ProcessConfig.class);
+ JobsService jobService = processConfig.jobsService();
+ Processes processes = application.get(Processes.class);
+ UnitOfWorkManager unitOfWorkManager = processConfig.unitOfWorkManager();
+ if (jobService instanceof InMemoryJobService inMemoryJobService) {
+ inMemoryJobService.registerJobExecutorFactory(new InMemoryProcessJobExecutorFactory(new InMemoryJobContext(null, unitOfWorkManager, processes, null)));
+ }
Workflow workflow = workflow("Polling").start(startTask)
.next(sleepState)
.next(pollTask)
diff --git a/quarkus/addons/jbpm-usertask-storage-jpa/runtime/src/main/java/org/jbpm/usertask/jpa/quarkus/mapper/QuarkusUserTaskInstanceEntityMapper.java b/quarkus/addons/jbpm-usertask-storage-jpa/runtime/src/main/java/org/jbpm/usertask/jpa/quarkus/mapper/QuarkusTaskDeadlineEntityMapper.java
similarity index 61%
copy from quarkus/addons/jbpm-usertask-storage-jpa/runtime/src/main/java/org/jbpm/usertask/jpa/quarkus/mapper/QuarkusUserTaskInstanceEntityMapper.java
copy to quarkus/addons/jbpm-usertask-storage-jpa/runtime/src/main/java/org/jbpm/usertask/jpa/quarkus/mapper/QuarkusTaskDeadlineEntityMapper.java
index e3f6c79e1a..3067cbb77f 100644
--- a/quarkus/addons/jbpm-usertask-storage-jpa/runtime/src/main/java/org/jbpm/usertask/jpa/quarkus/mapper/QuarkusUserTaskInstanceEntityMapper.java
+++ b/quarkus/addons/jbpm-usertask-storage-jpa/runtime/src/main/java/org/jbpm/usertask/jpa/quarkus/mapper/QuarkusTaskDeadlineEntityMapper.java
@@ -19,21 +19,21 @@
package org.jbpm.usertask.jpa.quarkus.mapper;
-import org.jbpm.usertask.jpa.mapper.*;
+import org.jbpm.usertask.jpa.mapper.TaskDeadlineEntityMapper;
+import org.jbpm.usertask.jpa.repository.TaskDeadlineRepository;
import jakarta.enterprise.context.ApplicationScoped;
import jakarta.inject.Inject;
@ApplicationScoped
-public class QuarkusUserTaskInstanceEntityMapper extends UserTaskInstanceEntityMapper {
+public class QuarkusTaskDeadlineEntityMapper extends TaskDeadlineEntityMapper {
- QuarkusUserTaskInstanceEntityMapper() {
- this(null, null, null, null, null);
+ public QuarkusTaskDeadlineEntityMapper() {
+ super(null);
}
@Inject
- public QuarkusUserTaskInstanceEntityMapper(AttachmentsEntityMapper attachmentsMapper, CommentsEntityMapper commentsMapper, TaskMetadataEntityMapper taskMetadataEntityMapper,
- TaskInputsEntityMapper taskInputsEntityMapper, TaskOutputsEntityMapper taskOutputsEntityMapper) {
- super(attachmentsMapper, commentsMapper, taskMetadataEntityMapper, taskInputsEntityMapper, taskOutputsEntityMapper);
+ public QuarkusTaskDeadlineEntityMapper(TaskDeadlineRepository repository) {
+ super(repository);
}
}
diff --git a/quarkus/addons/jbpm-usertask-storage-jpa/runtime/src/main/java/org/jbpm/usertask/jpa/quarkus/mapper/QuarkusUserTaskInstanceEntityMapper.java b/quarkus/addons/jbpm-usertask-storage-jpa/runtime/src/main/java/org/jbpm/usertask/jpa/quarkus/mapper/QuarkusTaskDeadlineTimerEntityMapper.java
similarity index 61%
copy from quarkus/addons/jbpm-usertask-storage-jpa/runtime/src/main/java/org/jbpm/usertask/jpa/quarkus/mapper/QuarkusUserTaskInstanceEntityMapper.java
copy to quarkus/addons/jbpm-usertask-storage-jpa/runtime/src/main/java/org/jbpm/usertask/jpa/quarkus/mapper/QuarkusTaskDeadlineTimerEntityMapper.java
index e3f6c79e1a..d7377affa7 100644
--- a/quarkus/addons/jbpm-usertask-storage-jpa/runtime/src/main/java/org/jbpm/usertask/jpa/quarkus/mapper/QuarkusUserTaskInstanceEntityMapper.java
+++ b/quarkus/addons/jbpm-usertask-storage-jpa/runtime/src/main/java/org/jbpm/usertask/jpa/quarkus/mapper/QuarkusTaskDeadlineTimerEntityMapper.java
@@ -19,21 +19,21 @@
package org.jbpm.usertask.jpa.quarkus.mapper;
-import org.jbpm.usertask.jpa.mapper.*;
+import org.jbpm.usertask.jpa.mapper.TaskDeadlineTimerEntityMapper;
+import org.jbpm.usertask.jpa.repository.TaskDeadlineTimerRepository;
import jakarta.enterprise.context.ApplicationScoped;
import jakarta.inject.Inject;
@ApplicationScoped
-public class QuarkusUserTaskInstanceEntityMapper extends UserTaskInstanceEntityMapper {
+public class QuarkusTaskDeadlineTimerEntityMapper extends TaskDeadlineTimerEntityMapper {
- QuarkusUserTaskInstanceEntityMapper() {
- this(null, null, null, null, null);
+ public QuarkusTaskDeadlineTimerEntityMapper() {
+ super(null);
}
@Inject
- public QuarkusUserTaskInstanceEntityMapper(AttachmentsEntityMapper attachmentsMapper, CommentsEntityMapper commentsMapper, TaskMetadataEntityMapper taskMetadataEntityMapper,
- TaskInputsEntityMapper taskInputsEntityMapper, TaskOutputsEntityMapper taskOutputsEntityMapper) {
- super(attachmentsMapper, commentsMapper, taskMetadataEntityMapper, taskInputsEntityMapper, taskOutputsEntityMapper);
+ public QuarkusTaskDeadlineTimerEntityMapper(TaskDeadlineTimerRepository repository) {
+ super(repository);
}
}
diff --git a/quarkus/addons/jbpm-usertask-storage-jpa/runtime/src/main/java/org/jbpm/usertask/jpa/quarkus/mapper/QuarkusUserTaskInstanceEntityMapper.java b/quarkus/addons/jbpm-usertask-storage-jpa/runtime/src/main/java/org/jbpm/usertask/jpa/quarkus/mapper/QuarkusTaskReassignmentEntityMapper.java
similarity index 61%
copy from quarkus/addons/jbpm-usertask-storage-jpa/runtime/src/main/java/org/jbpm/usertask/jpa/quarkus/mapper/QuarkusUserTaskInstanceEntityMapper.java
copy to quarkus/addons/jbpm-usertask-storage-jpa/runtime/src/main/java/org/jbpm/usertask/jpa/quarkus/mapper/QuarkusTaskReassignmentEntityMapper.java
index e3f6c79e1a..1d86a96522 100644
--- a/quarkus/addons/jbpm-usertask-storage-jpa/runtime/src/main/java/org/jbpm/usertask/jpa/quarkus/mapper/QuarkusUserTaskInstanceEntityMapper.java
+++ b/quarkus/addons/jbpm-usertask-storage-jpa/runtime/src/main/java/org/jbpm/usertask/jpa/quarkus/mapper/QuarkusTaskReassignmentEntityMapper.java
@@ -19,21 +19,21 @@
package org.jbpm.usertask.jpa.quarkus.mapper;
-import org.jbpm.usertask.jpa.mapper.*;
+import org.jbpm.usertask.jpa.mapper.TaskReassignmentEntityMapper;
+import org.jbpm.usertask.jpa.repository.TaskReassignmentRepository;
import jakarta.enterprise.context.ApplicationScoped;
import jakarta.inject.Inject;
@ApplicationScoped
-public class QuarkusUserTaskInstanceEntityMapper extends UserTaskInstanceEntityMapper {
+public class QuarkusTaskReassignmentEntityMapper extends TaskReassignmentEntityMapper {
- QuarkusUserTaskInstanceEntityMapper() {
- this(null, null, null, null, null);
+ public QuarkusTaskReassignmentEntityMapper() {
+ super(null);
}
@Inject
- public QuarkusUserTaskInstanceEntityMapper(AttachmentsEntityMapper attachmentsMapper, CommentsEntityMapper commentsMapper, TaskMetadataEntityMapper taskMetadataEntityMapper,
- TaskInputsEntityMapper taskInputsEntityMapper, TaskOutputsEntityMapper taskOutputsEntityMapper) {
- super(attachmentsMapper, commentsMapper, taskMetadataEntityMapper, taskInputsEntityMapper, taskOutputsEntityMapper);
+ public QuarkusTaskReassignmentEntityMapper(TaskReassignmentRepository repository) {
+ super(repository);
}
}
diff --git a/quarkus/addons/jbpm-usertask-storage-jpa/runtime/src/main/java/org/jbpm/usertask/jpa/quarkus/mapper/QuarkusUserTaskInstanceEntityMapper.java b/quarkus/addons/jbpm-usertask-storage-jpa/runtime/src/main/java/org/jbpm/usertask/jpa/quarkus/mapper/QuarkusTaskReassignmentTimerEntityMapper.java
similarity index 61%
copy from quarkus/addons/jbpm-usertask-storage-jpa/runtime/src/main/java/org/jbpm/usertask/jpa/quarkus/mapper/QuarkusUserTaskInstanceEntityMapper.java
copy to quarkus/addons/jbpm-usertask-storage-jpa/runtime/src/main/java/org/jbpm/usertask/jpa/quarkus/mapper/QuarkusTaskReassignmentTimerEntityMapper.java
index e3f6c79e1a..f5353c6ccb 100644
--- a/quarkus/addons/jbpm-usertask-storage-jpa/runtime/src/main/java/org/jbpm/usertask/jpa/quarkus/mapper/QuarkusUserTaskInstanceEntityMapper.java
+++ b/quarkus/addons/jbpm-usertask-storage-jpa/runtime/src/main/java/org/jbpm/usertask/jpa/quarkus/mapper/QuarkusTaskReassignmentTimerEntityMapper.java
@@ -19,21 +19,21 @@
package org.jbpm.usertask.jpa.quarkus.mapper;
-import org.jbpm.usertask.jpa.mapper.*;
+import org.jbpm.usertask.jpa.mapper.TaskReassignmentTimerEntityMapper;
+import org.jbpm.usertask.jpa.repository.TaskReassignmentTimerRepository;
import jakarta.enterprise.context.ApplicationScoped;
import jakarta.inject.Inject;
@ApplicationScoped
-public class QuarkusUserTaskInstanceEntityMapper extends UserTaskInstanceEntityMapper {
+public class QuarkusTaskReassignmentTimerEntityMapper extends TaskReassignmentTimerEntityMapper {
- QuarkusUserTaskInstanceEntityMapper() {
- this(null, null, null, null, null);
+ public QuarkusTaskReassignmentTimerEntityMapper() {
+ super(null);
}
@Inject
- public QuarkusUserTaskInstanceEntityMapper(AttachmentsEntityMapper attachmentsMapper, CommentsEntityMapper commentsMapper, TaskMetadataEntityMapper taskMetadataEntityMapper,
- TaskInputsEntityMapper taskInputsEntityMapper, TaskOutputsEntityMapper taskOutputsEntityMapper) {
- super(attachmentsMapper, commentsMapper, taskMetadataEntityMapper, taskInputsEntityMapper, taskOutputsEntityMapper);
+ public QuarkusTaskReassignmentTimerEntityMapper(TaskReassignmentTimerRepository repository) {
+ super(repository);
}
}
diff --git a/quarkus/addons/jbpm-usertask-storage-jpa/runtime/src/main/java/org/jbpm/usertask/jpa/quarkus/mapper/QuarkusUserTaskInstanceEntityMapper.java b/quarkus/addons/jbpm-usertask-storage-jpa/runtime/src/main/java/org/jbpm/usertask/jpa/quarkus/mapper/QuarkusUserTaskInstanceEntityMapper.java
index e3f6c79e1a..372301f761 100644
--- a/quarkus/addons/jbpm-usertask-storage-jpa/runtime/src/main/java/org/jbpm/usertask/jpa/quarkus/mapper/QuarkusUserTaskInstanceEntityMapper.java
+++ b/quarkus/addons/jbpm-usertask-storage-jpa/runtime/src/main/java/org/jbpm/usertask/jpa/quarkus/mapper/QuarkusUserTaskInstanceEntityMapper.java
@@ -19,21 +19,24 @@
package org.jbpm.usertask.jpa.quarkus.mapper;
-import org.jbpm.usertask.jpa.mapper.*;
+import java.util.Collections;
+
+import org.jbpm.usertask.jpa.mapper.EntityMapper;
+import org.jbpm.usertask.jpa.mapper.UserTaskInstanceEntityMapper;
import jakarta.enterprise.context.ApplicationScoped;
+import jakarta.enterprise.inject.Instance;
import jakarta.inject.Inject;
@ApplicationScoped
public class QuarkusUserTaskInstanceEntityMapper extends UserTaskInstanceEntityMapper {
QuarkusUserTaskInstanceEntityMapper() {
- this(null, null, null, null, null);
+ super(Collections.emptyList());
}
@Inject
- public QuarkusUserTaskInstanceEntityMapper(AttachmentsEntityMapper attachmentsMapper, CommentsEntityMapper commentsMapper, TaskMetadataEntityMapper taskMetadataEntityMapper,
- TaskInputsEntityMapper taskInputsEntityMapper, TaskOutputsEntityMapper taskOutputsEntityMapper) {
- super(attachmentsMapper, commentsMapper, taskMetadataEntityMapper, taskInputsEntityMapper, taskOutputsEntityMapper);
+ public QuarkusUserTaskInstanceEntityMapper(Instance<EntityMapper> mappers) {
+ super(mappers);
}
}
diff --git a/addons/common/jbpm-usertask-storage-jpa/src/main/java/org/jbpm/usertask/jpa/repository/TaskInputRepository.java b/quarkus/addons/jbpm-usertask-storage-jpa/runtime/src/main/java/org/jbpm/usertask/jpa/quarkus/repository/QuarkusTaskDeadlineRepository.java
similarity index 63%
copy from addons/common/jbpm-usertask-storage-jpa/src/main/java/org/jbpm/usertask/jpa/repository/TaskInputRepository.java
copy to quarkus/addons/jbpm-usertask-storage-jpa/runtime/src/main/java/org/jbpm/usertask/jpa/quarkus/repository/QuarkusTaskDeadlineRepository.java
index 6e85081ff7..9cf4d5eb09 100644
--- a/addons/common/jbpm-usertask-storage-jpa/src/main/java/org/jbpm/usertask/jpa/repository/TaskInputRepository.java
+++ b/quarkus/addons/jbpm-usertask-storage-jpa/runtime/src/main/java/org/jbpm/usertask/jpa/quarkus/repository/QuarkusTaskDeadlineRepository.java
@@ -17,19 +17,24 @@
* under the License.
*/
-package org.jbpm.usertask.jpa.repository;
+package org.jbpm.usertask.jpa.quarkus.repository;
-import org.jbpm.usertask.jpa.model.TaskDataEntityPK;
-import org.jbpm.usertask.jpa.model.TaskInputEntity;
+import org.jbpm.usertask.jpa.repository.TaskDeadlineRepository;
+import org.jbpm.usertask.jpa.repository.UserTaskJPAContext;
-public class TaskInputRepository extends BaseRepository<TaskInputEntity, TaskDataEntityPK> {
+import jakarta.enterprise.context.ApplicationScoped;
+import jakarta.inject.Inject;
- public TaskInputRepository(UserTaskJPAContext context) {
- super(context);
+@ApplicationScoped
+public class QuarkusTaskDeadlineRepository extends TaskDeadlineRepository {
+
+ QuarkusTaskDeadlineRepository() {
+ super(null);
}
- @Override
- public Class<TaskInputEntity> getEntityClass() {
- return TaskInputEntity.class;
+ @Inject
+ public QuarkusTaskDeadlineRepository(UserTaskJPAContext context) {
+ super(context);
}
+
}
diff --git a/addons/common/jbpm-usertask-storage-jpa/src/main/java/org/jbpm/usertask/jpa/repository/TaskInputRepository.java b/quarkus/addons/jbpm-usertask-storage-jpa/runtime/src/main/java/org/jbpm/usertask/jpa/quarkus/repository/QuarkusTaskDeadlineTimerRepository.java
similarity index 62%
copy from addons/common/jbpm-usertask-storage-jpa/src/main/java/org/jbpm/usertask/jpa/repository/TaskInputRepository.java
copy to quarkus/addons/jbpm-usertask-storage-jpa/runtime/src/main/java/org/jbpm/usertask/jpa/quarkus/repository/QuarkusTaskDeadlineTimerRepository.java
index 6e85081ff7..782b20a293 100644
--- a/addons/common/jbpm-usertask-storage-jpa/src/main/java/org/jbpm/usertask/jpa/repository/TaskInputRepository.java
+++ b/quarkus/addons/jbpm-usertask-storage-jpa/runtime/src/main/java/org/jbpm/usertask/jpa/quarkus/repository/QuarkusTaskDeadlineTimerRepository.java
@@ -17,19 +17,24 @@
* under the License.
*/
-package org.jbpm.usertask.jpa.repository;
+package org.jbpm.usertask.jpa.quarkus.repository;
-import org.jbpm.usertask.jpa.model.TaskDataEntityPK;
-import org.jbpm.usertask.jpa.model.TaskInputEntity;
+import org.jbpm.usertask.jpa.repository.TaskDeadlineTimerRepository;
+import org.jbpm.usertask.jpa.repository.UserTaskJPAContext;
-public class TaskInputRepository extends BaseRepository<TaskInputEntity, TaskDataEntityPK> {
+import jakarta.enterprise.context.ApplicationScoped;
+import jakarta.inject.Inject;
- public TaskInputRepository(UserTaskJPAContext context) {
- super(context);
+@ApplicationScoped
+public class QuarkusTaskDeadlineTimerRepository extends TaskDeadlineTimerRepository {
+
+ QuarkusTaskDeadlineTimerRepository() {
+ this(null);
}
- @Override
- public Class<TaskInputEntity> getEntityClass() {
- return TaskInputEntity.class;
+ @Inject
+ public QuarkusTaskDeadlineTimerRepository(UserTaskJPAContext context) {
+ super(context);
}
+
}
diff --git a/addons/common/jbpm-usertask-storage-jpa/src/main/java/org/jbpm/usertask/jpa/repository/TaskInputRepository.java b/quarkus/addons/jbpm-usertask-storage-jpa/runtime/src/main/java/org/jbpm/usertask/jpa/quarkus/repository/QuarkusTaskReassignmentRepository.java
similarity index 62%
copy from addons/common/jbpm-usertask-storage-jpa/src/main/java/org/jbpm/usertask/jpa/repository/TaskInputRepository.java
copy to quarkus/addons/jbpm-usertask-storage-jpa/runtime/src/main/java/org/jbpm/usertask/jpa/quarkus/repository/QuarkusTaskReassignmentRepository.java
index 6e85081ff7..e597dddc6c 100644
--- a/addons/common/jbpm-usertask-storage-jpa/src/main/java/org/jbpm/usertask/jpa/repository/TaskInputRepository.java
+++ b/quarkus/addons/jbpm-usertask-storage-jpa/runtime/src/main/java/org/jbpm/usertask/jpa/quarkus/repository/QuarkusTaskReassignmentRepository.java
@@ -17,19 +17,24 @@
* under the License.
*/
-package org.jbpm.usertask.jpa.repository;
+package org.jbpm.usertask.jpa.quarkus.repository;
-import org.jbpm.usertask.jpa.model.TaskDataEntityPK;
-import org.jbpm.usertask.jpa.model.TaskInputEntity;
+import org.jbpm.usertask.jpa.repository.TaskReassignmentRepository;
+import org.jbpm.usertask.jpa.repository.UserTaskJPAContext;
-public class TaskInputRepository extends BaseRepository<TaskInputEntity, TaskDataEntityPK> {
+import jakarta.enterprise.context.ApplicationScoped;
+import jakarta.inject.Inject;
- public TaskInputRepository(UserTaskJPAContext context) {
- super(context);
+@ApplicationScoped
+public class QuarkusTaskReassignmentRepository extends TaskReassignmentRepository {
+
+ QuarkusTaskReassignmentRepository() {
+ super(null);
}
- @Override
- public Class<TaskInputEntity> getEntityClass() {
- return TaskInputEntity.class;
+ @Inject
+ public QuarkusTaskReassignmentRepository(UserTaskJPAContext context) {
+ super(context);
}
+
}
diff --git a/addons/common/jbpm-usertask-storage-jpa/src/main/java/org/jbpm/usertask/jpa/repository/TaskInputRepository.java b/quarkus/addons/jbpm-usertask-storage-jpa/runtime/src/main/java/org/jbpm/usertask/jpa/quarkus/repository/QuarkusTaskReassignmentTimerRepository.java
similarity index 61%
copy from addons/common/jbpm-usertask-storage-jpa/src/main/java/org/jbpm/usertask/jpa/repository/TaskInputRepository.java
copy to quarkus/addons/jbpm-usertask-storage-jpa/runtime/src/main/java/org/jbpm/usertask/jpa/quarkus/repository/QuarkusTaskReassignmentTimerRepository.java
index 6e85081ff7..a92d3b6547 100644
--- a/addons/common/jbpm-usertask-storage-jpa/src/main/java/org/jbpm/usertask/jpa/repository/TaskInputRepository.java
+++ b/quarkus/addons/jbpm-usertask-storage-jpa/runtime/src/main/java/org/jbpm/usertask/jpa/quarkus/repository/QuarkusTaskReassignmentTimerRepository.java
@@ -17,19 +17,24 @@
* under the License.
*/
-package org.jbpm.usertask.jpa.repository;
+package org.jbpm.usertask.jpa.quarkus.repository;
-import org.jbpm.usertask.jpa.model.TaskDataEntityPK;
-import org.jbpm.usertask.jpa.model.TaskInputEntity;
+import org.jbpm.usertask.jpa.repository.TaskReassignmentTimerRepository;
+import org.jbpm.usertask.jpa.repository.UserTaskJPAContext;
-public class TaskInputRepository extends BaseRepository<TaskInputEntity, TaskDataEntityPK> {
+import jakarta.enterprise.context.ApplicationScoped;
+import jakarta.inject.Inject;
- public TaskInputRepository(UserTaskJPAContext context) {
- super(context);
+@ApplicationScoped
+public class QuarkusTaskReassignmentTimerRepository extends TaskReassignmentTimerRepository {
+
+ QuarkusTaskReassignmentTimerRepository() {
+ super(null);
}
- @Override
- public Class<TaskInputEntity> getEntityClass() {
- return TaskInputEntity.class;
+ @Inject
+ public QuarkusTaskReassignmentTimerRepository(UserTaskJPAContext context) {
+ super(context);
}
+
}
diff --git a/quarkus/addons/jobs/common/messaging/src/main/java/org/kie/kogito/jobs/messaging/quarkus/AbstractReactiveMessagingJobsService.java b/quarkus/addons/jobs/common/messaging/src/main/java/org/kie/kogito/jobs/messaging/quarkus/AbstractReactiveMessagingJobsService.java
index a238140469..3f61e1fe1d 100644
--- a/quarkus/addons/jobs/common/messaging/src/main/java/org/kie/kogito/jobs/messaging/quarkus/AbstractReactiveMessagingJobsService.java
+++ b/quarkus/addons/jobs/common/messaging/src/main/java/org/kie/kogito/jobs/messaging/quarkus/AbstractReactiveMessagingJobsService.java
@@ -23,10 +23,9 @@ import java.util.concurrent.CompletableFuture;
import org.eclipse.microprofile.reactive.messaging.Emitter;
import org.eclipse.microprofile.reactive.messaging.Message;
+import org.kie.kogito.jobs.JobDescription;
import org.kie.kogito.jobs.JobsService;
import org.kie.kogito.jobs.JobsServiceException;
-import org.kie.kogito.jobs.ProcessInstanceJobDescription;
-import org.kie.kogito.jobs.ProcessJobDescription;
import org.kie.kogito.jobs.service.api.Job;
import org.kie.kogito.jobs.service.api.JobLookupId;
import org.kie.kogito.jobs.service.api.event.CreateJobEvent;
@@ -73,12 +72,7 @@ public abstract class AbstractReactiveMessagingJobsService implements JobsServic
}
@Override
- public String scheduleProcessJob(ProcessJobDescription description) {
- throw new UnsupportedOperationException("Scheduling for process jobs is not yet implemented");
- }
-
- @Override
- public String scheduleProcessInstanceJob(ProcessInstanceJobDescription description) {
+ public String scheduleJob(JobDescription description) {
Job job = buildCallbackPatternJob(description, buildCallbackURI(description, serviceUrl.toString()), objectMapper);
LOGGER.debug("scheduleProcessInstanceJob job: {}", job);
CreateJobEvent event = CreateJobEvent.builder()
diff --git a/quarkus/addons/jobs/common/messaging/src/test/java/org/kie/kogito/jobs/messaging/quarkus/AbstractReactiveMessagingJobsServiceTest.java b/quarkus/addons/jobs/common/messaging/src/test/java/org/kie/kogito/jobs/messaging/quarkus/AbstractReactiveMessagingJobsServiceTest.java
index 3d22a9bfb1..ccb448a7af 100644
--- a/quarkus/addons/jobs/common/messaging/src/test/java/org/kie/kogito/jobs/messaging/quarkus/AbstractReactiveMessagingJobsServiceTest.java
+++ b/quarkus/addons/jobs/common/messaging/src/test/java/org/kie/kogito/jobs/messaging/quarkus/AbstractReactiveMessagingJobsServiceTest.java
@@ -29,10 +29,10 @@ import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.kie.kogito.jobs.ExactExpirationTime;
import org.kie.kogito.jobs.ExpirationTime;
+import org.kie.kogito.jobs.JobDescription;
import org.kie.kogito.jobs.JobsServiceException;
-import org.kie.kogito.jobs.ProcessInstanceJobDescription;
-import org.kie.kogito.jobs.ProcessJobDescription;
import org.kie.kogito.jobs.api.JobCallbackPayload;
+import org.kie.kogito.jobs.descriptors.ProcessInstanceJobDescription;
import org.kie.kogito.jobs.service.api.Job;
import org.kie.kogito.jobs.service.api.JobLookupId;
import org.kie.kogito.jobs.service.api.TemporalUnit;
@@ -105,12 +105,12 @@ public abstract class AbstractReactiveMessagingJobsServiceTest<T extends Abstrac
@Test
protected void scheduleProcessInstanceJobSuccessful() throws Exception {
- ProcessInstanceJobDescription description = mockProcessInstanceJobDescription();
+ JobDescription description = mockProcessInstanceJobDescription();
CreateJobEvent expectedEvent = mockExpectedCreateJobEvent();
doReturn(SERIALIZED_EVENT).when(objectMapper).writeValueAsString(any(CreateJobEvent.class));
doReturn(JSON_PAYLOAD).when(objectMapper).valueToTree(any(JobCallbackPayload.class));
- jobsService.scheduleProcessInstanceJob(description);
+ jobsService.scheduleJob(description);
verifyCreateJobEventWasCreated(1, expectedEvent);
verifyEmitterWasInvoked(1, SERIALIZED_EVENT);
@@ -137,7 +137,7 @@ public abstract class AbstractReactiveMessagingJobsServiceTest<T extends Abstrac
// Clear the errors and produce a second execution that must work fine.
eventsEmitter.clearErrors();
doReturn(SERIALIZED_SECOND_EVENT).when(objectMapper).writeValueAsString(any(CreateJobEvent.class));
- jobsService.scheduleProcessInstanceJob(description);
+ jobsService.scheduleJob(description);
verifyCreateJobEventWasCreated(2, expectedEvent, expectedEvent);
verifyEmitterWasInvoked(2, SERIALIZED_EVENT, SERIALIZED_SECOND_EVENT);
@@ -148,7 +148,7 @@ public abstract class AbstractReactiveMessagingJobsServiceTest<T extends Abstrac
RuntimeException nackError = new RuntimeException(ERROR);
eventsEmitter.setNackError(nackError);
// ensure the execution failed as programmed
- assertThatThrownBy(() -> jobsService.scheduleProcessInstanceJob(description))
+ assertThatThrownBy(() -> jobsService.scheduleJob(description))
.isInstanceOf(JobsServiceException.class)
.hasMessageContaining("Error while emitting JobCloudEvent")
.hasCause(nackError);
@@ -175,7 +175,7 @@ public abstract class AbstractReactiveMessagingJobsServiceTest<T extends Abstrac
// Clear the errors and produce a second execution that must work fine.
eventsEmitter.clearErrors();
doReturn(SERIALIZED_SECOND_EVENT).when(objectMapper).writeValueAsString(any(CreateJobEvent.class));
- jobsService.scheduleProcessInstanceJob(description);
+ jobsService.scheduleJob(description);
verifyCreateJobEventWasCreated(2, expectedEvent, expectedEvent);
verifyEmitterWasInvoked(2, SERIALIZED_EVENT, SERIALIZED_SECOND_EVENT);
@@ -186,7 +186,7 @@ public abstract class AbstractReactiveMessagingJobsServiceTest<T extends Abstrac
RuntimeException fatalError = new RuntimeException(FATAL_ERROR);
eventsEmitter.setFatalError(fatalError);
// ensure the execution failed as programmed
- assertThatThrownBy(() -> jobsService.scheduleProcessInstanceJob(description))
+ assertThatThrownBy(() -> jobsService.scheduleJob(description))
.isInstanceOf(JobsServiceException.class)
.hasMessageContaining("Error while emitting JobCloudEvent")
.hasCause(fatalError);
@@ -275,15 +275,8 @@ public abstract class AbstractReactiveMessagingJobsServiceTest<T extends Abstrac
.hasCause(fatalError);
}
- @Test
- protected void scheduleProcessJob() {
- ProcessJobDescription description = ProcessJobDescription.of(EXPIRATION_TIME, PROCESS_ID);
- assertThatThrownBy(() -> jobsService.scheduleProcessJob(description))
- .isInstanceOf(UnsupportedOperationException.class);
- }
-
protected ProcessInstanceJobDescription mockProcessInstanceJobDescription() {
- return ProcessInstanceJobDescription.builder()
+ return ProcessInstanceJobDescription.newProcessInstanceJobDescriptionBuilder()
.id(JOB_ID)
.timerId(TIMER_ID)
.expirationTime(EXPIRATION_TIME)
diff --git a/quarkus/addons/jobs/common/rest-callback/src/main/java/org/kie/kogito/jobs/quarkus/common/CallbackJobsServiceResource.java b/quarkus/addons/jobs/common/rest-callback/src/main/java/org/kie/kogito/jobs/quarkus/common/CallbackJobsServiceResource.java
index 0e67866619..cd4972bc63 100644
--- a/quarkus/addons/jobs/common/rest-callback/src/main/java/org/kie/kogito/jobs/quarkus/common/CallbackJobsServiceResource.java
+++ b/quarkus/addons/jobs/common/rest-callback/src/main/java/org/kie/kogito/jobs/quarkus/common/CallbackJobsServiceResource.java
@@ -22,6 +22,7 @@ import java.util.Optional;
import org.kie.kogito.Application;
import org.kie.kogito.Model;
+import org.kie.kogito.jobs.JobDescription;
import org.kie.kogito.jobs.api.JobCallbackPayload;
import org.kie.kogito.process.Process;
import org.kie.kogito.process.Processes;
@@ -42,14 +43,13 @@ import jakarta.ws.rs.core.Response;
import jakarta.ws.rs.core.Response.Status;
import static org.kie.kogito.jobs.api.JobCallbackResourceDef.JOBS_CALLBACK_POST_URI;
-import static org.kie.kogito.jobs.api.JobCallbackResourceDef.JOBS_CALLBACK_URI;
import static org.kie.kogito.jobs.api.JobCallbackResourceDef.LIMIT;
import static org.kie.kogito.jobs.api.JobCallbackResourceDef.LIMIT_DEFAULT_VALUE;
import static org.kie.kogito.jobs.api.JobCallbackResourceDef.PROCESS_ID;
import static org.kie.kogito.jobs.api.JobCallbackResourceDef.PROCESS_INSTANCE_ID;
import static org.kie.kogito.jobs.api.JobCallbackResourceDef.TIMER_ID;
-@Path(JOBS_CALLBACK_URI)
+@Path(JobDescription.JOBS_CALLBACK_URI)
public class CallbackJobsServiceResource {
@Inject
diff --git a/quarkus/addons/jobs/management/runtime/src/main/java/org/kie/kogito/jobs/management/quarkus/VertxJobsService.java b/quarkus/addons/jobs/management/runtime/src/main/java/org/kie/kogito/jobs/management/quarkus/VertxJobsService.java
index a7989885d0..c642ff6674 100644
--- a/quarkus/addons/jobs/management/runtime/src/main/java/org/kie/kogito/jobs/management/quarkus/VertxJobsService.java
+++ b/quarkus/addons/jobs/management/runtime/src/main/java/org/kie/kogito/jobs/management/quarkus/VertxJobsService.java
@@ -21,8 +21,7 @@ package org.kie.kogito.jobs.management.quarkus;
import java.net.URI;
import org.eclipse.microprofile.config.inject.ConfigProperty;
-import org.kie.kogito.jobs.ProcessInstanceJobDescription;
-import org.kie.kogito.jobs.ProcessJobDescription;
+import org.kie.kogito.jobs.JobDescription;
import org.kie.kogito.jobs.management.RestJobsService;
import org.kie.kogito.jobs.service.api.Job;
import org.slf4j.Logger;
@@ -89,13 +88,7 @@ public class VertxJobsService extends RestJobsService {
}
@Override
- public String scheduleProcessJob(ProcessJobDescription description) {
-
- throw new UnsupportedOperationException("Scheduling for process jobs is not yet implemented");
- }
-
- @Override
- public String scheduleProcessInstanceJob(ProcessInstanceJobDescription description) {
+ public String scheduleJob(JobDescription description) {
String callback = getCallbackEndpoint(description);
LOGGER.debug("Job to be scheduled {} with callback URL {}", description, callback);
final Job job = buildJob(description, callback);
diff --git a/quarkus/addons/jobs/management/runtime/src/test/java/org/kie/kogito/jobs/management/quarkus/VertxJobsServiceTest.java b/quarkus/addons/jobs/management/runtime/src/test/java/org/kie/kogito/jobs/management/quarkus/VertxJobsServiceTest.java
index 578d7f954c..56bc91ed72 100644
--- a/quarkus/addons/jobs/management/runtime/src/test/java/org/kie/kogito/jobs/management/quarkus/VertxJobsServiceTest.java
+++ b/quarkus/addons/jobs/management/runtime/src/test/java/org/kie/kogito/jobs/management/quarkus/VertxJobsServiceTest.java
@@ -20,8 +20,8 @@ package org.kie.kogito.jobs.management.quarkus;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
-import org.kie.kogito.jobs.ProcessInstanceJobDescription;
import org.kie.kogito.jobs.api.JobCallbackPayload;
+import org.kie.kogito.jobs.descriptors.ProcessInstanceJobDescription;
import org.kie.kogito.jobs.management.RestJobsServiceTest;
import org.kie.kogito.jobs.service.api.Job;
import org.mockito.ArgumentCaptor;
@@ -87,7 +87,7 @@ class VertxJobsServiceTest extends RestJobsServiceTest<VertxJobsService> {
when(webClient.post(anyString())).thenReturn(request);
when(objectMapper.valueToTree(any(JobCallbackPayload.class))).thenReturn(JSON_PAYLOAD);
ProcessInstanceJobDescription processInstanceJobDescription = buildProcessInstanceJobDescription();
- tested.scheduleProcessInstanceJob(processInstanceJobDescription);
+ tested.scheduleJob(processInstanceJobDescription);
verify(webClient).post("/v2/jobs");
ArgumentCaptor<Job> jobArgumentCaptor = forClass(Job.class);
verify(request).sendJson(jobArgumentCaptor.capture(), any(Handler.class));
diff --git a/quarkus/extensions/kogito-quarkus-workflow-extension-common/kogito-quarkus-workflow-common/src/main/java/org/kie/kogito/quarkus/workflow/KogitoBeanProducer.java b/quarkus/extensions/kogito-quarkus-workflow-extension-common/kogito-quarkus-workflow-common/src/main/java/org/kie/kogito/quarkus/workflow/KogitoBeanProducer.java
index 7b282dc8f9..963f5958fc 100644
--- a/quarkus/extensions/kogito-quarkus-workflow-extension-common/kogito-quarkus-workflow-common/src/main/java/org/kie/kogito/quarkus/workflow/KogitoBeanProducer.java
+++ b/quarkus/extensions/kogito-quarkus-workflow-extension-common/kogito-quarkus-workflow-common/src/main/java/org/kie/kogito/quarkus/workflow/KogitoBeanProducer.java
@@ -27,10 +27,13 @@ import org.kie.kogito.jobs.JobsService;
import org.kie.kogito.process.ProcessVersionResolver;
import org.kie.kogito.process.Processes;
import org.kie.kogito.process.version.ProjectVersionProcessVersionResolver;
+import org.kie.kogito.services.jobs.impl.InMemoryJobContext;
import org.kie.kogito.services.jobs.impl.InMemoryJobService;
+import org.kie.kogito.services.jobs.impl.InMemoryProcessJobExecutorFactory;
import org.kie.kogito.services.uow.CollectingUnitOfWorkFactory;
import org.kie.kogito.services.uow.DefaultUnitOfWorkManager;
import org.kie.kogito.uow.UnitOfWorkManager;
+import org.kie.kogito.usertask.UserTasks;
import io.quarkus.arc.DefaultBean;
import io.quarkus.arc.properties.IfBuildProperty;
@@ -61,8 +64,11 @@ public class KogitoBeanProducer {
@DefaultBean
@Produces
- JobsService jobsService(Instance<Processes> processes, UnitOfWorkManager uowm, ScheduledExecutorService executor) {
- return InMemoryJobService.get(processes.isResolvable() ? processes.get() : null, uowm, executor);
+ JobsService jobsService(Instance<Processes> processes, Instance<UserTasks> userTasks, UnitOfWorkManager uowm, ScheduledExecutorService executor) {
+ InMemoryJobContext context = new InMemoryJobContext(null, uowm, processes.isResolvable() ? processes.get() : null, userTasks.isResolvable() ? userTasks.get() : null);
+ InMemoryJobService inMemoryJobService = new InMemoryJobService(executor);
+ inMemoryJobService.registerJobExecutorFactory(new InMemoryProcessJobExecutorFactory(context));
+ return inMemoryJobService;
}
@Produces
diff --git a/springboot/addons/jbpm-usertask-storage-jpa/src/main/java/org/jbpm/usertask/jpa/springboot/mapper/SpringBootUserTaskInstanceEntityMapper.java b/springboot/addons/jbpm-usertask-storage-jpa/src/main/java/org/jbpm/usertask/jpa/springboot/mapper/SpringBootTaskDeadlineEntityMapper.java
similarity index 64%
copy from springboot/addons/jbpm-usertask-storage-jpa/src/main/java/org/jbpm/usertask/jpa/springboot/mapper/SpringBootUserTaskInstanceEntityMapper.java
copy to springboot/addons/jbpm-usertask-storage-jpa/src/main/java/org/jbpm/usertask/jpa/springboot/mapper/SpringBootTaskDeadlineEntityMapper.java
index 6c753b1b6a..03201da8fb 100644
--- a/springboot/addons/jbpm-usertask-storage-jpa/src/main/java/org/jbpm/usertask/jpa/springboot/mapper/SpringBootUserTaskInstanceEntityMapper.java
+++ b/springboot/addons/jbpm-usertask-storage-jpa/src/main/java/org/jbpm/usertask/jpa/springboot/mapper/SpringBootTaskDeadlineEntityMapper.java
@@ -19,16 +19,20 @@
package org.jbpm.usertask.jpa.springboot.mapper;
-import org.jbpm.usertask.jpa.mapper.*;
+import org.jbpm.usertask.jpa.mapper.TaskDeadlineEntityMapper;
+import org.jbpm.usertask.jpa.repository.TaskDeadlineRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@Component
-public class SpringBootUserTaskInstanceEntityMapper extends UserTaskInstanceEntityMapper {
+public class SpringBootTaskDeadlineEntityMapper extends TaskDeadlineEntityMapper {
+
+ public SpringBootTaskDeadlineEntityMapper() {
+ super(null);
+ }
@Autowired
- public SpringBootUserTaskInstanceEntityMapper(AttachmentsEntityMapper attachmentsMapper, CommentsEntityMapper commentsMapper, TaskMetadataEntityMapper taskMetadataEntityMapper,
- TaskInputsEntityMapper taskInputsEntityMapper, TaskOutputsEntityMapper taskOutputsEntityMapper) {
- super(attachmentsMapper, commentsMapper, taskMetadataEntityMapper, taskInputsEntityMapper, taskOutputsEntityMapper);
+ public SpringBootTaskDeadlineEntityMapper(TaskDeadlineRepository repository) {
+ super(repository);
}
}
diff --git a/springboot/addons/jbpm-usertask-storage-jpa/src/main/java/org/jbpm/usertask/jpa/springboot/mapper/SpringBootUserTaskInstanceEntityMapper.java b/springboot/addons/jbpm-usertask-storage-jpa/src/main/java/org/jbpm/usertask/jpa/springboot/mapper/SpringBootTaskDeadlineTimerEntityMapper.java
similarity index 64%
copy from springboot/addons/jbpm-usertask-storage-jpa/src/main/java/org/jbpm/usertask/jpa/springboot/mapper/SpringBootUserTaskInstanceEntityMapper.java
copy to springboot/addons/jbpm-usertask-storage-jpa/src/main/java/org/jbpm/usertask/jpa/springboot/mapper/SpringBootTaskDeadlineTimerEntityMapper.java
index 6c753b1b6a..399a958431 100644
--- a/springboot/addons/jbpm-usertask-storage-jpa/src/main/java/org/jbpm/usertask/jpa/springboot/mapper/SpringBootUserTaskInstanceEntityMapper.java
+++ b/springboot/addons/jbpm-usertask-storage-jpa/src/main/java/org/jbpm/usertask/jpa/springboot/mapper/SpringBootTaskDeadlineTimerEntityMapper.java
@@ -19,16 +19,20 @@
package org.jbpm.usertask.jpa.springboot.mapper;
-import org.jbpm.usertask.jpa.mapper.*;
+import org.jbpm.usertask.jpa.mapper.TaskDeadlineTimerEntityMapper;
+import org.jbpm.usertask.jpa.repository.TaskDeadlineTimerRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@Component
-public class SpringBootUserTaskInstanceEntityMapper extends UserTaskInstanceEntityMapper {
+public class SpringBootTaskDeadlineTimerEntityMapper extends TaskDeadlineTimerEntityMapper {
+
+ public SpringBootTaskDeadlineTimerEntityMapper() {
+ super(null);
+ }
@Autowired
- public SpringBootUserTaskInstanceEntityMapper(AttachmentsEntityMapper attachmentsMapper, CommentsEntityMapper commentsMapper, TaskMetadataEntityMapper taskMetadataEntityMapper,
- TaskInputsEntityMapper taskInputsEntityMapper, TaskOutputsEntityMapper taskOutputsEntityMapper) {
- super(attachmentsMapper, commentsMapper, taskMetadataEntityMapper, taskInputsEntityMapper, taskOutputsEntityMapper);
+ public SpringBootTaskDeadlineTimerEntityMapper(TaskDeadlineTimerRepository repository) {
+ super(repository);
}
}
diff --git a/springboot/addons/jbpm-usertask-storage-jpa/src/main/java/org/jbpm/usertask/jpa/springboot/mapper/SpringBootUserTaskInstanceEntityMapper.java b/springboot/addons/jbpm-usertask-storage-jpa/src/main/java/org/jbpm/usertask/jpa/springboot/mapper/SpringBootTaskReassignmentEntityMapper.java
similarity index 64%
copy from springboot/addons/jbpm-usertask-storage-jpa/src/main/java/org/jbpm/usertask/jpa/springboot/mapper/SpringBootUserTaskInstanceEntityMapper.java
copy to springboot/addons/jbpm-usertask-storage-jpa/src/main/java/org/jbpm/usertask/jpa/springboot/mapper/SpringBootTaskReassignmentEntityMapper.java
index 6c753b1b6a..7e32aaee44 100644
--- a/springboot/addons/jbpm-usertask-storage-jpa/src/main/java/org/jbpm/usertask/jpa/springboot/mapper/SpringBootUserTaskInstanceEntityMapper.java
+++ b/springboot/addons/jbpm-usertask-storage-jpa/src/main/java/org/jbpm/usertask/jpa/springboot/mapper/SpringBootTaskReassignmentEntityMapper.java
@@ -19,16 +19,20 @@
package org.jbpm.usertask.jpa.springboot.mapper;
-import org.jbpm.usertask.jpa.mapper.*;
+import org.jbpm.usertask.jpa.mapper.TaskReassignmentEntityMapper;
+import org.jbpm.usertask.jpa.repository.TaskReassignmentRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@Component
-public class SpringBootUserTaskInstanceEntityMapper extends UserTaskInstanceEntityMapper {
+public class SpringBootTaskReassignmentEntityMapper extends TaskReassignmentEntityMapper {
+
+ public SpringBootTaskReassignmentEntityMapper() {
+ super(null);
+ }
@Autowired
- public SpringBootUserTaskInstanceEntityMapper(AttachmentsEntityMapper attachmentsMapper, CommentsEntityMapper commentsMapper, TaskMetadataEntityMapper taskMetadataEntityMapper,
- TaskInputsEntityMapper taskInputsEntityMapper, TaskOutputsEntityMapper taskOutputsEntityMapper) {
- super(attachmentsMapper, commentsMapper, taskMetadataEntityMapper, taskInputsEntityMapper, taskOutputsEntityMapper);
+ public SpringBootTaskReassignmentEntityMapper(TaskReassignmentRepository repository) {
+ super(repository);
}
}
diff --git a/springboot/addons/jbpm-usertask-storage-jpa/src/main/java/org/jbpm/usertask/jpa/springboot/mapper/SpringBootUserTaskInstanceEntityMapper.java b/springboot/addons/jbpm-usertask-storage-jpa/src/main/java/org/jbpm/usertask/jpa/springboot/mapper/SpringBootTaskReassignmentTimerEntityMapper.java
similarity index 64%
copy from springboot/addons/jbpm-usertask-storage-jpa/src/main/java/org/jbpm/usertask/jpa/springboot/mapper/SpringBootUserTaskInstanceEntityMapper.java
copy to springboot/addons/jbpm-usertask-storage-jpa/src/main/java/org/jbpm/usertask/jpa/springboot/mapper/SpringBootTaskReassignmentTimerEntityMapper.java
index 6c753b1b6a..47eb8f1800 100644
--- a/springboot/addons/jbpm-usertask-storage-jpa/src/main/java/org/jbpm/usertask/jpa/springboot/mapper/SpringBootUserTaskInstanceEntityMapper.java
+++ b/springboot/addons/jbpm-usertask-storage-jpa/src/main/java/org/jbpm/usertask/jpa/springboot/mapper/SpringBootTaskReassignmentTimerEntityMapper.java
@@ -19,16 +19,20 @@
package org.jbpm.usertask.jpa.springboot.mapper;
-import org.jbpm.usertask.jpa.mapper.*;
+import org.jbpm.usertask.jpa.mapper.TaskReassignmentTimerEntityMapper;
+import org.jbpm.usertask.jpa.repository.TaskReassignmentTimerRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@Component
-public class SpringBootUserTaskInstanceEntityMapper extends UserTaskInstanceEntityMapper {
+public class SpringBootTaskReassignmentTimerEntityMapper extends TaskReassignmentTimerEntityMapper {
+
+ public SpringBootTaskReassignmentTimerEntityMapper() {
+ super(null);
+ }
@Autowired
- public SpringBootUserTaskInstanceEntityMapper(AttachmentsEntityMapper attachmentsMapper, CommentsEntityMapper commentsMapper, TaskMetadataEntityMapper taskMetadataEntityMapper,
- TaskInputsEntityMapper taskInputsEntityMapper, TaskOutputsEntityMapper taskOutputsEntityMapper) {
- super(attachmentsMapper, commentsMapper, taskMetadataEntityMapper, taskInputsEntityMapper, taskOutputsEntityMapper);
+ public SpringBootTaskReassignmentTimerEntityMapper(TaskReassignmentTimerRepository repository) {
+ super(repository);
}
}
diff --git a/springboot/addons/jbpm-usertask-storage-jpa/src/main/java/org/jbpm/usertask/jpa/springboot/mapper/SpringBootUserTaskInstanceEntityMapper.java b/springboot/addons/jbpm-usertask-storage-jpa/src/main/java/org/jbpm/usertask/jpa/springboot/mapper/SpringBootUserTaskInstanceEntityMapper.java
index 6c753b1b6a..33462df7f0 100644
--- a/springboot/addons/jbpm-usertask-storage-jpa/src/main/java/org/jbpm/usertask/jpa/springboot/mapper/SpringBootUserTaskInstanceEntityMapper.java
+++ b/springboot/addons/jbpm-usertask-storage-jpa/src/main/java/org/jbpm/usertask/jpa/springboot/mapper/SpringBootUserTaskInstanceEntityMapper.java
@@ -19,7 +19,10 @@
package org.jbpm.usertask.jpa.springboot.mapper;
-import org.jbpm.usertask.jpa.mapper.*;
+import java.util.List;
+
+import org.jbpm.usertask.jpa.mapper.EntityMapper;
+import org.jbpm.usertask.jpa.mapper.UserTaskInstanceEntityMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@@ -27,8 +30,8 @@ import org.springframework.stereotype.Component;
public class SpringBootUserTaskInstanceEntityMapper extends UserTaskInstanceEntityMapper {
@Autowired
- public SpringBootUserTaskInstanceEntityMapper(AttachmentsEntityMapper attachmentsMapper, CommentsEntityMapper commentsMapper, TaskMetadataEntityMapper taskMetadataEntityMapper,
- TaskInputsEntityMapper taskInputsEntityMapper, TaskOutputsEntityMapper taskOutputsEntityMapper) {
- super(attachmentsMapper, commentsMapper, taskMetadataEntityMapper, taskInputsEntityMapper, taskOutputsEntityMapper);
+ public SpringBootUserTaskInstanceEntityMapper(List<EntityMapper> mappers) {
+ super(mappers);
}
+
}
diff --git a/springboot/addons/jbpm-usertask-storage-jpa/src/main/java/org/jbpm/usertask/jpa/springboot/mapper/SpringBootUserTaskInstanceEntityMapper.java b/springboot/addons/jbpm-usertask-storage-jpa/src/main/java/org/jbpm/usertask/jpa/springboot/repository/SpringBootTaskDeadlineRepository.java
similarity index 61%
copy from springboot/addons/jbpm-usertask-storage-jpa/src/main/java/org/jbpm/usertask/jpa/springboot/mapper/SpringBootUserTaskInstanceEntityMapper.java
copy to springboot/addons/jbpm-usertask-storage-jpa/src/main/java/org/jbpm/usertask/jpa/springboot/repository/SpringBootTaskDeadlineRepository.java
index 6c753b1b6a..fe7f742cd4 100644
--- a/springboot/addons/jbpm-usertask-storage-jpa/src/main/java/org/jbpm/usertask/jpa/springboot/mapper/SpringBootUserTaskInstanceEntityMapper.java
+++ b/springboot/addons/jbpm-usertask-storage-jpa/src/main/java/org/jbpm/usertask/jpa/springboot/repository/SpringBootTaskDeadlineRepository.java
@@ -17,18 +17,23 @@
* under the License.
*/
-package org.jbpm.usertask.jpa.springboot.mapper;
+package org.jbpm.usertask.jpa.springboot.repository;
-import org.jbpm.usertask.jpa.mapper.*;
+import org.jbpm.usertask.jpa.repository.TaskDeadlineRepository;
+import org.jbpm.usertask.jpa.repository.UserTaskJPAContext;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@Component
-public class SpringBootUserTaskInstanceEntityMapper extends UserTaskInstanceEntityMapper {
+public class SpringBootTaskDeadlineRepository extends TaskDeadlineRepository {
+
+ SpringBootTaskDeadlineRepository() {
+ super(null);
+ }
@Autowired
- public SpringBootUserTaskInstanceEntityMapper(AttachmentsEntityMapper attachmentsMapper, CommentsEntityMapper commentsMapper, TaskMetadataEntityMapper taskMetadataEntityMapper,
- TaskInputsEntityMapper taskInputsEntityMapper, TaskOutputsEntityMapper taskOutputsEntityMapper) {
- super(attachmentsMapper, commentsMapper, taskMetadataEntityMapper, taskInputsEntityMapper, taskOutputsEntityMapper);
+ public SpringBootTaskDeadlineRepository(UserTaskJPAContext context) {
+ super(context);
}
+
}
diff --git a/springboot/addons/jbpm-usertask-storage-jpa/src/main/java/org/jbpm/usertask/jpa/springboot/mapper/SpringBootUserTaskInstanceEntityMapper.java b/springboot/addons/jbpm-usertask-storage-jpa/src/main/java/org/jbpm/usertask/jpa/springboot/repository/SpringBootTaskDeadlineTimerRepository.java
similarity index 61%
copy from springboot/addons/jbpm-usertask-storage-jpa/src/main/java/org/jbpm/usertask/jpa/springboot/mapper/SpringBootUserTaskInstanceEntityMapper.java
copy to springboot/addons/jbpm-usertask-storage-jpa/src/main/java/org/jbpm/usertask/jpa/springboot/repository/SpringBootTaskDeadlineTimerRepository.java
index 6c753b1b6a..85a1356819 100644
--- a/springboot/addons/jbpm-usertask-storage-jpa/src/main/java/org/jbpm/usertask/jpa/springboot/mapper/SpringBootUserTaskInstanceEntityMapper.java
+++ b/springboot/addons/jbpm-usertask-storage-jpa/src/main/java/org/jbpm/usertask/jpa/springboot/repository/SpringBootTaskDeadlineTimerRepository.java
@@ -17,18 +17,23 @@
* under the License.
*/
-package org.jbpm.usertask.jpa.springboot.mapper;
+package org.jbpm.usertask.jpa.springboot.repository;
-import org.jbpm.usertask.jpa.mapper.*;
+import org.jbpm.usertask.jpa.repository.TaskDeadlineTimerRepository;
+import org.jbpm.usertask.jpa.repository.UserTaskJPAContext;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@Component
-public class SpringBootUserTaskInstanceEntityMapper extends UserTaskInstanceEntityMapper {
+public class SpringBootTaskDeadlineTimerRepository extends TaskDeadlineTimerRepository {
+
+ SpringBootTaskDeadlineTimerRepository() {
+ this(null);
+ }
@Autowired
- public SpringBootUserTaskInstanceEntityMapper(AttachmentsEntityMapper attachmentsMapper, CommentsEntityMapper commentsMapper, TaskMetadataEntityMapper taskMetadataEntityMapper,
- TaskInputsEntityMapper taskInputsEntityMapper, TaskOutputsEntityMapper taskOutputsEntityMapper) {
- super(attachmentsMapper, commentsMapper, taskMetadataEntityMapper, taskInputsEntityMapper, taskOutputsEntityMapper);
+ public SpringBootTaskDeadlineTimerRepository(UserTaskJPAContext context) {
+ super(context);
}
+
}
diff --git a/springboot/addons/jbpm-usertask-storage-jpa/src/main/java/org/jbpm/usertask/jpa/springboot/mapper/SpringBootUserTaskInstanceEntityMapper.java b/springboot/addons/jbpm-usertask-storage-jpa/src/main/java/org/jbpm/usertask/jpa/springboot/repository/SpringBootTaskReassignmentRepository.java
similarity index 61%
copy from springboot/addons/jbpm-usertask-storage-jpa/src/main/java/org/jbpm/usertask/jpa/springboot/mapper/SpringBootUserTaskInstanceEntityMapper.java
copy to springboot/addons/jbpm-usertask-storage-jpa/src/main/java/org/jbpm/usertask/jpa/springboot/repository/SpringBootTaskReassignmentRepository.java
index 6c753b1b6a..1ccc6987f0 100644
--- a/springboot/addons/jbpm-usertask-storage-jpa/src/main/java/org/jbpm/usertask/jpa/springboot/mapper/SpringBootUserTaskInstanceEntityMapper.java
+++ b/springboot/addons/jbpm-usertask-storage-jpa/src/main/java/org/jbpm/usertask/jpa/springboot/repository/SpringBootTaskReassignmentRepository.java
@@ -17,18 +17,23 @@
* under the License.
*/
-package org.jbpm.usertask.jpa.springboot.mapper;
+package org.jbpm.usertask.jpa.springboot.repository;
-import org.jbpm.usertask.jpa.mapper.*;
+import org.jbpm.usertask.jpa.repository.TaskReassignmentRepository;
+import org.jbpm.usertask.jpa.repository.UserTaskJPAContext;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@Component
-public class SpringBootUserTaskInstanceEntityMapper extends UserTaskInstanceEntityMapper {
+public class SpringBootTaskReassignmentRepository extends TaskReassignmentRepository {
+
+ SpringBootTaskReassignmentRepository() {
+ super(null);
+ }
@Autowired
- public SpringBootUserTaskInstanceEntityMapper(AttachmentsEntityMapper attachmentsMapper, CommentsEntityMapper commentsMapper, TaskMetadataEntityMapper taskMetadataEntityMapper,
- TaskInputsEntityMapper taskInputsEntityMapper, TaskOutputsEntityMapper taskOutputsEntityMapper) {
- super(attachmentsMapper, commentsMapper, taskMetadataEntityMapper, taskInputsEntityMapper, taskOutputsEntityMapper);
+ public SpringBootTaskReassignmentRepository(UserTaskJPAContext context) {
+ super(context);
}
+
}
diff --git a/springboot/addons/jbpm-usertask-storage-jpa/src/main/java/org/jbpm/usertask/jpa/springboot/mapper/SpringBootUserTaskInstanceEntityMapper.java b/springboot/addons/jbpm-usertask-storage-jpa/src/main/java/org/jbpm/usertask/jpa/springboot/repository/SpringBootTaskReassignmentTimerRepository.java
similarity index 61%
copy from springboot/addons/jbpm-usertask-storage-jpa/src/main/java/org/jbpm/usertask/jpa/springboot/mapper/SpringBootUserTaskInstanceEntityMapper.java
copy to springboot/addons/jbpm-usertask-storage-jpa/src/main/java/org/jbpm/usertask/jpa/springboot/repository/SpringBootTaskReassignmentTimerRepository.java
index 6c753b1b6a..076452807f 100644
--- a/springboot/addons/jbpm-usertask-storage-jpa/src/main/java/org/jbpm/usertask/jpa/springboot/mapper/SpringBootUserTaskInstanceEntityMapper.java
+++ b/springboot/addons/jbpm-usertask-storage-jpa/src/main/java/org/jbpm/usertask/jpa/springboot/repository/SpringBootTaskReassignmentTimerRepository.java
@@ -17,18 +17,23 @@
* under the License.
*/
-package org.jbpm.usertask.jpa.springboot.mapper;
+package org.jbpm.usertask.jpa.springboot.repository;
-import org.jbpm.usertask.jpa.mapper.*;
+import org.jbpm.usertask.jpa.repository.TaskReassignmentTimerRepository;
+import org.jbpm.usertask.jpa.repository.UserTaskJPAContext;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@Component
-public class SpringBootUserTaskInstanceEntityMapper extends UserTaskInstanceEntityMapper {
+public class SpringBootTaskReassignmentTimerRepository extends TaskReassignmentTimerRepository {
+
+ SpringBootTaskReassignmentTimerRepository() {
+ super(null);
+ }
@Autowired
- public SpringBootUserTaskInstanceEntityMapper(AttachmentsEntityMapper attachmentsMapper, CommentsEntityMapper commentsMapper, TaskMetadataEntityMapper taskMetadataEntityMapper,
- TaskInputsEntityMapper taskInputsEntityMapper, TaskOutputsEntityMapper taskOutputsEntityMapper) {
- super(attachmentsMapper, commentsMapper, taskMetadataEntityMapper, taskInputsEntityMapper, taskOutputsEntityMapper);
+ public SpringBootTaskReassignmentTimerRepository(UserTaskJPAContext context) {
+ super(context);
}
+
}
diff --git a/springboot/addons/jobs/src/main/java/org/kie/kogito/jobs/management/springboot/CallbackJobsServiceResource.java b/springboot/addons/jobs/src/main/java/org/kie/kogito/jobs/management/springboot/CallbackJobsServiceResource.java
index 752c6a84c7..438ac1659f 100644
--- a/springboot/addons/jobs/src/main/java/org/kie/kogito/jobs/management/springboot/CallbackJobsServiceResource.java
+++ b/springboot/addons/jobs/src/main/java/org/kie/kogito/jobs/management/springboot/CallbackJobsServiceResource.java
@@ -39,8 +39,8 @@ import org.springframework.web.bind.annotation.RestController;
import com.fasterxml.jackson.databind.ObjectMapper;
+import static org.kie.kogito.jobs.JobDescription.JOBS_CALLBACK_URI;
import static org.kie.kogito.jobs.api.JobCallbackResourceDef.JOBS_CALLBACK_POST_URI;
-import static org.kie.kogito.jobs.api.JobCallbackResourceDef.JOBS_CALLBACK_URI;
import static org.kie.kogito.jobs.api.JobCallbackResourceDef.LIMIT;
import static org.kie.kogito.jobs.api.JobCallbackResourceDef.LIMIT_DEFAULT_VALUE;
import static org.kie.kogito.jobs.api.JobCallbackResourceDef.PROCESS_ID;
diff --git a/springboot/addons/jobs/src/main/java/org/kie/kogito/jobs/management/springboot/SpringRestJobsService.java b/springboot/addons/jobs/src/main/java/org/kie/kogito/jobs/management/springboot/SpringRestJobsService.java
index ac20763e55..b89392c51e 100644
--- a/springboot/addons/jobs/src/main/java/org/kie/kogito/jobs/management/springboot/SpringRestJobsService.java
+++ b/springboot/addons/jobs/src/main/java/org/kie/kogito/jobs/management/springboot/SpringRestJobsService.java
@@ -18,8 +18,7 @@
*/
package org.kie.kogito.jobs.management.springboot;
-import org.kie.kogito.jobs.ProcessInstanceJobDescription;
-import org.kie.kogito.jobs.ProcessJobDescription;
+import org.kie.kogito.jobs.JobDescription;
import org.kie.kogito.jobs.management.RestJobsService;
import org.kie.kogito.jobs.service.api.Job;
import org.slf4j.Logger;
@@ -73,13 +72,7 @@ public class SpringRestJobsService extends RestJobsService {
}
@Override
- public String scheduleProcessJob(ProcessJobDescription description) {
-
- throw new UnsupportedOperationException("Scheduling for process jobs is not yet implemented");
- }
-
- @Override
- public String scheduleProcessInstanceJob(ProcessInstanceJobDescription description) {
+ public String scheduleJob(JobDescription description) {
String callback = getCallbackEndpoint(description);
LOGGER.debug("Job to be scheduled {} with callback URL {}", description, callback);
final Job job = buildJob(description, callback);
diff --git a/springboot/addons/jobs/src/test/java/org/kie/kogito/jobs/management/springboot/SpringRestJobsServiceTest.java b/springboot/addons/jobs/src/test/java/org/kie/kogito/jobs/management/springboot/SpringRestJobsServiceTest.java
index 8804f608a8..0daf928680 100644
--- a/springboot/addons/jobs/src/test/java/org/kie/kogito/jobs/management/springboot/SpringRestJobsServiceTest.java
+++ b/springboot/addons/jobs/src/test/java/org/kie/kogito/jobs/management/springboot/SpringRestJobsServiceTest.java
@@ -22,7 +22,7 @@ import java.net.URI;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
-import org.kie.kogito.jobs.ProcessInstanceJobDescription;
+import org.kie.kogito.jobs.descriptors.ProcessInstanceJobDescription;
import org.kie.kogito.jobs.management.RestJobsServiceTest;
import org.kie.kogito.jobs.service.api.Job;
import org.mockito.ArgumentCaptor;
@@ -63,7 +63,7 @@ class SpringRestJobsServiceTest extends RestJobsServiceTest<SpringRestJobsServic
void scheduleProcessInstanceJob() throws Exception {
when(restTemplate.postForEntity(any(URI.class), any(HttpEntity.class), eq(String.class))).thenReturn(ResponseEntity.ok().build());
ProcessInstanceJobDescription processInstanceJobDescription = buildProcessInstanceJobDescription();
- tested.scheduleProcessInstanceJob(processInstanceJobDescription);
+ tested.scheduleJob(processInstanceJobDescription);
ArgumentCaptor<HttpEntity<String>> jobArgumentCaptor = forClass(HttpEntity.class);
verify(restTemplate).postForEntity(eq(tested.getJobsServiceUri()),
jobArgumentCaptor.capture(),
diff --git a/springboot/integration-tests/integration-tests-springboot-processes-persistence-it/integration-tests-springboot-processes-filesystem/.gitignore b/springboot/integration-tests/integration-tests-springboot-processes-persistence-it/integration-tests-springboot-processes-filesystem/.gitignore
index a180e83ba7..c2ca403117 100644
--- a/springboot/integration-tests/integration-tests-springboot-processes-persistence-it/integration-tests-springboot-processes-filesystem/.gitignore
+++ b/springboot/integration-tests/integration-tests-springboot-processes-persistence-it/integration-tests-springboot-processes-filesystem/.gitignore
@@ -19,3 +19,4 @@
*.bpmn
*.wid
+/target/
diff --git a/springboot/starters/kogito-processes-spring-boot-starter/src/main/java/org/kie/kogito/process/KogitoBeanProducer.java b/springboot/starters/kogito-processes-spring-boot-starter/src/main/java/org/kie/kogito/process/KogitoBeanProducer.java
index d1875057a9..1c65e780b9 100644
--- a/springboot/starters/kogito-processes-spring-boot-starter/src/main/java/org/kie/kogito/process/KogitoBeanProducer.java
+++ b/springboot/starters/kogito-processes-spring-boot-starter/src/main/java/org/kie/kogito/process/KogitoBeanProducer.java
@@ -18,13 +18,20 @@
*/
package org.kie.kogito.process;
+import java.util.List;
+
import org.kie.kogito.config.ConfigBean;
import org.kie.kogito.correlation.CorrelationService;
import org.kie.kogito.event.correlation.DefaultCorrelationService;
+import org.kie.kogito.jobs.JobsService;
import org.kie.kogito.process.version.ProjectVersionProcessVersionResolver;
+import org.kie.kogito.services.jobs.impl.InMemoryJobContext;
+import org.kie.kogito.services.jobs.impl.InMemoryJobService;
+import org.kie.kogito.services.jobs.impl.InMemoryProcessJobExecutorFactory;
import org.kie.kogito.services.uow.CollectingUnitOfWorkFactory;
import org.kie.kogito.services.uow.DefaultUnitOfWorkManager;
import org.kie.kogito.uow.UnitOfWorkManager;
+import org.kie.kogito.usertask.UserTasks;
import org.kogito.workitem.rest.RestWorkItemHandlerUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
@@ -50,6 +57,15 @@ public class KogitoBeanProducer {
return new DefaultCorrelationService();
}
+ @Bean
+ @ConditionalOnMissingBean(JobsService.class)
+ JobsService jobsService(List<Processes> processes, List<UserTasks> userTasks, UnitOfWorkManager uowm) {
+ InMemoryJobContext context = new InMemoryJobContext(null, uowm, !processes.isEmpty() ? processes.get(0) : null, !userTasks.isEmpty() ? userTasks.get(0) : null);
+ InMemoryJobService inMemoryJobService = new InMemoryJobService();
+ inMemoryJobService.registerJobExecutorFactory(new InMemoryProcessJobExecutorFactory(context));
+ return inMemoryJobService;
+ }
+
@Bean
@ConditionalOnProperty(value = "kogito.workflow.version-strategy", havingValue = "project")
ProcessVersionResolver projectVersionResolver() {
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@kie.apache.org
For additional commands, e-mail: commits-help@kie.apache.org