Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
35b953e
- simplified AbstractActionAPI
renczesstefan Oct 7, 2025
c50012b
Add Action API implementation and related configurations
renczesstefan Oct 9, 2025
78de22f
Refactor ActionApi methods to enhance type safety and clarity
renczesstefan Oct 15, 2025
8cb4abc
Refactor Action API to use AuthPrincipalDto for user context
renczesstefan Oct 15, 2025
111827a
Add searchUsers, findCase, and findTask methods to Action API
renczesstefan Oct 16, 2025
582f418
Refactor Querydsl dependencies and package structure.
renczesstefan Oct 17, 2025
95e084d
Refactor to use Map instead of HashMap and add method resolution logic
renczesstefan Oct 17, 2025
cf80649
Refactor ActionApiImpl and enhance exception class.
renczesstefan Oct 20, 2025
42ec6b4
Refine ConditionalOnMissingBean annotation for ActionApi
renczesstefan Oct 20, 2025
a1f164d
Add annotations to exclude sessionId from toString and equals
renczesstefan Oct 20, 2025
9eacdd0
Fix typo in enum constant name from SEARCH_USER to SEARCH_USERS
renczesstefan Oct 20, 2025
6642234
- removed duplicate dependency
renczesstefan Oct 20, 2025
9e726d1
- removed unused import
renczesstefan Oct 20, 2025
905a142
Remove redundant Serializable implementation in exception class
renczesstefan Oct 20, 2025
c497aba
Remove redundant Serializable implementation in exception class
renczesstefan Oct 20, 2025
f5df0dc
Enhance method handling and enforce non-null constraints
renczesstefan Oct 20, 2025
e1dad6c
Remove @NonNull annotations from AuthPrincipalDto fields
renczesstefan Nov 6, 2025
fffff2d
Merge branch 'release/7.0.0-rev9' into NAE-2229
renczesstefan Dec 2, 2025
50a4fb9
Improve null handling, performance, and serialization
renczesstefan Dec 2, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package com.netgrif.application.engine.actions;

import com.netgrif.application.engine.adapter.spring.actions.ActionApi;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class ActionApiConfiguration {

@Bean
@ConditionalOnMissingBean(ActionApi.class)
public ActionApi actionApi() {
return new ActionApiImpl();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,187 @@
package com.netgrif.application.engine.actions;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.netgrif.application.engine.adapter.spring.actions.ActionApi;
import com.netgrif.application.engine.auth.service.UserService;
import com.netgrif.application.engine.elastic.service.interfaces.IElasticCaseService;
import com.netgrif.application.engine.elastic.service.interfaces.IElasticTaskService;
import com.netgrif.application.engine.elastic.web.requestbodies.CaseSearchRequest;
import com.netgrif.application.engine.elastic.web.requestbodies.ElasticTaskSearchRequest;
import com.netgrif.application.engine.objects.auth.domain.AbstractUser;
import com.netgrif.application.engine.objects.auth.domain.ActorTransformer;
import com.netgrif.application.engine.objects.auth.domain.LoggedUser;
import com.netgrif.application.engine.objects.auth.domain.User;
import com.netgrif.application.engine.objects.auth.dto.AuthPrincipalDto;
import com.netgrif.application.engine.objects.petrinet.domain.throwable.TransitionNotExecutableException;
import com.netgrif.application.engine.objects.workflow.domain.Case;
import com.netgrif.application.engine.objects.workflow.domain.Task;
import com.netgrif.application.engine.objects.workflow.domain.eventoutcomes.caseoutcomes.CreateCaseEventOutcome;
import com.netgrif.application.engine.objects.workflow.domain.eventoutcomes.caseoutcomes.DeleteCaseEventOutcome;
import com.netgrif.application.engine.objects.workflow.domain.eventoutcomes.dataoutcomes.GetDataEventOutcome;
import com.netgrif.application.engine.objects.workflow.domain.eventoutcomes.dataoutcomes.SetDataEventOutcome;
import com.netgrif.application.engine.objects.workflow.domain.eventoutcomes.taskoutcomes.AssignTaskEventOutcome;
import com.netgrif.application.engine.objects.workflow.domain.eventoutcomes.taskoutcomes.CancelTaskEventOutcome;
import com.netgrif.application.engine.objects.workflow.domain.eventoutcomes.taskoutcomes.FinishTaskEventOutcome;
import com.netgrif.application.engine.workflow.service.interfaces.IDataService;
import com.netgrif.application.engine.workflow.service.interfaces.ITaskService;
import com.netgrif.application.engine.workflow.service.interfaces.IWorkflowService;
import com.querydsl.core.types.Predicate;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.i18n.LocaleContextHolder;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;

import java.util.*;

@Slf4j
public class ActionApiImpl implements ActionApi {

private UserService userService;

private IDataService dataService;

private ITaskService taskService;

private IWorkflowService workflowService;

private IElasticCaseService elasticCaseService;

private IElasticTaskService elasticTaskService;

private ObjectMapper objectMapper;

@Autowired
public void setDataService(IDataService dataService) {
this.dataService = dataService;
}

@Autowired
public void setTaskService(ITaskService taskService) {
this.taskService = taskService;
}

@Autowired
public void setWorkflowService(IWorkflowService workflowService) {
this.workflowService = workflowService;
}

@Autowired
public void setElasticCaseService(IElasticCaseService elasticCaseService) {
this.elasticCaseService = elasticCaseService;
}

@Autowired
public void setUserService(UserService userService) {
this.userService = userService;
}

@Autowired
public void setElasticTaskService(IElasticTaskService elasticTaskService) {
this.elasticTaskService = elasticTaskService;
}

@Autowired
public void setObjectMapper(ObjectMapper objectMapper) {
this.objectMapper = objectMapper;
}

@Override
public GetDataEventOutcome getData(String taskId, Map<String, String> params) {
return dataService.getData(taskId, params);
}

@Override
public SetDataEventOutcome setData(String taskId, Map<String, Map<String, String>> dataSet, Map<String, String> params) throws JsonProcessingException {
ObjectMapper mapper = new ObjectMapper();
String json = mapper.writeValueAsString(dataSet);
ObjectNode values = (ObjectNode) mapper.readTree(json);
return dataService.setData(taskId, values, params);
}

@Override
public Page<Case> searchCases(String processIdentifier, Predicate predicate, Pageable pageable) {
return workflowService.search(predicate, pageable);
}

@Override
public Page<Case> searchCases(List<String> elasticStringQueries, AuthPrincipalDto authPrincipalDto, Pageable pageable, Boolean isIntersection) {
boolean intersect = Boolean.TRUE.equals(isIntersection);
List<CaseSearchRequest> caseSearchRequests = elasticStringQueries.stream().map(query -> CaseSearchRequest.builder().query(query).build()).toList();
LoggedUser loggedUser = ActorTransformer.toLoggedUser(resolveAbstractUser(authPrincipalDto));
Locale locale = LocaleContextHolder.getLocale();
return elasticCaseService.search(caseSearchRequests, loggedUser, pageable, locale, intersect);
}

@Override
public CreateCaseEventOutcome createCaseByIdentifier(String identifier, String title, String color, AuthPrincipalDto authPrincipalDto, Map<String, String> params) {
LoggedUser loggedUser = ActorTransformer.toLoggedUser(resolveAbstractUser(authPrincipalDto));
Locale locale = LocaleContextHolder.getLocale();
return workflowService.createCaseByIdentifier(identifier, title, color, loggedUser, locale, params);
}

@Override
public DeleteCaseEventOutcome deleteCase(String caseId, Map<String, String> params) {
return workflowService.deleteCase(caseId, params);
}

@Override
public Page<Task> searchTasks(String processIdentifier, Predicate predicate, Pageable pageable) {
return taskService.search(predicate, pageable);
}

@Override
public Page<Task> searchTasks(List<String> elasticStringQueries, AuthPrincipalDto authPrincipalDto, Pageable pageable, Boolean isIntersection) {
boolean intersect = Boolean.TRUE.equals(isIntersection);
List<ElasticTaskSearchRequest> taskSearchRequests = elasticStringQueries.stream().map(query -> ElasticTaskSearchRequest.builder().query(query).build()).toList();
LoggedUser loggedUser = ActorTransformer.toLoggedUser(resolveAbstractUser(authPrincipalDto));
Locale locale = LocaleContextHolder.getLocale();
return elasticTaskService.search(taskSearchRequests, loggedUser, pageable, locale, intersect);
}

@Override
public AssignTaskEventOutcome assignTask(String taskId, AuthPrincipalDto authPrincipalDto, Map<String, String> params) throws TransitionNotExecutableException {
Task task = taskService.findOne(taskId);
AbstractUser user = resolveAbstractUser(authPrincipalDto);
return taskService.assignTask(task, user, params);
}

@Override
public CancelTaskEventOutcome cancelTask(String taskId, AuthPrincipalDto authPrincipalDto, Map<String, String> params) {
Task task = taskService.findOne(taskId);
AbstractUser user = resolveAbstractUser(authPrincipalDto);
return taskService.cancelTask(task, user, params);
}

@Override
public FinishTaskEventOutcome finishTask(String taskId, AuthPrincipalDto authPrincipalDto, Map<String, String> params) throws TransitionNotExecutableException {
Task task = taskService.findOne(taskId);
AbstractUser user = resolveAbstractUser(authPrincipalDto);
return taskService.finishTask(task, user, params);
}

@Override
public Case findCase(String caseId) {
return workflowService.findOne(caseId);
}

@Override
public Task findTask(String taskId) {
return taskService.findOne(taskId);
}

@Override
public Page<User> searchUsers(Predicate predicate, Pageable pageable, String realmId) {
return userService.search(predicate, pageable, realmId);
}

private AbstractUser resolveAbstractUser(AuthPrincipalDto authPrincipalDto) {
if (authPrincipalDto == null) {
throw new IllegalArgumentException("AuthPrincipalDto cannot be null.");
}
Optional<AbstractUser> userOptional = userService.findUserByUsername(authPrincipalDto.getUsername(), authPrincipalDto.getRealmId());
return userOptional.orElseThrow(() -> new IllegalArgumentException("User with username [%s] and realm ID [%s] not found".formatted(authPrincipalDto.getUsername(), authPrincipalDto.getRealmId())));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,14 @@
import com.netgrif.application.engine.workflow.web.requestbodies.taskSearch.PetriNet;
import com.netgrif.application.engine.workflow.web.requestbodies.taskSearch.TaskSearchCaseRequest;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.NoArgsConstructor;

import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Builder
@NoArgsConstructor
@AllArgsConstructor
public class ElasticTaskSearchRequest extends TaskSearchRequest {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,6 @@
import com.netgrif.application.engine.objects.importer.model.EventPhaseType;
import com.netgrif.application.engine.objects.petrinet.domain.PetriNet;
import com.netgrif.application.engine.objects.petrinet.domain.dataset.logic.action.Action;
import com.netgrif.application.engine.objects.workflow.domain.Case;
import com.netgrif.application.engine.objects.workflow.domain.QCase;
import com.netgrif.application.engine.petrinet.domain.dataset.logic.action.context.RoleContext;
import com.netgrif.application.engine.petrinet.domain.dataset.logic.action.runner.RoleActionsRunner;
import com.netgrif.application.engine.objects.petrinet.domain.events.Event;
Expand Down Expand Up @@ -102,8 +100,8 @@ public Optional<ProcessRole> get(ProcessResourceId processResourceId) {
}

@Override
public void delete(String s) {
Optional<ProcessRole> processRole = processRoleRepository.findByCompositeId(s);
public void delete(String roleId) {
Optional<ProcessRole> processRole = processRoleRepository.findByCompositeId(roleId);
processRole.ifPresent(processRoleRepository::delete);
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package com.netgrif.application.engine.objects.auth.dto;

import com.fasterxml.jackson.annotation.JsonIgnore;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.ToString;

import java.io.Serial;
import java.io.Serializable;

@Data
public class AuthPrincipalDto implements Serializable {

@Serial
private static final long serialVersionUID = 6725518942728316525L;

private String username;

private String realmId;

@ToString.Exclude
@EqualsAndHashCode.Exclude
@JsonIgnore
private String sessionId;
}
33 changes: 31 additions & 2 deletions nae-spring-core-adapter/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -98,14 +98,19 @@
<artifactId>jackson-module-jsonSchema</artifactId>
<version>${jackson.version}</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
</dependency>
<dependency>
<groupId>com.querydsl</groupId>
<artifactId>querydsl-core</artifactId>
<version>${querydsl.version}</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<groupId>com.querydsl</groupId>
<artifactId>querydsl-apt</artifactId>
<version>${querydsl.version}</version>
</dependency>
</dependencies>

Expand All @@ -131,6 +136,30 @@
</execution>
</executions>
</plugin>
<plugin>
<groupId>com.mysema.maven</groupId>
<artifactId>apt-maven-plugin</artifactId>
<version>1.1.3</version>
<executions>
<execution>
<goals>
<goal>process</goal>
</goals>
<configuration>
<outputDirectory>target/generated-sources/java</outputDirectory>
<processors>
<processor>
com.querydsl.apt.QuerydslAnnotationProcessor
</processor>
</processors>
<options>
<querydsl.excludedClasses>groovy.lang.MetaClass</querydsl.excludedClasses>
<querydsl.unknownAsEmbeddable>true</querydsl.unknownAsEmbeddable>
</options>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>

Expand Down
Loading
Loading