Skip to content

Commit

Permalink
[incubator-kie-issues#1545]: Create JPA persistence layer for Human T…
Browse files Browse the repository at this point in the history
…asks (apache#3735)

* incubator-kie-issues#1545: Create JPA persistence layer for Human Tasks
* - testing
* - springboot and it tests
* - cleanup
* - fix query
* - fix packages
 *- fix it tests endpoints
* - increase priority
  • Loading branch information
pefernan authored and rgdoliveira committed Nov 7, 2024
1 parent 4152095 commit 1679a83
Show file tree
Hide file tree
Showing 122 changed files with 8,998 additions and 52 deletions.
73 changes: 73 additions & 0 deletions addons/common/jbpm-usertask-storage-jpa/pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.kie</groupId>
<artifactId>kogito-addons-common-parent</artifactId>
<version>999-SNAPSHOT</version>
</parent>

<groupId>org.jbpm</groupId>
<artifactId>jbpm-addons-usertask-storage-jpa</artifactId>

<name>jBPM :: Add-Ons :: User Task Storage JPA :: Common </name>
<description>jBPM Add-Ons User Task Storage JPA Common</description>

<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<java.module.name>org.jbpm.usertask.storage.jpa</java.module.name>
</properties>

<dependencies>
<dependency>
<groupId>jakarta.persistence</groupId>
<artifactId>jakarta.persistence-api</artifactId>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
</dependency>
<dependency>
<groupId>org.kie.kogito</groupId>
<artifactId>kogito-api</artifactId>
</dependency>
<dependency>
<groupId>org.kie.kogito</groupId>
<artifactId>jbpm-usertask</artifactId>
</dependency>

<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-junit-jupiter</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-engine</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-params</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.assertj</groupId>
<artifactId>assertj-core</artifactId>
<scope>test</scope>
</dependency>
</dependencies>

</project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
/*
* 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;

import java.util.*;
import java.util.function.Function;

import org.jbpm.usertask.jpa.mapper.UserTaskInstanceEntityMapper;
import org.jbpm.usertask.jpa.model.UserTaskInstanceEntity;
import org.jbpm.usertask.jpa.repository.UserTaskInstanceRepository;
import org.kie.kogito.auth.IdentityProvider;
import org.kie.kogito.usertask.UserTaskInstance;
import org.kie.kogito.usertask.UserTaskInstances;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class JPAUserTaskInstances implements UserTaskInstances {
public static final Logger LOGGER = LoggerFactory.getLogger(JPAUserTaskInstances.class);

private final UserTaskInstanceRepository userTaskInstanceRepository;
private final UserTaskInstanceEntityMapper userTaskInstanceEntityMapper;

private Function<UserTaskInstance, UserTaskInstance> reconnectUserTaskInstance;
private Function<UserTaskInstance, UserTaskInstance> disconnectUserTaskInstance;

public JPAUserTaskInstances(UserTaskInstanceRepository userTaskInstanceRepository, UserTaskInstanceEntityMapper userTaskInstanceEntityMapper) {
this.userTaskInstanceRepository = userTaskInstanceRepository;
this.userTaskInstanceEntityMapper = userTaskInstanceEntityMapper;
}

@Override
public Optional<UserTaskInstance> findById(String userTaskInstanceId) {
return this.userTaskInstanceRepository.findById(userTaskInstanceId)
.map(userTaskInstanceEntityMapper::mapTaskEntityToInstance)
.map(reconnectUserTaskInstance);
}

@Override
public List<UserTaskInstance> findByIdentity(IdentityProvider identityProvider) {
return userTaskInstanceRepository.findByIdentity(identityProvider)
.stream()
.map(userTaskInstanceEntityMapper::mapTaskEntityToInstance)
.map(reconnectUserTaskInstance)
.toList();
}

@Override
public boolean exists(String userTaskInstanceId) {
return userTaskInstanceRepository.findById(userTaskInstanceId).isPresent();
}

@Override
public UserTaskInstance create(UserTaskInstance userTaskInstance) {
Optional<UserTaskInstanceEntity> optional = userTaskInstanceRepository.findById(userTaskInstance.getId());

if (optional.isPresent()) {
LOGGER.error("Cannot create userTaskInstance with id {}. Task Already exists.", userTaskInstance.getId());
throw new IllegalArgumentException("Cannot create userTaskInstance with id " + userTaskInstance.getId() + ". Task Already exists.");
}

UserTaskInstanceEntity entity = new UserTaskInstanceEntity();
entity.setId(userTaskInstance.getId());

this.userTaskInstanceRepository.persist(entity);

userTaskInstanceEntityMapper.mapTaskInstanceToEntity(userTaskInstance, entity);

return this.reconnectUserTaskInstance.apply(userTaskInstance);
}

@Override
public UserTaskInstance update(UserTaskInstance userTaskInstance) {

Optional<UserTaskInstanceEntity> optional = userTaskInstanceRepository.findById(userTaskInstance.getId());

if (optional.isEmpty()) {
LOGGER.error("Could not find userTaskInstance with id {}", userTaskInstance.getId());
throw new RuntimeException("Could not find userTaskInstance with id " + userTaskInstance.getId());
}

UserTaskInstanceEntity userTaskInstanceEntity = optional.get();

userTaskInstanceEntityMapper.mapTaskInstanceToEntity(userTaskInstance, userTaskInstanceEntity);

userTaskInstanceRepository.update(userTaskInstanceEntity);

return userTaskInstance;
}

@Override
public UserTaskInstance remove(UserTaskInstance userTaskInstance) {
Optional<UserTaskInstanceEntity> optional = userTaskInstanceRepository.findById(userTaskInstance.getId());

if (optional.isEmpty()) {
LOGGER.warn("Could not remove userTaskInstance with id {}, task cannot be found", userTaskInstance.getId());
throw new RuntimeException("Could not remove userTaskInstance with id " + userTaskInstance.getId() + ", userTaskInstance cannot be found");
}

this.userTaskInstanceRepository.remove(optional.get());
return this.disconnectUserTaskInstance.apply(userTaskInstance);
}

@Override
public void setReconnectUserTaskInstance(Function<UserTaskInstance, UserTaskInstance> reconnectUserTaskInstance) {
this.reconnectUserTaskInstance = reconnectUserTaskInstance;
}

@Override
public void setDisconnectUserTaskInstance(Function<UserTaskInstance, UserTaskInstance> disconnectUserTaskInstance) {
this.disconnectUserTaskInstance = disconnectUserTaskInstance;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
/*
* 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.net.URI;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

import org.jbpm.usertask.jpa.model.AttachmentEntity;
import org.jbpm.usertask.jpa.model.UserTaskInstanceEntity;
import org.jbpm.usertask.jpa.repository.AttachmentRepository;
import org.kie.kogito.usertask.UserTaskInstance;
import org.kie.kogito.usertask.impl.DefaultUserTaskInstance;
import org.kie.kogito.usertask.model.Attachment;

import static java.util.stream.Collectors.toCollection;

public class AttachmentsEntityMapper {
private final AttachmentRepository repository;

public AttachmentsEntityMapper(AttachmentRepository repository) {
this.repository = repository;
}

public void mapInstanceToEntity(UserTaskInstance userTaskInstance, UserTaskInstanceEntity userTaskInstanceEntity) {
Collection<AttachmentEntity> toRemove = userTaskInstanceEntity.getAttachments()
.stream()
.filter(entity -> userTaskInstance.getAttachments().stream().noneMatch(attachment -> attachment.getId().equals(entity.getId())))
.toList();

toRemove.forEach(attachment -> {
repository.remove(attachment);
userTaskInstanceEntity.removeAttachment(attachment);
});

userTaskInstance.getAttachments().forEach(attachment -> {
AttachmentEntity attachmentEntity = userTaskInstanceEntity.getAttachments().stream().filter(entity -> entity.getId().equals(attachment.getId())).findFirst().orElseGet(() -> {
AttachmentEntity entity = new AttachmentEntity();
userTaskInstanceEntity.addAttachment(entity);
return entity;
});
attachmentEntity.setId(attachment.getId());
attachmentEntity.setUpdatedBy(attachment.getUpdatedBy());
attachmentEntity.setName(attachment.getName());
attachmentEntity.setUrl(attachment.getContent().toString());
attachmentEntity.setUpdatedAt(attachment.getUpdatedAt());
});
}

public void mapEntityToInstance(UserTaskInstanceEntity userTaskInstanceEntity, UserTaskInstance userTaskInstance) {

List<Attachment> attachments = userTaskInstanceEntity.getAttachments().stream().map(attachmentEntity -> {
Attachment attachment = new Attachment(attachmentEntity.getId(), attachmentEntity.getUpdatedBy());
attachment.setId(attachmentEntity.getId());
attachment.setName(attachmentEntity.getName());
attachment.setContent(URI.create(attachmentEntity.getUrl()));
attachment.setUpdatedAt(attachmentEntity.getUpdatedAt());
return attachment;
}).collect(toCollection(ArrayList::new));

((DefaultUserTaskInstance) userTaskInstance).setAttachments(attachments);
}
}
Original file line number Diff line number Diff line change
@@ -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.mapper;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

import org.jbpm.usertask.jpa.model.CommentEntity;
import org.jbpm.usertask.jpa.model.UserTaskInstanceEntity;
import org.jbpm.usertask.jpa.repository.CommentRepository;
import org.kie.kogito.usertask.UserTaskInstance;
import org.kie.kogito.usertask.impl.DefaultUserTaskInstance;
import org.kie.kogito.usertask.model.Comment;

import static java.util.stream.Collectors.toCollection;

public class CommentsEntityMapper {

private final CommentRepository repository;

public CommentsEntityMapper(CommentRepository repository) {
this.repository = repository;
}

public void mapInstanceToEntity(UserTaskInstance userTaskInstance, UserTaskInstanceEntity userTaskInstanceEntity) {
Collection<CommentEntity> toRemove = userTaskInstanceEntity.getComments()
.stream()
.filter(entity -> userTaskInstance.getComments().stream().noneMatch(comment -> comment.getId().equals(entity.getId())))
.toList();

toRemove.forEach(comment -> {
repository.remove(comment);
userTaskInstanceEntity.removeComment(comment);
});

userTaskInstance.getComments().forEach(comment -> {
CommentEntity commentEntity = userTaskInstanceEntity.getComments().stream().filter(entity -> entity.getId().equals(comment.getId())).findFirst().orElseGet(() -> {
CommentEntity entity = new CommentEntity();
userTaskInstanceEntity.addComment(entity);
return entity;
});
commentEntity.setId(comment.getId());
commentEntity.setUpdatedBy(comment.getUpdatedBy());
commentEntity.setComment(comment.getContent());
commentEntity.setUpdatedAt(comment.getUpdatedAt());
});
}

public void mapEntityToInstance(UserTaskInstanceEntity userTaskInstanceEntity, UserTaskInstance userTaskInstance) {
List<Comment> comments = userTaskInstanceEntity.getComments().stream().map(commentEntity -> {
Comment comment = new Comment(commentEntity.getId(), commentEntity.getUpdatedBy());
comment.setId(commentEntity.getId());
comment.setContent(commentEntity.getComment());
comment.setUpdatedAt(commentEntity.getUpdatedAt());
return comment;
}).collect(toCollection(ArrayList::new));

((DefaultUserTaskInstance) userTaskInstance).setComments(comments);
}
}
Loading

0 comments on commit 1679a83

Please sign in to comment.