From ade2f550e5eec881673bd2055538e6c56a158dd8 Mon Sep 17 00:00:00 2001 From: chvostek Date: Thu, 16 Oct 2025 08:36:27 +0200 Subject: [PATCH 01/55] [NAE-2235] Improve Efficiency of Database Reads and Saves - update loggers in elastic package --- .../service/ElasticCaseMappingService.java | 19 ++++++------------- .../elastic/service/ElasticCaseService.java | 10 +++++----- .../elastic/service/ElasticIndexService.java | 4 ++-- .../service/ElasticPetriNetService.java | 8 ++++---- .../service/ElasticTaskQueueManager.java | 2 +- .../elastic/service/ReindexingTask.java | 4 ++-- .../elastic/service/executors/Executor.java | 8 ++++---- 7 files changed, 24 insertions(+), 31 deletions(-) diff --git a/application-engine/src/main/java/com/netgrif/application/engine/elastic/service/ElasticCaseMappingService.java b/application-engine/src/main/java/com/netgrif/application/engine/elastic/service/ElasticCaseMappingService.java index 6e836b94ce..a06a9375d5 100644 --- a/application-engine/src/main/java/com/netgrif/application/engine/elastic/service/ElasticCaseMappingService.java +++ b/application-engine/src/main/java/com/netgrif/application/engine/elastic/service/ElasticCaseMappingService.java @@ -1,13 +1,6 @@ package com.netgrif.application.engine.elastic.service; -import com.netgrif.application.engine.objects.elastic.domain.BooleanField; -import com.netgrif.application.engine.objects.elastic.domain.ButtonField; -import com.netgrif.application.engine.objects.elastic.domain.DateField; -import com.netgrif.application.engine.objects.elastic.domain.FileField; -import com.netgrif.application.engine.objects.elastic.domain.I18nField; -import com.netgrif.application.engine.objects.elastic.domain.NumberField; -import com.netgrif.application.engine.objects.elastic.domain.TextField; import com.netgrif.application.engine.objects.elastic.domain.UserField; import com.netgrif.application.engine.objects.elastic.domain.UserListField; import com.netgrif.application.engine.objects.elastic.domain.*; @@ -168,7 +161,7 @@ protected Optional transformStringCollectionField(com.netgrif.applica translations.add((String) value); } else { // TODO vyhodit exception? - log.error("MultichoiceField has element value of illegal type! Expected: I18nString, Found: " + value.getClass().getCanonicalName()); + log.error("MultichoiceField has element value of illegal type! Expected: I18nString, Found: {}", value.getClass().getCanonicalName()); } }); return Optional.of(new com.netgrif.application.engine.adapter.spring.elastic.domain.TextField(translations.toArray(new String[0]))); @@ -185,7 +178,7 @@ private Optional getMultichoiceValue(com.netgrif.application.engine.objects return Optional.of(values); } else { // TODO error? - log.error("Multichoice field has value of illegal type! Expected: Set, Found: " + multichoice.getValue().getClass().getCanonicalName()); + log.error("Multichoice field has value of illegal type! Expected: Set, Found: {}", multichoice.getValue().getClass().getCanonicalName()); return Optional.empty(); } } @@ -199,7 +192,7 @@ private Optional getMultichoiceValue(com.netgrif.application.engine.objects return Optional.of(new com.netgrif.application.engine.adapter.spring.elastic.domain.TextField((String) value)); } else { // TODO vyhodit exception? - log.error("Enumeration field has value of illegal type! Expected: I18nString, Found: " + value.getClass().getCanonicalName()); + log.error("Enumeration field has value of illegal type! Expected: I18nString, Found: {}", value.getClass().getCanonicalName()); return Optional.empty(); } } @@ -274,7 +267,7 @@ private StringBuilder buildFullName(String name, String surname) { return formatDateField(LocalDateTime.of(transformed.toLocalDate(), LocalTime.MIDNIGHT)); } else { // TODO throw error? - log.error(String.format("Unsupported DateField value type (%s)! Skipping indexation...", dateField.getValue().getClass().getCanonicalName())); + log.error("Unsupported DateField value type ({})! Skipping indexation...", dateField.getValue().getClass().getCanonicalName()); return Optional.empty(); } } @@ -288,7 +281,7 @@ private StringBuilder buildFullName(String name, String surname) { return formatDateField(this.transformDateValueField(dateTimeField)); } else { // TODO throw error? - log.error(String.format("Unsupported DateTimeField value type (%s)! Skipping indexation...", dateTimeField.getValue().getClass().getCanonicalName())); + log.error("Unsupported DateTimeField value type ({})! Skipping indexation...", dateTimeField.getValue().getClass().getCanonicalName()); return Optional.empty(); } } @@ -331,7 +324,7 @@ private Optional formatDateField(LocalDateTime date) { protected Optional transformOtherFields (com.netgrif.application.engine.objects.workflow.domain.DataField otherField, Field netField) { - log.warn("Field of type " + netField.getClass().getCanonicalName() + " is not supported for indexation by default. Indexing the toString() representation of its value..."); + log.warn("Field of type {} is not supported for indexation by default. Indexing the toString() representation of its value...", netField.getClass().getCanonicalName()); return Optional.of(new com.netgrif.application.engine.adapter.spring.elastic.domain.TextField(otherField.getValue().toString())); } } diff --git a/application-engine/src/main/java/com/netgrif/application/engine/elastic/service/ElasticCaseService.java b/application-engine/src/main/java/com/netgrif/application/engine/elastic/service/ElasticCaseService.java index 07d6901189..26f0151c9a 100644 --- a/application-engine/src/main/java/com/netgrif/application/engine/elastic/service/ElasticCaseService.java +++ b/application-engine/src/main/java/com/netgrif/application/engine/elastic/service/ElasticCaseService.java @@ -90,7 +90,7 @@ public void setElasticProperties(DataConfigurationProperties.ElasticsearchProper public void remove(String caseId) { executors.execute(caseId, () -> { repository.deleteAllById(caseId); - log.info("[" + caseId + "]: Case \"" + caseId + "\" deleted"); + log.info("[{}]: Case \"{}\" deleted", caseId, caseId); }); } @@ -98,7 +98,7 @@ public void remove(String caseId) { public void removeByPetriNetId(String processId) { executors.execute(processId, () -> { repository.deleteAllByProcessId(processId); - log.info("[" + processId + "]: All cases of Petri Net with id \"" + processId + "\" deleted"); + log.info("[{}]: All cases of Petri Net with id \"{}\" deleted", processId, processId); }); } @@ -114,13 +114,13 @@ public void index(ElasticCase useCase) { elasticCase.update(useCase); repository.save(elasticCase); } - log.debug("[" + useCase.getId() + "]: Case \"" + useCase.getTitle() + "\" indexed"); + log.debug("[{}]: Case \"{}\" indexed", useCase.getId(), useCase.getTitle()); publisher.publishEvent(new IndexCaseEvent(useCase)); } catch (InvalidDataAccessApiUsageException ignored) { - log.debug("[" + useCase.getId() + "]: Case \"" + useCase.getTitle() + "\" has duplicates, will be reindexed"); + log.debug("[{}]: Case \"{}\" has duplicates, will be reindexed", useCase.getId(), useCase.getTitle()); repository.deleteAllById(useCase.getId()); repository.save((com.netgrif.application.engine.adapter.spring.elastic.domain.ElasticCase) useCase); - log.debug("[" + useCase.getId() + "]: Case \"" + useCase.getTitle() + "\" indexed"); + log.debug("[{}]: Case \"{}\" indexed", useCase.getId(), useCase.getTitle()); } }); } diff --git a/application-engine/src/main/java/com/netgrif/application/engine/elastic/service/ElasticIndexService.java b/application-engine/src/main/java/com/netgrif/application/engine/elastic/service/ElasticIndexService.java index 05c4fbc53e..7866a2642b 100644 --- a/application-engine/src/main/java/com/netgrif/application/engine/elastic/service/ElasticIndexService.java +++ b/application-engine/src/main/java/com/netgrif/application/engine/elastic/service/ElasticIndexService.java @@ -190,10 +190,10 @@ public boolean deleteIndex(Class clazz, String... placeholders) { try { String indexName = getIndexName(clazz, placeholders); if (this.indexExists(indexName)) { - log.warn("Index: " + indexName + " has been deleted!"); + log.warn("Index: {} has been deleted!", indexName); return elasticsearchTemplate.indexOps(IndexCoordinates.of(indexName)).delete(); } else { - log.warn("Index: " + indexName + " not found!"); + log.warn("Index: {} not found!", indexName); } } catch (Exception e) { log.error("deleteIndex: ", e); diff --git a/application-engine/src/main/java/com/netgrif/application/engine/elastic/service/ElasticPetriNetService.java b/application-engine/src/main/java/com/netgrif/application/engine/elastic/service/ElasticPetriNetService.java index c64d947fe6..d678c86eea 100644 --- a/application-engine/src/main/java/com/netgrif/application/engine/elastic/service/ElasticPetriNetService.java +++ b/application-engine/src/main/java/com/netgrif/application/engine/elastic/service/ElasticPetriNetService.java @@ -73,12 +73,12 @@ public void index(ElasticPetriNet net) { elasticNet.update(net); repository.save(elasticNet); } - log.debug("[" + net.getId() + "]: PetriNet \"" + net.getTitle() + "\" indexed"); + log.debug("[{}]: PetriNet \"{}\" indexed", net.getId(), net.getTitle()); } catch (InvalidDataAccessApiUsageException ignored) { - log.debug("[" + net.getId() + "]: PetriNet \"" + net.getTitle() + "\" has duplicates, will be reindexed"); + log.debug("[{}]: PetriNet \"{}\" has duplicates, will be reindexed", net.getId(), net.getTitle()); repository.deleteAllById(net.getId()); repository.save((com.netgrif.application.engine.adapter.spring.elastic.domain.ElasticPetriNet) net); - log.debug("[" + net.getId() + "]: PetriNet \"" + net.getTitle() + "\" indexed"); + log.debug("[{}]: PetriNet \"{}\" indexed", net.getId(), net.getTitle()); } }); } @@ -92,7 +92,7 @@ public void indexNow(ElasticPetriNet net) { public void remove(String id) { executors.execute(id, () -> { repository.deleteAllById(id); - log.info("[" + id + "]: PetriNet \"" + id + "\" deleted"); + log.info("[{}]: PetriNet \"{}\" deleted", id, id); }); } diff --git a/application-engine/src/main/java/com/netgrif/application/engine/elastic/service/ElasticTaskQueueManager.java b/application-engine/src/main/java/com/netgrif/application/engine/elastic/service/ElasticTaskQueueManager.java index e02d87bad1..cc869a3911 100644 --- a/application-engine/src/main/java/com/netgrif/application/engine/elastic/service/ElasticTaskQueueManager.java +++ b/application-engine/src/main/java/com/netgrif/application/engine/elastic/service/ElasticTaskQueueManager.java @@ -56,7 +56,7 @@ public Future scheduleOperation(ElasticTaskJob task) { try { queue.add(taskWrapper); } catch (Exception e) { - log.error("Queue error:" + e.getMessage()); + log.error("Queue error: {}", e.getMessage()); throw e; } diff --git a/application-engine/src/main/java/com/netgrif/application/engine/elastic/service/ReindexingTask.java b/application-engine/src/main/java/com/netgrif/application/engine/elastic/service/ReindexingTask.java index 8c7307ef9e..6a5b81ded7 100644 --- a/application-engine/src/main/java/com/netgrif/application/engine/elastic/service/ReindexingTask.java +++ b/application-engine/src/main/java/com/netgrif/application/engine/elastic/service/ReindexingTask.java @@ -72,7 +72,7 @@ public ReindexingTask( @Scheduled(cron = "#{springElasticsearchReindex}") public void reindex() { - log.info("Reindexing stale cases: started reindexing after " + lastRun); + log.info("Reindexing stale cases: started reindexing after {}", lastRun); elasticIndexService.bulkIndex(false, lastRun, null, null); @@ -84,7 +84,7 @@ public void forceReindexPage(Predicate predicate, int page, long numOfPages) { } private void reindexPage(Predicate predicate, int page, long numOfPages, boolean forced) { - log.info("Reindexing " + (page + 1) + " / " + numOfPages); + log.info("Reindexing {} / {}", page + 1, numOfPages); Page cases = this.workflowService.search(predicate, PageRequest.of(page, pageSize)); for (Case aCase : cases) { diff --git a/application-engine/src/main/java/com/netgrif/application/engine/elastic/service/executors/Executor.java b/application-engine/src/main/java/com/netgrif/application/engine/elastic/service/executors/Executor.java index e61a18ef3a..3598f078f8 100644 --- a/application-engine/src/main/java/com/netgrif/application/engine/elastic/service/executors/Executor.java +++ b/application-engine/src/main/java/com/netgrif/application/engine/elastic/service/executors/Executor.java @@ -23,7 +23,7 @@ public class Executor { public Executor(@Value("${netgrif.engine.data.elasticsearch.executors.size:500}") long maxSize, @Value("${netgrif.engine.data.elasticsearch.executors.timeout:5}") long timeout) { this.executors = Collections.synchronizedMap(new ExecutorMaxSizeHashMap(maxSize, timeout)); - log.info("Executor created, thread capacity: " + maxSize); + log.info("Executor created, thread capacity: {}", maxSize); } @PreDestroy @@ -34,11 +34,11 @@ public void preDestroy() throws InterruptedException { if (!executor.awaitTermination(EXECUTOR_TIMEOUT, TimeUnit.SECONDS)) { executor.shutdownNow(); if (!executor.awaitTermination(EXECUTOR_TIMEOUT, TimeUnit.SECONDS)) { - log.error("Executor " + id + " did not terminate"); + log.error("Executor {} did not terminate", id); } } } catch (InterruptedException e) { - log.error("Thread (executor " + id + ") was interrupted while waiting for termination: ", e); + log.error("Thread (executor {}) was interrupted while waiting for termination: ", id, e); executor.shutdownNow(); } }); @@ -59,7 +59,7 @@ public void execute(String id, Runnable task) { } executorService.execute(task); } catch (RuntimeException e) { - log.error("Elastic executor was killed before finish: " + e.getMessage()); + log.error("Elastic executor was killed before finish: {}", e.getMessage(), e); } } } From dfd9dc18b237d9b1e9ee983b7559caba8f35e0d2 Mon Sep 17 00:00:00 2001 From: chvostek Date: Thu, 16 Oct 2025 08:57:29 +0200 Subject: [PATCH 02/55] [NAE-2235] Improve Efficiency of Database Reads and Saves - update loggers for MinIoStorageService and mail package --- .../application/engine/files/minio/MinIoStorageService.java | 2 +- .../netgrif/application/engine/mail/MailAttemptService.java | 4 ++-- .../com/netgrif/application/engine/mail/MailService.java | 6 +++--- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/application-engine/src/main/java/com/netgrif/application/engine/files/minio/MinIoStorageService.java b/application-engine/src/main/java/com/netgrif/application/engine/files/minio/MinIoStorageService.java index ac046d3e20..d1b691b88d 100644 --- a/application-engine/src/main/java/com/netgrif/application/engine/files/minio/MinIoStorageService.java +++ b/application-engine/src/main/java/com/netgrif/application/engine/files/minio/MinIoStorageService.java @@ -83,7 +83,7 @@ public InputStream get(StorageField field, String path) throws BadRequestExce throw new ServiceErrorException("Some http error from minio", e); } } catch (InvalidKeyException e) { - log.error("Key " + path + " is corrupted.", e); + log.error("Key {} is corrupted.", path, e); throw new BadRequestException("Key " + path + " is corrupted.", e); } catch (Exception e) { log.error("Some internal error from minio", e); diff --git a/application-engine/src/main/java/com/netgrif/application/engine/mail/MailAttemptService.java b/application-engine/src/main/java/com/netgrif/application/engine/mail/MailAttemptService.java index 2160c21104..c09d3ac8e0 100644 --- a/application-engine/src/main/java/com/netgrif/application/engine/mail/MailAttemptService.java +++ b/application-engine/src/main/java/com/netgrif/application/engine/mail/MailAttemptService.java @@ -36,7 +36,7 @@ public void mailAttempt(String key) { try { attempts = attemptsCache.get(key); } catch (ExecutionException e) { - log.error("Error reading mail attempts cache for key " + key, e); + log.error("Error reading mail attempts cache for key {}", key, e); attempts = 0; } attempts++; @@ -47,7 +47,7 @@ public boolean isBlocked(String key) { try { return attemptsCache.get(key) >= securityLimitsProperties.getEmailSendsAttempts(); } catch (ExecutionException e) { - log.error("Error reading mail attempts cache for key " + key, e); + log.error("Error reading mail attempts cache for key {}", key, e); return false; } } diff --git a/application-engine/src/main/java/com/netgrif/application/engine/mail/MailService.java b/application-engine/src/main/java/com/netgrif/application/engine/mail/MailService.java index 6260a1ec95..e43b98d9ab 100644 --- a/application-engine/src/main/java/com/netgrif/application/engine/mail/MailService.java +++ b/application-engine/src/main/java/com/netgrif/application/engine/mail/MailService.java @@ -74,7 +74,7 @@ public void sendRegistrationEmail(AbstractUser user) throws IOException, Templat MimeMessage email = buildEmail(mailDraft); mailSender.send(email); - log.info("Registration email sent to [" + user.getEmail() + "] with token [" + model.get(TOKEN) + "], expiring on [" + model.get(EXPIRATION) + "]"); + log.info("Registration email sent to [{}] with token [{}], expiring on [{}]", user.getEmail(), model.get(TOKEN), model.get(EXPIRATION)); } @Override @@ -94,7 +94,7 @@ public void sendPasswordResetEmail(AbstractUser user) throws IOException, Templa MimeMessage email = buildEmail(mailDraft); mailSender.send(email); - log.info("Reset email sent to [" + user.getEmail() + "] with token [" + model.get(TOKEN) + "], expiring on [" + model.get(EXPIRATION) + "]"); + log.info("Reset email sent to [{}] with token [{}], expiring on [{}]", user.getEmail(), model.get(TOKEN), model.get(EXPIRATION)); } @Override @@ -115,7 +115,7 @@ public void sendMail(MailDraft mailDraft) throws IOException, TemplateException, mailSender.send(email); String formattedRecipients = StringUtils.join(mailDraft.getTo(), ", "); - log.info("Email sent to [" + formattedRecipients + "]"); + log.info("Email sent to [{}]", formattedRecipients); } protected MimeMessage buildEmail(MailDraft draft) throws MessagingException, IOException, TemplateException { From acdf0c1ebcb855a299ffb4f4a072b223d456d83b Mon Sep 17 00:00:00 2001 From: chvostek Date: Thu, 16 Oct 2025 12:05:07 +0200 Subject: [PATCH 03/55] [NAE-2235] Improve Efficiency of Database Reads and Saves - update loggers in PetriNetService - fix cacheable self-invocation in PetriNetService - remove code that is commented out in PetriNetService - fix nullptr exception in PetriNetService.findByImportId - resolve some warnings in PetriNetService --- .../petrinet/params/DeletePetriNetParams.java | 17 +++ .../petrinet/params/ImportPetriNetParams.java | 37 +++++ .../petrinet/service/PetriNetService.java | 136 +++++++++--------- .../service/interfaces/IPetriNetService.java | 55 ++----- .../petrinet/web/PetriNetController.java | 14 +- 5 files changed, 138 insertions(+), 121 deletions(-) create mode 100644 application-engine/src/main/java/com/netgrif/application/engine/petrinet/params/DeletePetriNetParams.java create mode 100644 application-engine/src/main/java/com/netgrif/application/engine/petrinet/params/ImportPetriNetParams.java diff --git a/application-engine/src/main/java/com/netgrif/application/engine/petrinet/params/DeletePetriNetParams.java b/application-engine/src/main/java/com/netgrif/application/engine/petrinet/params/DeletePetriNetParams.java new file mode 100644 index 0000000000..4183661804 --- /dev/null +++ b/application-engine/src/main/java/com/netgrif/application/engine/petrinet/params/DeletePetriNetParams.java @@ -0,0 +1,17 @@ +package com.netgrif.application.engine.petrinet.params; + +import com.netgrif.application.engine.objects.auth.domain.LoggedUser; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; + +@Data +@AllArgsConstructor +@Builder(builderMethodName = "with") +public class DeletePetriNetParams { + // todo javadoc + private String petriNetId; + private LoggedUser loggedUser; +// * @param force whether to force the deletion without running events + private boolean force; +} diff --git a/application-engine/src/main/java/com/netgrif/application/engine/petrinet/params/ImportPetriNetParams.java b/application-engine/src/main/java/com/netgrif/application/engine/petrinet/params/ImportPetriNetParams.java new file mode 100644 index 0000000000..11bc1996ee --- /dev/null +++ b/application-engine/src/main/java/com/netgrif/application/engine/petrinet/params/ImportPetriNetParams.java @@ -0,0 +1,37 @@ +package com.netgrif.application.engine.petrinet.params; + +import com.netgrif.application.engine.objects.auth.domain.LoggedUser; +import com.netgrif.application.engine.objects.petrinet.domain.VersionType; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; + +import java.io.InputStream; +import java.util.HashMap; +import java.util.Map; + +@Data +@AllArgsConstructor +@Builder(builderMethodName = "with") +public class ImportPetriNetParams { + + // todo javadoc + + private InputStream xmlFile; + private String uriNodeId; + private VersionType releaseType; + private LoggedUser author; + @Builder.Default + private Map params = new HashMap<>(); + + public ImportPetriNetParams(InputStream xmlFile, VersionType releaseType, LoggedUser author, String uriNodeId) { + this.xmlFile = xmlFile; + this.releaseType = releaseType; + this.author = author; + this.uriNodeId = uriNodeId; + } + + public ImportPetriNetParams(InputStream xmlFile, VersionType releaseType, LoggedUser author) { + this(xmlFile, releaseType, author, null); + } +} diff --git a/application-engine/src/main/java/com/netgrif/application/engine/petrinet/service/PetriNetService.java b/application-engine/src/main/java/com/netgrif/application/engine/petrinet/service/PetriNetService.java index a468461636..a74ec8d140 100644 --- a/application-engine/src/main/java/com/netgrif/application/engine/petrinet/service/PetriNetService.java +++ b/application-engine/src/main/java/com/netgrif/application/engine/petrinet/service/PetriNetService.java @@ -5,14 +5,14 @@ import com.netgrif.application.engine.objects.auth.domain.ActorTransformer; import com.netgrif.application.engine.configuration.properties.CacheConfigurationProperties; import com.netgrif.application.engine.files.minio.StorageConfigurationProperties; +import com.netgrif.application.engine.petrinet.params.DeletePetriNetParams; +import com.netgrif.application.engine.petrinet.params.ImportPetriNetParams; import com.netgrif.application.engine.petrinet.service.interfaces.IPetriNetService; import com.netgrif.application.engine.petrinet.web.responsebodies.ArcImportReference; -import com.netgrif.application.engine.objects.auth.domain.Group; import com.netgrif.application.engine.objects.auth.domain.LoggedUser; import com.netgrif.application.engine.auth.service.UserService; import com.netgrif.application.engine.elastic.service.interfaces.IElasticPetriNetMappingService; import com.netgrif.application.engine.elastic.service.interfaces.IElasticPetriNetService; -import com.netgrif.application.engine.objects.event.events.Event; import com.netgrif.application.engine.objects.event.events.petrinet.ProcessDeleteEvent; import com.netgrif.application.engine.objects.event.events.petrinet.ProcessDeployEvent; import com.netgrif.application.engine.importer.service.Importer; @@ -20,7 +20,6 @@ import com.netgrif.application.engine.objects.petrinet.domain.PetriNet; import com.netgrif.application.engine.objects.petrinet.domain.PetriNetSearch; import com.netgrif.application.engine.objects.petrinet.domain.Transition; -import com.netgrif.application.engine.objects.petrinet.domain.VersionType; import com.netgrif.application.engine.objects.petrinet.domain.dataset.logic.action.Action; import com.netgrif.application.engine.petrinet.domain.dataset.logic.action.FieldActionsRunner; import com.netgrif.application.engine.objects.petrinet.domain.events.EventPhase; @@ -59,7 +58,6 @@ import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; -import java.io.InputStream; import java.nio.file.Path; import java.util.*; import java.util.stream.Collectors; @@ -82,9 +80,6 @@ public class PetriNetService implements IPetriNetService { @Autowired protected StorageConfigurationProperties fileStorageConfiguration; -// @Autowired -// protected IRuleEngine ruleEngine; - @Autowired protected IWorkflowService workflowService; @@ -97,9 +92,6 @@ public class PetriNetService implements IPetriNetService { @Autowired protected FieldActionsRunner actionsRunner; -// @Autowired(required = false) -// protected ILdapGroupRefService ldapGroupService; - @Autowired protected IFieldActionsCacheService functionCacheService; @@ -109,9 +101,6 @@ public class PetriNetService implements IPetriNetService { @Autowired protected IEventService eventService; -// @Autowired -// protected IHistoryService historyService; - @Autowired protected CacheManager cacheManager; @@ -177,29 +166,20 @@ public List get(List petriNetIds) { return self.get(petriNetIds.stream().map(ObjectId::new).collect(Collectors.toList())); } - @Override - @Deprecated - public ImportPetriNetEventOutcome importPetriNet(InputStream xmlFile, String releaseType, LoggedUser author) throws IOException, MissingPetriNetMetaDataException, MissingIconKeyException { - return importPetriNet(xmlFile, VersionType.valueOf(releaseType.trim().toUpperCase()), author); - } - - @Override - public ImportPetriNetEventOutcome importPetriNet(InputStream xmlFile, VersionType releaseType, LoggedUser author) throws IOException, MissingPetriNetMetaDataException, MissingIconKeyException { - return importPetriNet(xmlFile, releaseType, author, new HashMap<>()); - } + public ImportPetriNetEventOutcome importPetriNet(ImportPetriNetParams importPetriNetParams) throws IOException, + MissingPetriNetMetaDataException, MissingIconKeyException { + fillAndValidateAttributes(importPetriNetParams); - @Override - public ImportPetriNetEventOutcome importPetriNet(InputStream xmlFile, VersionType releaseType, LoggedUser author, Map params) throws IOException, MissingPetriNetMetaDataException, MissingIconKeyException { ImportPetriNetEventOutcome outcome = new ImportPetriNetEventOutcome(); ByteArrayOutputStream xmlCopy = new ByteArrayOutputStream(); - IOUtils.copy(xmlFile, xmlCopy); + IOUtils.copy(importPetriNetParams.getXmlFile(), xmlCopy); Optional imported = getImporter().importPetriNet(new ByteArrayInputStream(xmlCopy.toByteArray())); if (imported.isEmpty()) { return outcome; } PetriNet net = imported.get(); - PetriNet existingNet = getNewestVersionByIdentifier(net.getIdentifier()); + PetriNet existingNet = self.getNewestVersionByIdentifier(net.getIdentifier()); if (existingNet != null) { if (existingNet.getVersion().equals(net.getVersion())) { @@ -207,33 +187,31 @@ public ImportPetriNetEventOutcome importPetriNet(InputStream xmlFile, VersionTyp } if (net.getVersion() == null) { net.setVersion(existingNet.getVersion()); - net.incrementVersion(releaseType); + net.incrementVersion(importPetriNetParams.getReleaseType()); } } else if (net.getVersion() == null) { net.setVersion(new Version()); } processRoleService.saveAll(net.getRoles().values()); - net.setAuthor(ActorTransformer.toActorRef(author)); + net.setAuthor(ActorTransformer.toActorRef(importPetriNetParams.getAuthor())); functionCacheService.cachePetriNetFunctions(net); Path savedPath = getImporter().saveNetFile(net, new ByteArrayInputStream(xmlCopy.toByteArray())); xmlCopy.close(); - log.info("Petri net " + net.getTitle() + " (" + net.getInitials() + " v" + net.getVersion() + ") imported successfully and saved in a folder: " + savedPath.toString()); + log.info("Petri net {} ({} v{}) imported successfully and saved in a folder: {}", net.getTitle(), net.getInitials(), + net.getVersion(), savedPath); - outcome.setOutcomes(eventService.runActions(net.getPreUploadActions(), null, Optional.empty(), params)); + outcome.setOutcomes(eventService.runActions(net.getPreUploadActions(), null, Optional.empty(), + importPetriNetParams.getParams())); publisher.publishEvent(new ProcessDeployEvent(outcome, EventPhase.PRE)); save(net); - outcome.setOutcomes(eventService.runActions(net.getPostUploadActions(), null, Optional.empty(), params)); + outcome.setOutcomes(eventService.runActions(net.getPostUploadActions(), null, Optional.empty(), + importPetriNetParams.getParams())); outcome.setNet(imported.get()); publisher.publishEvent(new ProcessDeployEvent(outcome, EventPhase.POST)); return outcome; } - protected void evaluateRules(Event event) { - publisher.publishEvent(event); - - } - @Override public Optional save(PetriNet petriNet) { petriNet.initializeArcs(); @@ -243,7 +221,7 @@ public Optional save(PetriNet petriNet) { try { elasticPetriNetService.indexNow(this.petriNetMappingService.transform(petriNet)); } catch (Exception e) { - log.error("Indexing failed [" + petriNet.getStringId() + "]", e); + log.error("Indexing failed [{}]", petriNet.getStringId(), e); } return Optional.of(petriNet); @@ -286,7 +264,8 @@ public List findAllById(List ids) { @Override @Cacheable(value = "petriNetNewest", unless = "#result == null") public PetriNet getNewestVersionByIdentifier(String identifier) { - List nets = repository.findByIdentifier(identifier, PageRequest.of(0, 1, Sort.Direction.DESC, "version.major", "version.minor", "version.patch")).getContent(); + List nets = repository.findByIdentifier(identifier, PageRequest.of(0, 1, + Sort.Direction.DESC, "version.major", "version.minor", "version.patch")).getContent(); if (nets.isEmpty()) { return null; } @@ -345,10 +324,11 @@ public Page getAll(Pageable pageable) { @Override public FileSystemResource getFile(String netId, String title) { - if (title == null || title.length() == 0) { + if (title == null || title.isEmpty()) { Query query = Query.query(Criteria.where("_id").is(new ObjectId(netId))); query.fields().include("_id").include("title"); - List nets = mongoTemplate.find(query, com.netgrif.application.engine.adapter.spring.petrinet.domain.PetriNet.class); + List nets = mongoTemplate.find(query, + com.netgrif.application.engine.adapter.spring.petrinet.domain.PetriNet.class); if (nets.isEmpty()) return null; title = nets.getFirst().getTitle().getDefaultValue(); @@ -373,9 +353,7 @@ public Page getReferencesByVersion(Version version, LoggedUse GroupOperation groupByIdentifier = Aggregation.group("identifier").max("version").as("version"); Aggregation aggregation; if (pageable == null || pageable.isUnpaged()) { - aggregation = Aggregation.newAggregation( - groupByIdentifier - ); + aggregation = Aggregation.newAggregation(groupByIdentifier); } else { aggregation = Aggregation.newAggregation( groupByIdentifier, @@ -388,7 +366,8 @@ public Page getReferencesByVersion(Version version, LoggedUse List referenceList = results.stream() .map(doc -> { Document versionDoc = doc.get("version", Document.class); - Version refVersion = new Version(versionDoc.getLong("major"), versionDoc.getLong("minor"), versionDoc.getLong("patch")); + Version refVersion = new Version(versionDoc.getLong("major"), versionDoc.getLong("minor"), + versionDoc.getLong("patch")); return getReference(doc.getString("_id"), refVersion, user, locale); }) .collect(Collectors.toList()); @@ -417,12 +396,14 @@ public Page getReferencesByVersion(Version version, LoggedUse @Override public List getReferencesByUsersProcessRoles(LoggedUser user, Locale locale) { Query query = Query.query(getProcessRolesCriteria(user)); - return mongoTemplate.find(query, com.netgrif.application.engine.adapter.spring.petrinet.domain.PetriNet.class).stream().map(net -> transformToReference(net, locale)).collect(Collectors.toList()); + return mongoTemplate.find(query, com.netgrif.application.engine.adapter.spring.petrinet.domain.PetriNet.class).stream() + .map(net -> transformToReference(net, locale)) + .collect(Collectors.toList()); } @Override public PetriNetReference getReference(String identifier, Version version, LoggedUser user, Locale locale) { - PetriNet net = version == null ? getNewestVersionByIdentifier(identifier) : getPetriNet(identifier, version); + PetriNet net = version == null ? self.getNewestVersionByIdentifier(identifier) : self.getPetriNet(identifier, version); return net != null ? transformToReference(net, locale) : new PetriNetReference(); } @@ -431,8 +412,8 @@ public List getTransitionReferences(List netIds, Lo Iterable nets = get(netIds); List references = new ArrayList<>(); - nets.forEach(net -> references.addAll(net.getTransitions().entrySet().stream() - .map(entry -> transformToReference(net, entry.getValue(), locale)).collect(Collectors.toList()))); + nets.forEach(net -> references.addAll(net.getTransitions().values().stream() + .map(transition -> transformToReference(net, transition, locale)).toList())); return references; } @@ -448,9 +429,9 @@ public List getDataFieldReferences(List .forEach(transition -> { Transition trans; if ((trans = net.getTransition(transition.getStringId())) != null) { - dataRefs.addAll(trans.getDataSet().entrySet().stream() - .map(entry -> transformToReference(net, trans, net.getDataSet().get(entry.getKey()), locale)) - .collect(Collectors.toList())); + dataRefs.addAll(trans.getDataSet().keySet().stream() + .map(fieldId -> transformToReference(net, trans, net.getDataSet().get(fieldId), locale)) + .toList()); } })); @@ -459,7 +440,7 @@ public List getDataFieldReferences(List @Override public Optional findByImportId(String id) { - return Optional.of(repository.findByImportId(id)); + return Optional.ofNullable(repository.findByImportId(id)); } @Override @@ -515,41 +496,40 @@ public Page search(PetriNetSearch criteriaClass, LoggedUser u this.addValueCriteria(query, queryTotal, Criteria.where("negativeViewRoles").in(criteriaClass.getNegativeViewRoles())); } if (criteriaClass.getTags() != null) { - criteriaClass.getTags().entrySet().forEach(stringStringEntry -> this.addValueCriteria(query, queryTotal, Criteria.where("tags." + stringStringEntry.getKey()).is(stringStringEntry.getValue()))); + criteriaClass.getTags().forEach((tagKey, tagValue) -> + this.addValueCriteria(query, queryTotal, Criteria.where("tags." + tagKey).is(tagValue))); } query.with(pageable); - List nets = mongoTemplate.find(query, com.netgrif.application.engine.adapter.spring.petrinet.domain.PetriNet.class); - return new PageImpl<>(nets.stream().map(net -> new PetriNetReference(net, locale)).collect(Collectors.toList()), pageable, mongoTemplate.count(queryTotal, com.netgrif.application.engine.adapter.spring.petrinet.domain.PetriNet.class)); + List nets = mongoTemplate.find(query, + com.netgrif.application.engine.adapter.spring.petrinet.domain.PetriNet.class); + return new PageImpl<>(nets.stream().map(net -> new PetriNetReference(net, locale)).collect(Collectors.toList()), + pageable, mongoTemplate.count(queryTotal, com.netgrif.application.engine.adapter.spring.petrinet.domain.PetriNet.class)); } - private void addValueCriteria(Query query, Query queryTotal, Criteria criteria) { + protected void addValueCriteria(Query query, Query queryTotal, Criteria criteria) { query.addCriteria(criteria); queryTotal.addCriteria(criteria); } @Override @Transactional - public void deletePetriNet(String processId, LoggedUser loggedUser) { - deletePetriNet(processId, loggedUser, false); - } - - @Override - @Transactional - public void deletePetriNet(String processId, LoggedUser loggedUser, boolean force) { - Optional petriNetOptional = repository.findById(processId); + public void deletePetriNet(DeletePetriNetParams deletePetriNetParams) { + Optional petriNetOptional = repository.findById(deletePetriNetParams.getPetriNetId()); if (petriNetOptional.isEmpty()) { - throw new IllegalArgumentException("Could not find process with id [" + processId + "]"); + throw new IllegalArgumentException("Could not find process with id [" + deletePetriNetParams.getPetriNetId() + "]"); } PetriNet petriNet = petriNetOptional.get(); - log.info("[{}]: Initiating deletion of Petri net {} version {}", processId, petriNet.getIdentifier(), petriNet.getVersion().toString()); + log.info("[{}]: Initiating deletion of Petri net {} version {}", deletePetriNetParams.getPetriNetId(), + petriNet.getIdentifier(), petriNet.getVersion().toString()); userService.removeRoleOfDeletedPetriNet(petriNet); - workflowService.deleteInstancesOfPetriNet(petriNet, force); - processRoleService.deleteRolesOfNet(petriNet, loggedUser); + workflowService.deleteInstancesOfPetriNet(petriNet, deletePetriNetParams.isForce()); + processRoleService.deleteRolesOfNet(petriNet, deletePetriNetParams.getLoggedUser()); - log.info("[{}]: User [{}] is deleting Petri net {} version {}", processId, userService.getLoggedOrSystem().getStringId(), petriNet.getIdentifier(), petriNet.getVersion().toString()); + log.info("[{}]: User [{}] is deleting Petri net {} version {}", deletePetriNetParams.getPetriNetId(), + userService.getLoggedOrSystem().getStringId(), petriNet.getIdentifier(), petriNet.getVersion().toString()); publisher.publishEvent(new ProcessDeleteEvent(petriNet, EventPhase.PRE)); repository.deleteBy_id(petriNet.getObjectId()); evictCache(petriNet); @@ -557,14 +537,14 @@ public void deletePetriNet(String processId, LoggedUser loggedUser, boolean forc publisher.publishEvent(new ProcessDeleteEvent(petriNet, EventPhase.POST)); } - private Criteria getProcessRolesCriteria(LoggedUser user) { + protected Criteria getProcessRolesCriteria(LoggedUser user) { return new Criteria().orOperator(user.getProcessRoles().stream() .map(role -> Criteria.where("permissions." + role).exists(true)).toArray(Criteria[]::new)); } @Override public void runActions(List actions, PetriNet petriNet) { - log.info("Running actions of net [" + petriNet.getStringId() + "]"); + log.info("Running actions of net [{}]", petriNet.getStringId()); actions.forEach(action -> { actionsRunner.run(action, null, new HashMap<>(), petriNet.getFunctions()); @@ -580,4 +560,16 @@ protected T requireNonNull(T obj, Object... item) { } return obj; } + + protected void fillAndValidateAttributes(ImportPetriNetParams importPetriNetParams) throws IllegalArgumentException { + if (importPetriNetParams.getXmlFile() == null) { + throw new IllegalArgumentException("No Petriflow source file provided."); + } + if (importPetriNetParams.getAuthor() == null) { + throw new IllegalArgumentException("No author of PetriNet provided."); + } + if (importPetriNetParams.getReleaseType() == null) { + throw new IllegalArgumentException("Version type is null."); + } + } } diff --git a/application-engine/src/main/java/com/netgrif/application/engine/petrinet/service/interfaces/IPetriNetService.java b/application-engine/src/main/java/com/netgrif/application/engine/petrinet/service/interfaces/IPetriNetService.java index c6fd966cb5..56c138ce85 100644 --- a/application-engine/src/main/java/com/netgrif/application/engine/petrinet/service/interfaces/IPetriNetService.java +++ b/application-engine/src/main/java/com/netgrif/application/engine/petrinet/service/interfaces/IPetriNetService.java @@ -10,6 +10,8 @@ import com.netgrif.application.engine.objects.petrinet.domain.throwable.MissingIconKeyException; import com.netgrif.application.engine.objects.petrinet.domain.throwable.MissingPetriNetMetaDataException; import com.netgrif.application.engine.objects.petrinet.domain.version.Version; +import com.netgrif.application.engine.petrinet.params.DeletePetriNetParams; +import com.netgrif.application.engine.petrinet.params.ImportPetriNetParams; import com.netgrif.application.engine.petrinet.web.responsebodies.DataFieldReference; import com.netgrif.application.engine.petrinet.web.responsebodies.PetriNetImportReference; import com.netgrif.application.engine.petrinet.web.responsebodies.PetriNetReference; @@ -67,48 +69,18 @@ static DataFieldReference transformToReference(PetriNet net, Transition transiti return new DataFieldReference(field.getStringId(), field.getName().getTranslation(locale), net.getStringId(), transition.getStringId()); } - /** - * Imports a PetriNet from XML input. - * - * @param xmlFile the input stream of the XML file - * @param releaseType the type of release - * @param user the user performing the import - * @return an {@link ImportPetriNetEventOutcome} representing the result - * @throws IOException if an I/O error occurs - * @throws MissingPetriNetMetaDataException if metadata is incomplete - * @throws MissingIconKeyException if an icon key is missing - * @deprecated Use {@link #importPetriNet(InputStream, VersionType, LoggedUser)} instead. - */ - @Deprecated - ImportPetriNetEventOutcome importPetriNet(InputStream xmlFile, String releaseType, LoggedUser user) throws IOException, MissingPetriNetMetaDataException, MissingIconKeyException; - - /** - * Imports a PetriNet from XML input. - * - * @param xmlFile the input stream of the XML file - * @param releaseType the type of release {@link VersionType} - * @param user the user performing the import - * @return an {@link ImportPetriNetEventOutcome} representing the result - * @throws IOException if an I/O error occurs - * @throws MissingPetriNetMetaDataException if metadata is incomplete - * @throws MissingIconKeyException if an icon key is missing - */ - ImportPetriNetEventOutcome importPetriNet(InputStream xmlFile, VersionType releaseType, LoggedUser user) throws IOException, MissingPetriNetMetaDataException, MissingIconKeyException; - - /** * Imports a PetriNet from XML input. + * todo javadoc * - * @param xmlFile the input stream of the XML file - * @param releaseType the type of release {@link VersionType} - * @param user the user performing the import - * @param params additional parameters + * @param importPetriNetParams additional parameters * @return an {@link ImportPetriNetEventOutcome} representing the result * @throws IOException if an I/O error occurs * @throws MissingPetriNetMetaDataException if metadata is incomplete * @throws MissingIconKeyException if an icon key is missing */ - ImportPetriNetEventOutcome importPetriNet(InputStream xmlFile, VersionType releaseType, LoggedUser user, Map params) throws IOException, MissingPetriNetMetaDataException, MissingIconKeyException; + ImportPetriNetEventOutcome importPetriNet(ImportPetriNetParams importPetriNetParams) throws IOException, + MissingPetriNetMetaDataException, MissingIconKeyException; /** * Saves a PetriNet object. @@ -305,20 +277,9 @@ static DataFieldReference transformToReference(PetriNet net, Transition transiti /** * Deletes a PetriNet by its ID. - * - * @param id the ID of the PetriNet to delete - * @param loggedUser the user requesting the deletion - */ - void deletePetriNet(String id, LoggedUser loggedUser); - - /** - * Deletes a PetriNet by its ID. - * - * @param id the ID of the PetriNet to delete - * @param loggedUser the user requesting the deletion - * @param force whether to force the deletion without running events + * todo javadoc */ - void deletePetriNet(String id, LoggedUser loggedUser, boolean force); + void deletePetriNet(DeletePetriNetParams deletePetriNetParams); /** * Runs the specified set of actions on a PetriNet. diff --git a/application-engine/src/main/java/com/netgrif/application/engine/petrinet/web/PetriNetController.java b/application-engine/src/main/java/com/netgrif/application/engine/petrinet/web/PetriNetController.java index eb9cb4f90f..200b5382f5 100644 --- a/application-engine/src/main/java/com/netgrif/application/engine/petrinet/web/PetriNetController.java +++ b/application-engine/src/main/java/com/netgrif/application/engine/petrinet/web/PetriNetController.java @@ -13,6 +13,8 @@ import com.netgrif.application.engine.objects.petrinet.domain.throwable.MissingPetriNetMetaDataException; import com.netgrif.application.engine.objects.workflow.domain.eventoutcomes.petrinetoutcomes.ImportPetriNetEventOutcome; import com.netgrif.application.engine.petrinet.domain.version.StringToVersionConverter; +import com.netgrif.application.engine.petrinet.params.DeletePetriNetParams; +import com.netgrif.application.engine.petrinet.params.ImportPetriNetParams; import com.netgrif.application.engine.petrinet.service.interfaces.IPetriNetService; import com.netgrif.application.engine.petrinet.web.responsebodies.*; import com.netgrif.application.engine.workflow.domain.eventoutcomes.response.EventOutcomeWithMessage; @@ -109,7 +111,11 @@ public EntityModel importPetriNet( Authentication auth, Locale locale) throws MissingPetriNetMetaDataException, MissingIconKeyException { try { VersionType release = releaseType == null ? VersionType.MAJOR : VersionType.valueOf(releaseType.trim().toUpperCase()); - ImportPetriNetEventOutcome importPetriNetOutcome = service.importPetriNet(multipartFile.getInputStream(), release, (LoggedUser) auth.getPrincipal()); + ImportPetriNetEventOutcome importPetriNetOutcome = service.importPetriNet(ImportPetriNetParams.with() + .xmlFile(multipartFile.getInputStream()) + .releaseType(release) + .author((LoggedUser) auth.getPrincipal()) + .build()); return EventOutcomeWithMessageResource.successMessage("Petri net " + multipartFile.getOriginalFilename() + " imported successfully", LocalisedEventOutcomeFactory.from(importPetriNetOutcome, locale)); } catch (IOException | IllegalArgumentException e) { @@ -230,7 +236,11 @@ public MessageResource deletePetriNet(@PathVariable("id") String processId, @Req return MessageResource.errorMessage("Deleting Petri net " + processId + " failed!"); } LoggedUser user = (LoggedUser) auth.getPrincipal(); - asyncRunner.execute(() -> this.service.deletePetriNet(decodedProcessId, user, force)); + asyncRunner.execute(() -> this.service.deletePetriNet(DeletePetriNetParams.with() + .petriNetId(decodedProcessId) + .loggedUser(user) + .force(force) + .build())); return MessageResource.successMessage("Petri net " + decodedProcessId + " is being deleted"); } From 35907bbd018918842b80bbca60afe181645a8f40 Mon Sep 17 00:00:00 2001 From: chvostek Date: Thu, 16 Oct 2025 15:08:16 +0200 Subject: [PATCH 04/55] [NAE-2235] Improve Efficiency of Database Reads and Saves - optimize ProcessRoleService.delete - add todos - remove redundant method overload in ProcessRoleService --- .../repositories/PetriNetRepository.java | 3 ++ .../domain/roles/ProcessRoleRepository.java | 26 ++++++++++ .../petrinet/service/PetriNetService.java | 9 ++++ .../petrinet/service/ProcessRoleService.java | 47 ++++++++++--------- .../service/interfaces/IPetriNetService.java | 7 ++- .../workflow/domain/ProcessResourceId.java | 3 ++ .../petrinet/service/ProcessRoleService.java | 1 - 7 files changed, 71 insertions(+), 25 deletions(-) diff --git a/application-engine/src/main/java/com/netgrif/application/engine/petrinet/domain/repositories/PetriNetRepository.java b/application-engine/src/main/java/com/netgrif/application/engine/petrinet/domain/repositories/PetriNetRepository.java index a8dd005b20..de3310bc60 100644 --- a/application-engine/src/main/java/com/netgrif/application/engine/petrinet/domain/repositories/PetriNetRepository.java +++ b/application-engine/src/main/java/com/netgrif/application/engine/petrinet/domain/repositories/PetriNetRepository.java @@ -68,4 +68,7 @@ public interface PetriNetRepository extends MongoRepository, Q */ @Query("{ 'roles.?0' : { $exists: true } }") Page findAllByRoleId(String roleId, Pageable pageable); + + @Query("{ 'roles.?0' : { $exists: true } }") + boolean existsByRoleId(String roleId); } \ No newline at end of file diff --git a/application-engine/src/main/java/com/netgrif/application/engine/petrinet/domain/roles/ProcessRoleRepository.java b/application-engine/src/main/java/com/netgrif/application/engine/petrinet/domain/roles/ProcessRoleRepository.java index 87c6d92884..b18654d04c 100755 --- a/application-engine/src/main/java/com/netgrif/application/engine/petrinet/domain/roles/ProcessRoleRepository.java +++ b/application-engine/src/main/java/com/netgrif/application/engine/petrinet/domain/roles/ProcessRoleRepository.java @@ -73,6 +73,12 @@ public interface ProcessRoleRepository extends MongoRepository findByIdObjectId(ObjectId objectId); + /** + * todo javadoc + */ + @Query("{ '_id.objectId': ?0 }") + void deleteByObjectId(ObjectId objectId); + /** * Finds all {@link ProcessRole} entities by their object IDs. * @@ -132,6 +138,20 @@ default Optional findByCompositeId(String compositeId) { } } + /** + * todo javadoc + */ + default void deleteByCompositeId(String compositeId) { + String[] parts = compositeId.split(ProcessResourceId.ID_SEPARATOR); + if (parts.length == 2) { + String networkId = parts[0]; + ObjectId objectId = new ObjectId(parts[1]); + deleteByNetworkIdAndObjectId(networkId, objectId); + } else { + deleteByObjectId(new ObjectId(compositeId)); + } + } + /** * Finds a {@link ProcessRole} by a network ID and object ID. * @@ -142,6 +162,12 @@ default Optional findByCompositeId(String compositeId) { @Query("{ '_id.shortProcessId': ?0, '_id.objectId': ?1 }") Optional findByNetworkIdAndObjectId(String networkId, ObjectId objectId); + /** + * todo javadoc + */ + @Query("{ '_id.shortProcessId': ?0, '_id.objectId': ?1 }") + void deleteByNetworkIdAndObjectId(String networkId, ObjectId objectId); + /** * Finds all {@link ProcessRole} entities by a collection of composite resource IDs. * diff --git a/application-engine/src/main/java/com/netgrif/application/engine/petrinet/service/PetriNetService.java b/application-engine/src/main/java/com/netgrif/application/engine/petrinet/service/PetriNetService.java index a74ec8d140..7b6098a7bd 100644 --- a/application-engine/src/main/java/com/netgrif/application/engine/petrinet/service/PetriNetService.java +++ b/application-engine/src/main/java/com/netgrif/application/engine/petrinet/service/PetriNetService.java @@ -315,6 +315,15 @@ public Page findAllByRoleId(String roleId, Pageable pageable) { return nets; } + @Override + public boolean existsByRoleId(String roleId) { + // todo test + if (roleId == null) { + return false; + } + return repository.existsByRoleId(roleId); + } + @Override public Page getAll(Pageable pageable) { Page nets = repository.findAll(pageable); diff --git a/application-engine/src/main/java/com/netgrif/application/engine/petrinet/service/ProcessRoleService.java b/application-engine/src/main/java/com/netgrif/application/engine/petrinet/service/ProcessRoleService.java index 1c94340d3a..89a887380e 100644 --- a/application-engine/src/main/java/com/netgrif/application/engine/petrinet/service/ProcessRoleService.java +++ b/application-engine/src/main/java/com/netgrif/application/engine/petrinet/service/ProcessRoleService.java @@ -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; @@ -41,7 +39,6 @@ import java.util.*; import java.util.stream.Collectors; -import java.util.stream.StreamSupport; public class ProcessRoleService implements com.netgrif.application.engine.adapter.spring.petrinet.service.ProcessRoleService { @@ -102,9 +99,12 @@ public Optional get(ProcessResourceId processResourceId) { } @Override - public void delete(String s) { - Optional processRole = processRoleRepository.findByCompositeId(s); - processRole.ifPresent(processRoleRepository::delete); + public void delete(String compositeId) { + // todo test + if (compositeId == null) { + return; + } + processRoleRepository.deleteByCompositeId(compositeId); } @Override @@ -121,12 +121,7 @@ public void deleteAll() { @Override public void assignRolesToUser(AbstractUser user, Collection processResourceIds, LoggedUser loggedUser) { - assignRolesToUser(user, processResourceIds, loggedUser, new HashMap<>()); - } - - @Override - public void assignRolesToUser(AbstractUser user, Collection requestedRolesIds, LoggedUser loggedUser, Map map) { - assignRolesToActor(user.getProcessRoles(), requestedRolesIds); + assignRolesToActor(user.getProcessRoles(), processResourceIds); saveUserAndReloadContext(user, loggedUser); } @@ -213,7 +208,7 @@ public List findAllByIds(Collection collection) @Override public List saveAll(Collection entities) { - return StreamSupport.stream(entities.spliterator(), false).map(processRole -> { + return entities.stream().map(processRole -> { if (!processRole.isGlobal() || processRoleRepository.findByImportId(processRole.getImportId()).isEmpty()) { return processRoleRepository.save(processRole); } @@ -284,6 +279,8 @@ private Set mapUserRolesToIds(Collection processRoles) { .collect(Collectors.toSet()); } + // todo remove unused methods + private void runAllPreActions(Set newRoles, Set removedRoles, AbstractUser user, PetriNet petriNet, Map params) { runAllSuitableActionsOnRoles(newRoles, EventType.ASSIGN, EventPhaseType.PRE, user, petriNet, params); runAllSuitableActionsOnRoles(removedRoles, EventType.CANCEL, EventPhaseType.PRE, user, petriNet, params); @@ -415,8 +412,12 @@ public Page findAllByDefaultName(String name, Pageable pageable) { @Override public void deleteRolesOfNet(PetriNet net, LoggedUser loggedUser) { - log.info("[" + net.getStringId() + "]: Initiating deletion of all roles of Petri net " + net.getIdentifier() + " version " + net.getVersion().toString()); - List deletedRoleIds = this.findAllByNetStringId(net.getStringId()).stream().filter(processRole -> processRole.getProcessId() != null).map(ProcessRole::get_id).collect(Collectors.toList()); + log.info("[{}]: Initiating deletion of all roles of Petri net {} version {}", net.getStringId(), net.getIdentifier(), + net.getVersion().toString()); + List deletedRoleIds = this.findAllByNetStringId(net.getStringId()).stream() + .filter(processRole -> processRole.getProcessId() != null) + .map(ProcessRole::get_id) + .collect(Collectors.toList()); Set deletedRoleStringIds = deletedRoleIds.stream().map(ProcessResourceId::toString).collect(Collectors.toSet()); Pageable realmPageable = PageRequest.of(0, paginationProperties.getBackendPageSize()); @@ -431,7 +432,8 @@ public void deleteRolesOfNet(PetriNet net, LoggedUser loggedUser) { users = this.userService.findAllByProcessRoles(new HashSet<>(deletedRoleIds), realm.getName(), usersPageable); for (AbstractUser user : users) { - log.info("[" + net.getStringId() + "]: Removing deleted roles of Petri net " + net.getIdentifier() + " version " + net.getVersion().toString() + " from user " + user.getFullName() + " with id " + user.getStringId()); + log.info("[{}]: Removing deleted roles of Petri net {} version {} from user {} with id {}", + net.getStringId(), net.getIdentifier(), net.getVersion().toString(), user.getFullName(), user.getStringId()); if (user.getProcessRoles().isEmpty()) { continue; @@ -451,7 +453,8 @@ public void deleteRolesOfNet(PetriNet net, LoggedUser loggedUser) { realmPageable = realmPageable.next(); } while (realms.hasNext()); - log.info("[" + net.getStringId() + "]: Deleting all roles of Petri net " + net.getIdentifier() + " version " + net.getVersion().toString()); + log.info("[{}]: Deleting all roles of Petri net {} version {}", net.getStringId(), net.getIdentifier(), + net.getVersion().toString()); this.processRoleRepository.deleteAllBy_idIn(deletedRoleIds); } @@ -476,7 +479,8 @@ public void deleteGlobalRole(String roleId, LoggedUser loggedUser) { if (isRoleReferenced(processRole)) { throw new RoleReferencedException("Role with id [%s] is referenced by other processes. Please delete or update the process before deleting.".formatted(roleId)); } - log.info("Initiating deletion of global role with import ID [{}] and object ID [{}]", processRole.getImportId(), processRole.getStringId()); + log.info("Initiating deletion of global role with import ID [{}] and object ID [{}]", processRole.getImportId(), + processRole.getStringId()); Pageable realmPageable = PageRequest.of(0, paginationProperties.getBackendPageSize()); Page realms; do { @@ -499,13 +503,12 @@ public void deleteGlobalRole(String roleId, LoggedUser loggedUser) { } protected boolean isRoleReferenced(ProcessRole processRole) { - Pageable pageable = PageRequest.of(0, paginationProperties.getBackendPageSize()); - Page petriNetPage = petriNetService.findAllByRoleId(processRole.getStringId(), pageable); - return petriNetPage.getTotalElements() > 0; + return petriNetService.existsByRoleId(processRole.getStringId()); } private void removeRoleFromUser(AbstractUser user, ProcessRole processRole, LoggedUser loggedUser) { - log.info("Removing global role with import ID [{}] and object ID [{}] from user [{}] with id [{}]", processRole.getImportId(), processRole.getStringId(), user.getFullName(), user.getStringId()); + log.info("Removing global role with import ID [{}] and object ID [{}] from user [{}] with id [{}]", + processRole.getImportId(), processRole.getStringId(), user.getFullName(), user.getStringId()); if (user.getProcessRoles().isEmpty()) { return; } diff --git a/application-engine/src/main/java/com/netgrif/application/engine/petrinet/service/interfaces/IPetriNetService.java b/application-engine/src/main/java/com/netgrif/application/engine/petrinet/service/interfaces/IPetriNetService.java index 56c138ce85..3fce2f414b 100644 --- a/application-engine/src/main/java/com/netgrif/application/engine/petrinet/service/interfaces/IPetriNetService.java +++ b/application-engine/src/main/java/com/netgrif/application/engine/petrinet/service/interfaces/IPetriNetService.java @@ -4,7 +4,6 @@ import com.netgrif.application.engine.objects.petrinet.domain.PetriNet; import com.netgrif.application.engine.objects.petrinet.domain.PetriNetSearch; import com.netgrif.application.engine.objects.petrinet.domain.Transition; -import com.netgrif.application.engine.objects.petrinet.domain.VersionType; import com.netgrif.application.engine.objects.petrinet.domain.dataset.Field; import com.netgrif.application.engine.objects.petrinet.domain.dataset.logic.action.Action; import com.netgrif.application.engine.objects.petrinet.domain.throwable.MissingIconKeyException; @@ -23,7 +22,6 @@ import org.springframework.data.domain.Pageable; import java.io.IOException; -import java.io.InputStream; import java.util.*; /** @@ -315,4 +313,9 @@ ImportPetriNetEventOutcome importPetriNet(ImportPetriNetParams importPetriNetPar * @return a {@link Page} of {@link PetriNet} objects matching the role ID */ Page findAllByRoleId(String roleId, Pageable pageable); + + /** + * todo javadoc + */ + boolean existsByRoleId(String roleId); } \ No newline at end of file diff --git a/nae-object-library/src/main/java/com/netgrif/application/engine/objects/workflow/domain/ProcessResourceId.java b/nae-object-library/src/main/java/com/netgrif/application/engine/objects/workflow/domain/ProcessResourceId.java index d11dfd4408..abcbb4b859 100644 --- a/nae-object-library/src/main/java/com/netgrif/application/engine/objects/workflow/domain/ProcessResourceId.java +++ b/nae-object-library/src/main/java/com/netgrif/application/engine/objects/workflow/domain/ProcessResourceId.java @@ -19,6 +19,9 @@ public final class ProcessResourceId implements Comparable, S public static final String ID_SEPARATOR = "-"; public static final String NONE_SHORT_ID_VALUE = "NONE"; + // todo resolve warnings, reuse 1 constructor implementation instead of multiple constructor implementations + // todo add example values to javadoc + private ObjectId objectId; private String shortProcessId; diff --git a/nae-spring-core-adapter/src/main/java/com/netgrif/application/engine/adapter/spring/petrinet/service/ProcessRoleService.java b/nae-spring-core-adapter/src/main/java/com/netgrif/application/engine/adapter/spring/petrinet/service/ProcessRoleService.java index 77869a0093..4b4ee16127 100644 --- a/nae-spring-core-adapter/src/main/java/com/netgrif/application/engine/adapter/spring/petrinet/service/ProcessRoleService.java +++ b/nae-spring-core-adapter/src/main/java/com/netgrif/application/engine/adapter/spring/petrinet/service/ProcessRoleService.java @@ -20,7 +20,6 @@ public interface ProcessRoleService { void deleteAll(Collection ids); void deleteAll(); void assignRolesToUser(AbstractUser user, Collection roleIds, LoggedUser loggedUser); - void assignRolesToUser(AbstractUser user, Collection roleIds, LoggedUser loggedUser, Map params); void assignRolesToGroup(Group group, Collection requestedRolesIds); ProcessRole getDefaultRole(); ProcessRole getAnonymousRole(); From cbf2bc1cdee18584caa61d1baa4ad9c75b5764e9 Mon Sep 17 00:00:00 2001 From: chvostek Date: Mon, 20 Oct 2025 10:58:42 +0200 Subject: [PATCH 05/55] [NAE-2235] Improve Efficiency of Database Reads and Saves - implement create case performance test --- .../workflow/WorkflowPerformanceTest.java | 88 ++++ .../test_create_case_performance.xml | 459 ++++++++++++++++++ 2 files changed, 547 insertions(+) create mode 100644 application-engine/src/test/java/com/netgrif/application/engine/workflow/WorkflowPerformanceTest.java create mode 100644 application-engine/src/test/resources/petriNets/test_create_case_performance.xml diff --git a/application-engine/src/test/java/com/netgrif/application/engine/workflow/WorkflowPerformanceTest.java b/application-engine/src/test/java/com/netgrif/application/engine/workflow/WorkflowPerformanceTest.java new file mode 100644 index 0000000000..2786bee7a9 --- /dev/null +++ b/application-engine/src/test/java/com/netgrif/application/engine/workflow/WorkflowPerformanceTest.java @@ -0,0 +1,88 @@ +package com.netgrif.application.engine.workflow; + +import com.netgrif.application.engine.TestHelper; +import com.netgrif.application.engine.objects.petrinet.domain.PetriNet; +import com.netgrif.application.engine.objects.petrinet.domain.VersionType; +import com.netgrif.application.engine.objects.petrinet.domain.throwable.MissingPetriNetMetaDataException; +import com.netgrif.application.engine.petrinet.params.ImportPetriNetParams; +import com.netgrif.application.engine.petrinet.service.interfaces.IPetriNetService; +import com.netgrif.application.engine.startup.runner.SuperCreatorRunner; +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 lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Disabled; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.ActiveProfiles; +import org.springframework.test.context.junit.jupiter.SpringExtension; + +import java.io.FileInputStream; +import java.io.IOException; +import java.util.Locale; + +@Slf4j +@Disabled +@SpringBootTest +@RequiredArgsConstructor +@ActiveProfiles({"test"}) +@ExtendWith(SpringExtension.class) +public class WorkflowPerformanceTest { + + private final IWorkflowService workflowService; + private final ITaskService taskService; + private final IDataService dataService; + private final IPetriNetService petriNetService; + private final SuperCreatorRunner superCreatorRunner; + private final TestHelper testHelper; + + @BeforeEach + public void beforeEach() { + testHelper.truncateDbs(); + } + + @Test + public void testCreatePerformance() throws IOException, MissingPetriNetMetaDataException { + PetriNet net = petriNetService.importPetriNet(ImportPetriNetParams.with() + .xmlFile(new FileInputStream("src/test/resources/test_create_case_performance.xml")) + .releaseType(VersionType.MAJOR) + .author(superCreatorRunner.getLoggedSuper()) + .build()).getNet(); + iterateAndShowAvgTime("createCase", () -> workflowService.createCase(net.getStringId(), null, null, + superCreatorRunner.getLoggedSuper(), Locale.getDefault()), 100); + } + + @Test + public void testAssignPerformance() { + + } + + @Test + public void testCancelPerformance() { + + } + + @Test + public void testFinishPerformance() { + + } + + @Test + public void testSetDataPerformance() { + + } + + private void iterateAndShowAvgTime(String event, Runnable callback, int iterations) { + long totalElapsedTime = 0; + for (int i = 0; i < iterations; i++) { + long start = System.currentTimeMillis(); + callback.run(); + long finish = System.currentTimeMillis(); + totalElapsedTime += finish - start; + } + log.info("AVG time for event [{}] is [{} ms] for [{}] iterations", event, totalElapsedTime / iterations, iterations); + } +} diff --git a/application-engine/src/test/resources/petriNets/test_create_case_performance.xml b/application-engine/src/test/resources/petriNets/test_create_case_performance.xml new file mode 100644 index 0000000000..c142d5b9aa --- /dev/null +++ b/application-engine/src/test/resources/petriNets/test_create_case_performance.xml @@ -0,0 +1,459 @@ + + test_create_case_performance + 1.0.0 + TCC + Test create case performance + device_hub + true + true + false + DEF NAME + + role1 + + true + true + true + + + + role2 + + true + true + true + + + + role3 + + true + true + true + + + + role1 + + </role> + <role> + <id>role2</id> + <title/> + </role> + <role> + <id>role3</id> + <title/> + </role> + <data type="text"> + <id>data1</id> + <title/> + </data> + <data type="text"> + <id>data10</id> + <title/> + <init>1</init> + </data> + <data type="text"> + <id>data2</id> + <title/> + </data> + <data type="text"> + <id>data3</id> + <title/> + </data> + <data type="text"> + <id>data4</id> + <title/> + </data> + <data type="text"> + <id>data5</id> + <title/> + </data> + <data type="text"> + <id>data6</id> + <title/> + <init>5</init> + </data> + <data type="text"> + <id>data7</id> + <title/> + <init>4</init> + </data> + <data type="text"> + <id>data8</id> + <title/> + <init>3</init> + </data> + <data type="text"> + <id>data9</id> + <title/> + <init>2</init> + </data> + <transition> + <id>t1</id> + <x>400</x> + <y>368</y> + <label/> + <roleRef> + <id>role1</id> + <logic> + <perform>true</perform> + </logic> + </roleRef> + <roleRef> + <id>role2</id> + <logic> + <perform>true</perform> + </logic> + </roleRef> + <roleRef> + <id>role3</id> + <logic> + <perform>true</perform> + </logic> + </roleRef> + </transition> + <transition> + <id>t2</id> + <x>656</x> + <y>368</y> + <label/> + <roleRef> + <id>role1</id> + <logic> + <perform>true</perform> + </logic> + </roleRef> + <roleRef> + <id>role2</id> + <logic> + <perform>true</perform> + </logic> + </roleRef> + <roleRef> + <id>role3</id> + <logic> + <perform>true</perform> + </logic> + </roleRef> + </transition> + <transition> + <id>t3</id> + <x>944</x> + <y>304</y> + <label/> + <roleRef> + <id>role1</id> + <logic> + <perform>true</perform> + </logic> + </roleRef> + <roleRef> + <id>role2</id> + <logic> + <perform>true</perform> + </logic> + </roleRef> + <roleRef> + <id>role3</id> + <logic> + <perform>true</perform> + </logic> + </roleRef> + </transition> + <transition> + <id>t4</id> + <x>944</x> + <y>432</y> + <label/> + <roleRef> + <id>role1</id> + <logic> + <perform>true</perform> + </logic> + </roleRef> + <roleRef> + <id>role2</id> + <logic> + <perform>true</perform> + </logic> + </roleRef> + <roleRef> + <id>role3</id> + <logic> + <perform>true</perform> + </logic> + </roleRef> + </transition> + <transition> + <id>t5</id> + <x>1200</x> + <y>368</y> + <label/> + <roleRef> + <id>role1</id> + <logic> + <perform>true</perform> + </logic> + </roleRef> + <roleRef> + <id>role2</id> + <logic> + <perform>true</perform> + </logic> + </roleRef> + <roleRef> + <id>role3</id> + <logic> + <perform>true</perform> + </logic> + </roleRef> + </transition> + <transition> + <id>t6</id> + <x>1456</x> + <y>272</y> + <label/> + <roleRef> + <id>role1</id> + <logic> + <perform>true</perform> + </logic> + </roleRef> + <roleRef> + <id>role2</id> + <logic> + <perform>true</perform> + </logic> + </roleRef> + <roleRef> + <id>role3</id> + <logic> + <perform>true</perform> + </logic> + </roleRef> + </transition> + <transition> + <id>t7</id> + <x>1456</x> + <y>464</y> + <label/> + <roleRef> + <id>role1</id> + <logic> + <perform>true</perform> + </logic> + </roleRef> + <roleRef> + <id>role2</id> + <logic> + <perform>true</perform> + </logic> + </roleRef> + <roleRef> + <id>role3</id> + <logic> + <perform>true</perform> + </logic> + </roleRef> + </transition> + <transition> + <id>t8</id> + <x>1584</x> + <y>496</y> + <label/> + <roleRef> + <id>role1</id> + <logic> + <perform>true</perform> + </logic> + </roleRef> + <roleRef> + <id>role2</id> + <logic> + <perform>true</perform> + </logic> + </roleRef> + <roleRef> + <id>role3</id> + <logic> + <perform>true</perform> + </logic> + </roleRef> + </transition> + <place> + <id>p1</id> + <x>272</x> + <y>368</y> + <tokens>1</tokens> + <static>false</static> + </place> + <place> + <id>p2</id> + <x>528</x> + <y>368</y> + <tokens>0</tokens> + <static>false</static> + </place> + <place> + <id>p3</id> + <x>816</x> + <y>368</y> + <tokens>0</tokens> + <static>false</static> + </place> + <place> + <id>p4</id> + <x>1072</x> + <y>368</y> + <tokens>0</tokens> + <static>false</static> + </place> + <place> + <id>p5</id> + <x>1296</x> + <y>272</y> + <tokens>0</tokens> + <static>false</static> + </place> + <place> + <id>p6</id> + <x>1296</x> + <y>464</y> + <tokens>0</tokens> + <static>false</static> + </place> + <place> + <id>p7</id> + <x>1584</x> + <y>368</y> + <tokens>0</tokens> + <static>false</static> + </place> + <place> + <id>p8</id> + <x>1584</x> + <y>656</y> + <tokens>0</tokens> + <static>false</static> + </place> + <arc> + <id>a1</id> + <type>regular</type> + <sourceId>p1</sourceId> + <destinationId>t1</destinationId> + <multiplicity>1</multiplicity> + </arc> + <arc> + <id>a10</id> + <type>regular</type> + <sourceId>t5</sourceId> + <destinationId>p5</destinationId> + <multiplicity>1</multiplicity> + </arc> + <arc> + <id>a11</id> + <type>regular</type> + <sourceId>p5</sourceId> + <destinationId>t6</destinationId> + <multiplicity>1</multiplicity> + </arc> + <arc> + <id>a12</id> + <type>regular</type> + <sourceId>t6</sourceId> + <destinationId>p7</destinationId> + <multiplicity>1</multiplicity> + </arc> + <arc> + <id>a13</id> + <type>regular</type> + <sourceId>p7</sourceId> + <destinationId>t8</destinationId> + <multiplicity>1</multiplicity> + </arc> + <arc> + <id>a14</id> + <type>regular</type> + <sourceId>t8</sourceId> + <destinationId>p8</destinationId> + <multiplicity>1</multiplicity> + </arc> + <arc> + <id>a15</id> + <type>regular</type> + <sourceId>t5</sourceId> + <destinationId>p6</destinationId> + <multiplicity>1</multiplicity> + </arc> + <arc> + <id>a16</id> + <type>regular</type> + <sourceId>p6</sourceId> + <destinationId>t7</destinationId> + <multiplicity>1</multiplicity> + </arc> + <arc> + <id>a17</id> + <type>regular</type> + <sourceId>t7</sourceId> + <destinationId>p7</destinationId> + <multiplicity>1</multiplicity> + </arc> + <arc> + <id>a2</id> + <type>regular</type> + <sourceId>t1</sourceId> + <destinationId>p2</destinationId> + <multiplicity>1</multiplicity> + </arc> + <arc> + <id>a3</id> + <type>regular</type> + <sourceId>p2</sourceId> + <destinationId>t2</destinationId> + <multiplicity>1</multiplicity> + </arc> + <arc> + <id>a4</id> + <type>regular</type> + <sourceId>t2</sourceId> + <destinationId>p3</destinationId> + <multiplicity>1</multiplicity> + </arc> + <arc> + <id>a5</id> + <type>regular</type> + <sourceId>p3</sourceId> + <destinationId>t3</destinationId> + <multiplicity>1</multiplicity> + </arc> + <arc> + <id>a6</id> + <type>regular</type> + <sourceId>p3</sourceId> + <destinationId>t4</destinationId> + <multiplicity>1</multiplicity> + </arc> + <arc> + <id>a7</id> + <type>regular</type> + <sourceId>t3</sourceId> + <destinationId>p4</destinationId> + <multiplicity>1</multiplicity> + </arc> + <arc> + <id>a8</id> + <type>regular</type> + <sourceId>t4</sourceId> + <destinationId>p4</destinationId> + <multiplicity>1</multiplicity> + </arc> + <arc> + <id>a9</id> + <type>regular</type> + <sourceId>p4</sourceId> + <destinationId>t5</destinationId> + <multiplicity>1</multiplicity> + </arc> +</document> \ No newline at end of file From e04adf23d9009350d5bd238c80458beee356869b Mon Sep 17 00:00:00 2001 From: chvostek <chvostek@netgrif.com> Date: Mon, 20 Oct 2025 13:17:35 +0200 Subject: [PATCH 06/55] [NAE-2235] Improve Efficiency of Database Reads and Saves - update method calls after parameters change --- .../engine/migration/ActionMigration.groovy | 7 +++- .../engine/startup/ImportHelper.groovy | 9 ++++- .../engine/auth/SecurityContextTest.groovy | 7 +++- .../ConstructorAndDestructorTest.java | 7 +++- .../engine/importer/ImporterTest.java | 37 ++++++++++++++++--- .../service/ProcessRoleServiceTest.java | 31 +++++++++++++--- .../workflow/WorkflowPerformanceTest.java | 28 +++++++------- .../workflow/service/TaskServiceTest.java | 13 ++++++- .../engine/workflow/web/VariableArcsTest.java | 7 +++- 9 files changed, 114 insertions(+), 32 deletions(-) diff --git a/application-engine/src/main/groovy/com/netgrif/application/engine/migration/ActionMigration.groovy b/application-engine/src/main/groovy/com/netgrif/application/engine/migration/ActionMigration.groovy index d2ae62c461..ef6e9c652f 100644 --- a/application-engine/src/main/groovy/com/netgrif/application/engine/migration/ActionMigration.groovy +++ b/application-engine/src/main/groovy/com/netgrif/application/engine/migration/ActionMigration.groovy @@ -4,6 +4,7 @@ import com.netgrif.application.engine.auth.service.UserService import com.netgrif.application.engine.objects.auth.domain.ActorTransformer import com.netgrif.application.engine.objects.petrinet.domain.PetriNet import com.netgrif.application.engine.objects.petrinet.domain.VersionType +import com.netgrif.application.engine.petrinet.params.ImportPetriNetParams import com.netgrif.application.engine.petrinet.service.interfaces.IPetriNetService import com.netgrif.application.engine.objects.workflow.domain.eventoutcomes.petrinetoutcomes.ImportPetriNetEventOutcome import groovy.util.logging.Slf4j @@ -25,7 +26,11 @@ class ActionMigration { void migrateActions(String petriNetPath) { InputStream netStream = new ClassPathResource(petriNetPath).inputStream - ImportPetriNetEventOutcome newPetriNet = petriNetService.importPetriNet(netStream, VersionType.MAJOR, ActorTransformer.toLoggedUser(userService.getLoggedOrSystem())) + ImportPetriNetEventOutcome newPetriNet = petriNetService.importPetriNet(ImportPetriNetParams.with() + .xmlFile(netStream) + .releaseType(VersionType.MAJOR) + .author(ActorTransformer.toLoggedUser(userService.getLoggedOrSystem())) + .build()) List<PetriNet> oldPetriNets if(newPetriNet.getNet() != null) { diff --git a/application-engine/src/main/groovy/com/netgrif/application/engine/startup/ImportHelper.groovy b/application-engine/src/main/groovy/com/netgrif/application/engine/startup/ImportHelper.groovy index 651bf31abb..5005c9c831 100644 --- a/application-engine/src/main/groovy/com/netgrif/application/engine/startup/ImportHelper.groovy +++ b/application-engine/src/main/groovy/com/netgrif/application/engine/startup/ImportHelper.groovy @@ -6,6 +6,7 @@ import com.netgrif.application.engine.adapter.spring.petrinet.service.ProcessRol import com.netgrif.application.engine.objects.auth.domain.AbstractUser import com.netgrif.application.engine.objects.auth.domain.ActorTransformer import com.netgrif.application.engine.petrinet.domain.repositories.PetriNetRepository +import com.netgrif.application.engine.petrinet.params.ImportPetriNetParams import com.netgrif.application.engine.petrinet.service.interfaces.IPetriNetService import com.netgrif.application.engine.startup.runner.SuperCreatorRunner import com.netgrif.application.engine.workflow.domain.repositories.CaseRepository @@ -112,12 +113,16 @@ class ImportHelper { } Optional<PetriNet> createNet(String fileName, String release, LoggedUser author = ActorTransformer.toLoggedUser(userService.getSystem())) { - return createNet(fileName, VersionType.valueOf(release.trim().toUpperCase()), author, uriNodeId) + return createNet(fileName, VersionType.valueOf(release.trim().toUpperCase()), author) } Optional<PetriNet> createNet(String fileName, VersionType release = VersionType.MAJOR, LoggedUser author = ActorTransformer.toLoggedUser(userService.getSystem())) { InputStream netStream = new ClassPathResource("petriNets/$fileName" as String).inputStream - def outcome = petriNetService.importPetriNet(netStream, release, author) + def outcome = petriNetService.importPetriNet(ImportPetriNetParams.with() + .xmlFile(netStream) + .releaseType(release) + .author(author) + .build()) PetriNet petriNet = outcome.getNet() if (petriNet == null) { log.warn("Import of [$fileName] produced no PetriNet object") diff --git a/application-engine/src/test/groovy/com/netgrif/application/engine/auth/SecurityContextTest.groovy b/application-engine/src/test/groovy/com/netgrif/application/engine/auth/SecurityContextTest.groovy index 49c63a7bb3..a337fcc963 100644 --- a/application-engine/src/test/groovy/com/netgrif/application/engine/auth/SecurityContextTest.groovy +++ b/application-engine/src/test/groovy/com/netgrif/application/engine/auth/SecurityContextTest.groovy @@ -12,6 +12,7 @@ import com.netgrif.application.engine.objects.auth.domain.User import com.netgrif.application.engine.objects.petrinet.domain.PetriNet import com.netgrif.application.engine.objects.petrinet.domain.VersionType import com.netgrif.application.engine.petrinet.domain.dataset.logic.action.ActionDelegate +import com.netgrif.application.engine.petrinet.params.ImportPetriNetParams import com.netgrif.application.engine.petrinet.service.interfaces.IPetriNetService import com.netgrif.application.engine.adapter.spring.petrinet.service.ProcessRoleService import com.netgrif.application.engine.security.service.ISecurityContextService @@ -73,7 +74,11 @@ class SecurityContextTest { user = userService.saveUser(user, null) assert user != null - net = petriNetService.importPetriNet(new FileInputStream("src/test/resources/all_data.xml"), VersionType.MAJOR, ActorTransformer.toLoggedUser(userService.getLoggedOrSystem())).getNet() + net = petriNetService.importPetriNet(ImportPetriNetParams.with() + .xmlFile(new FileInputStream("src/test/resources/all_data.xml")) + .releaseType(VersionType.MAJOR) + .author(ActorTransformer.toLoggedUser(userService.getLoggedOrSystem())) + .build()).getNet() assert net != null } diff --git a/application-engine/src/test/java/com/netgrif/application/engine/importer/ConstructorAndDestructorTest.java b/application-engine/src/test/java/com/netgrif/application/engine/importer/ConstructorAndDestructorTest.java index 839a8a11ac..bd4739c806 100644 --- a/application-engine/src/test/java/com/netgrif/application/engine/importer/ConstructorAndDestructorTest.java +++ b/application-engine/src/test/java/com/netgrif/application/engine/importer/ConstructorAndDestructorTest.java @@ -4,6 +4,7 @@ import com.netgrif.application.engine.importer.service.throwable.MissingIconKeyException; import com.netgrif.application.engine.objects.petrinet.domain.VersionType; import com.netgrif.application.engine.objects.petrinet.domain.throwable.MissingPetriNetMetaDataException; +import com.netgrif.application.engine.petrinet.params.ImportPetriNetParams; import com.netgrif.application.engine.petrinet.service.interfaces.IPetriNetService; import com.netgrif.application.engine.startup.runner.SuperCreatorRunner; import com.netgrif.application.engine.objects.workflow.domain.Case; @@ -46,7 +47,11 @@ public void before() { @Test public void testConstructorAndDestructor() throws MissingPetriNetMetaDataException, IOException, MissingIconKeyException { - ImportPetriNetEventOutcome outcome = petriNetService.importPetriNet(new FileInputStream("src/test/resources/constructor_destructor.xml"), VersionType.MAJOR, superCreator.getLoggedSuper()); + ImportPetriNetEventOutcome outcome = petriNetService.importPetriNet(ImportPetriNetParams.with() + .xmlFile(new FileInputStream("src/test/resources/constructor_destructor.xml")) + .releaseType(VersionType.MAJOR) + .author(superCreator.getLoggedSuper()) + .build()); assert outcome.getNet() != null; Optional<Case> caseOpt = caseRepository.findOne(QCase.case$.title.eq("Construct")); diff --git a/application-engine/src/test/java/com/netgrif/application/engine/importer/ImporterTest.java b/application-engine/src/test/java/com/netgrif/application/engine/importer/ImporterTest.java index aedbe6e565..589a455910 100644 --- a/application-engine/src/test/java/com/netgrif/application/engine/importer/ImporterTest.java +++ b/application-engine/src/test/java/com/netgrif/application/engine/importer/ImporterTest.java @@ -7,6 +7,7 @@ import com.netgrif.application.engine.objects.petrinet.domain.VersionType; import com.netgrif.application.engine.petrinet.domain.repositories.PetriNetRepository; import com.netgrif.application.engine.objects.petrinet.domain.throwable.MissingPetriNetMetaDataException; +import com.netgrif.application.engine.petrinet.params.ImportPetriNetParams; import com.netgrif.application.engine.petrinet.service.interfaces.IPetriNetService; import com.netgrif.application.engine.startup.runner.SuperCreatorRunner; import com.netgrif.application.engine.utils.FullPageRequest; @@ -62,13 +63,21 @@ public void before() { @Test public void importPetriNet() throws MissingPetriNetMetaDataException, IOException, MissingIconKeyException { - petriNetService.importPetriNet(new FileInputStream("src/test/resources/prikladFM_test.xml"), VersionType.MAJOR, superCreator.getLoggedSuper()); + petriNetService.importPetriNet(ImportPetriNetParams.with() + .xmlFile(new FileInputStream("src/test/resources/prikladFM_test.xml")) + .releaseType(VersionType.MAJOR) + .author(superCreator.getLoggedSuper()) + .build()); assertNetProperlyImported(); } @Test public void priorityTest() throws MissingPetriNetMetaDataException, IOException, MissingIconKeyException { - ImportPetriNetEventOutcome outcome = petriNetService.importPetriNet(new FileInputStream("src/test/resources/priority_test.xml"), VersionType.MAJOR, superCreator.getLoggedSuper()); + ImportPetriNetEventOutcome outcome = petriNetService.importPetriNet(ImportPetriNetParams.with() + .xmlFile(new FileInputStream("src/test/resources/priority_test.xml")) + .releaseType(VersionType.MAJOR) + .author(superCreator.getLoggedSuper()) + .build()); assert outcome.getNet() != null; CreateCaseEventOutcome caseOutcome = workflowService.createCase(outcome.getNet().getStringId(), outcome.getNet().getTitle().getDefaultValue(), "color", superCreator.getLoggedSuper()); @@ -78,19 +87,31 @@ public void priorityTest() throws MissingPetriNetMetaDataException, IOException, @Test public void dataGroupTest() throws MissingPetriNetMetaDataException, IOException, MissingIconKeyException { - ImportPetriNetEventOutcome outcome = petriNetService.importPetriNet(new FileInputStream("src/test/resources/datagroup_test.xml"), VersionType.MAJOR, superCreator.getLoggedSuper()); + ImportPetriNetEventOutcome outcome = petriNetService.importPetriNet(ImportPetriNetParams.with() + .xmlFile(new FileInputStream("src/test/resources/datagroup_test.xml")) + .releaseType(VersionType.MAJOR) + .author(superCreator.getLoggedSuper()) + .build()); assert outcome.getNet() != null; } @Test public void readArcImportTest() throws MissingPetriNetMetaDataException, IOException, MissingIconKeyException { - petriNetService.importPetriNet(new FileInputStream("src/test/resources/read_test.xml"), VersionType.MAJOR, superCreator.getLoggedSuper()); + petriNetService.importPetriNet(ImportPetriNetParams.with() + .xmlFile(new FileInputStream("src/test/resources/read_test.xml")) + .releaseType(VersionType.MAJOR) + .author(superCreator.getLoggedSuper()) + .build()); } @Test public void externalMappingTest() throws MissingPetriNetMetaDataException, IOException, MissingIconKeyException { - ImportPetriNetEventOutcome outcome = petriNetService.importPetriNet(new FileInputStream("src/test/resources/mapping_test.xml"), VersionType.MAJOR, superCreator.getLoggedSuper()); + ImportPetriNetEventOutcome outcome = petriNetService.importPetriNet(ImportPetriNetParams.with() + .xmlFile(new FileInputStream("src/test/resources/mapping_test.xml")) + .releaseType(VersionType.MAJOR) + .author(superCreator.getLoggedSuper()) + .build()); assertExternalMappingImport(outcome.getNet()); } @@ -102,7 +123,11 @@ void importInvalidDataRefLayoutTest() throws FileNotFoundException { FileInputStream fileInputStream = new FileInputStream("src/test/resources/invalid_data_ref_layout.xml"); - assertThatThrownBy(() -> petriNetService.importPetriNet(fileInputStream, VersionType.MAJOR, loggedUser)) + assertThatThrownBy(() -> petriNetService.importPetriNet(ImportPetriNetParams.with() + .xmlFile(fileInputStream) + .releaseType(VersionType.MAJOR) + .author(superCreator.getLoggedSuper()) + .build())) .isInstanceOf(IllegalArgumentException.class) .hasMessageContaining("doesn't have a layout"); diff --git a/application-engine/src/test/java/com/netgrif/application/engine/petrinet/service/ProcessRoleServiceTest.java b/application-engine/src/test/java/com/netgrif/application/engine/petrinet/service/ProcessRoleServiceTest.java index cda0786716..38d5cafa1f 100644 --- a/application-engine/src/test/java/com/netgrif/application/engine/petrinet/service/ProcessRoleServiceTest.java +++ b/application-engine/src/test/java/com/netgrif/application/engine/petrinet/service/ProcessRoleServiceTest.java @@ -4,6 +4,7 @@ import com.netgrif.application.engine.objects.petrinet.domain.VersionType; import com.netgrif.application.engine.objects.petrinet.domain.roles.ProcessRole; import com.netgrif.application.engine.objects.petrinet.domain.throwable.MissingPetriNetMetaDataException; +import com.netgrif.application.engine.petrinet.params.ImportPetriNetParams; import com.netgrif.application.engine.petrinet.service.interfaces.IPetriNetService; import com.netgrif.application.engine.adapter.spring.petrinet.service.ProcessRoleService; import com.netgrif.application.engine.startup.runner.SuperCreatorRunner; @@ -55,8 +56,16 @@ public void before() { void shouldFindAllProcessRoles() throws IOException, MissingPetriNetMetaDataException { Page<ProcessRole> roles = processRoleService.findAll(Pageable.unpaged()); long originalRoles = roles.getTotalElements(); - petriNetService.importPetriNet(new FileInputStream("src/test/resources/all_data.xml"), VersionType.MAJOR, superCreator.getLoggedSuper()); - petriNetService.importPetriNet(new FileInputStream("src/test/resources/role_all_data.xml"), VersionType.MAJOR, superCreator.getLoggedSuper()); + petriNetService.importPetriNet(ImportPetriNetParams.with() + .xmlFile(new FileInputStream("src/test/resources/all_data.xml")) + .releaseType(VersionType.MAJOR) + .author(superCreator.getLoggedSuper()) + .build()); + petriNetService.importPetriNet(ImportPetriNetParams.with() + .xmlFile(new FileInputStream("src/test/resources/role_all_data.xml")) + .releaseType(VersionType.MAJOR) + .author(superCreator.getLoggedSuper()) + .build()); roles = processRoleService.findAll(Pageable.unpaged()); assertNotNull(roles); assertFalse(roles.isEmpty()); @@ -65,7 +74,11 @@ void shouldFindAllProcessRoles() throws IOException, MissingPetriNetMetaDataExce @Test void shouldFindAllProcessRolesByPetriNet() throws IOException, MissingPetriNetMetaDataException { - ImportPetriNetEventOutcome eventOutcome = petriNetService.importPetriNet(new FileInputStream("src/test/resources/all_data.xml"), VersionType.MAJOR, superCreator.getLoggedSuper()); + ImportPetriNetEventOutcome eventOutcome = petriNetService.importPetriNet(ImportPetriNetParams.with() + .xmlFile(new FileInputStream("src/test/resources/all_data.xml")) + .releaseType(VersionType.MAJOR) + .author(superCreator.getLoggedSuper()) + .build()); List<ProcessRole> roles = processRoleService.findAllByNetStringId(eventOutcome.getNet().getStringId()); assertNotNull(roles); assertFalse(roles.isEmpty()); @@ -92,7 +105,11 @@ void shouldGetGetAnonymousRole() { @Test void shouldFindAllProcessRolesByImportId() throws IOException, MissingPetriNetMetaDataException { - petriNetService.importPetriNet(new FileInputStream("src/test/resources/all_data.xml"), VersionType.MAJOR, superCreator.getLoggedSuper()); + petriNetService.importPetriNet(ImportPetriNetParams.with() + .xmlFile(new FileInputStream("src/test/resources/all_data.xml")) + .releaseType(VersionType.MAJOR) + .author(superCreator.getLoggedSuper()) + .build()); Page<ProcessRole> roles = processRoleService.findAllByImportId(ROLE_IMPORT_ID, Pageable.unpaged()); assertNotNull(roles); assertFalse(roles.isEmpty()); @@ -102,7 +119,11 @@ void shouldFindAllProcessRolesByImportId() throws IOException, MissingPetriNetMe @Test void shouldFindAllProcessRolesByName() throws IOException, MissingPetriNetMetaDataException { - petriNetService.importPetriNet(new FileInputStream("src/test/resources/all_data.xml"), VersionType.MAJOR, superCreator.getLoggedSuper()); + petriNetService.importPetriNet(ImportPetriNetParams.with() + .xmlFile(new FileInputStream("src/test/resources/all_data.xml")) + .releaseType(VersionType.MAJOR) + .author(superCreator.getLoggedSuper()) + .build()); Page<ProcessRole> roles = processRoleService.findAllByDefaultName("Process role", Pageable.unpaged()); assertNotNull(roles); assertFalse(roles.isEmpty()); diff --git a/application-engine/src/test/java/com/netgrif/application/engine/workflow/WorkflowPerformanceTest.java b/application-engine/src/test/java/com/netgrif/application/engine/workflow/WorkflowPerformanceTest.java index 2786bee7a9..8509911d84 100644 --- a/application-engine/src/test/java/com/netgrif/application/engine/workflow/WorkflowPerformanceTest.java +++ b/application-engine/src/test/java/com/netgrif/application/engine/workflow/WorkflowPerformanceTest.java @@ -7,15 +7,13 @@ import com.netgrif.application.engine.petrinet.params.ImportPetriNetParams; import com.netgrif.application.engine.petrinet.service.interfaces.IPetriNetService; import com.netgrif.application.engine.startup.runner.SuperCreatorRunner; -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 lombok.RequiredArgsConstructor; +import com.netgrif.application.engine.workflow.service.WorkflowService; import lombok.extern.slf4j.Slf4j; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.context.ActiveProfiles; import org.springframework.test.context.junit.jupiter.SpringExtension; @@ -27,17 +25,21 @@ @Slf4j @Disabled @SpringBootTest -@RequiredArgsConstructor @ActiveProfiles({"test"}) @ExtendWith(SpringExtension.class) public class WorkflowPerformanceTest { - private final IWorkflowService workflowService; - private final ITaskService taskService; - private final IDataService dataService; - private final IPetriNetService petriNetService; - private final SuperCreatorRunner superCreatorRunner; - private final TestHelper testHelper; + @Autowired + private WorkflowService workflowService; + + @Autowired + private IPetriNetService petriNetService; + + @Autowired + private SuperCreatorRunner superCreatorRunner; + + @Autowired + private TestHelper testHelper; @BeforeEach public void beforeEach() { @@ -47,12 +49,12 @@ public void beforeEach() { @Test public void testCreatePerformance() throws IOException, MissingPetriNetMetaDataException { PetriNet net = petriNetService.importPetriNet(ImportPetriNetParams.with() - .xmlFile(new FileInputStream("src/test/resources/test_create_case_performance.xml")) + .xmlFile(new FileInputStream("src/test/resources/petriNets/test_create_case_performance.xml")) .releaseType(VersionType.MAJOR) .author(superCreatorRunner.getLoggedSuper()) .build()).getNet(); iterateAndShowAvgTime("createCase", () -> workflowService.createCase(net.getStringId(), null, null, - superCreatorRunner.getLoggedSuper(), Locale.getDefault()), 100); + superCreatorRunner.getLoggedSuper(), Locale.getDefault()), 1000); } @Test diff --git a/application-engine/src/test/java/com/netgrif/application/engine/workflow/service/TaskServiceTest.java b/application-engine/src/test/java/com/netgrif/application/engine/workflow/service/TaskServiceTest.java index ace0aca266..96686e79f8 100644 --- a/application-engine/src/test/java/com/netgrif/application/engine/workflow/service/TaskServiceTest.java +++ b/application-engine/src/test/java/com/netgrif/application/engine/workflow/service/TaskServiceTest.java @@ -18,6 +18,7 @@ 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.petrinet.domain.repositories.PetriNetRepository; +import com.netgrif.application.engine.petrinet.params.ImportPetriNetParams; import com.netgrif.application.engine.petrinet.service.interfaces.IPetriNetService; import com.netgrif.application.engine.startup.runner.DefaultRealmRunner; import com.netgrif.application.engine.startup.runner.SuperCreatorRunner; @@ -94,14 +95,22 @@ public void setUp() throws Exception { realmRunner.run(null); userRunner.run(null); - petriNetService.importPetriNet(new FileInputStream("src/test/resources/prikladFM.xml"), VersionType.MAJOR, superCreator.getLoggedSuper()); + petriNetService.importPetriNet(ImportPetriNetParams.with() + .xmlFile(new FileInputStream("src/test/resources/prikladFM.xml")) + .releaseType(VersionType.MAJOR) + .author(superCreator.getLoggedSuper()) + .build()); PetriNet net = petriNetRepository.findAll().get(0); workflowService.createCase(net.getStringId(), "Storage Unit", "color", mock.mockLoggedUser()); } @Test public void resetArcTest() throws TransitionNotExecutableException, MissingPetriNetMetaDataException, IOException, MissingIconKeyException { - PetriNet net = petriNetService.importPetriNet(new FileInputStream("src/test/resources/reset_inhibitor_test.xml"), VersionType.MAJOR, superCreator.getLoggedSuper()).getNet(); + PetriNet net = petriNetService.importPetriNet(ImportPetriNetParams.with() + .xmlFile(new FileInputStream("src/test/resources/reset_inhibitor_test.xml")) + .releaseType(VersionType.MAJOR) + .author(superCreator.getLoggedSuper()) + .build()).getNet(); LoggedUser loggedUser = mock.mockLoggedUser(); CreateCaseEventOutcome outcome = workflowService.createCase(net.getStringId(), "Reset test", "color", loggedUser); User user = new User(); diff --git a/application-engine/src/test/java/com/netgrif/application/engine/workflow/web/VariableArcsTest.java b/application-engine/src/test/java/com/netgrif/application/engine/workflow/web/VariableArcsTest.java index bd6cd1cddb..643a714380 100644 --- a/application-engine/src/test/java/com/netgrif/application/engine/workflow/web/VariableArcsTest.java +++ b/application-engine/src/test/java/com/netgrif/application/engine/workflow/web/VariableArcsTest.java @@ -13,6 +13,7 @@ import com.netgrif.application.engine.petrinet.domain.repositories.PetriNetRepository; import com.netgrif.application.engine.objects.petrinet.domain.roles.ProcessRole; import com.netgrif.application.engine.objects.petrinet.domain.throwable.TransitionNotExecutableException; +import com.netgrif.application.engine.petrinet.params.ImportPetriNetParams; import com.netgrif.application.engine.petrinet.service.interfaces.IPetriNetService; import com.netgrif.application.engine.adapter.spring.petrinet.service.ProcessRoleService; import com.netgrif.application.engine.startup.ImportHelper; @@ -110,7 +111,11 @@ public void before() throws Exception { repository.deleteAll(); assertNotNull(processRoleService.getDefaultRole()); testHelper.truncateDbs(); - ImportPetriNetEventOutcome outcome = service.importPetriNet(new FileInputStream(NET_PATH), VersionType.MAJOR, superCreator.getLoggedSuper()); + ImportPetriNetEventOutcome outcome = service.importPetriNet(ImportPetriNetParams.with() + .xmlFile(new FileInputStream(NET_PATH)) + .releaseType(VersionType.MAJOR) + .author(superCreator.getLoggedSuper()) + .build()); assert outcome.getNet() != null; PetriNet net = outcome.getNet(); From 4022c5b2428b5dcf68167c62379a80c5db468b89 Mon Sep 17 00:00:00 2001 From: chvostek <chvostek@netgrif.com> Date: Mon, 20 Oct 2025 13:27:32 +0200 Subject: [PATCH 07/55] [NAE-2235] Improve Efficiency of Database Reads and Saves - add performance test --- .../workflow/WorkflowPerformanceTest.java | 11 + ...st_create_case_performance_with_action.xml | 470 ++++++++++++++++++ 2 files changed, 481 insertions(+) create mode 100644 application-engine/src/test/resources/petriNets/test_create_case_performance_with_action.xml diff --git a/application-engine/src/test/java/com/netgrif/application/engine/workflow/WorkflowPerformanceTest.java b/application-engine/src/test/java/com/netgrif/application/engine/workflow/WorkflowPerformanceTest.java index 8509911d84..8621a66a25 100644 --- a/application-engine/src/test/java/com/netgrif/application/engine/workflow/WorkflowPerformanceTest.java +++ b/application-engine/src/test/java/com/netgrif/application/engine/workflow/WorkflowPerformanceTest.java @@ -57,6 +57,17 @@ public void testCreatePerformance() throws IOException, MissingPetriNetMetaDataE superCreatorRunner.getLoggedSuper(), Locale.getDefault()), 1000); } + @Test + public void testCreate2Performance() throws IOException, MissingPetriNetMetaDataException { + PetriNet net = petriNetService.importPetriNet(ImportPetriNetParams.with() + .xmlFile(new FileInputStream("src/test/resources/petriNets/test_create_case_performance_with_action.xml")) + .releaseType(VersionType.MAJOR) + .author(superCreatorRunner.getLoggedSuper()) + .build()).getNet(); + iterateAndShowAvgTime("createCaseWithAction", () -> workflowService.createCase(net.getStringId(), null, null, + superCreatorRunner.getLoggedSuper(), Locale.getDefault()), 1000); + } + @Test public void testAssignPerformance() { diff --git a/application-engine/src/test/resources/petriNets/test_create_case_performance_with_action.xml b/application-engine/src/test/resources/petriNets/test_create_case_performance_with_action.xml new file mode 100644 index 0000000000..2825b5f020 --- /dev/null +++ b/application-engine/src/test/resources/petriNets/test_create_case_performance_with_action.xml @@ -0,0 +1,470 @@ +<document xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="https://petriflow.com/petriflow.schema.xsd"> + <id>test_create_case_performance_with_action</id> + <version>1.0.0</version> + <initials>TCC</initials> + <title>Test create case performance with action + device_hub + true + true + false + DEF NAME + + + awd + + + data8: f.data8; + change data8 value { "awd" } + + + + + + role1 + + true + true + true + + + + role2 + + true + true + true + + + + role3 + + true + true + true + + + + role1 + + </role> + <role> + <id>role2</id> + <title/> + </role> + <role> + <id>role3</id> + <title/> + </role> + <data type="text"> + <id>data1</id> + <title/> + </data> + <data type="text"> + <id>data10</id> + <title/> + <init>1</init> + </data> + <data type="text"> + <id>data2</id> + <title/> + </data> + <data type="text"> + <id>data3</id> + <title/> + </data> + <data type="text"> + <id>data4</id> + <title/> + </data> + <data type="text"> + <id>data5</id> + <title/> + </data> + <data type="text"> + <id>data6</id> + <title/> + <init>5</init> + </data> + <data type="text"> + <id>data7</id> + <title/> + <init>4</init> + </data> + <data type="text"> + <id>data8</id> + <title/> + <init>3</init> + </data> + <data type="text"> + <id>data9</id> + <title/> + <init>2</init> + </data> + <transition> + <id>t1</id> + <x>400</x> + <y>368</y> + <label/> + <roleRef> + <id>role1</id> + <logic> + <perform>true</perform> + </logic> + </roleRef> + <roleRef> + <id>role2</id> + <logic> + <perform>true</perform> + </logic> + </roleRef> + <roleRef> + <id>role3</id> + <logic> + <perform>true</perform> + </logic> + </roleRef> + </transition> + <transition> + <id>t2</id> + <x>656</x> + <y>368</y> + <label/> + <roleRef> + <id>role1</id> + <logic> + <perform>true</perform> + </logic> + </roleRef> + <roleRef> + <id>role2</id> + <logic> + <perform>true</perform> + </logic> + </roleRef> + <roleRef> + <id>role3</id> + <logic> + <perform>true</perform> + </logic> + </roleRef> + </transition> + <transition> + <id>t3</id> + <x>944</x> + <y>304</y> + <label/> + <roleRef> + <id>role1</id> + <logic> + <perform>true</perform> + </logic> + </roleRef> + <roleRef> + <id>role2</id> + <logic> + <perform>true</perform> + </logic> + </roleRef> + <roleRef> + <id>role3</id> + <logic> + <perform>true</perform> + </logic> + </roleRef> + </transition> + <transition> + <id>t4</id> + <x>944</x> + <y>432</y> + <label/> + <roleRef> + <id>role1</id> + <logic> + <perform>true</perform> + </logic> + </roleRef> + <roleRef> + <id>role2</id> + <logic> + <perform>true</perform> + </logic> + </roleRef> + <roleRef> + <id>role3</id> + <logic> + <perform>true</perform> + </logic> + </roleRef> + </transition> + <transition> + <id>t5</id> + <x>1200</x> + <y>368</y> + <label/> + <roleRef> + <id>role1</id> + <logic> + <perform>true</perform> + </logic> + </roleRef> + <roleRef> + <id>role2</id> + <logic> + <perform>true</perform> + </logic> + </roleRef> + <roleRef> + <id>role3</id> + <logic> + <perform>true</perform> + </logic> + </roleRef> + </transition> + <transition> + <id>t6</id> + <x>1456</x> + <y>272</y> + <label/> + <roleRef> + <id>role1</id> + <logic> + <perform>true</perform> + </logic> + </roleRef> + <roleRef> + <id>role2</id> + <logic> + <perform>true</perform> + </logic> + </roleRef> + <roleRef> + <id>role3</id> + <logic> + <perform>true</perform> + </logic> + </roleRef> + </transition> + <transition> + <id>t7</id> + <x>1456</x> + <y>464</y> + <label/> + <roleRef> + <id>role1</id> + <logic> + <perform>true</perform> + </logic> + </roleRef> + <roleRef> + <id>role2</id> + <logic> + <perform>true</perform> + </logic> + </roleRef> + <roleRef> + <id>role3</id> + <logic> + <perform>true</perform> + </logic> + </roleRef> + </transition> + <transition> + <id>t8</id> + <x>1584</x> + <y>496</y> + <label/> + <roleRef> + <id>role1</id> + <logic> + <perform>true</perform> + </logic> + </roleRef> + <roleRef> + <id>role2</id> + <logic> + <perform>true</perform> + </logic> + </roleRef> + <roleRef> + <id>role3</id> + <logic> + <perform>true</perform> + </logic> + </roleRef> + </transition> + <place> + <id>p1</id> + <x>272</x> + <y>368</y> + <tokens>1</tokens> + <static>false</static> + </place> + <place> + <id>p2</id> + <x>528</x> + <y>368</y> + <tokens>0</tokens> + <static>false</static> + </place> + <place> + <id>p3</id> + <x>816</x> + <y>368</y> + <tokens>0</tokens> + <static>false</static> + </place> + <place> + <id>p4</id> + <x>1072</x> + <y>368</y> + <tokens>0</tokens> + <static>false</static> + </place> + <place> + <id>p5</id> + <x>1296</x> + <y>272</y> + <tokens>0</tokens> + <static>false</static> + </place> + <place> + <id>p6</id> + <x>1296</x> + <y>464</y> + <tokens>0</tokens> + <static>false</static> + </place> + <place> + <id>p7</id> + <x>1584</x> + <y>368</y> + <tokens>0</tokens> + <static>false</static> + </place> + <place> + <id>p8</id> + <x>1584</x> + <y>656</y> + <tokens>0</tokens> + <static>false</static> + </place> + <arc> + <id>a1</id> + <type>regular</type> + <sourceId>p1</sourceId> + <destinationId>t1</destinationId> + <multiplicity>1</multiplicity> + </arc> + <arc> + <id>a10</id> + <type>regular</type> + <sourceId>t5</sourceId> + <destinationId>p5</destinationId> + <multiplicity>1</multiplicity> + </arc> + <arc> + <id>a11</id> + <type>regular</type> + <sourceId>p5</sourceId> + <destinationId>t6</destinationId> + <multiplicity>1</multiplicity> + </arc> + <arc> + <id>a12</id> + <type>regular</type> + <sourceId>t6</sourceId> + <destinationId>p7</destinationId> + <multiplicity>1</multiplicity> + </arc> + <arc> + <id>a13</id> + <type>regular</type> + <sourceId>p7</sourceId> + <destinationId>t8</destinationId> + <multiplicity>1</multiplicity> + </arc> + <arc> + <id>a14</id> + <type>regular</type> + <sourceId>t8</sourceId> + <destinationId>p8</destinationId> + <multiplicity>1</multiplicity> + </arc> + <arc> + <id>a15</id> + <type>regular</type> + <sourceId>t5</sourceId> + <destinationId>p6</destinationId> + <multiplicity>1</multiplicity> + </arc> + <arc> + <id>a16</id> + <type>regular</type> + <sourceId>p6</sourceId> + <destinationId>t7</destinationId> + <multiplicity>1</multiplicity> + </arc> + <arc> + <id>a17</id> + <type>regular</type> + <sourceId>t7</sourceId> + <destinationId>p7</destinationId> + <multiplicity>1</multiplicity> + </arc> + <arc> + <id>a2</id> + <type>regular</type> + <sourceId>t1</sourceId> + <destinationId>p2</destinationId> + <multiplicity>1</multiplicity> + </arc> + <arc> + <id>a3</id> + <type>regular</type> + <sourceId>p2</sourceId> + <destinationId>t2</destinationId> + <multiplicity>1</multiplicity> + </arc> + <arc> + <id>a4</id> + <type>regular</type> + <sourceId>t2</sourceId> + <destinationId>p3</destinationId> + <multiplicity>1</multiplicity> + </arc> + <arc> + <id>a5</id> + <type>regular</type> + <sourceId>p3</sourceId> + <destinationId>t3</destinationId> + <multiplicity>1</multiplicity> + </arc> + <arc> + <id>a6</id> + <type>regular</type> + <sourceId>p3</sourceId> + <destinationId>t4</destinationId> + <multiplicity>1</multiplicity> + </arc> + <arc> + <id>a7</id> + <type>regular</type> + <sourceId>t3</sourceId> + <destinationId>p4</destinationId> + <multiplicity>1</multiplicity> + </arc> + <arc> + <id>a8</id> + <type>regular</type> + <sourceId>t4</sourceId> + <destinationId>p4</destinationId> + <multiplicity>1</multiplicity> + </arc> + <arc> + <id>a9</id> + <type>regular</type> + <sourceId>p4</sourceId> + <destinationId>t5</destinationId> + <multiplicity>1</multiplicity> + </arc> +</document> \ No newline at end of file From 79823276904b88bf3e44b5423eae1072e9727306 Mon Sep 17 00:00:00 2001 From: chvostek <chvostek@netgrif.com> Date: Tue, 21 Oct 2025 14:28:19 +0200 Subject: [PATCH 08/55] [NAE-2235] Improve Efficiency of Database Reads and Saves - optimize createCase event --- .../logic/action/ActionDelegate.groovy | 1 + .../services/DashboardItemServiceImpl.java | 8 +- .../DashboardManagementServiceImpl.java | 8 +- .../engine/menu/services/MenuItemService.java | 8 +- .../startup/runner/DefaultFiltersRunner.java | 10 +- .../domain/outcomes/ReloadTaskOutcome.java | 11 + .../workflow/params/CreateCaseParams.java | 54 ++++ .../engine/workflow/service/DataService.java | 2 +- .../engine/workflow/service/EventService.java | 10 +- .../service/FilterImportExportService.java | 15 +- .../service/MenuImportExportService.java | 13 +- .../engine/workflow/service/TaskService.java | 109 ++++---- .../workflow/service/WorkflowService.java | 232 +++++++++--------- .../service/interfaces/ITaskService.java | 3 +- .../service/interfaces/IWorkflowService.java | 19 +- .../web/PublicWorkflowController.java | 11 +- .../workflow/web/WorkflowController.java | 15 +- .../engine/importer/ImporterTest.java | 8 +- .../workflow/WorkflowPerformanceTest.java | 15 +- .../workflow/service/TaskServiceTest.java | 15 +- .../engine/workflow/web/VariableArcsTest.java | 8 +- .../engine/objects/workflow/domain/Case.java | 9 +- .../engine/objects/workflow/domain/Task.java | 9 +- 23 files changed, 380 insertions(+), 213 deletions(-) create mode 100644 application-engine/src/main/java/com/netgrif/application/engine/workflow/domain/outcomes/ReloadTaskOutcome.java create mode 100644 application-engine/src/main/java/com/netgrif/application/engine/workflow/params/CreateCaseParams.java diff --git a/application-engine/src/main/groovy/com/netgrif/application/engine/petrinet/domain/dataset/logic/action/ActionDelegate.groovy b/application-engine/src/main/groovy/com/netgrif/application/engine/petrinet/domain/dataset/logic/action/ActionDelegate.groovy index f0275b57fb..e30243b7c5 100644 --- a/application-engine/src/main/groovy/com/netgrif/application/engine/petrinet/domain/dataset/logic/action/ActionDelegate.groovy +++ b/application-engine/src/main/groovy/com/netgrif/application/engine/petrinet/domain/dataset/logic/action/ActionDelegate.groovy @@ -938,6 +938,7 @@ class ActionDelegate { } Case createCase(String identifier, String title = null, String color = "", AbstractUser author = userService.loggedOrSystem, Locale locale = LocaleContextHolder.getLocale(), Map<String, String> params = [:]) { + // todo 2235 return workflowService.createCaseByIdentifier(identifier, title, color, ActorTransformer.toLoggedUser(author), locale, params).getCase() } diff --git a/application-engine/src/main/java/com/netgrif/application/engine/menu/services/DashboardItemServiceImpl.java b/application-engine/src/main/java/com/netgrif/application/engine/menu/services/DashboardItemServiceImpl.java index c0a5627de0..cc8034ff0e 100644 --- a/application-engine/src/main/java/com/netgrif/application/engine/menu/services/DashboardItemServiceImpl.java +++ b/application-engine/src/main/java/com/netgrif/application/engine/menu/services/DashboardItemServiceImpl.java @@ -17,6 +17,7 @@ import com.netgrif.application.engine.objects.workflow.domain.menu.dashboard.DashboardItemConstants; import com.netgrif.application.engine.petrinet.service.interfaces.IPetriNetService; import com.netgrif.application.engine.startup.ImportHelper; +import com.netgrif.application.engine.workflow.params.CreateCaseParams; 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; @@ -62,7 +63,12 @@ public Case getOrCreate(DashboardItemBody body) throws TransitionNotExecutableEx } LoggedUser loggedUser = ActorTransformer.toLoggedUser(userService.getLoggedOrSystem()); - itemCase = workflowService.createCase(petriNetService.getNewestVersionByIdentifier(DashboardItemConstants.PROCESS_IDENTIFIER).getStringId(), body.getName().getDefaultValue(), "", loggedUser).getCase(); + itemCase = workflowService.createCase(CreateCaseParams.with() + .petriNetIdentifier(DashboardItemConstants.PROCESS_IDENTIFIER) + .title(body.getName().getDefaultValue()) + .color("") + .loggedUser(loggedUser) + .build()).getCase(); ToDataSetOutcome outcome = body.toDataSet(); itemCase = setDataWithExecute(itemCase, DashboardItemConstants.TASK_CONFIGURE, outcome.getDataSet()); return itemCase; diff --git a/application-engine/src/main/java/com/netgrif/application/engine/menu/services/DashboardManagementServiceImpl.java b/application-engine/src/main/java/com/netgrif/application/engine/menu/services/DashboardManagementServiceImpl.java index 95a426e88e..c25b760df3 100644 --- a/application-engine/src/main/java/com/netgrif/application/engine/menu/services/DashboardManagementServiceImpl.java +++ b/application-engine/src/main/java/com/netgrif/application/engine/menu/services/DashboardManagementServiceImpl.java @@ -19,6 +19,7 @@ import com.netgrif.application.engine.objects.workflow.domain.menu.dashboard.DashboardManagementConstants; import com.netgrif.application.engine.petrinet.service.interfaces.IPetriNetService; import com.netgrif.application.engine.startup.ImportHelper; +import com.netgrif.application.engine.workflow.params.CreateCaseParams; 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; @@ -64,7 +65,12 @@ public Case createDashboardManagement(DashboardManagementBody body) throws Trans } addReferencedMenuItems(body); LoggedUser loggedUser = ActorTransformer.toLoggedUser(userService.getLoggedOrSystem()); - managementCase = workflowService.createCase(petriNetService.getNewestVersionByIdentifier(DashboardManagementConstants.PROCESS_IDENTIFIER).getStringId(), body.getName().getDefaultValue(), "", loggedUser).getCase(); + managementCase = workflowService.createCase(CreateCaseParams.with() + .petriNetIdentifier(DashboardManagementConstants.PROCESS_IDENTIFIER) + .title(body.getName().getDefaultValue()) + .color("") + .loggedUser(loggedUser) + .build()).getCase(); ToDataSetOutcome outcome = body.toDataSet(); managementCase = setDataWithExecute(managementCase, DashboardItemConstants.TASK_CONFIGURE, outcome.getDataSet()); return managementCase; diff --git a/application-engine/src/main/java/com/netgrif/application/engine/menu/services/MenuItemService.java b/application-engine/src/main/java/com/netgrif/application/engine/menu/services/MenuItemService.java index 0ade5316a6..f14075a6e3 100644 --- a/application-engine/src/main/java/com/netgrif/application/engine/menu/services/MenuItemService.java +++ b/application-engine/src/main/java/com/netgrif/application/engine/menu/services/MenuItemService.java @@ -25,6 +25,7 @@ import com.netgrif.application.engine.startup.runner.DefaultFiltersRunner; import com.netgrif.application.engine.startup.runner.FilterRunner; import com.netgrif.application.engine.startup.runner.MenuProcessRunner; +import com.netgrif.application.engine.workflow.params.CreateCaseParams; 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; @@ -667,7 +668,12 @@ protected void addConfigurationIntoDataSet(Case configurationCase, Map<String, M } protected Case createCase(String identifier, String title, LoggedUser loggedUser) { - return workflowService.createCaseByIdentifier(identifier, title, "", loggedUser).getCase(); + return workflowService.createCase(CreateCaseParams.with() + .petriNetIdentifier(identifier) + .title(title) + .color("") + .loggedUser(loggedUser) + .build()).getCase(); } protected Case setData(Case useCase, String transId, Map<String, Map<String, Object>> dataSet) { diff --git a/application-engine/src/main/java/com/netgrif/application/engine/startup/runner/DefaultFiltersRunner.java b/application-engine/src/main/java/com/netgrif/application/engine/startup/runner/DefaultFiltersRunner.java index 93a2618d03..f6abaaca5a 100644 --- a/application-engine/src/main/java/com/netgrif/application/engine/startup/runner/DefaultFiltersRunner.java +++ b/application-engine/src/main/java/com/netgrif/application/engine/startup/runner/DefaultFiltersRunner.java @@ -14,13 +14,12 @@ import com.netgrif.application.engine.adapter.spring.workflow.domain.QCase; import com.netgrif.application.engine.adapter.spring.workflow.domain.QTask; import com.netgrif.application.engine.objects.workflow.domain.Task; +import com.netgrif.application.engine.workflow.params.CreateCaseParams; 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.netgrif.application.engine.objects.auth.domain.LoggedUser; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; -import org.springframework.beans.factory.annotation.Value; import org.springframework.boot.ApplicationArguments; import org.springframework.stereotype.Component; @@ -438,7 +437,12 @@ private Optional<Case> createFilterCase(String title, String icon, String filter } try { - Case filterCase = this.workflowService.createCase(filterNet.getStringId(), title, null, ActorTransformer.toLoggedUser(loggedUser)).getCase(); + Case filterCase = this.workflowService.createCase(CreateCaseParams.with() + .petriNet(filterNet) + .title(title) + .color(null) + .loggedUser(ActorTransformer.toLoggedUser(loggedUser)) + .build()).getCase(); filterCase.setIcon(icon); filterCase = this.workflowService.save(filterCase); Task newFilterTask = this.taskService.searchOne(QTask.task.transitionId.eq(AUTO_CREATE_TRANSITION).and(QTask.task.caseId.eq(filterCase.getStringId()))); diff --git a/application-engine/src/main/java/com/netgrif/application/engine/workflow/domain/outcomes/ReloadTaskOutcome.java b/application-engine/src/main/java/com/netgrif/application/engine/workflow/domain/outcomes/ReloadTaskOutcome.java new file mode 100644 index 0000000000..492f62b8ee --- /dev/null +++ b/application-engine/src/main/java/com/netgrif/application/engine/workflow/domain/outcomes/ReloadTaskOutcome.java @@ -0,0 +1,11 @@ +package com.netgrif.application.engine.workflow.domain.outcomes; + +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@NoArgsConstructor +public class ReloadTaskOutcome { + private boolean anyTaskExecuted; + private boolean useCaseSaved; +} diff --git a/application-engine/src/main/java/com/netgrif/application/engine/workflow/params/CreateCaseParams.java b/application-engine/src/main/java/com/netgrif/application/engine/workflow/params/CreateCaseParams.java new file mode 100644 index 0000000000..4b07e5bfa7 --- /dev/null +++ b/application-engine/src/main/java/com/netgrif/application/engine/workflow/params/CreateCaseParams.java @@ -0,0 +1,54 @@ +package com.netgrif.application.engine.workflow.params; + +import com.netgrif.application.engine.objects.auth.domain.LoggedUser; +import com.netgrif.application.engine.objects.petrinet.domain.PetriNet; +import com.netgrif.application.engine.objects.workflow.domain.Case; +import lombok.Builder; +import lombok.Data; +import org.springframework.context.i18n.LocaleContextHolder; + +import java.util.HashMap; +import java.util.Locale; +import java.util.Map; +import java.util.function.Function; + +@Data +@Builder(builderMethodName = "with") +public class CreateCaseParams { + private String petriNetId; + private String petriNetIdentifier; + private PetriNet petriNet; + private String title; + private Function<Case, String> makeTitle; + private String color; + private LoggedUser loggedUser; + @Builder.Default + private Locale locale = LocaleContextHolder.getLocale(); + @Builder.Default + private Map<String, String> params = new HashMap<>(); + + public static class CreateCaseParamsBuilder { + /** + * Sets the {@link #title} and {@link #makeTitle} as well + * */ + public CreateCaseParams.CreateCaseParamsBuilder title(String title) { + this.title = title; + if (title != null) { + this.makeTitle = (u) -> title; + } else { + this.makeTitle = null; + } + return this; + } + + /** + * Sets the {@link #petriNet} as clone, {@link #petriNetIdentifier} and {@link #petriNetId} + * */ + public CreateCaseParams.CreateCaseParamsBuilder petriNet(PetriNet petriNet) { + this.petriNet = new com.netgrif.application.engine.adapter.spring.petrinet.domain.PetriNet((com.netgrif.application.engine.adapter.spring.petrinet.domain.PetriNet) petriNet); + this.petriNetIdentifier = petriNet.getIdentifier(); + this.petriNetId = petriNet.getStringId(); + return this; + } + } +} diff --git a/application-engine/src/main/java/com/netgrif/application/engine/workflow/service/DataService.java b/application-engine/src/main/java/com/netgrif/application/engine/workflow/service/DataService.java index b74c8337fc..f4f423792b 100644 --- a/application-engine/src/main/java/com/netgrif/application/engine/workflow/service/DataService.java +++ b/application-engine/src/main/java/com/netgrif/application/engine/workflow/service/DataService.java @@ -776,7 +776,7 @@ public Case applyFieldConnectedChanges(Case useCase, String fieldId) { public Case applyFieldConnectedChanges(Case useCase, Field field) { switch (field.getType()) { case USERLIST: - return workflowService.resolveUserRef(useCase); + return workflowService.resolveUserRef(useCase, true); default: return useCase; } diff --git a/application-engine/src/main/java/com/netgrif/application/engine/workflow/service/EventService.java b/application-engine/src/main/java/com/netgrif/application/engine/workflow/service/EventService.java index ae3644df19..0c76d49ecd 100644 --- a/application-engine/src/main/java/com/netgrif/application/engine/workflow/service/EventService.java +++ b/application-engine/src/main/java/com/netgrif/application/engine/workflow/service/EventService.java @@ -36,7 +36,7 @@ public EventService(FieldActionsRunner actionsRunner, IWorkflowService workflowS @Override public List<EventOutcome> runActions(List<Action> actions, Case useCase, Task task, Transition transition, Map<String, String> params) { - log.info("[" + useCase.getStringId() + "]: Running actions of transition " + transition.getStringId()); + log.info("[{}]: Running actions of transition {}", useCase.getStringId(), transition.getStringId()); return runActions(actions, useCase, Optional.of(task), params); } @@ -60,7 +60,7 @@ public List<EventOutcome> runActions(List<Action> actions, Case useCase, Optiona }); allOutcomes.addAll(outcomes); }); - if (useCase != null) { + if (useCase != null && !allOutcomes.isEmpty()) { workflowService.save(useCase); } return allOutcomes; @@ -114,9 +114,9 @@ public void runEventActionsOnChanged(Task task, SetDataEventOutcome outcome, Dat outcome.getChangedFields().forEach((s, changedField) -> { if (changedField.getAttributes().containsKey("value") && trigger == DataEventType.SET) { Field field = outcome.getCase().getField(s); - log.info("[" + outcome.getCase().getStringId() + "] " + outcome.getCase().getTitle() + ": Running actions on changed field " + s); - outcome.addOutcomes(processDataEvents(field, trigger, EventPhase.PRE, (Case) outcome.getCase(), (Task) outcome.getTask(), params)); - outcome.addOutcomes(processDataEvents(field, trigger, EventPhase.POST, (Case) outcome.getCase(), (Task) outcome.getTask(), params)); + log.info("[{}] {}: Running actions on changed field {}", outcome.getCase().getStringId(), outcome.getCase().getTitle(), s); + outcome.addOutcomes(processDataEvents(field, trigger, EventPhase.PRE, outcome.getCase(), outcome.getTask(), params)); + outcome.addOutcomes(processDataEvents(field, trigger, EventPhase.POST, outcome.getCase(), outcome.getTask(), params)); } }); } diff --git a/application-engine/src/main/java/com/netgrif/application/engine/workflow/service/FilterImportExportService.java b/application-engine/src/main/java/com/netgrif/application/engine/workflow/service/FilterImportExportService.java index 9dd6cea3f5..2edad2d2ed 100644 --- a/application-engine/src/main/java/com/netgrif/application/engine/workflow/service/FilterImportExportService.java +++ b/application-engine/src/main/java/com/netgrif/application/engine/workflow/service/FilterImportExportService.java @@ -26,6 +26,7 @@ import com.netgrif.application.engine.startup.ImportHelper; import com.netgrif.application.engine.utils.InputStreamToString; import com.netgrif.application.engine.objects.workflow.domain.*; +import com.netgrif.application.engine.workflow.params.CreateCaseParams; import com.netgrif.application.engine.workflow.service.interfaces.IDataService; import com.netgrif.application.engine.workflow.service.interfaces.IFilterImportExportService; import com.netgrif.application.engine.workflow.service.interfaces.ITaskService; @@ -100,12 +101,22 @@ public class FilterImportExportService implements IFilterImportExportService { @Override public void createFilterImport(AbstractUser author) { - workflowService.createCaseByIdentifier(IMPORT_NET_IDENTIFIER, "Import filters " + author.getName(), "", ActorTransformer.toLoggedUser(author)); + workflowService.createCase(CreateCaseParams.with() + .petriNetIdentifier(IMPORT_NET_IDENTIFIER) + .title("Import filters %s".formatted(author.getName())) + .color("") + .loggedUser(ActorTransformer.toLoggedUser(author)) + .build()); } @Override public void createFilterExport(AbstractUser author) { - workflowService.createCaseByIdentifier(EXPORT_NET_IDENTIFIER, "Export filters " + author.getName(), "", ActorTransformer.toLoggedUser(author)); + workflowService.createCase(CreateCaseParams.with() + .petriNetIdentifier(EXPORT_NET_IDENTIFIER) + .title("Export filters %s".formatted(author.getName())) + .color("") + .loggedUser(ActorTransformer.toLoggedUser(author)) + .build()); } /** diff --git a/application-engine/src/main/java/com/netgrif/application/engine/workflow/service/MenuImportExportService.java b/application-engine/src/main/java/com/netgrif/application/engine/workflow/service/MenuImportExportService.java index 1eb921882b..f9e02d59a3 100644 --- a/application-engine/src/main/java/com/netgrif/application/engine/workflow/service/MenuImportExportService.java +++ b/application-engine/src/main/java/com/netgrif/application/engine/workflow/service/MenuImportExportService.java @@ -10,6 +10,7 @@ import com.netgrif.application.engine.objects.auth.domain.ActorTransformer; import com.netgrif.application.engine.workflow.domain.FilterDeserializer; import com.netgrif.application.engine.workflow.domain.IllegalMenuFileException; +import com.netgrif.application.engine.workflow.params.CreateCaseParams; import com.netgrif.application.engine.workflow.service.interfaces.IMenuImportExportService; import com.netgrif.application.engine.workflow.service.interfaces.IWorkflowService; import com.netgrif.application.engine.objects.petrinet.domain.I18nString; @@ -260,12 +261,12 @@ public String createMenuItemCase(StringBuilder resultMessage, MenuEntry item, St }); } //Creating new Case of preference_filter_item net and setting its data... - Case menuItemCase = workflowService.createCase( - petriNetService.getNewestVersionByIdentifier("preference_filter_item").getStringId(), - item.getEntryName() + "_" + menuIdentifier, - "", - ActorTransformer.toLoggedUser(userService.getSystem()) - ).getCase(); + Case menuItemCase = workflowService.createCase(CreateCaseParams.with() + .petriNetIdentifier("preference_filter_item") + .title("%s_%s".formatted(item.getEntryName(), menuIdentifier)) + .color("") + .loggedUser(ActorTransformer.toLoggedUser(userService.getSystem())) + .build()).getCase(); QTask qTask = new QTask("task"); Task task = taskService.searchOne(qTask.transitionId.eq("init").and(qTask.caseId.eq(menuItemCase.getStringId()))); diff --git a/application-engine/src/main/java/com/netgrif/application/engine/workflow/service/TaskService.java b/application-engine/src/main/java/com/netgrif/application/engine/workflow/service/TaskService.java index ac21c61ae5..7cacf27c54 100644 --- a/application-engine/src/main/java/com/netgrif/application/engine/workflow/service/TaskService.java +++ b/application-engine/src/main/java/com/netgrif/application/engine/workflow/service/TaskService.java @@ -28,6 +28,7 @@ import com.netgrif.application.engine.objects.workflow.domain.eventoutcomes.EventOutcome; import com.netgrif.application.engine.objects.workflow.domain.eventoutcomes.dataoutcomes.SetDataEventOutcome; import com.netgrif.application.engine.objects.workflow.domain.eventoutcomes.taskoutcomes.*; +import com.netgrif.application.engine.workflow.domain.outcomes.ReloadTaskOutcome; import com.netgrif.application.engine.workflow.domain.repositories.TaskRepository; import com.netgrif.application.engine.objects.workflow.domain.triggers.TimeTrigger; import com.netgrif.application.engine.objects.workflow.domain.triggers.Trigger; @@ -54,6 +55,7 @@ import java.time.LocalDateTime; import java.util.*; +import java.util.concurrent.atomic.AtomicBoolean; import java.util.function.Predicate; import java.util.function.Supplier; import java.util.stream.Collectors; @@ -200,7 +202,7 @@ protected Case assignTaskToUser(AbstractUser user, Task task, String useCaseId) useCase = workflowService.save(useCase); save(task); - reloadTasks(useCase); + reloadTasks(useCase, false); useCase = workflowService.findOne(useCase.getStringId()); return useCase; } @@ -284,7 +286,7 @@ public FinishTaskEventOutcome finishTask(Task task, AbstractUser user, Map<Strin useCase = workflowService.findOne(useCase.getStringId()); save(task); - reloadTasks(useCase); + reloadTasks(useCase, false); useCase = workflowService.findOne(useCase.getStringId()); publisher.publishEvent(new FinishTaskEvent(outcome, EventPhase.PRE, user)); outcomes.addAll(eventService.runActions(transition.getPostFinishActions(), useCase, task, transition, params)); @@ -349,7 +351,7 @@ public CancelTaskEventOutcome cancelTask(Task task, AbstractUser user, Map<Strin useCase = evaluateRules(new CancelTaskEvent(outcome, EventPhase.PRE)); task = returnTokens(task, useCase.getStringId()); useCase = workflowService.findOne(useCase.getStringId()); - reloadTasks(useCase); + reloadTasks(useCase, false); useCase = workflowService.findOne(useCase.getStringId()); publisher.publishEvent(new CancelTaskEvent(outcome, EventPhase.POST, user)); outcomes.addAll(eventService.runActions(transition.getPostCancelActions(), useCase, task, transition, params)); @@ -443,7 +445,7 @@ public DelegateTaskEventOutcome delegateTask(LoggedUser loggedUser, String deleg useCase = evaluateRules(new DelegateTaskEvent(new DelegateTaskEventOutcome(useCase, task, outcomes), EventPhase.POST)); useCase = workflowService.findOne(useCase.getStringId()); - reloadTasks(useCase); + reloadTasks(useCase, false); outcome = new DelegateTaskEventOutcome(useCase, task, outcomes); addMessageToOutcome(transition, EventType.DELEGATE, outcome); @@ -484,12 +486,14 @@ protected Case evaluateRules(TaskEvent taskEvent) { * <td>Transition not executable</td><td>destroy task</td><td>no action</td> * </tr> * </table> + * todo javadoc */ @SuppressWarnings("StatementWithEmptyBody") @Override - public void reloadTasks(Case useCase) { - log.info("[" + useCase.getStringId() + "]: Reloading tasks in [" + useCase.getTitle() + "]"); + public ReloadTaskOutcome reloadTasks(Case useCase, boolean lazyCaseSave) { + log.info("[{}]: Reloading tasks in [{}]", useCase.getStringId(), useCase.getTitle()); PetriNet net = useCase.getPetriNet(); + ReloadTaskOutcome outcome = new ReloadTaskOutcome(); List<Task> newTasks = new ArrayList<>(); List<Task> disabledTasks = new ArrayList<>(); @@ -524,27 +528,31 @@ public void reloadTasks(Case useCase) { } save(newTasks); delete(disabledTasks, useCase); - useCase = workflowService.resolveUserRef(useCase); + useCase = workflowService.resolveUserRef(useCase, false); - for (Task task : newTasks) { - executeIfAutoTrigger(useCase, net, task); + if (!lazyCaseSave && (!newTasks.isEmpty() || !disabledTasks.isEmpty())) { + useCase = workflowService.save(useCase); + outcome.setUseCaseSaved(true); } - } - private void executeIfAutoTrigger(Case useCase, PetriNet net, Task task) { - try { - Transition transition = net.getTransition(task.getTransitionId()); - if (transition.hasAutoTrigger()) { + for (Task task : newTasks) { + if (shouldExecuteTask(net, task)) { + if (!outcome.isUseCaseSaved()) { + useCase = workflowService.save(useCase); + } executeTransition(task, useCase); + outcome.setAnyTaskExecuted(true); } - } catch (TaskNotFoundException e) { - log.info("Could not execute auto trigger on task [" + task.getStringId() + "],[" + task.getTransitionId() + "], reason: " + e.getMessage()); - } catch (Exception e) { - log.error(e.getMessage(), e); } + return outcome; } - boolean isExecutable(Transition transition, PetriNet net) { + protected boolean shouldExecuteTask(PetriNet net, Task task) { + Transition transition = net.getTransition(task.getTransitionId()); + return transition.hasAutoTrigger(); + } + + protected boolean isExecutable(Transition transition, PetriNet net) { Collection<Arc> arcsOfTransition = net.getArcsOfTransition(transition); if (arcsOfTransition == null) { @@ -556,7 +564,7 @@ boolean isExecutable(Transition transition, PetriNet net) { .allMatch(Arc::isExecutable); } - void finishExecution(Transition transition, String useCaseId) throws TransitionNotExecutableException { + protected void finishExecution(Transition transition, String useCaseId) throws TransitionNotExecutableException { Case useCase = workflowService.findOne(useCaseId); log.info("[" + useCaseId + "]: Finish execution of task [" + transition.getTitle() + "] in case [" + useCase.getTitle() + "]"); execute(transition, useCase, arc -> arc.getSource().equals(transition)); @@ -590,20 +598,20 @@ protected void execute(Transition transition, Case useCase, Predicate<Arc> predi workflowService.updateMarking(useCase); } - protected List<EventOutcome> executeTransition(Task task, Case useCase) { - log.info("[" + useCase.getStringId() + "]: executeTransition [" + task.getTransitionId() + "] in case [" + useCase.getTitle() + "]"); - List<EventOutcome> outcomes = new ArrayList<>(); + protected void executeTransition(Task task, Case useCase) { + log.info("[{}]: executeTransition [{}] in case [{}]", useCase.getStringId(), task.getTransitionId(), useCase.getTitle()); try { - log.info("assignTask [" + task.getTitle() + "] in case [" + useCase.getTitle() + "]"); - outcomes.add(assignTask(task.getStringId())); - log.info("getData [" + task.getTitle() + "] in case [" + useCase.getTitle() + "]"); - outcomes.add(dataService.getData(task.getStringId())); - log.info("finishTask [" + task.getTitle() + "] in case [" + useCase.getTitle() + "]"); - outcomes.add(finishTask(task.getStringId())); - } catch (TransitionNotExecutableException e) { - log.error("execution of task [" + task.getTitle() + "] in case [" + useCase.getTitle() + "] failed: ", e); + log.info("assignTask [{}] in case [{}]", task.getTitle(), useCase.getTitle()); + assignTask(task.getStringId()); + + log.info("getData [{}] in case [{}]", task.getTitle(), useCase.getTitle()); + dataService.getData(task.getStringId()); + + log.info("finishTask [{}] in case [{}]", task.getTitle(), useCase.getTitle()); + finishTask(task.getStringId()); + } catch (Exception e) { + log.error("Execution of task [{}] in case [{}] failed: ", task.getTitle(), useCase.getTitle(), e); } - return outcomes; } void validateData(Transition transition, Case useCase) { @@ -630,14 +638,8 @@ void validateData(Transition transition, Case useCase) { } protected void scheduleTaskExecution(Task task, LocalDateTime time, Case useCase) { - log.info("[" + useCase.getStringId() + "]: Task " + task.getTitle() + " scheduled to run at " + time.toString()); - scheduler.schedule(() -> { - try { - executeTransition(task, useCase); - } catch (Exception e) { - log.info("[" + useCase.getStringId() + "]: Scheduled task [" + task.getTitle() + "] of case [" + useCase.getTitle() + "] could not be executed: " + e); - } - }, DateUtils.localDateTimeToDate(time)); + log.info("[{}]: Task {} scheduled to run at {}", useCase.getStringId(), task.getTitle(), time); + scheduler.schedule(() -> executeTransition(task, useCase), DateUtils.localDateTimeToDate(time)); } @Override @@ -792,6 +794,9 @@ public Task save(Task task) { @Override public List<Task> save(List<Task> tasks) { + if (tasks.isEmpty()) { + return tasks; + } tasks = taskRepository.saveAll(tasks); tasks.forEach(task -> elasticTaskService.index(this.taskMappingService.transform(task))); return tasks; @@ -808,24 +813,33 @@ public void resolveUserRef(Case useCase) { @Override public Task resolveUserRef(Task task, Case useCase) { + AtomicBoolean isTaskModified = new AtomicBoolean(!task.getUsers().isEmpty() || !task.getNegativeViewUsers().isEmpty()); task.getUsers().clear(); task.getNegativeViewUsers().clear(); task.getUserRefs().forEach((id, permission) -> { List<String> userIds = getExistingUsers((UserListFieldValue) useCase.getDataSet().get(id).getValue()); - if (userIds != null && userIds.size() != 0 && permission.containsKey("view") && !permission.get("view")) { + if (userIds != null && !userIds.isEmpty() && permission.containsKey("view") && !permission.get("view")) { task.getNegativeViewUsers().addAll(userIds); - } else if (userIds != null && userIds.size() != 0) { + isTaskModified.set(true); + } else if (userIds != null && !userIds.isEmpty()) { task.addUsers(new HashSet<>(userIds), permission); + isTaskModified.set(true); } }); - task.resolveViewUsers(); - return taskRepository.save(task); + if (task.resolveViewUsers()) { + isTaskModified.set(true); + } + if (isTaskModified.get()) { + return taskRepository.save(task); + } + return task; } private List<String> getExistingUsers(UserListFieldValue userListValue) { if (userListValue == null) return null; - return userListValue.getUserValues().stream().map(UserFieldValue::getId) + return userListValue.getUserValues().stream() + .map(UserFieldValue::getId) .filter(id -> userService.findById(id, null) != null) .collect(Collectors.toList()); } @@ -916,8 +930,11 @@ private Page<Task> loadUsers(Page<Task> tasks) { @Override public void delete(List<Task> tasks, Case useCase) { + if (tasks.isEmpty()) { + return; + } workflowService.removeTasksFromCase(tasks, useCase); - log.info("[" + useCase.getStringId() + "]: Tasks of case " + useCase.getTitle() + " are being deleted"); + log.info("[{}]: Tasks of case {} are being deleted", useCase.getStringId(), useCase.getTitle()); taskRepository.deleteAll(tasks); tasks.forEach(t -> elasticTaskService.remove(t.getStringId())); } diff --git a/application-engine/src/main/java/com/netgrif/application/engine/workflow/service/WorkflowService.java b/application-engine/src/main/java/com/netgrif/application/engine/workflow/service/WorkflowService.java index 9fdb0e83f1..cf8bab91d5 100644 --- a/application-engine/src/main/java/com/netgrif/application/engine/workflow/service/WorkflowService.java +++ b/application-engine/src/main/java/com/netgrif/application/engine/workflow/service/WorkflowService.java @@ -30,7 +30,9 @@ import com.netgrif.application.engine.objects.workflow.domain.eventoutcomes.EventOutcome; 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.workflow.domain.outcomes.ReloadTaskOutcome; import com.netgrif.application.engine.workflow.domain.repositories.CaseRepository; +import com.netgrif.application.engine.workflow.params.CreateCaseParams; import com.netgrif.application.engine.workflow.service.interfaces.IEventService; import com.netgrif.application.engine.objects.workflow.service.InitValueExpressionEvaluator; import com.netgrif.application.engine.workflow.service.interfaces.ITaskService; @@ -42,7 +44,6 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.ApplicationEventPublisher; import org.springframework.context.annotation.Lazy; -import org.springframework.context.i18n.LocaleContextHolder; import org.springframework.data.domain.Page; import org.springframework.data.domain.PageImpl; import org.springframework.data.domain.PageRequest; @@ -54,6 +55,7 @@ import java.time.LocalDateTime; import java.util.*; +import java.util.concurrent.atomic.AtomicBoolean; import java.util.function.Function; import java.util.stream.Collectors; import java.util.stream.LongStream; @@ -131,7 +133,7 @@ public Case save(Case useCase) { setImmediateDataFields(useCase); elasticCaseService.indexNow(this.caseMappingService.transform(useCase)); } catch (Exception e) { - log.error("Indexing failed [" + useCase.getStringId() + "]", e); + log.error("Indexing failed [{}]", useCase.getStringId(), e); } return useCase; } @@ -169,7 +171,7 @@ public List<Case> findAllById(List<String> ids) { List<Case> cases = repository.findAllByObjectIdsIn(objectIds).stream() .filter(Objects::nonNull) - .collect(Collectors.toList()); + .toList(); Map<String, Case> caseMap = cases.stream() .collect(Collectors.toMap(Case::getStringId, caze -> caze)); @@ -227,26 +229,39 @@ public long count(Map<String, Object> request, LoggedUser user, Locale locale) { } @Override - public Case resolveUserRef(Case useCase) { + public Case resolveUserRef(Case useCase, boolean canSaveUseCase) { + AtomicBoolean isUseCaseModified = new AtomicBoolean(!useCase.getUsers().isEmpty() || !useCase.getNegativeViewUsers().isEmpty()); useCase.getUsers().clear(); useCase.getNegativeViewUsers().clear(); useCase.getUserRefs().forEach((id, permission) -> { - resolveUserRefPermissions(useCase, id, permission); + if (resolveUserRefPermissions(useCase, id, permission)) { + isUseCaseModified.set(true); + } }); - useCase.resolveViewUsers(); + if (useCase.resolveViewUsers()) { + isUseCaseModified.set(true); + } taskService.resolveUserRef(useCase); - return save(useCase); + if (isUseCaseModified.get() && canSaveUseCase) { + return save(useCase); + } + return useCase; } - private void resolveUserRefPermissions(Case useCase, String userListId, Map<String, Boolean> permission) { + /** + * todo javadoc + * */ + private boolean resolveUserRefPermissions(Case useCase, String userListId, Map<String, Boolean> permission) { List<String> userIds = getExistingUsers((UserListFieldValue) useCase.getDataSet().get(userListId).getValue()); - if (userIds != null && userIds.size() != 0) { + if (userIds != null && !userIds.isEmpty()) { if (permission.containsKey("view") && !permission.get("view")) { - useCase.getNegativeViewUsers().addAll(userIds); + return useCase.getNegativeViewUsers().addAll(userIds); } else { useCase.addUsers(new HashSet<>(userIds), permission); + return true; } } + return false; } private List<String> getExistingUsers(UserListFieldValue userListValue) { @@ -257,115 +272,93 @@ private List<String> getExistingUsers(UserListFieldValue userListValue) { .collect(Collectors.toList()); } - @Override - public CreateCaseEventOutcome createCase(String netId, String title, String color, LoggedUser user, Locale locale, Map<String, String> params) { - if (locale == null) { - locale = LocaleContextHolder.getLocale(); - } - if (title == null) { - return this.createCase(netId, resolveDefaultCaseTitle(netId, locale, params), color, user, params); - } - return this.createCase(netId, title, color, user, params); - } + public CreateCaseEventOutcome createCase(CreateCaseParams createCaseParams) { + fillMissingAttributes(createCaseParams); + PetriNet petriNet = createCaseParams.getPetriNet(); - @Override - public CreateCaseEventOutcome createCase(String netId, String title, String color, LoggedUser user, Locale locale) { - return this.createCase(netId, title, color, user, locale, new HashMap<>()); - } + CreateCaseEventOutcome outcome = new CreateCaseEventOutcome(); + outcome.addOutcomes(eventService.runActions(petriNet.getPreCreateActions(), null, Optional.empty(), + createCaseParams.getParams())); - @Override - public CreateCaseEventOutcome createCase(String netId, String title, String color, LoggedUser user, Map<String, String> params) { - return createCase(netId, (u) -> title, color, user, params); - } + publisher.publishEvent(new CreateCaseEvent(outcome, EventPhase.PRE)); - @Override - public CreateCaseEventOutcome createCase(String netId, String title, String color, LoggedUser user) { - return this.createCase(netId, (u) -> title, color, user); - } + Case useCase = createCaseObject(createCaseParams); + log.info("[{}]: Case {} created", useCase.getStringId(), useCase.getTitle()); - @Override - public CreateCaseEventOutcome createCaseByIdentifier(String identifier, String title, String color, LoggedUser user, Locale locale, Map<String, String> params) { - PetriNet net = petriNetService.getNewestVersionByIdentifier(identifier); - if (net == null) { - throw new IllegalArgumentException("Petri net with identifier [" + identifier + "] does not exist."); + ReloadTaskOutcome reloadTaskOutcome = taskService.reloadTasks(useCase, true); + if (reloadTaskOutcome.isAnyTaskExecuted()) { + useCase = findOne(useCase.getStringId()); + } + boolean anyTaskDataFieldInitialized = resolveTaskRefs(useCase); + if (anyTaskDataFieldInitialized || !reloadTaskOutcome.isUseCaseSaved()) { + save(useCase); } - return this.createCase(net.getStringId(), title != null && !title.equals("") ? title : net.getDefaultCaseName().getTranslation(locale), color, user, params); - } - @Override - public CreateCaseEventOutcome createCaseByIdentifier(String identifier, String title, String color, LoggedUser user, Locale locale) { - return this.createCaseByIdentifier(identifier, title, color, user, locale, new HashMap<>()); - } - @Override - public CreateCaseEventOutcome createCaseByIdentifier(String identifier, String title, String color, LoggedUser user, Map<String, String> params) { - PetriNet net = petriNetService.getNewestVersionByIdentifier(identifier); - if (net == null) { - throw new IllegalArgumentException("Petri net with identifier [" + identifier + "] does not exist."); - } - return this.createCase(net.getStringId(), title, color, user, params); - } + outcome.addOutcomes(eventService.runActions(petriNet.getPostCreateActions(), useCase, Optional.empty(), + createCaseParams.getParams())); - @Override - public CreateCaseEventOutcome createCaseByIdentifier(String identifier, String title, String color, LoggedUser user) { - PetriNet net = petriNetService.getNewestVersionByIdentifier(identifier); - if (net == null) { - throw new IllegalArgumentException("Petri net with identifier [" + identifier + "] does not exist."); - } - return this.createCase(net.getStringId(), title, color, user); - } + useCase = evaluateRules(new CreateCaseEvent(new CreateCaseEventOutcome(useCase, outcome.getOutcomes()), EventPhase.POST)); - public CreateCaseEventOutcome createCase(String netId, Function<Case, String> makeTitle, String color, LoggedUser user) { - return this.createCase(netId, makeTitle, color, user, new HashMap<>()); + outcome.setCase(setImmediateDataFields(useCase)); + addMessageToOutcome(petriNet, CaseEventType.CREATE, outcome); + publisher.publishEvent(new CreateCaseEvent(outcome, EventPhase.POST)); + + return outcome; } - public CreateCaseEventOutcome createCase(String netId, Function<Case, String> makeTitle, String color, LoggedUser user, Map<String, String> params) { - // TODO: impersonation -// LoggedUser loggedOrImpersonated = user.getSelfOrImpersonated(); - LoggedUser loggedOrImpersonated = user; - PetriNet petriNet = new com.netgrif.application.engine.adapter.spring.petrinet.domain.PetriNet((com.netgrif.application.engine.adapter.spring.petrinet.domain.PetriNet) petriNetService.get(new ObjectId(netId))); -// int rulesExecuted; + /** + * Creates pure {@link Case} object without any {@link Task} object initialized. + * + * @param createCaseParams parameters for object creation + * + * @return created {@link Case} object + * */ + private Case createCaseObject(CreateCaseParams createCaseParams) { + PetriNet petriNet = new com.netgrif.application.engine.adapter.spring.petrinet.domain.PetriNet((com.netgrif.application.engine.adapter.spring.petrinet.domain.PetriNet) createCaseParams.getPetriNet()); Case useCase = new com.netgrif.application.engine.adapter.spring.workflow.domain.Case(petriNet); - useCase.populateDataSet(initValueExpressionEvaluator, params); - useCase.setColor(color); - useCase.setAuthor(ActorTransformer.toActorRef(loggedOrImpersonated)); + useCase.populateDataSet(initValueExpressionEvaluator, createCaseParams.getParams()); + useCase.setColor(createCaseParams.getColor()); + useCase.setAuthor(ActorTransformer.toActorRef(createCaseParams.getLoggedUser())); // TODO: impersonation useCase.setCreationDate(LocalDateTime.now()); - useCase.setTitle(makeTitle.apply(useCase)); - - CreateCaseEventOutcome outcome = new CreateCaseEventOutcome(); - outcome.addOutcomes(eventService.runActions(petriNet.getPreCreateActions(), null, Optional.empty(), params)); - //evaluateRules(new CreateCaseEvent(new CreateCaseEventOutcome(null, outcome.getOutcomes()), EventPhase.PRE)); - - publisher.publishEvent(new CreateCaseEvent(outcome, EventPhase.PRE)); - log.info("[" + useCase.getStringId() + "]: Case " + useCase.getTitle() + " created"); + useCase.setTitle(createCaseParams.getMakeTitle().apply(useCase)); useCase.getPetriNet().initializeArcs(useCase.getDataSet()); - taskService.reloadTasks(useCase); - useCase = findOne(useCase.getStringId()); - resolveTaskRefs(useCase); - useCase = findOne(useCase.getStringId()); - outcome.addOutcomes(eventService.runActions(petriNet.getPostCreateActions(), useCase, Optional.empty(), params)); - useCase = findOne(useCase.getStringId()); - useCase = evaluateRules(new CreateCaseEvent(new CreateCaseEventOutcome(useCase, outcome.getOutcomes()), EventPhase.POST)); -// rulesExecuted = ruleEngine.evaluateRules(useCase, new CaseCreatedFact(useCase.getStringId(), EventPhase.POST)); -// if (rulesExecuted > 0) { -// useCase = save(useCase); -// } - outcome.setCase(setImmediateDataFields(useCase)); - addMessageToOutcome(petriNet, CaseEventType.CREATE, outcome); - publisher.publishEvent(new CreateCaseEvent(outcome, EventPhase.POST)); - return outcome; + return useCase; } - protected Function<Case, String> resolveDefaultCaseTitle(String netId, Locale locale, Map<String, String> params) { - PetriNet petriNet = new com.netgrif.application.engine.adapter.spring.petrinet.domain.PetriNet((com.netgrif.application.engine.adapter.spring.petrinet.domain.PetriNet) petriNetService.get(new ObjectId(netId))); + private void fillMissingAttributes(CreateCaseParams createCaseParams) throws IllegalArgumentException { + if (createCaseParams.getLoggedUser() == null) { + throw new IllegalArgumentException("Logged user cannot be null on Case creation."); + } + if (createCaseParams.getPetriNet() == null) { + PetriNet petriNet; + if (createCaseParams.getPetriNetId() != null) { + petriNet = new com.netgrif.application.engine.adapter.spring.petrinet.domain.PetriNet((com.netgrif.application.engine.adapter.spring.petrinet.domain.PetriNet) petriNetService.get(new ObjectId(createCaseParams.getPetriNetId()))); + } else if (createCaseParams.getPetriNetIdentifier() != null) { + petriNet = new com.netgrif.application.engine.adapter.spring.petrinet.domain.PetriNet((com.netgrif.application.engine.adapter.spring.petrinet.domain.PetriNet) petriNetService.getNewestVersionByIdentifier(createCaseParams.getPetriNetIdentifier())); + } else { + throw new IllegalArgumentException("Could not find the PetriNet for the Case from provided inputs on case creation."); + } + createCaseParams.setPetriNet(petriNet); + } + if (createCaseParams.getMakeTitle() == null && createCaseParams.getPetriNet() != null) { + createCaseParams.setMakeTitle(resolveDefaultCaseTitle(createCaseParams)); + } + } + + private Function<Case, String> resolveDefaultCaseTitle(CreateCaseParams createCaseParams) { + Locale locale = createCaseParams.getLocale(); + PetriNet petriNet = createCaseParams.getPetriNet(); Function<Case, String> makeTitle; if (petriNet.hasDynamicCaseName()) { - makeTitle = (u) -> initValueExpressionEvaluator.evaluateCaseName(u, petriNet.getDefaultCaseNameExpression(), params).getTranslation(locale); + makeTitle = (u) -> initValueExpressionEvaluator.evaluateCaseName(u, petriNet.getDefaultCaseNameExpression(), + createCaseParams.getParams()).getTranslation(locale); } else { - makeTitle = (u) -> petriNet.getDefaultCaseName().getTranslation(locale); + makeTitle = (u) -> petriNet.getTranslatedDefaultCaseName(locale); } + return makeTitle; } @@ -376,7 +369,7 @@ public Page<Case> findAllByAuthor(String authorId, String petriNet, Pageable pag query = (BasicQuery) query.with(pageable); List<Case> cases = mongoTemplate.find(query, Case.class); decryptDataSets(cases); - return setImmediateDataFields(new PageImpl<Case>(cases, pageable, mongoTemplate.count(new BasicQuery(queryString, "{_id:1}"), Case.class))); + return setImmediateDataFields(new PageImpl<>(cases, pageable, mongoTemplate.count(new BasicQuery(queryString, "{_id:1}"), Case.class))); } @Override @@ -403,7 +396,8 @@ public DeleteCaseEventOutcome deleteCase(Case useCase, Map<String, String> param publisher.publishEvent(new DeleteCaseEvent(outcome, EventPhase.PRE)); useCase = ((Evaluator<DeleteCaseEvent, Case>) evaluationService.getEvaluator("default")).apply(new DeleteCaseEvent(outcome, EventPhase.PRE)); } - log.info("[" + useCase.getStringId() + "]: User [" + userService.getLoggedOrSystem().getStringId() + "] is deleting case " + useCase.getTitle()); + log.info("[{}]: User [{}] is deleting case {}", useCase.getStringId(), userService.getLoggedOrSystem().getStringId(), + useCase.getTitle()); taskService.deleteTasksByCase(useCase.getStringId()); repository.delete(useCase); @@ -433,7 +427,8 @@ public void deleteInstancesOfPetriNet(PetriNet net) { @Override public void deleteInstancesOfPetriNet(PetriNet net, boolean force) { - log.info("[" + net.getStringId() + "]: User " + userService.getLoggedOrSystem().getStringId() + " is deleting all cases and tasks of Petri net " + net.getIdentifier() + " version " + net.getVersion().toString()); + log.info("[{}]: User {} is deleting all cases and tasks of Petri net {} version {}", net.getStringId(), + userService.getLoggedOrSystem().getStringId(), net.getIdentifier(), net.getVersion().toString()); List<Case> cases = this.searchAll(QCase.case$.petriNetObjectId.eq(net.getObjectId())).getContent(); if (!cases.isEmpty()) { cases.forEach(aCase -> deleteCase(aCase, new HashMap<>(), force)); @@ -508,19 +503,28 @@ public void setPetriNet(Case useCase) { model.initializeArcs(useCase.getDataSet()); } - private void resolveTaskRefs(Case useCase) { - useCase.getPetriNet().getDataSet().values().stream().filter(f -> f instanceof TaskField).map(TaskField.class::cast).forEach(field -> { - if (field.getDefaultValue() != null && !field.getDefaultValue().isEmpty() && useCase.getDataField(field.getStringId()).getValue() != null && - useCase.getDataField(field.getStringId()).getValue().equals(field.getDefaultValue())) { - useCase.getDataField(field.getStringId()).setValue(new ArrayList<>()); - List<TaskPair> taskPairList = useCase.getTasks().stream().filter(t -> - (field.getDefaultValue().contains(t.getTransition()))).collect(Collectors.toList()); - if (!taskPairList.isEmpty()) { - taskPairList.forEach(pair -> ((List<String>) useCase.getDataField(field.getStringId()).getValue()).add(pair.getTask())); - } - } - }); - save(useCase); + /** + * todo javadoc + * */ + protected boolean resolveTaskRefs(Case useCase) { + AtomicBoolean anyDataFieldChanged = new AtomicBoolean(false); + useCase.getPetriNet().getDataSet().values().stream() + .filter(field -> field instanceof TaskField) + .map(TaskField.class::cast) + .forEach(taskField -> { + DataField taskDataField = useCase.getDataField(taskField.getStringId()); + if (taskField.getDefaultValue() != null && !taskField.getDefaultValue().isEmpty() && taskDataField.getValue() != null + && taskDataField.getValue().equals(taskField.getDefaultValue())) { + taskDataField.setValue(new ArrayList<>()); + useCase.getTasks().stream() + .filter(taskPair -> (taskField.getDefaultValue().contains(taskPair.getTransition()))) + .forEach(taskPair -> { + ((List<String>) taskDataField.getValue()).add(taskPair.getTask()); + anyDataFieldChanged.set(true); + }); + } + }); + return anyDataFieldChanged.get(); } // @Deprecated @@ -551,7 +555,7 @@ private void setImmediateDataFieldsReadOnly(Case useCase) { Field clone = fieldFactory.buildImmediateField(useCase, fieldId); immediateData.add(clone); } catch (Exception e) { - log.error("Could not built immediate field [" + fieldId + "]"); + log.error("Could not built immediate field [{}]", fieldId); } }); LongStream.range(0L, immediateData.size()).forEach(index -> immediateData.get((int) index).setOrder(index)); diff --git a/application-engine/src/main/java/com/netgrif/application/engine/workflow/service/interfaces/ITaskService.java b/application-engine/src/main/java/com/netgrif/application/engine/workflow/service/interfaces/ITaskService.java index e8bf1f73ed..c41d2ad4f2 100644 --- a/application-engine/src/main/java/com/netgrif/application/engine/workflow/service/interfaces/ITaskService.java +++ b/application-engine/src/main/java/com/netgrif/application/engine/workflow/service/interfaces/ITaskService.java @@ -11,6 +11,7 @@ import com.netgrif.application.engine.objects.workflow.domain.eventoutcomes.taskoutcomes.CancelTaskEventOutcome; import com.netgrif.application.engine.objects.workflow.domain.eventoutcomes.taskoutcomes.DelegateTaskEventOutcome; import com.netgrif.application.engine.objects.workflow.domain.eventoutcomes.taskoutcomes.FinishTaskEventOutcome; +import com.netgrif.application.engine.workflow.domain.outcomes.ReloadTaskOutcome; import com.netgrif.application.engine.workflow.web.requestbodies.TaskSearchRequest; import com.netgrif.application.engine.workflow.web.responsebodies.TaskReference; import org.springframework.data.domain.Page; @@ -20,7 +21,7 @@ public interface ITaskService { - void reloadTasks(Case useCase); + ReloadTaskOutcome reloadTasks(Case useCase, boolean lazyCaseSave); Task findOne(String taskId); diff --git a/application-engine/src/main/java/com/netgrif/application/engine/workflow/service/interfaces/IWorkflowService.java b/application-engine/src/main/java/com/netgrif/application/engine/workflow/service/interfaces/IWorkflowService.java index 74d8eab44a..2c62d1899d 100644 --- a/application-engine/src/main/java/com/netgrif/application/engine/workflow/service/interfaces/IWorkflowService.java +++ b/application-engine/src/main/java/com/netgrif/application/engine/workflow/service/interfaces/IWorkflowService.java @@ -7,6 +7,7 @@ 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.workflow.params.CreateCaseParams; import com.querydsl.core.types.Predicate; import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; @@ -27,23 +28,9 @@ public interface IWorkflowService { Page<Case> getAll(Pageable pageable); - Case resolveUserRef(Case useCase); + Case resolveUserRef(Case useCase, boolean canSaveUseCase); - CreateCaseEventOutcome createCase(String netId, String title, String color, LoggedUser user, Locale locale, Map<String, String> params); - - CreateCaseEventOutcome createCase(String netId, String title, String color, LoggedUser user, Locale locale); - - CreateCaseEventOutcome createCase(String netId, String title, String color, LoggedUser user, Map<String, String> params); - - CreateCaseEventOutcome createCase(String netId, String title, String color, LoggedUser user); - - CreateCaseEventOutcome createCaseByIdentifier(String identifier, String title, String color, LoggedUser user, Map<String, String> params); - - CreateCaseEventOutcome createCaseByIdentifier(String identifier, String title, String color, LoggedUser user); - - CreateCaseEventOutcome createCaseByIdentifier(String identifier, String title, String color, LoggedUser user, Locale locale, Map<String, String> params); - - CreateCaseEventOutcome createCaseByIdentifier(String identifier, String title, String color, LoggedUser user, Locale locale); + CreateCaseEventOutcome createCase(CreateCaseParams createCaseParams); Page<Case> findAllByAuthor(String authorId, String petriNet, Pageable pageable); diff --git a/application-engine/src/main/java/com/netgrif/application/engine/workflow/web/PublicWorkflowController.java b/application-engine/src/main/java/com/netgrif/application/engine/workflow/web/PublicWorkflowController.java index 0683e405e4..ec13682427 100644 --- a/application-engine/src/main/java/com/netgrif/application/engine/workflow/web/PublicWorkflowController.java +++ b/application-engine/src/main/java/com/netgrif/application/engine/workflow/web/PublicWorkflowController.java @@ -7,6 +7,7 @@ import com.netgrif.application.engine.objects.workflow.domain.eventoutcomes.caseoutcomes.CreateCaseEventOutcome; import com.netgrif.application.engine.workflow.domain.eventoutcomes.response.EventOutcomeWithMessage; import com.netgrif.application.engine.workflow.domain.eventoutcomes.response.EventOutcomeWithMessageResource; +import com.netgrif.application.engine.workflow.params.CreateCaseParams; import com.netgrif.application.engine.workflow.service.interfaces.IWorkflowService; import com.netgrif.application.engine.workflow.web.requestbodies.CreateCaseBody; import io.swagger.v3.oas.annotations.Operation; @@ -49,11 +50,17 @@ public PublicWorkflowController(IWorkflowService workflowService, UserService us public EntityModel<EventOutcomeWithMessage> createCase(@RequestBody CreateCaseBody body, Locale locale) { LoggedUser loggedUser = ActorTransformer.toLoggedUser(userService.getLoggedUser()); try { - CreateCaseEventOutcome outcome = this.workflowService.createCase(body.netId, body.title, body.color, loggedUser, locale); + CreateCaseEventOutcome outcome = this.workflowService.createCase(CreateCaseParams.with() + .petriNetId(body.netId) + .title(body.title) + .color(body.color) + .loggedUser(loggedUser) + .locale(locale) + .build()); return EventOutcomeWithMessageResource.successMessage("Case created successfully", LocalisedEventOutcomeFactory.from(outcome, locale)); } catch (Exception e) { - log.error("Creating case failed:" + e.getMessage(), e); + log.error("Creating case failed: {}", e.getMessage(), e); return EventOutcomeWithMessageResource.errorMessage("Creating case failed: " + e.getMessage()); } } diff --git a/application-engine/src/main/java/com/netgrif/application/engine/workflow/web/WorkflowController.java b/application-engine/src/main/java/com/netgrif/application/engine/workflow/web/WorkflowController.java index bf93216113..15e087e548 100644 --- a/application-engine/src/main/java/com/netgrif/application/engine/workflow/web/WorkflowController.java +++ b/application-engine/src/main/java/com/netgrif/application/engine/workflow/web/WorkflowController.java @@ -11,6 +11,7 @@ import com.netgrif.application.engine.objects.workflow.domain.eventoutcomes.caseoutcomes.DeleteCaseEventOutcome; import com.netgrif.application.engine.workflow.domain.eventoutcomes.response.EventOutcomeWithMessage; import com.netgrif.application.engine.workflow.domain.eventoutcomes.response.EventOutcomeWithMessageResource; +import com.netgrif.application.engine.workflow.params.CreateCaseParams; import com.netgrif.application.engine.workflow.service.FileFieldInputStream; import com.netgrif.application.engine.workflow.service.interfaces.IDataService; import com.netgrif.application.engine.workflow.service.interfaces.ITaskService; @@ -85,7 +86,13 @@ public class WorkflowController { public EntityModel<EventOutcomeWithMessage> createCase(@RequestBody CreateCaseBody body, Authentication auth, Locale locale) { LoggedUser loggedUser = (LoggedUser) auth.getPrincipal(); try { - CreateCaseEventOutcome outcome = workflowService.createCase(body.netId, body.title, body.color, loggedUser, locale); + CreateCaseEventOutcome outcome = workflowService.createCase(CreateCaseParams.with() + .petriNetId(body.netId) + .title(body.title) + .color(body.color) + .loggedUser(loggedUser) + .locale(locale) + .build()); return EventOutcomeWithMessageResource.successMessage("Case with id " + outcome.getCase().getStringId() + " was created succesfully", LocalisedEventOutcomeFactory.from(outcome, locale)); } catch (Exception e) { // TODO: 5. 2. 2017 change to custom exception @@ -180,13 +187,13 @@ public PagedModel<CaseResource> findAllByAuthor(@PathVariable("id") String autho }) public MessageResource reloadTasks(@PathVariable("id") String caseId) { try { - caseId = URLDecoder.decode(caseId, StandardCharsets.UTF_8.name()); + caseId = URLDecoder.decode(caseId, StandardCharsets.UTF_8); Case aCase = workflowService.findOne(caseId); - taskService.reloadTasks(aCase); + taskService.reloadTasks(aCase, false); return MessageResource.successMessage("Task reloaded in case [" + caseId + "]"); } catch (Exception e) { - log.error("Reloading tasks of case [" + caseId + "] failed:", e); + log.error("Reloading tasks of case [{}] failed:", caseId, e); return MessageResource.errorMessage("Reloading tasks in case " + caseId + " has failed!"); } } diff --git a/application-engine/src/test/java/com/netgrif/application/engine/importer/ImporterTest.java b/application-engine/src/test/java/com/netgrif/application/engine/importer/ImporterTest.java index 589a455910..58870e97e7 100644 --- a/application-engine/src/test/java/com/netgrif/application/engine/importer/ImporterTest.java +++ b/application-engine/src/test/java/com/netgrif/application/engine/importer/ImporterTest.java @@ -13,6 +13,7 @@ import com.netgrif.application.engine.utils.FullPageRequest; import com.netgrif.application.engine.objects.workflow.domain.eventoutcomes.caseoutcomes.CreateCaseEventOutcome; import com.netgrif.application.engine.objects.workflow.domain.eventoutcomes.petrinetoutcomes.ImportPetriNetEventOutcome; +import com.netgrif.application.engine.workflow.params.CreateCaseParams; import com.netgrif.application.engine.workflow.service.interfaces.IWorkflowService; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -80,7 +81,12 @@ public void priorityTest() throws MissingPetriNetMetaDataException, IOException, .build()); assert outcome.getNet() != null; - CreateCaseEventOutcome caseOutcome = workflowService.createCase(outcome.getNet().getStringId(), outcome.getNet().getTitle().getDefaultValue(), "color", superCreator.getLoggedSuper()); + CreateCaseEventOutcome caseOutcome = workflowService.createCase(CreateCaseParams.with() + .petriNet(outcome.getNet()) + .title(outcome.getNet().getTitle().getDefaultValue()) + .color("color") + .loggedUser(superCreator.getLoggedSuper()) + .build()); assert caseOutcome.getCase() != null; } diff --git a/application-engine/src/test/java/com/netgrif/application/engine/workflow/WorkflowPerformanceTest.java b/application-engine/src/test/java/com/netgrif/application/engine/workflow/WorkflowPerformanceTest.java index 8621a66a25..e773d199a3 100644 --- a/application-engine/src/test/java/com/netgrif/application/engine/workflow/WorkflowPerformanceTest.java +++ b/application-engine/src/test/java/com/netgrif/application/engine/workflow/WorkflowPerformanceTest.java @@ -7,6 +7,7 @@ import com.netgrif.application.engine.petrinet.params.ImportPetriNetParams; import com.netgrif.application.engine.petrinet.service.interfaces.IPetriNetService; import com.netgrif.application.engine.startup.runner.SuperCreatorRunner; +import com.netgrif.application.engine.workflow.params.CreateCaseParams; import com.netgrif.application.engine.workflow.service.WorkflowService; import lombok.extern.slf4j.Slf4j; import org.junit.jupiter.api.BeforeEach; @@ -53,8 +54,11 @@ public void testCreatePerformance() throws IOException, MissingPetriNetMetaDataE .releaseType(VersionType.MAJOR) .author(superCreatorRunner.getLoggedSuper()) .build()).getNet(); - iterateAndShowAvgTime("createCase", () -> workflowService.createCase(net.getStringId(), null, null, - superCreatorRunner.getLoggedSuper(), Locale.getDefault()), 1000); + iterateAndShowAvgTime("createCase", () -> workflowService.createCase(CreateCaseParams.with() + .petriNet(net) + .loggedUser(superCreatorRunner.getLoggedSuper()) + .locale(Locale.getDefault()) + .build()), 1000); } @Test @@ -64,8 +68,11 @@ public void testCreate2Performance() throws IOException, MissingPetriNetMetaData .releaseType(VersionType.MAJOR) .author(superCreatorRunner.getLoggedSuper()) .build()).getNet(); - iterateAndShowAvgTime("createCaseWithAction", () -> workflowService.createCase(net.getStringId(), null, null, - superCreatorRunner.getLoggedSuper(), Locale.getDefault()), 1000); + iterateAndShowAvgTime("createCaseWithAction", () -> workflowService.createCase(CreateCaseParams.with() + .petriNet(net) + .loggedUser(superCreatorRunner.getLoggedSuper()) + .locale(Locale.getDefault()) + .build()), 1000); } @Test diff --git a/application-engine/src/test/java/com/netgrif/application/engine/workflow/service/TaskServiceTest.java b/application-engine/src/test/java/com/netgrif/application/engine/workflow/service/TaskServiceTest.java index 96686e79f8..c1c4604747 100644 --- a/application-engine/src/test/java/com/netgrif/application/engine/workflow/service/TaskServiceTest.java +++ b/application-engine/src/test/java/com/netgrif/application/engine/workflow/service/TaskServiceTest.java @@ -28,6 +28,7 @@ import com.netgrif.application.engine.objects.workflow.domain.eventoutcomes.caseoutcomes.CreateCaseEventOutcome; import com.netgrif.application.engine.workflow.domain.repositories.CaseRepository; import com.netgrif.application.engine.workflow.domain.repositories.TaskRepository; +import com.netgrif.application.engine.workflow.params.CreateCaseParams; import com.netgrif.application.engine.workflow.service.interfaces.ITaskService; import com.netgrif.application.engine.workflow.service.interfaces.IWorkflowService; import org.bson.types.ObjectId; @@ -101,7 +102,12 @@ public void setUp() throws Exception { .author(superCreator.getLoggedSuper()) .build()); PetriNet net = petriNetRepository.findAll().get(0); - workflowService.createCase(net.getStringId(), "Storage Unit", "color", mock.mockLoggedUser()); + workflowService.createCase(CreateCaseParams.with() + .petriNet(net) + .title("Storage Unit") + .color("color") + .loggedUser(mock.mockLoggedUser()) + .build()); } @Test @@ -112,7 +118,12 @@ public void resetArcTest() throws TransitionNotExecutableException, MissingPetri .author(superCreator.getLoggedSuper()) .build()).getNet(); LoggedUser loggedUser = mock.mockLoggedUser(); - CreateCaseEventOutcome outcome = workflowService.createCase(net.getStringId(), "Reset test", "color", loggedUser); + CreateCaseEventOutcome outcome = workflowService.createCase(CreateCaseParams.with() + .petriNet(net) + .title("Reset test") + .color("color") + .loggedUser(loggedUser) + .build()); User user = new User(); user.setFirstName("name"); user.setPassword("password"); diff --git a/application-engine/src/test/java/com/netgrif/application/engine/workflow/web/VariableArcsTest.java b/application-engine/src/test/java/com/netgrif/application/engine/workflow/web/VariableArcsTest.java index 643a714380..925b151f37 100644 --- a/application-engine/src/test/java/com/netgrif/application/engine/workflow/web/VariableArcsTest.java +++ b/application-engine/src/test/java/com/netgrif/application/engine/workflow/web/VariableArcsTest.java @@ -25,6 +25,7 @@ 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.petrinetoutcomes.ImportPetriNetEventOutcome; +import com.netgrif.application.engine.workflow.params.CreateCaseParams; import com.netgrif.application.engine.workflow.service.interfaces.ITaskService; import com.netgrif.application.engine.workflow.service.interfaces.IWorkflowService; import com.netgrif.application.engine.workflow.web.responsebodies.TaskReference; @@ -141,7 +142,12 @@ public void importTest() throws MissingIconKeyException { List<Arc> arcs = this.loaded.getArcs().values().stream().flatMap(List::stream).collect(Collectors.toList()); assert arcs.size() > 0; - CreateCaseEventOutcome caseOutcome = workflowService.createCase(this.loaded.getStringId(), "VARTEST", "red", mock.mockLoggedUser()); + CreateCaseEventOutcome caseOutcome = workflowService.createCase(CreateCaseParams.with() + .petriNet(this.loaded) + .title("VARTEST") + .color("red") + .loggedUser(mock.mockLoggedUser()) + .build()); assert caseOutcome.getCase().getPetriNet().getArcs() .values() diff --git a/nae-object-library/src/main/java/com/netgrif/application/engine/objects/workflow/domain/Case.java b/nae-object-library/src/main/java/com/netgrif/application/engine/objects/workflow/domain/Case.java index 34c2168398..7c72e087fb 100644 --- a/nae-object-library/src/main/java/com/netgrif/application/engine/objects/workflow/domain/Case.java +++ b/nae-object-library/src/main/java/com/netgrif/application/engine/objects/workflow/domain/Case.java @@ -19,6 +19,7 @@ import java.security.SecureRandom; import java.time.LocalDateTime; import java.util.*; +import java.util.concurrent.atomic.AtomicBoolean; import java.util.stream.Collectors; @Getter @@ -305,13 +306,19 @@ public void resolveViewUserRefs() { }); } - public void resolveViewUsers() { + /** + * todo javadoc + * */ + public boolean resolveViewUsers() { + AtomicBoolean isModified = new AtomicBoolean(!this.viewUsers.isEmpty()); this.viewUsers.clear(); this.users.forEach((user, perms) -> { if (perms.containsKey(RolePermission.VIEW.getValue()) && perms.get(RolePermission.VIEW.getValue())) { viewUsers.add(user); + isModified.set(true); } }); + return isModified.get(); } private void compareExistingUserPermissions(String userId, Map<String, Boolean> permissions) { diff --git a/nae-object-library/src/main/java/com/netgrif/application/engine/objects/workflow/domain/Task.java b/nae-object-library/src/main/java/com/netgrif/application/engine/objects/workflow/domain/Task.java index eb52c24a81..a2f9c4c7bd 100644 --- a/nae-object-library/src/main/java/com/netgrif/application/engine/objects/workflow/domain/Task.java +++ b/nae-object-library/src/main/java/com/netgrif/application/engine/objects/workflow/domain/Task.java @@ -22,6 +22,7 @@ import java.io.Serializable; import java.time.LocalDateTime; import java.util.*; +import java.util.concurrent.atomic.AtomicBoolean; @QueryEntity @AllArgsConstructor @@ -312,14 +313,20 @@ public void resolveViewUserRefs() { }); } - public void resolveViewUsers() { + /** + * todo javadoc + * */ + public boolean resolveViewUsers() { getViewUsers(); + AtomicBoolean isModified = new AtomicBoolean(!this.viewUsers.isEmpty()); this.viewUsers.clear(); this.users.forEach((role, perms) -> { if (perms.containsKey(RolePermission.VIEW.getValue()) && perms.get(RolePermission.VIEW.getValue())) { viewUsers.add(role); + isModified.set(true); } }); + return isModified.get(); } private void compareExistingUserPermissions(String userId, Map<String, Boolean> permissions) { From f9adc7fdbb2a112a18b09c8bff4799cce57ebddd Mon Sep 17 00:00:00 2001 From: chvostek <chvostek@netgrif.com> Date: Wed, 22 Oct 2025 09:28:53 +0200 Subject: [PATCH 09/55] [NAE-2235] Improve Efficiency of Database Reads and Saves - optimize createCase event --- .../engine/workflow/service/EventService.java | 2 +- .../engine/workflow/service/TaskService.java | 27 +++++++------ .../engine/objects/workflow/domain/Case.java | 38 +++++++++---------- 3 files changed, 32 insertions(+), 35 deletions(-) diff --git a/application-engine/src/main/java/com/netgrif/application/engine/workflow/service/EventService.java b/application-engine/src/main/java/com/netgrif/application/engine/workflow/service/EventService.java index 0c76d49ecd..edadca06cc 100644 --- a/application-engine/src/main/java/com/netgrif/application/engine/workflow/service/EventService.java +++ b/application-engine/src/main/java/com/netgrif/application/engine/workflow/service/EventService.java @@ -60,7 +60,7 @@ public List<EventOutcome> runActions(List<Action> actions, Case useCase, Optiona }); allOutcomes.addAll(outcomes); }); - if (useCase != null && !allOutcomes.isEmpty()) { + if (useCase != null) { workflowService.save(useCase); } return allOutcomes; diff --git a/application-engine/src/main/java/com/netgrif/application/engine/workflow/service/TaskService.java b/application-engine/src/main/java/com/netgrif/application/engine/workflow/service/TaskService.java index 7cacf27c54..cf1d59f481 100644 --- a/application-engine/src/main/java/com/netgrif/application/engine/workflow/service/TaskService.java +++ b/application-engine/src/main/java/com/netgrif/application/engine/workflow/service/TaskService.java @@ -496,6 +496,7 @@ public ReloadTaskOutcome reloadTasks(Case useCase, boolean lazyCaseSave) { ReloadTaskOutcome outcome = new ReloadTaskOutcome(); List<Task> newTasks = new ArrayList<>(); + List<Task> tasksToBeExecuted = new ArrayList<>(); List<Task> disabledTasks = new ArrayList<>(); Map<String, String> tasks = useCase.getTasks().stream().collect(Collectors.toMap(TaskPair::getTransition, TaskPair::getTask)); for (Transition transition : net.getTransitions().values()) { @@ -504,8 +505,12 @@ public ReloadTaskOutcome reloadTasks(Case useCase, boolean lazyCaseSave) { if (taskId != null) { // task exists - do nothing } else { - // task does not exist - create a new task - newTasks.add(createFromTransition(transition, useCase)); + // task does not exist - create a new task and check a trigger + Task newTask = createFromTransition(transition, useCase); + newTasks.add(newTask); + if (transition.hasAutoTrigger()) { + tasksToBeExecuted.add(newTask); + } } } else { if (taskId != null) { @@ -535,23 +540,17 @@ public ReloadTaskOutcome reloadTasks(Case useCase, boolean lazyCaseSave) { outcome.setUseCaseSaved(true); } - for (Task task : newTasks) { - if (shouldExecuteTask(net, task)) { - if (!outcome.isUseCaseSaved()) { - useCase = workflowService.save(useCase); - } - executeTransition(task, useCase); - outcome.setAnyTaskExecuted(true); + for (Task task : tasksToBeExecuted) { + if (!outcome.isUseCaseSaved()) { + useCase = workflowService.save(useCase); + outcome.setUseCaseSaved(true); } + executeTransition(task, useCase); + outcome.setAnyTaskExecuted(true); } return outcome; } - protected boolean shouldExecuteTask(PetriNet net, Task task) { - Transition transition = net.getTransition(task.getTransitionId()); - return transition.hasAutoTrigger(); - } - protected boolean isExecutable(Transition transition, PetriNet net) { Collection<Arc> arcsOfTransition = net.getArcsOfTransition(transition); diff --git a/nae-object-library/src/main/java/com/netgrif/application/engine/objects/workflow/domain/Case.java b/nae-object-library/src/main/java/com/netgrif/application/engine/objects/workflow/domain/Case.java index 7c72e087fb..1a90ba49a7 100644 --- a/nae-object-library/src/main/java/com/netgrif/application/engine/objects/workflow/domain/Case.java +++ b/nae-object-library/src/main/java/com/netgrif/application/engine/objects/workflow/domain/Case.java @@ -190,32 +190,30 @@ public void populateDataSet(InitValueExpressionEvaluator initValueExpressionEval List<MapOptionsField<I18nString, ?>> dynamicOptionsFields = new LinkedList<>(); List<ChoiceField<?>> dynamicChoicesFields = new LinkedList<>(); petriNet.getDataSet().forEach((key, field) -> { + DataField dataField; if (field.isDynamicDefaultValue()) { dynamicInitFields.add(field); - this.dataSet.put(key, new DataField()); + dataField = new DataField(); + this.dataSet.put(key, dataField); } else { - this.dataSet.put(key, new DataField(field.getDefaultValue())); + dataField = new DataField(field.getDefaultValue()); + this.dataSet.put(key, dataField); } if (field.getComponent() != null) { - this.dataSet.get(key).setComponent(field.getComponent()); + dataField.setComponent(field.getComponent()); } - if (field instanceof UserField) { - this.dataSet.get(key).setChoices(((UserField) field).getRoles().stream().map(I18nString::new).collect(Collectors.toSet())); - } - if (field instanceof UserListField) { - this.dataSet.get(key).setChoices(((UserListField) field).getRoles().stream().map(I18nString::new).collect(Collectors.toSet())); - } - if (field instanceof FieldWithAllowedNets) { - this.dataSet.get(key).setAllowedNets(((FieldWithAllowedNets) field).getAllowedNets()); - } - if (field instanceof FilterField) { - this.dataSet.get(key).setFilterMetadata(((FilterField) field).getFilterMetadata()); - } - if (field instanceof MapOptionsField && ((MapOptionsField) field).isDynamic()) { - dynamicOptionsFields.add((MapOptionsField<I18nString, ?>) field); - } - if (field instanceof ChoiceField && ((ChoiceField) field).isDynamic()) { - dynamicChoicesFields.add((ChoiceField<?>) field); + switch (field) { + case UserField userField -> + dataField.setChoices(userField.getRoles().stream().map(I18nString::new).collect(Collectors.toSet())); + case UserListField userListField -> + dataField.setChoices(userListField.getRoles().stream().map(I18nString::new).collect(Collectors.toSet())); + case FilterField filterField -> dataField.setFilterMetadata(filterField.getFilterMetadata()); + case FieldWithAllowedNets fieldWithAllowedNets -> + dataField.setAllowedNets(fieldWithAllowedNets.getAllowedNets()); + case MapOptionsField mapOptionsField when mapOptionsField.isDynamic() -> + dynamicOptionsFields.add((MapOptionsField<I18nString, ?>) field); + case ChoiceField choiceField when choiceField.isDynamic() -> dynamicChoicesFields.add(choiceField); + default -> {} } }); dynamicInitFields.forEach(field -> this.dataSet.get(field.getImportId()).setValue(initValueExpressionEvaluator.evaluate(this, field, params))); From 0edc172263d58b78bfe368c892a8157f6a0438ce Mon Sep 17 00:00:00 2001 From: chvostek <chvostek@netgrif.com> Date: Wed, 22 Oct 2025 11:53:22 +0200 Subject: [PATCH 10/55] [NAE-2235] Improve Efficiency of Database Reads and Saves - update WorkflowPerformanceTest --- .../workflow/WorkflowPerformanceTest.java | 161 +++++++++++++++++- 1 file changed, 157 insertions(+), 4 deletions(-) diff --git a/application-engine/src/test/java/com/netgrif/application/engine/workflow/WorkflowPerformanceTest.java b/application-engine/src/test/java/com/netgrif/application/engine/workflow/WorkflowPerformanceTest.java index e773d199a3..3d752fe78f 100644 --- a/application-engine/src/test/java/com/netgrif/application/engine/workflow/WorkflowPerformanceTest.java +++ b/application-engine/src/test/java/com/netgrif/application/engine/workflow/WorkflowPerformanceTest.java @@ -1,13 +1,18 @@ package com.netgrif.application.engine.workflow; import com.netgrif.application.engine.TestHelper; +import com.netgrif.application.engine.objects.auth.domain.LoggedUser; import com.netgrif.application.engine.objects.petrinet.domain.PetriNet; import com.netgrif.application.engine.objects.petrinet.domain.VersionType; import com.netgrif.application.engine.objects.petrinet.domain.throwable.MissingPetriNetMetaDataException; +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.petrinet.params.ImportPetriNetParams; import com.netgrif.application.engine.petrinet.service.interfaces.IPetriNetService; import com.netgrif.application.engine.startup.runner.SuperCreatorRunner; import com.netgrif.application.engine.workflow.params.CreateCaseParams; +import com.netgrif.application.engine.workflow.service.TaskService; import com.netgrif.application.engine.workflow.service.WorkflowService; import lombok.extern.slf4j.Slf4j; import org.junit.jupiter.api.BeforeEach; @@ -33,6 +38,9 @@ public class WorkflowPerformanceTest { @Autowired private WorkflowService workflowService; + @Autowired + private TaskService taskService; + @Autowired private IPetriNetService petriNetService; @@ -62,7 +70,7 @@ public void testCreatePerformance() throws IOException, MissingPetriNetMetaDataE } @Test - public void testCreate2Performance() throws IOException, MissingPetriNetMetaDataException { + public void testCreateWithActionPerformance() throws IOException, MissingPetriNetMetaDataException { PetriNet net = petriNetService.importPetriNet(ImportPetriNetParams.with() .xmlFile(new FileInputStream("src/test/resources/petriNets/test_create_case_performance_with_action.xml")) .releaseType(VersionType.MAJOR) @@ -76,18 +84,163 @@ public void testCreate2Performance() throws IOException, MissingPetriNetMetaData } @Test - public void testAssignPerformance() { + public void testAssignPerformance() throws IOException, MissingPetriNetMetaDataException, TransitionNotExecutableException { + PetriNet net = petriNetService.importPetriNet(ImportPetriNetParams.with() + .xmlFile(new FileInputStream("src/test/resources/petriNets/test_task_event.xml")) + .releaseType(VersionType.MAJOR) + .author(superCreatorRunner.getLoggedSuper()) + .build()).getNet(); + long totalElapsedTime = 0; + int iterations = 5000; + LoggedUser loggedUser = superCreatorRunner.getLoggedSuper(); + + for (int i = 0; i < iterations; i++) { + Case useCase = workflowService.createCase(CreateCaseParams.with() + .petriNet(net) + .loggedUser(loggedUser) + .locale(Locale.getDefault()) + .build()).getCase(); + String taskId = useCase.getTasks().stream().findFirst().get().getTask(); + long start = System.currentTimeMillis(); + taskService.assignTask(taskId); + long finish = System.currentTimeMillis(); + totalElapsedTime += finish - start; + } + log.info("AVG time for event [assignTask] is [{} ms] for [{}] iterations", totalElapsedTime / iterations, iterations); + } + + @Test + public void testAssignWithActionPerformance() throws IOException, MissingPetriNetMetaDataException, TransitionNotExecutableException { + PetriNet net = petriNetService.importPetriNet(ImportPetriNetParams.with() + .xmlFile(new FileInputStream("src/test/resources/petriNets/test_task_event_with_action.xml")) + .releaseType(VersionType.MAJOR) + .author(superCreatorRunner.getLoggedSuper()) + .build()).getNet(); + long totalElapsedTime = 0; + int iterations = 5000; + LoggedUser loggedUser = superCreatorRunner.getLoggedSuper(); + + for (int i = 0; i < iterations; i++) { + Case useCase = workflowService.createCase(CreateCaseParams.with() + .petriNet(net) + .loggedUser(loggedUser) + .locale(Locale.getDefault()) + .build()).getCase(); + String taskId = useCase.getTasks().stream().findFirst().get().getTask(); + long start = System.currentTimeMillis(); + taskService.assignTask(taskId); + long finish = System.currentTimeMillis(); + totalElapsedTime += finish - start; + } + log.info("AVG time for event [assignTaskWithAction] is [{} ms] for [{}] iterations", totalElapsedTime / iterations, iterations); + } + + @Test + public void testCancelPerformance() throws IOException, MissingPetriNetMetaDataException, TransitionNotExecutableException { + PetriNet net = petriNetService.importPetriNet(ImportPetriNetParams.with() + .xmlFile(new FileInputStream("src/test/resources/petriNets/test_task_event.xml")) + .releaseType(VersionType.MAJOR) + .author(superCreatorRunner.getLoggedSuper()) + .build()).getNet(); + long totalElapsedTime = 0; + int iterations = 5000; + LoggedUser loggedUser = superCreatorRunner.getLoggedSuper(); + + for (int i = 0; i < iterations; i++) { + Case useCase = workflowService.createCase(CreateCaseParams.with() + .petriNet(net) + .loggedUser(loggedUser) + .locale(Locale.getDefault()) + .build()).getCase(); + String taskId = useCase.getTasks().stream().findFirst().get().getTask(); + Task task = taskService.assignTask(taskId).getTask(); + long start = System.currentTimeMillis(); + taskService.cancelTask(task, loggedUser); + long finish = System.currentTimeMillis(); + totalElapsedTime += finish - start; + } + log.info("AVG time for event [cancelTask] is [{} ms] for [{}] iterations", totalElapsedTime / iterations, iterations); + } + + @Test + public void testCancelWithActionPerformance() throws IOException, MissingPetriNetMetaDataException, TransitionNotExecutableException { + PetriNet net = petriNetService.importPetriNet(ImportPetriNetParams.with() + .xmlFile(new FileInputStream("src/test/resources/petriNets/test_task_event_with_action.xml")) + .releaseType(VersionType.MAJOR) + .author(superCreatorRunner.getLoggedSuper()) + .build()).getNet(); + long totalElapsedTime = 0; + int iterations = 5000; + LoggedUser loggedUser = superCreatorRunner.getLoggedSuper(); + for (int i = 0; i < iterations; i++) { + Case useCase = workflowService.createCase(CreateCaseParams.with() + .petriNet(net) + .loggedUser(loggedUser) + .locale(Locale.getDefault()) + .build()).getCase(); + String taskId = useCase.getTasks().stream().findFirst().get().getTask(); + Task task = taskService.assignTask(taskId).getTask(); + long start = System.currentTimeMillis(); + taskService.cancelTask(task, loggedUser); + long finish = System.currentTimeMillis(); + totalElapsedTime += finish - start; + } + log.info("AVG time for event [cancelTaskWithAction] is [{} ms] for [{}] iterations", totalElapsedTime / iterations, iterations); } @Test - public void testCancelPerformance() { + public void testFinishPerformance() throws IOException, MissingPetriNetMetaDataException, TransitionNotExecutableException { + PetriNet net = petriNetService.importPetriNet(ImportPetriNetParams.with() + .xmlFile(new FileInputStream("src/test/resources/petriNets/test_task_event.xml")) + .releaseType(VersionType.MAJOR) + .author(superCreatorRunner.getLoggedSuper()) + .build()).getNet(); + long totalElapsedTime = 0; + int iterations = 5000; + LoggedUser loggedUser = superCreatorRunner.getLoggedSuper(); + for (int i = 0; i < iterations; i++) { + Case useCase = workflowService.createCase(CreateCaseParams.with() + .petriNet(net) + .loggedUser(loggedUser) + .locale(Locale.getDefault()) + .build()).getCase(); + String taskId = useCase.getTasks().stream().findFirst().get().getTask(); + Task task = taskService.assignTask(taskId).getTask(); + long start = System.currentTimeMillis(); + taskService.finishTask(task, loggedUser); + long finish = System.currentTimeMillis(); + totalElapsedTime += finish - start; + } + log.info("AVG time for event [finishTask] is [{} ms] for [{}] iterations", totalElapsedTime / iterations, iterations); } @Test - public void testFinishPerformance() { + public void testFinishWithActionPerformance() throws IOException, MissingPetriNetMetaDataException, TransitionNotExecutableException { + PetriNet net = petriNetService.importPetriNet(ImportPetriNetParams.with() + .xmlFile(new FileInputStream("src/test/resources/petriNets/test_task_event_with_action.xml")) + .releaseType(VersionType.MAJOR) + .author(superCreatorRunner.getLoggedSuper()) + .build()).getNet(); + long totalElapsedTime = 0; + int iterations = 5000; + LoggedUser loggedUser = superCreatorRunner.getLoggedSuper(); + for (int i = 0; i < iterations; i++) { + Case useCase = workflowService.createCase(CreateCaseParams.with() + .petriNet(net) + .loggedUser(loggedUser) + .locale(Locale.getDefault()) + .build()).getCase(); + String taskId = useCase.getTasks().stream().findFirst().get().getTask(); + Task task = taskService.assignTask(taskId).getTask(); + long start = System.currentTimeMillis(); + taskService.finishTask(task, loggedUser); + long finish = System.currentTimeMillis(); + totalElapsedTime += finish - start; + } + log.info("AVG time for event [finishTaskWithAction] is [{} ms] for [{}] iterations", totalElapsedTime / iterations, iterations); } @Test From 6b120256ab3ab6a99ce85e36761ea7245fccddb0 Mon Sep 17 00:00:00 2001 From: chvostek <chvostek@netgrif.com> Date: Wed, 22 Oct 2025 11:54:43 +0200 Subject: [PATCH 11/55] [NAE-2235] Improve Efficiency of Database Reads and Saves - add nets for WorkflowPerformanceTest --- .../resources/petriNets/test_task_event.xml | 44 ++++++++++++ .../petriNets/test_task_event_with_action.xml | 68 +++++++++++++++++++ 2 files changed, 112 insertions(+) create mode 100644 application-engine/src/test/resources/petriNets/test_task_event.xml create mode 100644 application-engine/src/test/resources/petriNets/test_task_event_with_action.xml diff --git a/application-engine/src/test/resources/petriNets/test_task_event.xml b/application-engine/src/test/resources/petriNets/test_task_event.xml new file mode 100644 index 0000000000..49037e5951 --- /dev/null +++ b/application-engine/src/test/resources/petriNets/test_task_event.xml @@ -0,0 +1,44 @@ +<document xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="https://petriflow.com/petriflow.schema.xsd"> + <id>test_task_event</id> + <version>1.0.0</version> + <initials>TTE</initials> + <title>Test task event + device_hub + true + true + false + + t1 + 368 + 208 + + + p1 + 272 + 208 + 1 + false + + + p2 + 464 + 208 + 0 + false + + + a1 + regular + p1 + t1 + 1 + + + a2 + regular + t1 + p2 + 1 + + \ No newline at end of file diff --git a/application-engine/src/test/resources/petriNets/test_task_event_with_action.xml b/application-engine/src/test/resources/petriNets/test_task_event_with_action.xml new file mode 100644 index 0000000000..d1f4a0e72a --- /dev/null +++ b/application-engine/src/test/resources/petriNets/test_task_event_with_action.xml @@ -0,0 +1,68 @@ + + test_task_event_with_action + 1.0.0 + TTE + Test task event with action + device_hub + true + true + false + + t1 + 368 + 208 + + + p1 + 272 + 208 + 1 + false + + + p2 + 464 + 208 + 0 + false + + + a1 + regular + p1 + t1 + 1 + + + a2 + regular + t1 + p2 + 1 + + \ No newline at end of file From 69baaf62943d48b41b6a621bd8ea791509778b99 Mon Sep 17 00:00:00 2001 From: chvostek Date: Wed, 22 Oct 2025 14:40:32 +0200 Subject: [PATCH 12/55] [NAE-2235] Improve Efficiency of Database Reads and Saves - update WorkflowService.deleteCase - optimize WorkflowService.deleteSubtreeRootedAt - optimize logging in TaskService --- .../engine/menu/services/MenuItemService.java | 5 +- .../workflow/params/CreateCaseParams.java | 2 + .../workflow/params/DeleteCaseParams.java | 47 +++++++++++++++ .../engine/workflow/service/TaskService.java | 34 +++++------ .../workflow/service/WorkflowService.java | 58 +++++++++---------- .../service/interfaces/IWorkflowService.java | 13 +---- .../workflow/web/WorkflowController.java | 7 ++- 7 files changed, 104 insertions(+), 62 deletions(-) create mode 100644 application-engine/src/main/java/com/netgrif/application/engine/workflow/params/DeleteCaseParams.java diff --git a/application-engine/src/main/java/com/netgrif/application/engine/menu/services/MenuItemService.java b/application-engine/src/main/java/com/netgrif/application/engine/menu/services/MenuItemService.java index f14075a6e3..0a2373eb75 100644 --- a/application-engine/src/main/java/com/netgrif/application/engine/menu/services/MenuItemService.java +++ b/application-engine/src/main/java/com/netgrif/application/engine/menu/services/MenuItemService.java @@ -26,6 +26,7 @@ import com.netgrif.application.engine.startup.runner.FilterRunner; import com.netgrif.application.engine.startup.runner.MenuProcessRunner; import com.netgrif.application.engine.workflow.params.CreateCaseParams; +import com.netgrif.application.engine.workflow.params.DeleteCaseParams; 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; @@ -505,7 +506,9 @@ protected Case updateView(Case viewCase, ViewBody body) throws TransitionNotExec } protected void removeView(Case viewCase) { - workflowService.deleteCase(viewCase); + workflowService.deleteCase(DeleteCaseParams.with() + .useCase(viewCase) + .build()); log.trace("Removed configuration view case [{}].", viewCase.getStringId()); } diff --git a/application-engine/src/main/java/com/netgrif/application/engine/workflow/params/CreateCaseParams.java b/application-engine/src/main/java/com/netgrif/application/engine/workflow/params/CreateCaseParams.java index 4b07e5bfa7..1c210b4434 100644 --- a/application-engine/src/main/java/com/netgrif/application/engine/workflow/params/CreateCaseParams.java +++ b/application-engine/src/main/java/com/netgrif/application/engine/workflow/params/CreateCaseParams.java @@ -15,6 +15,8 @@ @Data @Builder(builderMethodName = "with") public class CreateCaseParams { + // todo javadoc + private String petriNetId; private String petriNetIdentifier; private PetriNet petriNet; diff --git a/application-engine/src/main/java/com/netgrif/application/engine/workflow/params/DeleteCaseParams.java b/application-engine/src/main/java/com/netgrif/application/engine/workflow/params/DeleteCaseParams.java new file mode 100644 index 0000000000..fa8aad92f7 --- /dev/null +++ b/application-engine/src/main/java/com/netgrif/application/engine/workflow/params/DeleteCaseParams.java @@ -0,0 +1,47 @@ +package com.netgrif.application.engine.workflow.params; + +import com.netgrif.application.engine.objects.workflow.domain.Case; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; + +import java.util.HashMap; +import java.util.Map; + +@Data +@AllArgsConstructor +@Builder(builderMethodName = "with") +public class DeleteCaseParams { + + // todo javadoc + + private String useCaseId; + private Case useCase; + private boolean force; + @Builder.Default + private Map params = new HashMap<>(); + + public DeleteCaseParams(Case useCase) { + this.useCase = useCase; + if (useCase != null) { + this.useCaseId = useCase.getStringId(); + } + } + + public DeleteCaseParams(String useCaseId) { + this.useCaseId = useCaseId; + } + + public static class DeleteCaseParamsBuilder { + /** + * Sets the {@link #useCase} and {@link #useCaseId} + * */ + public DeleteCaseParams.DeleteCaseParamsBuilder useCase(Case useCase) { + this.useCase = useCase; + if (useCase != null) { + this.useCaseId = useCase.getStringId(); + } + return this; + } + } +} diff --git a/application-engine/src/main/java/com/netgrif/application/engine/workflow/service/TaskService.java b/application-engine/src/main/java/com/netgrif/application/engine/workflow/service/TaskService.java index cf1d59f481..875d217f93 100644 --- a/application-engine/src/main/java/com/netgrif/application/engine/workflow/service/TaskService.java +++ b/application-engine/src/main/java/com/netgrif/application/engine/workflow/service/TaskService.java @@ -178,9 +178,9 @@ public AssignTaskEventOutcome assignTask(Task task, AbstractUser user, Map outcomes = new ArrayList<>(eventService.runActions(transition.getPreFinishActions(), useCase, task, transition, params)); @@ -296,8 +295,8 @@ public FinishTaskEventOutcome finishTask(Task task, AbstractUser user, Map outcomes = new ArrayList<>(eventService.runActions(transition.getPreCancelActions(), useCase, task, transition, params)); task = findOne(task.getStringId()); @@ -362,8 +360,8 @@ public CancelTaskEventOutcome cancelTask(Task task, AbstractUser user, Map outcomes = new ArrayList<>(eventService.runActions(transition.getPreDelegateActions(), useCase, task, transition, params)); task = findOne(task.getStringId()); @@ -451,8 +449,8 @@ public DelegateTaskEventOutcome delegateTask(LoggedUser loggedUser, String deleg addMessageToOutcome(transition, EventType.DELEGATE, outcome); publisher.publishEvent(new DelegateTaskEvent(outcome, EventPhase.POST, delegateUser, delegatedUser.getStringId())); // TODO: impersonation -// log.info("Task [" + task.getTitle() + "] in case [" + useCase.getTitle() + "] assigned to [" + delegateUser.getSelfOrImpersonated().getEmail() + "] was delegated to [" + delegatedUser.getEmail() + "]"); - log.info("Task [" + task.getTitle() + "] in case [" + useCase.getTitle() + "] assigned to [" + delegateUser.getEmail() + "] was delegated to [" + delegatedUser.getEmail() + "]"); + log.info("Task [{}] in case [{}] assigned to [{}] was delegated to [{}]", task.getTitle(), useCase.getTitle(), + delegatedUser.getEmail(), delegatedUser.getEmail()); return outcome; } @@ -565,7 +563,7 @@ protected boolean isExecutable(Transition transition, PetriNet net) { protected void finishExecution(Transition transition, String useCaseId) throws TransitionNotExecutableException { Case useCase = workflowService.findOne(useCaseId); - log.info("[" + useCaseId + "]: Finish execution of task [" + transition.getTitle() + "] in case [" + useCase.getTitle() + "]"); + log.info("[{}]: Finish execution of task [{}] in case [{}]", useCaseId, transition.getTitle(), useCase.getTitle()); execute(transition, useCase, arc -> arc.getSource().equals(transition)); Supplier> arcStreamSupplier = () -> useCase.getPetriNet().getArcsOfTransition(transition.getStringId()).stream(); arcStreamSupplier.get().filter(arc -> useCase.getConsumedTokens().containsKey(arc.getStringId())).forEach(arc -> useCase.getConsumedTokens().remove(arc.getStringId())); @@ -573,7 +571,7 @@ protected void finishExecution(Transition transition, String useCaseId) throws T } public void startExecution(Transition transition, Case useCase) throws TransitionNotExecutableException { - log.info("[" + useCase.getStringId() + "]: Start execution of " + transition.getTitle() + " in case " + useCase.getTitle()); + log.info("[{}]: Start execution of {} in case {}", useCase.getStringId(), transition.getTitle(), useCase.getTitle()); execute(transition, useCase, arc -> arc.getDestination().equals(transition)); } diff --git a/application-engine/src/main/java/com/netgrif/application/engine/workflow/service/WorkflowService.java b/application-engine/src/main/java/com/netgrif/application/engine/workflow/service/WorkflowService.java index cf8bab91d5..cb9842a64f 100644 --- a/application-engine/src/main/java/com/netgrif/application/engine/workflow/service/WorkflowService.java +++ b/application-engine/src/main/java/com/netgrif/application/engine/workflow/service/WorkflowService.java @@ -33,6 +33,7 @@ import com.netgrif.application.engine.workflow.domain.outcomes.ReloadTaskOutcome; import com.netgrif.application.engine.workflow.domain.repositories.CaseRepository; import com.netgrif.application.engine.workflow.params.CreateCaseParams; +import com.netgrif.application.engine.workflow.params.DeleteCaseParams; import com.netgrif.application.engine.workflow.service.interfaces.IEventService; import com.netgrif.application.engine.objects.workflow.service.InitValueExpressionEvaluator; import com.netgrif.application.engine.workflow.service.interfaces.ITaskService; @@ -373,26 +374,15 @@ public Page findAllByAuthor(String authorId, String petriNet, Pageable pag } @Override - public DeleteCaseEventOutcome deleteCase(String caseId, Map params) { - Case useCase = findOne(caseId); - return deleteCase(useCase, params); - } + public DeleteCaseEventOutcome deleteCase(DeleteCaseParams deleteCaseParams) { + fillMissingAttributes(deleteCaseParams); - @Override - public DeleteCaseEventOutcome deleteCase(String caseId) { - return deleteCase(caseId, new HashMap<>()); - } - - @Override - public DeleteCaseEventOutcome deleteCase(Case useCase, Map params) { - return deleteCase(useCase, params, false); - } - - @Override - public DeleteCaseEventOutcome deleteCase(Case useCase, Map params, boolean force) { DeleteCaseEventOutcome outcome = null; - if (!force) { - outcome = new DeleteCaseEventOutcome(useCase, eventService.runActions(useCase.getPetriNet().getPreDeleteActions(), useCase, Optional.empty(), params)); + Case useCase = deleteCaseParams.getUseCase(); + + if (!deleteCaseParams.isForce()) { + outcome = new DeleteCaseEventOutcome(useCase, eventService.runActions(useCase.getPetriNet().getPreDeleteActions(), + useCase, Optional.empty(), deleteCaseParams.getParams())); publisher.publishEvent(new DeleteCaseEvent(outcome, EventPhase.PRE)); useCase = ((Evaluator) evaluationService.getEvaluator("default")).apply(new DeleteCaseEvent(outcome, EventPhase.PRE)); } @@ -401,23 +391,26 @@ public DeleteCaseEventOutcome deleteCase(Case useCase, Map param taskService.deleteTasksByCase(useCase.getStringId()); repository.delete(useCase); - if (!force) { - outcome.addOutcomes(eventService.runActions(useCase.getPetriNet().getPostDeleteActions(), null, Optional.empty(), params)); + + if (!deleteCaseParams.isForce()) { + outcome.addOutcomes(eventService.runActions(useCase.getPetriNet().getPostDeleteActions(), null, + Optional.empty(), deleteCaseParams.getParams())); addMessageToOutcome(useCase.getPetriNet(), CaseEventType.DELETE, outcome); ((Evaluator) evaluationService.getEvaluator("noContext")).apply(new DeleteCaseEvent(outcome, EventPhase.POST)); publisher.publishEvent(new DeleteCaseEvent(outcome, EventPhase.POST)); } - return outcome; - } - @Override - public DeleteCaseEventOutcome deleteCase(Case useCase) { - return deleteCase(useCase, false); + return outcome; } - @Override - public DeleteCaseEventOutcome deleteCase(Case useCase, boolean force) { - return deleteCase(useCase, new HashMap<>(), force); + protected void fillMissingAttributes(DeleteCaseParams deleteCaseParams) throws IllegalArgumentException { + if (deleteCaseParams.getUseCase() == null) { + if (deleteCaseParams.getUseCaseId() != null) { + deleteCaseParams.setUseCase(findOne(deleteCaseParams.getUseCaseId())); + } else { + throw new IllegalArgumentException("At least case id must be provided on case removal."); + } + } } @Override @@ -431,7 +424,10 @@ public void deleteInstancesOfPetriNet(PetriNet net, boolean force) { userService.getLoggedOrSystem().getStringId(), net.getIdentifier(), net.getVersion().toString()); List cases = this.searchAll(QCase.case$.petriNetObjectId.eq(net.getObjectId())).getContent(); if (!cases.isEmpty()) { - cases.forEach(aCase -> deleteCase(aCase, new HashMap<>(), force)); + cases.forEach(aCase -> deleteCase(DeleteCaseParams.with() + .useCase(aCase) + .force(force) + .build())); } } @@ -441,7 +437,9 @@ public DeleteCaseEventOutcome deleteSubtreeRootedAt(String subtreeRootCaseId) { if (subtreeRoot.getImmediateDataFields().contains("treeChildCases")) { ((List) subtreeRoot.getDataSet().get("treeChildCases").getValue()).forEach(this::deleteSubtreeRootedAt); } - return deleteCase(subtreeRootCaseId); + return deleteCase(DeleteCaseParams.with() + .useCase(subtreeRoot) + .build()); } @Override diff --git a/application-engine/src/main/java/com/netgrif/application/engine/workflow/service/interfaces/IWorkflowService.java b/application-engine/src/main/java/com/netgrif/application/engine/workflow/service/interfaces/IWorkflowService.java index 2c62d1899d..1a51275a89 100644 --- a/application-engine/src/main/java/com/netgrif/application/engine/workflow/service/interfaces/IWorkflowService.java +++ b/application-engine/src/main/java/com/netgrif/application/engine/workflow/service/interfaces/IWorkflowService.java @@ -8,6 +8,7 @@ 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.workflow.params.CreateCaseParams; +import com.netgrif.application.engine.workflow.params.DeleteCaseParams; import com.querydsl.core.types.Predicate; import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; @@ -34,20 +35,10 @@ public interface IWorkflowService { Page findAllByAuthor(String authorId, String petriNet, Pageable pageable); - DeleteCaseEventOutcome deleteCase(String caseId, Map params); - - DeleteCaseEventOutcome deleteCase(String caseId); + DeleteCaseEventOutcome deleteCase(DeleteCaseParams deleteCaseParams); DeleteCaseEventOutcome deleteSubtreeRootedAt(String caseId); - DeleteCaseEventOutcome deleteCase(Case useCase, Map params); - - DeleteCaseEventOutcome deleteCase(Case useCase, Map params, boolean force); - - DeleteCaseEventOutcome deleteCase(Case useCase); - - DeleteCaseEventOutcome deleteCase(Case useCase, boolean force); - void deleteInstancesOfPetriNet(PetriNet net); void deleteInstancesOfPetriNet(PetriNet net, boolean force); diff --git a/application-engine/src/main/java/com/netgrif/application/engine/workflow/web/WorkflowController.java b/application-engine/src/main/java/com/netgrif/application/engine/workflow/web/WorkflowController.java index 15e087e548..afd6c94d65 100644 --- a/application-engine/src/main/java/com/netgrif/application/engine/workflow/web/WorkflowController.java +++ b/application-engine/src/main/java/com/netgrif/application/engine/workflow/web/WorkflowController.java @@ -12,6 +12,7 @@ import com.netgrif.application.engine.workflow.domain.eventoutcomes.response.EventOutcomeWithMessage; import com.netgrif.application.engine.workflow.domain.eventoutcomes.response.EventOutcomeWithMessageResource; import com.netgrif.application.engine.workflow.params.CreateCaseParams; +import com.netgrif.application.engine.workflow.params.DeleteCaseParams; import com.netgrif.application.engine.workflow.service.FileFieldInputStream; import com.netgrif.application.engine.workflow.service.interfaces.IDataService; import com.netgrif.application.engine.workflow.service.interfaces.ITaskService; @@ -222,12 +223,14 @@ public EntityModel deleteCase(Authentication auth, @Pat if (deleteSubtree) { outcome = workflowService.deleteSubtreeRootedAt(caseId); } else { - outcome = workflowService.deleteCase(caseId); + outcome = workflowService.deleteCase(DeleteCaseParams.with() + .useCaseId(caseId) + .build()); } return EventOutcomeWithMessageResource.successMessage("Case " + caseId + " was deleted", LocalisedEventOutcomeFactory.from(outcome, LocaleContextHolder.getLocale())); } catch (UnsupportedEncodingException e) { - log.error("Deleting case [" + caseId + "] failed:", e); + log.error("Deleting case [{}] failed:", caseId, e); return EventOutcomeWithMessageResource.errorMessage("Deleting case " + caseId + " has failed!"); } } From 5e7d29d6d2170d1e93471be5e25f584019e623b3 Mon Sep 17 00:00:00 2001 From: chvostek Date: Wed, 22 Oct 2025 15:26:52 +0200 Subject: [PATCH 13/55] [NAE-2235] Improve Efficiency of Database Reads and Saves - change task service method parameters --- .../services/DashboardItemServiceImpl.java | 11 +- .../DashboardManagementServiceImpl.java | 11 +- .../engine/menu/services/MenuItemService.java | 11 +- .../startup/runner/DefaultFiltersRunner.java | 11 +- .../engine/workflow/params/TaskParams.java | 44 +++++ .../service/MenuImportExportService.java | 18 +- .../engine/workflow/service/TaskService.java | 174 +++++++----------- .../service/interfaces/ITaskService.java | 34 +--- .../workflow/web/AbstractTaskController.java | 24 ++- .../workflow/WorkflowPerformanceTest.java | 45 ++++- .../workflow/service/TaskServiceTest.java | 11 +- .../engine/workflow/web/VariableArcsTest.java | 81 ++++++-- 12 files changed, 290 insertions(+), 185 deletions(-) create mode 100644 application-engine/src/main/java/com/netgrif/application/engine/workflow/params/TaskParams.java diff --git a/application-engine/src/main/java/com/netgrif/application/engine/menu/services/DashboardItemServiceImpl.java b/application-engine/src/main/java/com/netgrif/application/engine/menu/services/DashboardItemServiceImpl.java index cc8034ff0e..fe88113cc1 100644 --- a/application-engine/src/main/java/com/netgrif/application/engine/menu/services/DashboardItemServiceImpl.java +++ b/application-engine/src/main/java/com/netgrif/application/engine/menu/services/DashboardItemServiceImpl.java @@ -18,6 +18,7 @@ import com.netgrif.application.engine.petrinet.service.interfaces.IPetriNetService; import com.netgrif.application.engine.startup.ImportHelper; import com.netgrif.application.engine.workflow.params.CreateCaseParams; +import com.netgrif.application.engine.workflow.params.TaskParams; 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; @@ -114,9 +115,15 @@ protected Case setDataWithExecute(Case useCase, String transId, Map createFilterCase(String title, String icon, String filter filterCase.setIcon(icon); filterCase = this.workflowService.save(filterCase); Task newFilterTask = this.taskService.searchOne(QTask.task.transitionId.eq(AUTO_CREATE_TRANSITION).and(QTask.task.caseId.eq(filterCase.getStringId()))); - this.taskService.assignTask(newFilterTask, this.userService.getLoggedOrSystem()); + this.taskService.assignTask(TaskParams.with() + .task(newFilterTask) + .user(this.userService.getLoggedOrSystem()) + .build()); Map> setDataMap = new LinkedHashMap<>(); setDataMap.put(FILTER_TYPE_FIELD_ID, Map.of( @@ -488,7 +492,10 @@ private Optional createFilterCase(String title, String icon, String filter filterCase.getDataSet().get(FILTER_I18N_TITLE_FIELD_ID).setValue(translatedTitle); workflowService.save(filterCase); - this.taskService.finishTask(newFilterTask, this.userService.getLoggedOrSystem()); + this.taskService.finishTask(TaskParams.with() + .task(newFilterTask) + .user(this.userService.getLoggedOrSystem()) + .build()); return Optional.of(this.workflowService.findOne(filterCase.getStringId())); } catch (Exception ex) { log.error("Failed to create filter case", ex); diff --git a/application-engine/src/main/java/com/netgrif/application/engine/workflow/params/TaskParams.java b/application-engine/src/main/java/com/netgrif/application/engine/workflow/params/TaskParams.java new file mode 100644 index 0000000000..6f31ca0b31 --- /dev/null +++ b/application-engine/src/main/java/com/netgrif/application/engine/workflow/params/TaskParams.java @@ -0,0 +1,44 @@ +package com.netgrif.application.engine.workflow.params; + +import com.netgrif.application.engine.objects.auth.domain.AbstractUser; +import com.netgrif.application.engine.objects.workflow.domain.Case; +import com.netgrif.application.engine.objects.workflow.domain.Task; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; + +import java.util.HashMap; +import java.util.Map; + +@Data +@AllArgsConstructor +@Builder(builderMethodName = "with") +public class TaskParams { + + // todo javadoc + + private String taskId; + private Task task; + private Case useCase; + private AbstractUser user; + @Builder.Default + private Map params = new HashMap<>(); + + public TaskParams(Task task) { + this(task, null); + } + + public TaskParams(Task task, AbstractUser user) { + this.task = task; + this.user = user; + } + + public TaskParams(String taskId) { + this(taskId, null); + } + + public TaskParams(String taskId, AbstractUser user) { + this.taskId = taskId; + this.user = user; + } +} diff --git a/application-engine/src/main/java/com/netgrif/application/engine/workflow/service/MenuImportExportService.java b/application-engine/src/main/java/com/netgrif/application/engine/workflow/service/MenuImportExportService.java index f9e02d59a3..47bac2e4f9 100644 --- a/application-engine/src/main/java/com/netgrif/application/engine/workflow/service/MenuImportExportService.java +++ b/application-engine/src/main/java/com/netgrif/application/engine/workflow/service/MenuImportExportService.java @@ -11,6 +11,7 @@ import com.netgrif.application.engine.workflow.domain.FilterDeserializer; import com.netgrif.application.engine.workflow.domain.IllegalMenuFileException; import com.netgrif.application.engine.workflow.params.CreateCaseParams; +import com.netgrif.application.engine.workflow.params.TaskParams; import com.netgrif.application.engine.workflow.service.interfaces.IMenuImportExportService; import com.netgrif.application.engine.workflow.service.interfaces.IWorkflowService; import com.netgrif.application.engine.objects.petrinet.domain.I18nString; @@ -193,11 +194,15 @@ public List importMenu(List menuItemCases, FileFieldValue ffv, Str Task importedFilterTask = taskService.findOne(taskId); Case filterCase = workflowService.findOne(importedFilterTask.getCaseId()); try { - taskService.assignTask(importedFilterTask.getStringId()); - taskService.finishTask(importedFilterTask.getStringId()); + taskService.assignTask(TaskParams.with() + .task(importedFilterTask) + .build()); + taskService.finishTask(TaskParams.with() + .task(importedFilterTask) + .build()); workflowService.save(filterCase); } catch (TransitionNotExecutableException e) { - log.error("Failed to execute \"import_filter\" task with id: " + taskId, e); + log.error("Failed to execute \"import_filter\" task with id: {}", taskId, e); } }); @@ -271,14 +276,17 @@ public String createMenuItemCase(StringBuilder resultMessage, MenuEntry item, St QTask qTask = new QTask("task"); Task task = taskService.searchOne(qTask.transitionId.eq("init").and(qTask.caseId.eq(menuItemCase.getStringId()))); try { - taskService.assignTask(task, userService.getLoggedUser()); + taskService.assignTask(TaskParams.with() + .task(task) + .user(userService.getLoggedUser()) + .build()); menuItemCase.getDataSet().get(MENU_IDENTIFIER).setValue(menuIdentifier); menuItemCase.getDataSet().get(PARENT_ID).setValue(parentId); menuItemCase.getDataSet().get(ALLOWED_ROLES).setOptions(allowedRoles); menuItemCase.getDataSet().get(BANNED_ROLES).setOptions(bannedRoles); workflowService.save(menuItemCase); } catch (TransitionNotExecutableException e) { - log.error("Failed to execute \"init\" task on preference filter item case with id: " + menuItemCase.getStringId(), e); + log.error("Failed to execute \"init\" task on preference filter item case with id: {}", menuItemCase.getStringId(), e); netCheck.set(false); resultMessage.append("- Failed to execute \"init\" task"); } diff --git a/application-engine/src/main/java/com/netgrif/application/engine/workflow/service/TaskService.java b/application-engine/src/main/java/com/netgrif/application/engine/workflow/service/TaskService.java index 875d217f93..f87fc889b5 100644 --- a/application-engine/src/main/java/com/netgrif/application/engine/workflow/service/TaskService.java +++ b/application-engine/src/main/java/com/netgrif/application/engine/workflow/service/TaskService.java @@ -32,6 +32,7 @@ import com.netgrif.application.engine.workflow.domain.repositories.TaskRepository; import com.netgrif.application.engine.objects.workflow.domain.triggers.TimeTrigger; import com.netgrif.application.engine.objects.workflow.domain.triggers.Trigger; +import com.netgrif.application.engine.workflow.params.TaskParams; import com.netgrif.application.engine.workflow.service.interfaces.IDataService; import com.netgrif.application.engine.workflow.service.interfaces.IEventService; import com.netgrif.application.engine.workflow.service.interfaces.ITaskService; @@ -125,62 +126,39 @@ public List assignTasks(List tasks, AbstractUser u public List assignTasks(List tasks, AbstractUser user, Map params) throws TransitionNotExecutableException { List outcomes = new ArrayList<>(); for (Task task : tasks) { - outcomes.add(assignTask(task, user, params)); + outcomes.add(assignTask(TaskParams.with() + .task(task) + .user(user) + .params(params) + .build())); } return outcomes; } @Override - public AssignTaskEventOutcome assignTask(LoggedUser loggedUser, String taskId) throws TransitionNotExecutableException { - return assignTask(loggedUser, taskId, new HashMap<>()); - } - - @Override - public AssignTaskEventOutcome assignTask(LoggedUser loggedUser, String taskId, Map params) throws TransitionNotExecutableException { - Task task = this.findById(taskId); - if (task == null) { - throw new TaskNotFoundException("Could not find task with id [" + taskId + "]"); - } - - AbstractUser user = getUserFromLoggedUser(loggedUser); - return assignTask(task, user, params); - } - - @Override - public AssignTaskEventOutcome assignTask(String taskId) throws TransitionNotExecutableException { - return assignTask(taskId, new HashMap<>()); - } - - @Override - public AssignTaskEventOutcome assignTask(String taskId, Map params) throws TransitionNotExecutableException { - LoggedUser user = ActorTransformer.toLoggedUser(userService.getLoggedOrSystem()); - return assignTask(user, taskId, params); - } - - @Override - public AssignTaskEventOutcome assignTask(Task task, AbstractUser user) throws TransitionNotExecutableException { - return assignTask(task, user, new HashMap<>()); - } + public AssignTaskEventOutcome assignTask(TaskParams taskParams) throws TransitionNotExecutableException { + fillMissingAttributes(taskParams); - @Override - public AssignTaskEventOutcome assignTask(Task task, AbstractUser user, Map params) throws TransitionNotExecutableException { - Case useCase = workflowService.findOne(task.getCaseId()); + Case useCase = taskParams.getUseCase(); + Task task = taskParams.getTask(); Transition transition = useCase.getPetriNet().getTransition(task.getTransitionId()); - List outcomes = new ArrayList<>(eventService.runActions(transition.getPreAssignActions(), useCase, task, transition, params)); + List outcomes = new ArrayList<>(eventService.runActions(transition.getPreAssignActions(), useCase, + task, transition, taskParams.getParams())); task = findOne(task.getStringId()); AssignTaskEventOutcome outcome = new AssignTaskEventOutcome(useCase, task, outcomes); useCase = evaluateRules(new AssignTaskEvent(outcome, EventPhase.PRE)); - useCase = assignTaskToUser(user, task, useCase.getStringId()); - publisher.publishEvent(new AssignTaskEvent(outcome, EventPhase.PRE, user)); - outcomes.addAll((eventService.runActions(transition.getPostAssignActions(), useCase, task, transition, params))); + useCase = assignTaskToUser(taskParams.getUser(), task, useCase.getStringId()); + publisher.publishEvent(new AssignTaskEvent(outcome, EventPhase.PRE, taskParams.getUser())); + outcomes.addAll((eventService.runActions(transition.getPostAssignActions(), useCase, task, transition, taskParams.getParams()))); useCase = evaluateRules(new AssignTaskEvent(new AssignTaskEventOutcome(useCase, task, outcomes), EventPhase.POST)); outcome = new AssignTaskEventOutcome(useCase, task, outcomes); - publisher.publishEvent(new AssignTaskEvent(outcome, EventPhase.POST, user)); + publisher.publishEvent(new AssignTaskEvent(outcome, EventPhase.POST, taskParams.getUser())); addMessageToOutcome(transition, EventType.ASSIGN, outcome); // TODO: impersonation user.getSelfOrImpersonated().getEmail() log.info("[{}]: Task [{}] in case [{}] assigned to [{}]", useCase.getStringId(), task.getTitle(), - useCase.getTitle(), user.getEmail()); + useCase.getTitle(), taskParams.getUser().getEmail()); + return outcome; } @@ -216,63 +194,38 @@ public List finishTasks(List tasks, AbstractUser u public List finishTasks(List tasks, AbstractUser user, Map params) throws TransitionNotExecutableException { List outcomes = new ArrayList<>(); for (Task task : tasks) { - outcomes.add(finishTask(task, user, params)); + outcomes.add(finishTask(TaskParams.with() + .task(task) + .user(user) + .params(params) + .build())); } return outcomes; } @Override - public FinishTaskEventOutcome finishTask(String taskId) throws IllegalArgumentException, TransitionNotExecutableException { - return finishTask(taskId, new HashMap<>()); - } - - @Override - public FinishTaskEventOutcome finishTask(String taskId, Map params) throws IllegalArgumentException, TransitionNotExecutableException { - LoggedUser user = ActorTransformer.toLoggedUser(userService.getLoggedOrSystem()); - return finishTask(user, taskId, params); - } + public FinishTaskEventOutcome finishTask(TaskParams taskParams) throws TransitionNotExecutableException { + fillMissingAttributes(taskParams); - @Override - public FinishTaskEventOutcome finishTask(LoggedUser loggedUser, String taskId) throws IllegalArgumentException, TransitionNotExecutableException { - return finishTask(loggedUser, taskId, new HashMap<>()); - } - - @Override - public FinishTaskEventOutcome finishTask(LoggedUser loggedUser, String taskId, Map params) throws IllegalArgumentException, TransitionNotExecutableException { - Task task = this.findById(taskId); - if (task == null) { - throw new IllegalArgumentException("Could not find task with id [" + taskId + "]"); - } - AbstractUser user = getUserFromLoggedUser(loggedUser); + Task task = taskParams.getTask(); + Case useCase = taskParams.getUseCase(); + AbstractUser user = taskParams.getUser(); if (task.getUserId() == null) { - throw new IllegalArgumentException("Task with id=" + taskId + " is not assigned to any user."); + throw new IllegalArgumentException("Task with id=%s is not assigned to any user.".formatted(task.getStringId())); } - // TODO: 14. 4. 2017 replace with @PreAuthorize // TODO: impersonation -// if (!task.getUserId().equals(user.getSelfOrImpersonated().getStringId()) && !((Boolean) loggedUser.getAttributes().containsKey("anonymous"))) { - if (!task.getUserId().equals(user.getStringId()) && !((Boolean) loggedUser.getAttributes().containsKey("anonymous"))) { + if (!task.getUserId().equals(user.getStringId()) && !((Boolean) user.getAttributes().containsKey("anonymous"))) { throw new IllegalArgumentException("User that is not assigned tried to finish task"); } - - return finishTask(task, user, params); - } - - @Override - public FinishTaskEventOutcome finishTask(Task task, AbstractUser user) throws TransitionNotExecutableException { - return finishTask(task, user, new HashMap<>()); - } - - @Override - public FinishTaskEventOutcome finishTask(Task task, AbstractUser user, Map params) throws TransitionNotExecutableException { - Case useCase = workflowService.findOne(task.getCaseId()); Transition transition = useCase.getPetriNet().getTransition(task.getTransitionId()); // TODO: impersonation log.info("[{}]: Finishing task [{}] to user [{}]", useCase.getStringId(), task.getTitle(), user.getEmail()); validateData(transition, useCase); - List outcomes = new ArrayList<>(eventService.runActions(transition.getPreFinishActions(), useCase, task, transition, params)); + List outcomes = new ArrayList<>(eventService.runActions(transition.getPreFinishActions(), useCase, + task, transition, taskParams.getParams())); task = findOne(task.getStringId()); FinishTaskEventOutcome outcome = new FinishTaskEventOutcome(useCase, task, outcomes); useCase = evaluateRules(new FinishTaskEvent(outcome, EventPhase.PRE)); @@ -288,7 +241,7 @@ public FinishTaskEventOutcome finishTask(Task task, AbstractUser user, Map cancelTasks(List tasks, AbstractUser u public List cancelTasks(List tasks, AbstractUser user, Map params) { List outcomes = new ArrayList<>(); for (Task task : tasks) { - outcomes.add(cancelTask(task, user, params)); + outcomes.add(cancelTask(TaskParams.with() + .task(task) + .user(user) + .params(params) + .build())); } return outcomes; } @Override - public CancelTaskEventOutcome cancelTask(LoggedUser loggedUser, String taskId) { - return cancelTask(loggedUser, taskId, new HashMap<>()); - } - - @Override - public CancelTaskEventOutcome cancelTask(LoggedUser loggedUser, String taskId, Map params) { - Task task = this.findById(taskId); - if (task == null) { - throw new IllegalArgumentException("Could not find task with id [" + taskId + "]"); - } - AbstractUser user = getUserFromLoggedUser(loggedUser); - return cancelTask(task, user, params); - } - - @Override - public CancelTaskEventOutcome cancelTask(Task task, AbstractUser user) { - return cancelTask(task, user, new HashMap<>()); - } - - @Override - public CancelTaskEventOutcome cancelTask(Task task, AbstractUser user, Map params) { - Case useCase = workflowService.findOne(task.getCaseId()); + public CancelTaskEventOutcome cancelTask(TaskParams taskParams) { + Task task = taskParams.getTask(); + Case useCase = taskParams.getUseCase(); + AbstractUser user = taskParams.getUser(); Transition transition = useCase.getPetriNet().getTransition(task.getTransitionId()); // TODO: impersonation log.info("[{}]: Canceling task [{}] to user [{}]", useCase.getStringId(), task.getTitle(), user.getEmail()); - List outcomes = new ArrayList<>(eventService.runActions(transition.getPreCancelActions(), useCase, task, transition, params)); + List outcomes = new ArrayList<>(eventService.runActions(transition.getPreCancelActions(), useCase, + task, transition, taskParams.getParams())); task = findOne(task.getStringId()); CancelTaskEventOutcome outcome = new CancelTaskEventOutcome(useCase, task, outcomes); useCase = evaluateRules(new CancelTaskEvent(outcome, EventPhase.PRE)); @@ -352,7 +292,7 @@ public CancelTaskEventOutcome cancelTask(Task task, AbstractUser user, Map transitions, String caseId, Map } } + protected void fillMissingAttributes(TaskParams taskParams) { + if (taskParams.getTask() == null) { + Task task = findOne(taskParams.getTaskId()); + taskParams.setTask(task); + } + if (taskParams.getUseCase() == null) { + Case useCase = workflowService.findOne(taskParams.getTask().getCaseId()); + taskParams.setUseCase(useCase); + } + if (taskParams.getUser() == null) { + AbstractUser user = userService.getLoggedOrSystem(); + taskParams.setUser(user); + } + } + private Task returnTokens(Task task, String useCaseId) { Case useCase = workflowService.findOne(useCaseId); PetriNet net = useCase.getPetriNet(); @@ -599,13 +555,17 @@ protected void executeTransition(Task task, Case useCase) { log.info("[{}]: executeTransition [{}] in case [{}]", useCase.getStringId(), task.getTransitionId(), useCase.getTitle()); try { log.info("assignTask [{}] in case [{}]", task.getTitle(), useCase.getTitle()); - assignTask(task.getStringId()); + assignTask(TaskParams.with() + .task(task) + .build()); log.info("getData [{}] in case [{}]", task.getTitle(), useCase.getTitle()); dataService.getData(task.getStringId()); log.info("finishTask [{}] in case [{}]", task.getTitle(), useCase.getTitle()); - finishTask(task.getStringId()); + finishTask(TaskParams.with() + .task(task) + .build()); } catch (Exception e) { log.error("Execution of task [{}] in case [{}] failed: ", task.getTitle(), useCase.getTitle(), e); } diff --git a/application-engine/src/main/java/com/netgrif/application/engine/workflow/service/interfaces/ITaskService.java b/application-engine/src/main/java/com/netgrif/application/engine/workflow/service/interfaces/ITaskService.java index c41d2ad4f2..3701b34980 100644 --- a/application-engine/src/main/java/com/netgrif/application/engine/workflow/service/interfaces/ITaskService.java +++ b/application-engine/src/main/java/com/netgrif/application/engine/workflow/service/interfaces/ITaskService.java @@ -1,7 +1,6 @@ package com.netgrif.application.engine.workflow.service.interfaces; import com.netgrif.application.engine.objects.auth.domain.AbstractUser; -import com.netgrif.application.engine.workflow.domain.TaskNotFoundException; import com.netgrif.application.engine.objects.auth.domain.LoggedUser; import com.netgrif.application.engine.objects.petrinet.domain.throwable.TransitionNotExecutableException; import com.netgrif.application.engine.objects.workflow.domain.Case; @@ -12,6 +11,7 @@ import com.netgrif.application.engine.objects.workflow.domain.eventoutcomes.taskoutcomes.DelegateTaskEventOutcome; import com.netgrif.application.engine.objects.workflow.domain.eventoutcomes.taskoutcomes.FinishTaskEventOutcome; import com.netgrif.application.engine.workflow.domain.outcomes.ReloadTaskOutcome; +import com.netgrif.application.engine.workflow.params.TaskParams; import com.netgrif.application.engine.workflow.web.requestbodies.TaskSearchRequest; import com.netgrif.application.engine.workflow.web.responsebodies.TaskReference; import org.springframework.data.domain.Page; @@ -53,45 +53,19 @@ public interface ITaskService { List finishTasks(List tasks, AbstractUser user, Map params) throws TransitionNotExecutableException; - FinishTaskEventOutcome finishTask(Task task, AbstractUser user) throws TransitionNotExecutableException; - - FinishTaskEventOutcome finishTask(Task task, AbstractUser user, Map params) throws TransitionNotExecutableException; - - FinishTaskEventOutcome finishTask(LoggedUser loggedUser, String taskId) throws IllegalArgumentException, TransitionNotExecutableException; - - FinishTaskEventOutcome finishTask(LoggedUser loggedUser, String taskId, Map params) throws IllegalArgumentException, TransitionNotExecutableException; - - FinishTaskEventOutcome finishTask(String taskId) throws IllegalArgumentException, TransitionNotExecutableException; - - FinishTaskEventOutcome finishTask(String taskId, Map params) throws IllegalArgumentException, TransitionNotExecutableException; + FinishTaskEventOutcome finishTask(TaskParams taskParams) throws TransitionNotExecutableException; List assignTasks(List tasks, AbstractUser user) throws TransitionNotExecutableException; List assignTasks(List tasks, AbstractUser user, Map params) throws TransitionNotExecutableException; - AssignTaskEventOutcome assignTask(Task task, AbstractUser user) throws TransitionNotExecutableException; - - AssignTaskEventOutcome assignTask(Task task, AbstractUser user, Map params) throws TransitionNotExecutableException; - - AssignTaskEventOutcome assignTask(LoggedUser loggedUser, String taskId) throws TransitionNotExecutableException, TaskNotFoundException; - - AssignTaskEventOutcome assignTask(LoggedUser loggedUser, String taskId, Map params) throws TransitionNotExecutableException, TaskNotFoundException; - - AssignTaskEventOutcome assignTask(String taskId) throws TransitionNotExecutableException; - - AssignTaskEventOutcome assignTask(String taskId, Map params) throws TransitionNotExecutableException; + AssignTaskEventOutcome assignTask(TaskParams taskParams) throws TransitionNotExecutableException; List cancelTasks(List tasks, AbstractUser user); List cancelTasks(List tasks, AbstractUser user, Map params); - CancelTaskEventOutcome cancelTask(Task task, AbstractUser user); - - CancelTaskEventOutcome cancelTask(Task task, AbstractUser user, Map params); - - CancelTaskEventOutcome cancelTask(LoggedUser loggedUser, String taskId); - - CancelTaskEventOutcome cancelTask(LoggedUser loggedUser, String taskId, Map params); + CancelTaskEventOutcome cancelTask(TaskParams taskParams); /** * cancel task action diff --git a/application-engine/src/main/java/com/netgrif/application/engine/workflow/web/AbstractTaskController.java b/application-engine/src/main/java/com/netgrif/application/engine/workflow/web/AbstractTaskController.java index eafa862bf8..104ecab794 100644 --- a/application-engine/src/main/java/com/netgrif/application/engine/workflow/web/AbstractTaskController.java +++ b/application-engine/src/main/java/com/netgrif/application/engine/workflow/web/AbstractTaskController.java @@ -7,6 +7,7 @@ import com.netgrif.application.engine.elastic.service.interfaces.IElasticTaskService; import com.netgrif.application.engine.elastic.web.requestbodies.singleaslist.SingleElasticTaskSearchRequestAsList; import com.netgrif.application.engine.eventoutcomes.LocalisedEventOutcomeFactory; +import com.netgrif.application.engine.workflow.params.TaskParams; import com.netgrif.application.engine.workflow.web.responsebodies.LocalisedTaskResource; import com.netgrif.application.engine.objects.petrinet.domain.throwable.TransitionNotExecutableException; import com.netgrif.application.engine.workflow.domain.IllegalArgumentWithChangedFieldsException; @@ -103,9 +104,12 @@ public LocalisedTaskResource getOne(String taskId, Locale locale) { public EntityModel assign(LoggedUser loggedUser, String taskId, Locale locale) { try { return EventOutcomeWithMessageResource.successMessage("LocalisedTask " + taskId + " assigned to " + loggedUser.getName(), - LocalisedEventOutcomeFactory.from(taskService.assignTask(loggedUser, taskId), locale)); + LocalisedEventOutcomeFactory.from(taskService.assignTask(TaskParams.with() + .taskId(taskId) + .user(loggedUser) + .build()), locale)); } catch (TransitionNotExecutableException e) { - log.error("Assigning task [" + taskId + "] failed: ", e); + log.error("Assigning task [{}] failed: ", taskId, e); return EventOutcomeWithMessageResource.errorMessage("LocalisedTask " + taskId + " cannot be assigned"); } } @@ -115,7 +119,7 @@ public EntityModel delegate(LoggedUser loggedUser, Stri return EventOutcomeWithMessageResource.successMessage("LocalisedTask " + taskId + " assigned to [" + delegatedId + "]", LocalisedEventOutcomeFactory.from(taskService.delegateTask(loggedUser, delegatedId, taskId), locale)); } catch (Exception e) { - log.error("Delegating task [" + taskId + "] failed: ", e); + log.error("Delegating task [{}] failed: ", taskId, e); return EventOutcomeWithMessageResource.errorMessage("LocalisedTask " + taskId + " cannot be assigned"); } } @@ -124,9 +128,12 @@ public EntityModel finish(LoggedUser loggedUser, String try { return EventOutcomeWithMessageResource.successMessage("LocalisedTask " + taskId + " finished", - LocalisedEventOutcomeFactory.from(taskService.finishTask(loggedUser, taskId), locale)); + LocalisedEventOutcomeFactory.from(taskService.finishTask(TaskParams.with() + .taskId(taskId) + .user(loggedUser) + .build()), locale)); } catch (Exception e) { - log.error("Finishing task [" + taskId + "] failed: ", e); + log.error("Finishing task [{}] failed: ", taskId, e); if (e instanceof IllegalArgumentWithChangedFieldsException) { return EventOutcomeWithMessageResource.errorMessage(e.getMessage(), LocalisedEventOutcomeFactory.from(((IllegalArgumentWithChangedFieldsException) e).getOutcome(), locale)); } else { @@ -138,9 +145,12 @@ public EntityModel finish(LoggedUser loggedUser, String public EntityModel cancel(LoggedUser loggedUser, String taskId, Locale locale) { try { return EventOutcomeWithMessageResource.successMessage("LocalisedTask " + taskId + " canceled", - LocalisedEventOutcomeFactory.from(taskService.cancelTask(loggedUser, taskId), locale)); + LocalisedEventOutcomeFactory.from(taskService.cancelTask(TaskParams.with() + .taskId(taskId) + .user(loggedUser) + .build()), locale)); } catch (Exception e) { - log.error("Canceling task [" + taskId + "] failed: ", e); + log.error("Canceling task [{}] failed: ", taskId, e); if (e instanceof IllegalArgumentWithChangedFieldsException) { return EventOutcomeWithMessageResource.errorMessage(e.getMessage(), LocalisedEventOutcomeFactory.from(((IllegalArgumentWithChangedFieldsException) e).getOutcome(), locale)); } else { diff --git a/application-engine/src/test/java/com/netgrif/application/engine/workflow/WorkflowPerformanceTest.java b/application-engine/src/test/java/com/netgrif/application/engine/workflow/WorkflowPerformanceTest.java index 3d752fe78f..9cdeb27807 100644 --- a/application-engine/src/test/java/com/netgrif/application/engine/workflow/WorkflowPerformanceTest.java +++ b/application-engine/src/test/java/com/netgrif/application/engine/workflow/WorkflowPerformanceTest.java @@ -12,6 +12,7 @@ import com.netgrif.application.engine.petrinet.service.interfaces.IPetriNetService; import com.netgrif.application.engine.startup.runner.SuperCreatorRunner; import com.netgrif.application.engine.workflow.params.CreateCaseParams; +import com.netgrif.application.engine.workflow.params.TaskParams; import com.netgrif.application.engine.workflow.service.TaskService; import com.netgrif.application.engine.workflow.service.WorkflowService; import lombok.extern.slf4j.Slf4j; @@ -102,7 +103,9 @@ public void testAssignPerformance() throws IOException, MissingPetriNetMetaDataE .build()).getCase(); String taskId = useCase.getTasks().stream().findFirst().get().getTask(); long start = System.currentTimeMillis(); - taskService.assignTask(taskId); + taskService.assignTask(TaskParams.with() + .taskId(taskId) + .build()); long finish = System.currentTimeMillis(); totalElapsedTime += finish - start; } @@ -128,7 +131,9 @@ public void testAssignWithActionPerformance() throws IOException, MissingPetriNe .build()).getCase(); String taskId = useCase.getTasks().stream().findFirst().get().getTask(); long start = System.currentTimeMillis(); - taskService.assignTask(taskId); + taskService.assignTask(TaskParams.with() + .taskId(taskId) + .build()); long finish = System.currentTimeMillis(); totalElapsedTime += finish - start; } @@ -153,9 +158,14 @@ public void testCancelPerformance() throws IOException, MissingPetriNetMetaDataE .locale(Locale.getDefault()) .build()).getCase(); String taskId = useCase.getTasks().stream().findFirst().get().getTask(); - Task task = taskService.assignTask(taskId).getTask(); + Task task = taskService.assignTask(TaskParams.with() + .taskId(taskId) + .build()).getTask(); long start = System.currentTimeMillis(); - taskService.cancelTask(task, loggedUser); + taskService.cancelTask(TaskParams.with() + .task(task) + .user(loggedUser) + .build()); long finish = System.currentTimeMillis(); totalElapsedTime += finish - start; } @@ -180,9 +190,14 @@ public void testCancelWithActionPerformance() throws IOException, MissingPetriNe .locale(Locale.getDefault()) .build()).getCase(); String taskId = useCase.getTasks().stream().findFirst().get().getTask(); - Task task = taskService.assignTask(taskId).getTask(); + Task task = taskService.assignTask(TaskParams.with() + .taskId(taskId) + .build()).getTask(); long start = System.currentTimeMillis(); - taskService.cancelTask(task, loggedUser); + taskService.cancelTask(TaskParams.with() + .task(task) + .user(loggedUser) + .build()); long finish = System.currentTimeMillis(); totalElapsedTime += finish - start; } @@ -207,9 +222,14 @@ public void testFinishPerformance() throws IOException, MissingPetriNetMetaDataE .locale(Locale.getDefault()) .build()).getCase(); String taskId = useCase.getTasks().stream().findFirst().get().getTask(); - Task task = taskService.assignTask(taskId).getTask(); + Task task = taskService.assignTask(TaskParams.with() + .taskId(taskId) + .build()).getTask(); long start = System.currentTimeMillis(); - taskService.finishTask(task, loggedUser); + taskService.finishTask(TaskParams.with() + .task(task) + .user(loggedUser) + .build()); long finish = System.currentTimeMillis(); totalElapsedTime += finish - start; } @@ -234,9 +254,14 @@ public void testFinishWithActionPerformance() throws IOException, MissingPetriNe .locale(Locale.getDefault()) .build()).getCase(); String taskId = useCase.getTasks().stream().findFirst().get().getTask(); - Task task = taskService.assignTask(taskId).getTask(); + Task task = taskService.assignTask(TaskParams.with() + .taskId(taskId) + .build()).getTask(); long start = System.currentTimeMillis(); - taskService.finishTask(task, loggedUser); + taskService.finishTask(TaskParams.with() + .task(task) + .user(loggedUser) + .build()); long finish = System.currentTimeMillis(); totalElapsedTime += finish - start; } diff --git a/application-engine/src/test/java/com/netgrif/application/engine/workflow/service/TaskServiceTest.java b/application-engine/src/test/java/com/netgrif/application/engine/workflow/service/TaskServiceTest.java index c1c4604747..4da77f5e5f 100644 --- a/application-engine/src/test/java/com/netgrif/application/engine/workflow/service/TaskServiceTest.java +++ b/application-engine/src/test/java/com/netgrif/application/engine/workflow/service/TaskServiceTest.java @@ -29,6 +29,7 @@ import com.netgrif.application.engine.workflow.domain.repositories.CaseRepository; import com.netgrif.application.engine.workflow.domain.repositories.TaskRepository; import com.netgrif.application.engine.workflow.params.CreateCaseParams; +import com.netgrif.application.engine.workflow.params.TaskParams; import com.netgrif.application.engine.workflow.service.interfaces.ITaskService; import com.netgrif.application.engine.workflow.service.interfaces.IWorkflowService; import org.bson.types.ObjectId; @@ -140,14 +141,20 @@ public void resetArcTest() throws TransitionNotExecutableException, MissingPetri assert task != null; - service.assignTask(ActorTransformer.toLoggedUser(user), task.getStringId()); + service.assignTask(TaskParams.with() + .task(task) + .user(user) + .build()); Case useCase = caseRepository.findById(outcome.getCase().getStringId()).get(); assert useCase.getConsumedTokens().size() == 1; assert useCase.getConsumedTokens().values().contains(5); assert useCase.getActivePlaces().size() == 0; - service.cancelTask(ActorTransformer.toLoggedUser(user), task.getStringId()); + service.cancelTask(TaskParams.with() + .task(task) + .user(user) + .build()); useCase = caseRepository.findById(useCase.getStringId()).get(); assert useCase.getConsumedTokens().size() == 0; diff --git a/application-engine/src/test/java/com/netgrif/application/engine/workflow/web/VariableArcsTest.java b/application-engine/src/test/java/com/netgrif/application/engine/workflow/web/VariableArcsTest.java index 925b151f37..427ac54678 100644 --- a/application-engine/src/test/java/com/netgrif/application/engine/workflow/web/VariableArcsTest.java +++ b/application-engine/src/test/java/com/netgrif/application/engine/workflow/web/VariableArcsTest.java @@ -26,6 +26,7 @@ import com.netgrif.application.engine.objects.workflow.domain.eventoutcomes.caseoutcomes.CreateCaseEventOutcome; import com.netgrif.application.engine.objects.workflow.domain.eventoutcomes.petrinetoutcomes.ImportPetriNetEventOutcome; import com.netgrif.application.engine.workflow.params.CreateCaseParams; +import com.netgrif.application.engine.workflow.params.TaskParams; import com.netgrif.application.engine.workflow.service.interfaces.ITaskService; import com.netgrif.application.engine.workflow.service.interfaces.IWorkflowService; import com.netgrif.application.engine.workflow.web.responsebodies.TaskReference; @@ -170,11 +171,17 @@ public void finishTasksTest() throws TransitionNotExecutableException { private void assertInhibArcsFinishTask(List tasks) throws TransitionNotExecutableException { for (TaskReference taskRef : tasks) { Task task = taskService.findOne(taskRef.getStringId()); - taskService.assignTask(task, testUser); + taskService.assignTask(TaskParams.with() + .task(task) + .user(testUser) + .build()); finishCase = workflowService.findOne(task.getCaseId()); assert !finishCase.getActivePlaces().containsKey(task.getTitle().getDefaultValue() + "_start") && !finishCase.getActivePlaces().containsKey(task.getTitle().getDefaultValue() + "_res"); - taskService.finishTask(task, testUser); + taskService.finishTask(TaskParams.with() + .task(task) + .user(testUser) + .build()); finishCase = workflowService.findOne(task.getCaseId()); assert !finishCase.getActivePlaces().containsKey(task.getTitle().getDefaultValue() + "_start") && finishCase.getActivePlaces().containsKey(task.getTitle().getDefaultValue() + "_res"); @@ -186,12 +193,18 @@ private void assertReadArcsFinishTask(List tasks) throws Transiti Task task = taskService.findOne(taskRef.getStringId()); int markingBeforeAssign = 0; markingBeforeAssign = finishCase.getActivePlaces().get(task.getTitle().getDefaultValue() + "_start"); - taskService.assignTask(task, testUser); + taskService.assignTask(TaskParams.with() + .task(task) + .user(testUser) + .build()); finishCase = workflowService.findOne(task.getCaseId()); assert markingBeforeAssign == finishCase.getActivePlaces().get(task.getTitle().getDefaultValue() + "_start"); - taskService.finishTask(task, testUser); + taskService.finishTask(TaskParams.with() + .task(task) + .user(testUser) + .build()); finishCase = workflowService.findOne(task.getCaseId()); assert markingBeforeAssign == finishCase.getActivePlaces().get(task.getTitle().getDefaultValue() + "_start") && @@ -203,12 +216,18 @@ private void assertFinishTasks(String arcType, List tasks) throws List filteredTasks = tasks.stream().filter(task -> task.getTitle().contains(arcType)).collect(Collectors.toList()); for (TaskReference taskRef : filteredTasks) { Task task = taskService.findOne(taskRef.getStringId()); - taskService.assignTask(task, testUser); + taskService.assignTask(TaskParams.with() + .task(task) + .user(testUser) + .build()); finishCase = workflowService.findOne(task.getCaseId()); assert !finishCase.getActivePlaces().containsKey(task.getTitle().getDefaultValue() + "_start"); - taskService.finishTask(task, testUser); + taskService.finishTask(TaskParams.with() + .task(task) + .user(testUser) + .build()); finishCase = workflowService.findOne(task.getCaseId()); assert !finishCase.getActivePlaces().containsKey(task.getTitle().getDefaultValue() + "_start") && @@ -220,12 +239,18 @@ private void assertOutArcsFinishTasks(List tasks) throws Transiti List filteredTasks = tasks.stream().filter(task -> task.getTitle().equals("var_arc_out") || task.getTitle().equals("place_var_arc_out")).collect(Collectors.toList()); for (TaskReference taskRef : filteredTasks) { Task task = taskService.findOne(taskRef.getStringId()); - taskService.assignTask(task, testUser); + taskService.assignTask(TaskParams.with() + .task(task) + .user(testUser) + .build()); finishCase = workflowService.findOne(task.getCaseId()); assert !finishCase.getActivePlaces().containsKey(task.getTitle().getDefaultValue() + "_end"); - taskService.finishTask(task, testUser); + taskService.finishTask(TaskParams.with() + .task(task) + .user(testUser) + .build()); finishCase = workflowService.findOne(task.getCaseId()); assert finishCase.getActivePlaces().containsKey(task.getTitle().getDefaultValue() + "_end") && @@ -261,7 +286,10 @@ private void assertCancelTasks(String arcType, List tasks) throws if (!arcType.equals("inhib")) { tokensBeforeAssign = cancelCase.getActivePlaces().get(task.getTitle().getDefaultValue() + "_start"); } - taskService.assignTask(task, testUser); + taskService.assignTask(TaskParams.with() + .task(task) + .user(testUser) + .build()); cancelCase = workflowService.findOne(task.getCaseId()); assert !cancelCase.getActivePlaces().containsKey(task.getTitle().getDefaultValue() + "_res"); if (arcType.equals("read")) { @@ -277,11 +305,20 @@ private void assertCancelTasks(String arcType, List tasks) throws if (task.getTitle().getDefaultValue().contains("ref")) { QTask qTask = new QTask("task"); Task addTokensTask = taskService.searchOne(qTask.transitionId.eq("add_tokens").and(qTask.caseId.eq(cancelCase.getStringId()))); - taskService.assignTask(ActorTransformer.toLoggedUser(testUser), addTokensTask.getStringId()); - taskService.finishTask(addTokensTask, testUser); + taskService.assignTask(TaskParams.with() + .task(addTokensTask) + .user(testUser) + .build()); + taskService.finishTask(TaskParams.with() + .task(addTokensTask) + .user(testUser) + .build()); } int tokensAfterCancel = 0; - taskService.cancelTask(task, testUser); + taskService.cancelTask(TaskParams.with() + .task(task) + .user(testUser) + .build()); cancelCase = workflowService.findOne(task.getCaseId()); if (!arcType.equals("inhib")) { tokensAfterCancel = cancelCase.getActivePlaces().get(task.getTitle().getDefaultValue() + "_start"); @@ -301,8 +338,14 @@ private void assertCancelTasks(String arcType, List tasks) throws if (task.getTitle().getDefaultValue().contains("ref")) { QTask qTask = new QTask("task"); Task removeTokensTask = taskService.searchOne(qTask.transitionId.eq("remove_tokens").and(qTask.caseId.eq(cancelCase.getStringId()))); - taskService.assignTask(ActorTransformer.toLoggedUser(testUser), removeTokensTask.getStringId()); - taskService.finishTask(removeTokensTask, testUser); + taskService.assignTask(TaskParams.with() + .task(removeTokensTask) + .user(testUser) + .build()); + taskService.finishTask(TaskParams.with() + .task(removeTokensTask) + .user(testUser) + .build()); tasksAfterPlaceRefReset = taskService.findAllByCase(cancelCase.getStringId(), LocaleContextHolder.getLocale()); } } @@ -312,12 +355,18 @@ private void assertOutArcsCancelTasks(List tasks) throws Transiti List filteredTasks = tasks.stream().filter(task -> task.getTitle().equals("var_arc_out") || task.getTitle().equals("place_var_arc_out")).collect(Collectors.toList()); for (TaskReference taskRef : filteredTasks) { Task task = taskService.findOne(taskRef.getStringId()); - taskService.assignTask(task, testUser); + taskService.assignTask(TaskParams.with() + .task(task) + .user(testUser) + .build()); cancelCase = workflowService.findOne(task.getCaseId()); assert !cancelCase.getActivePlaces().containsKey(task.getTitle().getDefaultValue() + "_end"); - taskService.cancelTask(task, testUser); + taskService.cancelTask(TaskParams.with() + .task(task) + .user(testUser) + .build()); cancelCase = workflowService.findOne(task.getCaseId()); assert !cancelCase.getActivePlaces().containsKey(task.getTitle().getDefaultValue() + "_res"); From 0e36c5f7937771b1f8caef15d8bd832e2da29fe4 Mon Sep 17 00:00:00 2001 From: chvostek Date: Wed, 22 Oct 2025 16:39:41 +0200 Subject: [PATCH 14/55] [NAE-2235] Improve Efficiency of Database Reads and Saves - optimize TaskService.assignTask --- .../engine/workflow/service/TaskService.java | 34 +++++++------------ .../workflow/service/WorkflowService.java | 1 - 2 files changed, 13 insertions(+), 22 deletions(-) diff --git a/application-engine/src/main/java/com/netgrif/application/engine/workflow/service/TaskService.java b/application-engine/src/main/java/com/netgrif/application/engine/workflow/service/TaskService.java index f87fc889b5..f80a9d68ad 100644 --- a/application-engine/src/main/java/com/netgrif/application/engine/workflow/service/TaskService.java +++ b/application-engine/src/main/java/com/netgrif/application/engine/workflow/service/TaskService.java @@ -2,8 +2,6 @@ import com.google.common.collect.Ordering; import com.netgrif.application.engine.objects.auth.domain.AbstractUser; -import com.netgrif.application.engine.objects.auth.domain.ActorTransformer; -import com.netgrif.application.engine.workflow.domain.TaskNotFoundException; import com.netgrif.application.engine.objects.auth.domain.LoggedUser; import com.netgrif.application.engine.auth.service.UserService; import com.netgrif.application.engine.elastic.service.interfaces.IElasticTaskMappingService; @@ -102,9 +100,6 @@ public class TaskService implements ITaskService { protected IElasticTaskService elasticTaskService; -// @Autowired -// protected IHistoryService historyService; - @Autowired protected IValidationService validation; @@ -114,9 +109,6 @@ public void setElasticTaskService(IElasticTaskService elasticTaskService) { this.elasticTaskService = elasticTaskService; } -// @Autowired -// private IRuleEngine ruleEngine; - @Override public List assignTasks(List tasks, AbstractUser user) throws TransitionNotExecutableException { return assignTasks(tasks, user, new HashMap<>()); @@ -142,17 +134,20 @@ public AssignTaskEventOutcome assignTask(TaskParams taskParams) throws Transitio Case useCase = taskParams.getUseCase(); Task task = taskParams.getTask(); Transition transition = useCase.getPetriNet().getTransition(task.getTransitionId()); + List outcomes = new ArrayList<>(eventService.runActions(transition.getPreAssignActions(), useCase, task, transition, taskParams.getParams())); - task = findOne(task.getStringId()); + if (!outcomes.isEmpty()) { + useCase = workflowService.findOne(useCase.getStringId()); + } AssignTaskEventOutcome outcome = new AssignTaskEventOutcome(useCase, task, outcomes); useCase = evaluateRules(new AssignTaskEvent(outcome, EventPhase.PRE)); - useCase = assignTaskToUser(taskParams.getUser(), task, useCase.getStringId()); + + useCase = assignTaskToUser(taskParams.getUser(), task, useCase, transition); publisher.publishEvent(new AssignTaskEvent(outcome, EventPhase.PRE, taskParams.getUser())); outcomes.addAll((eventService.runActions(transition.getPostAssignActions(), useCase, task, transition, taskParams.getParams()))); - useCase = evaluateRules(new AssignTaskEvent(new AssignTaskEventOutcome(useCase, task, outcomes), EventPhase.POST)); + useCase = evaluateRules(new AssignTaskEvent(outcome, EventPhase.POST)); - outcome = new AssignTaskEventOutcome(useCase, task, outcomes); publisher.publishEvent(new AssignTaskEvent(outcome, EventPhase.POST, taskParams.getUser())); addMessageToOutcome(transition, EventType.ASSIGN, outcome); // TODO: impersonation user.getSelfOrImpersonated().getEmail() @@ -162,13 +157,11 @@ public AssignTaskEventOutcome assignTask(TaskParams taskParams) throws Transitio return outcome; } - protected Case assignTaskToUser(AbstractUser user, Task task, String useCaseId) throws TransitionNotExecutableException { - Case useCase = workflowService.findOne(useCaseId); + protected Case assignTaskToUser(AbstractUser user, Task task, Case useCase, Transition transition) throws TransitionNotExecutableException { useCase.getPetriNet().initializeArcs(); - Transition transition = useCase.getPetriNet().getTransition(task.getTransitionId()); // TODO: impersonation user.getSelfOrImpersonated().getEmail() - log.info("[{}]: Assigning task [{}] to user [{}]", useCaseId, task.getTitle(), user.getEmail()); + log.info("[{}]: Assigning task [{}] to user [{}]", useCase.getStringId(), task.getTitle(), user.getEmail()); startExecution(transition, useCase); // TODO: impersonation @@ -393,7 +386,7 @@ public DelegateTaskEventOutcome delegateTask(LoggedUser loggedUser, String deleg task = findOne(task.getStringId()); DelegateTaskEventOutcome outcome = new DelegateTaskEventOutcome(useCase, task, outcomes); useCase = evaluateRules(new DelegateTaskEvent(outcome, EventPhase.PRE)); - delegate(delegatedUser, task, useCase); + delegate(delegatedUser, task, useCase, transition); publisher.publishEvent(new DelegateTaskEvent(outcome, EventPhase.PRE, delegateUser, delegatedUser.getStringId())); outcomes.addAll(eventService.runActions(transition.getPostDelegateActions(), useCase, task, transition, params)); useCase = evaluateRules(new DelegateTaskEvent(new DelegateTaskEventOutcome(useCase, task, outcomes), EventPhase.POST)); @@ -411,14 +404,14 @@ public DelegateTaskEventOutcome delegateTask(LoggedUser loggedUser, String deleg return outcome; } - protected void delegate(AbstractUser delegated, Task task, Case useCase) throws TransitionNotExecutableException { + protected void delegate(AbstractUser delegated, Task task, Case useCase, Transition transition) throws TransitionNotExecutableException { if (task.getUserId() != null) { task.setUserId(delegated.getStringId()); task.setUserRealmId(delegated.getRealmId()); task.setUser(delegated); save(task); } else { - assignTaskToUser(delegated, task, useCase.getStringId()); + assignTaskToUser(delegated, task, useCase, transition); } } @@ -932,11 +925,10 @@ private void setUser(Task task) { } } - private EventOutcome addMessageToOutcome(Transition transition, EventType type, TaskEventOutcome outcome) { + private void addMessageToOutcome(Transition transition, EventType type, TaskEventOutcome outcome) { if (transition.getEvents().containsKey(type)) { outcome.setMessage(transition.getEvents().get(type).getMessage()); } - return outcome; } @Override diff --git a/application-engine/src/main/java/com/netgrif/application/engine/workflow/service/WorkflowService.java b/application-engine/src/main/java/com/netgrif/application/engine/workflow/service/WorkflowService.java index cb9842a64f..fc4045549f 100644 --- a/application-engine/src/main/java/com/netgrif/application/engine/workflow/service/WorkflowService.java +++ b/application-engine/src/main/java/com/netgrif/application/engine/workflow/service/WorkflowService.java @@ -295,7 +295,6 @@ public CreateCaseEventOutcome createCase(CreateCaseParams createCaseParams) { save(useCase); } - outcome.addOutcomes(eventService.runActions(petriNet.getPostCreateActions(), useCase, Optional.empty(), createCaseParams.getParams())); From eb619dbace8428a448e739577b99420377347169 Mon Sep 17 00:00:00 2001 From: chvostek Date: Tue, 28 Oct 2025 19:12:10 +0100 Subject: [PATCH 15/55] [NAE-2235] Improve Efficiency of Database Reads and Saves - more optimization for TaskService.assignTask --- .../application/engine/workflow/service/TaskService.java | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/application-engine/src/main/java/com/netgrif/application/engine/workflow/service/TaskService.java b/application-engine/src/main/java/com/netgrif/application/engine/workflow/service/TaskService.java index f80a9d68ad..86247d9a84 100644 --- a/application-engine/src/main/java/com/netgrif/application/engine/workflow/service/TaskService.java +++ b/application-engine/src/main/java/com/netgrif/application/engine/workflow/service/TaskService.java @@ -173,8 +173,10 @@ protected Case assignTaskToUser(AbstractUser user, Task task, Case useCase, Tran useCase = workflowService.save(useCase); save(task); - reloadTasks(useCase, false); - useCase = workflowService.findOne(useCase.getStringId()); + ReloadTaskOutcome reloadTaskOutcome = reloadTasks(useCase, false); + if (reloadTaskOutcome.isAnyTaskExecuted()) { + useCase = workflowService.findOne(useCase.getStringId()); + } return useCase; } From da52d1a079d41e4872c9213cc35c2f0e7117865f Mon Sep 17 00:00:00 2001 From: chvostek Date: Tue, 28 Oct 2025 19:44:19 +0100 Subject: [PATCH 16/55] [NAE-2235] Improve Efficiency of Database Reads and Saves - optimize TaskService.cancelTask and TaskService.cancelTasksWithoutReload --- .../engine/workflow/service/TaskService.java | 55 ++++++++++++------- .../workflow/WorkflowPerformanceTest.java | 10 +++- 2 files changed, 42 insertions(+), 23 deletions(-) diff --git a/application-engine/src/main/java/com/netgrif/application/engine/workflow/service/TaskService.java b/application-engine/src/main/java/com/netgrif/application/engine/workflow/service/TaskService.java index 86247d9a84..4209035c65 100644 --- a/application-engine/src/main/java/com/netgrif/application/engine/workflow/service/TaskService.java +++ b/application-engine/src/main/java/com/netgrif/application/engine/workflow/service/TaskService.java @@ -269,6 +269,8 @@ public List cancelTasks(List tasks, AbstractUser u @Override public CancelTaskEventOutcome cancelTask(TaskParams taskParams) { + fillMissingAttributes(taskParams); + Task task = taskParams.getTask(); Case useCase = taskParams.getUseCase(); AbstractUser user = taskParams.getUser(); @@ -279,16 +281,21 @@ public CancelTaskEventOutcome cancelTask(TaskParams taskParams) { List outcomes = new ArrayList<>(eventService.runActions(transition.getPreCancelActions(), useCase, task, transition, taskParams.getParams())); - task = findOne(task.getStringId()); + if (!outcomes.isEmpty()) { + useCase = workflowService.findOne(useCase.getStringId()); + } CancelTaskEventOutcome outcome = new CancelTaskEventOutcome(useCase, task, outcomes); useCase = evaluateRules(new CancelTaskEvent(outcome, EventPhase.PRE)); - task = returnTokens(task, useCase.getStringId()); - useCase = workflowService.findOne(useCase.getStringId()); - reloadTasks(useCase, false); - useCase = workflowService.findOne(useCase.getStringId()); + + useCase = returnTokens(task, useCase); + ReloadTaskOutcome reloadTaskOutcome = reloadTasks(useCase, false); + if (reloadTaskOutcome.isAnyTaskExecuted()) { + useCase = workflowService.findOne(useCase.getStringId()); + } + publisher.publishEvent(new CancelTaskEvent(outcome, EventPhase.POST, user)); outcomes.addAll(eventService.runActions(transition.getPostCancelActions(), useCase, task, transition, taskParams.getParams())); - useCase = evaluateRules(new CancelTaskEvent(new CancelTaskEventOutcome(useCase, task, outcomes), EventPhase.POST)); + useCase = evaluateRules(new CancelTaskEvent(outcome, EventPhase.POST)); outcome = new CancelTaskEventOutcome(useCase, task); outcome.setOutcomes(outcomes); @@ -317,14 +324,21 @@ public void cancelTasksWithoutReload(Set transitions, String caseId, Map List tasks = taskRepository.findAllByTransitionIdInAndCaseId(transitions, caseId); Case useCase = null; for (Task task : tasks) { - if (task.getUserId() != null) { - if (useCase == null) - useCase = workflowService.findOne(task.getCaseId()); - Transition transition = useCase.getPetriNet().getTransition(task.getTransitionId()); - eventService.runActions(transition.getPreCancelActions(), useCase, task, transition, params); - returnTokens(task, useCase.getStringId()); - eventService.runActions(transition.getPostCancelActions(), useCase, task, transition, params); + if (task.getUserId() == null) { + continue; + } + if (useCase == null) { + useCase = workflowService.findOne(task.getCaseId()); } + + Transition transition = useCase.getPetriNet().getTransition(task.getTransitionId()); + boolean anyActionExecuted = eventService.runActions(transition.getPreCancelActions(), useCase, task, + transition, params).isEmpty(); + if (anyActionExecuted) { + useCase = workflowService.findOne(useCase.getStringId()); + } + returnTokens(task, useCase); + eventService.runActions(transition.getPostCancelActions(), useCase, task, transition, params); } } @@ -343,24 +357,25 @@ protected void fillMissingAttributes(TaskParams taskParams) { } } - private Task returnTokens(Task task, String useCaseId) { - Case useCase = workflowService.findOne(useCaseId); + private Case returnTokens(Task task, Case useCase) { PetriNet net = useCase.getPetriNet(); + Case finalUseCase = useCase; net.getArcsOfTransition(task.getTransitionId()).stream() .filter(arc -> arc.getSource() instanceof Place) .forEach(arc -> { - arc.rollbackExecution(useCase.getConsumedTokens().get(arc.getStringId())); - useCase.getConsumedTokens().remove(arc.getStringId()); + arc.rollbackExecution(finalUseCase.getConsumedTokens().get(arc.getStringId())); + finalUseCase.getConsumedTokens().remove(arc.getStringId()); }); workflowService.updateMarking(useCase); task.setUserId(null); task.setUserRealmId(null); task.setStartDate(null); - task = save(task); - workflowService.save(useCase); - return task; + useCase = workflowService.save(useCase); + save(task); + + return useCase; } @Override diff --git a/application-engine/src/test/java/com/netgrif/application/engine/workflow/WorkflowPerformanceTest.java b/application-engine/src/test/java/com/netgrif/application/engine/workflow/WorkflowPerformanceTest.java index 9cdeb27807..382a36f973 100644 --- a/application-engine/src/test/java/com/netgrif/application/engine/workflow/WorkflowPerformanceTest.java +++ b/application-engine/src/test/java/com/netgrif/application/engine/workflow/WorkflowPerformanceTest.java @@ -8,6 +8,7 @@ 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.taskoutcomes.AssignTaskEventOutcome; import com.netgrif.application.engine.petrinet.params.ImportPetriNetParams; import com.netgrif.application.engine.petrinet.service.interfaces.IPetriNetService; import com.netgrif.application.engine.startup.runner.SuperCreatorRunner; @@ -105,6 +106,7 @@ public void testAssignPerformance() throws IOException, MissingPetriNetMetaDataE long start = System.currentTimeMillis(); taskService.assignTask(TaskParams.with() .taskId(taskId) + .useCase(useCase) .build()); long finish = System.currentTimeMillis(); totalElapsedTime += finish - start; @@ -133,6 +135,7 @@ public void testAssignWithActionPerformance() throws IOException, MissingPetriNe long start = System.currentTimeMillis(); taskService.assignTask(TaskParams.with() .taskId(taskId) + .useCase(useCase) .build()); long finish = System.currentTimeMillis(); totalElapsedTime += finish - start; @@ -158,12 +161,13 @@ public void testCancelPerformance() throws IOException, MissingPetriNetMetaDataE .locale(Locale.getDefault()) .build()).getCase(); String taskId = useCase.getTasks().stream().findFirst().get().getTask(); - Task task = taskService.assignTask(TaskParams.with() + AssignTaskEventOutcome assignOutcome = taskService.assignTask(TaskParams.with() .taskId(taskId) - .build()).getTask(); + .build()); long start = System.currentTimeMillis(); taskService.cancelTask(TaskParams.with() - .task(task) + .task(assignOutcome.getTask()) + .useCase(assignOutcome.getCase()) .user(loggedUser) .build()); long finish = System.currentTimeMillis(); From f9caa870dd079b4efa8d0b2a1e180bbe1dd39b7a Mon Sep 17 00:00:00 2001 From: chvostek Date: Wed, 29 Oct 2025 09:13:38 +0100 Subject: [PATCH 17/55] [NAE-2235] Improve Efficiency of Database Reads and Saves - optimize TaskService.finishTask --- .../engine/workflow/service/TaskService.java | 71 +++++++++++-------- .../workflow/WorkflowPerformanceTest.java | 23 +++--- 2 files changed, 56 insertions(+), 38 deletions(-) diff --git a/application-engine/src/main/java/com/netgrif/application/engine/workflow/service/TaskService.java b/application-engine/src/main/java/com/netgrif/application/engine/workflow/service/TaskService.java index 4209035c65..8161107715 100644 --- a/application-engine/src/main/java/com/netgrif/application/engine/workflow/service/TaskService.java +++ b/application-engine/src/main/java/com/netgrif/application/engine/workflow/service/TaskService.java @@ -101,7 +101,7 @@ public class TaskService implements ITaskService { protected IElasticTaskService elasticTaskService; @Autowired - protected IValidationService validation; + protected IValidationService validationService; @Lazy @Autowired @@ -221,23 +221,21 @@ public FinishTaskEventOutcome finishTask(TaskParams taskParams) throws Transitio validateData(transition, useCase); List outcomes = new ArrayList<>(eventService.runActions(transition.getPreFinishActions(), useCase, task, transition, taskParams.getParams())); - task = findOne(task.getStringId()); + if (!outcomes.isEmpty()) { + useCase = workflowService.findOne(useCase.getStringId()); + } FinishTaskEventOutcome outcome = new FinishTaskEventOutcome(useCase, task, outcomes); useCase = evaluateRules(new FinishTaskEvent(outcome, EventPhase.PRE)); - finishExecution(transition, useCase.getStringId()); - task.setFinishDate(LocalDateTime.now()); - task.setFinishedBy(task.getUserId()); - task.setUserId(null); - task.setUserRealmId(null); + useCase = finishExecution(transition, task, useCase); + ReloadTaskOutcome reloadTaskOutcome = reloadTasks(useCase, false); + if (reloadTaskOutcome.isAnyTaskExecuted()) { + useCase = workflowService.findOne(useCase.getStringId()); + } - useCase = workflowService.findOne(useCase.getStringId()); - save(task); - reloadTasks(useCase, false); - useCase = workflowService.findOne(useCase.getStringId()); publisher.publishEvent(new FinishTaskEvent(outcome, EventPhase.PRE, user)); outcomes.addAll(eventService.runActions(transition.getPostFinishActions(), useCase, task, transition, taskParams.getParams())); - useCase = evaluateRules(new FinishTaskEvent(new FinishTaskEventOutcome(useCase, task, outcomes), EventPhase.POST)); + useCase = evaluateRules(new FinishTaskEvent(outcome, EventPhase.POST)); outcome = new FinishTaskEventOutcome(useCase, task, outcomes); addMessageToOutcome(transition, EventType.FINISH, outcome); @@ -527,13 +525,21 @@ protected boolean isExecutable(Transition transition, PetriNet net) { .allMatch(Arc::isExecutable); } - protected void finishExecution(Transition transition, String useCaseId) throws TransitionNotExecutableException { - Case useCase = workflowService.findOne(useCaseId); - log.info("[{}]: Finish execution of task [{}] in case [{}]", useCaseId, transition.getTitle(), useCase.getTitle()); + protected Case finishExecution(Transition transition, Task task, Case useCase) throws TransitionNotExecutableException { + log.info("[{}]: Finish execution of task [{}] in case [{}]", useCase.getStringId(), transition.getTitle(), useCase.getTitle()); + execute(transition, useCase, arc -> arc.getSource().equals(transition)); - Supplier> arcStreamSupplier = () -> useCase.getPetriNet().getArcsOfTransition(transition.getStringId()).stream(); - arcStreamSupplier.get().filter(arc -> useCase.getConsumedTokens().containsKey(arc.getStringId())).forEach(arc -> useCase.getConsumedTokens().remove(arc.getStringId())); - workflowService.save(useCase); + useCase.getPetriNet().getArcsOfTransition(transition.getStringId()).stream() + .filter(arc -> useCase.getConsumedTokens().containsKey(arc.getStringId())) + .forEach(arc -> useCase.getConsumedTokens().remove(arc.getStringId())); + + task.setFinishDate(LocalDateTime.now()); + task.setFinishedBy(task.getUserId()); + task.setUserId(null); + task.setUserRealmId(null); + + save(task); + return workflowService.save(useCase); } public void startExecution(Transition transition, Case useCase) throws TransitionNotExecutableException { @@ -583,23 +589,30 @@ protected void executeTransition(Task task, Case useCase) { void validateData(Transition transition, Case useCase) { for (Map.Entry entry : transition.getDataSet().entrySet()) { - if (useCase.getPetriNet().getDataSet().get(entry.getKey()) != null - && useCase.getPetriNet().getDataSet().get(entry.getKey()).getValidations() != null) { - validation.valid(useCase.getPetriNet().getDataSet().get(entry.getKey()), useCase.getDataField(entry.getKey())); + Field field = useCase.getField(entry.getKey()); + DataField dataField = useCase.getDataField(entry.getKey()); + if (field != null && field.getValidations() != null) { + validationService.valid(field, dataField); } - if (!useCase.getDataField(entry.getKey()).isRequired(transition.getImportId())) - continue; - if (useCase.getDataField(entry.getKey()).isUndefined(transition.getImportId()) && !entry.getValue().isRequired()) + if (!dataField.isRequired(transition.getImportId()) + || dataField.isUndefined(transition.getImportId()) && !entry.getValue().isRequired()) { continue; + } - Object value = useCase.getDataSet().get(entry.getKey()).getValue(); + Object value = dataField.getValue(); if (value == null) { - Field field = useCase.getField(entry.getKey()); - throw new IllegalArgumentException("Field \"" + field.getName() + "\" has null value"); + if (field == null) { + throw new IllegalArgumentException("Some field has null value"); + } else { + throw new IllegalArgumentException("Field \"%s\" has null value".formatted(field.getName())); + } } if (value instanceof String && ((String) value).isEmpty()) { - Field field = useCase.getField(entry.getKey()); - throw new IllegalArgumentException("Field \"" + field.getName() + "\" has empty value"); + if (field == null) { + throw new IllegalArgumentException("Some field has empty value"); + } else { + throw new IllegalArgumentException("Field \"%s\" has empty value".formatted(field.getName())); + } } } } diff --git a/application-engine/src/test/java/com/netgrif/application/engine/workflow/WorkflowPerformanceTest.java b/application-engine/src/test/java/com/netgrif/application/engine/workflow/WorkflowPerformanceTest.java index 382a36f973..8f03a879cb 100644 --- a/application-engine/src/test/java/com/netgrif/application/engine/workflow/WorkflowPerformanceTest.java +++ b/application-engine/src/test/java/com/netgrif/application/engine/workflow/WorkflowPerformanceTest.java @@ -194,12 +194,13 @@ public void testCancelWithActionPerformance() throws IOException, MissingPetriNe .locale(Locale.getDefault()) .build()).getCase(); String taskId = useCase.getTasks().stream().findFirst().get().getTask(); - Task task = taskService.assignTask(TaskParams.with() + AssignTaskEventOutcome assignOutcome = taskService.assignTask(TaskParams.with() .taskId(taskId) - .build()).getTask(); + .build()); long start = System.currentTimeMillis(); taskService.cancelTask(TaskParams.with() - .task(task) + .task(assignOutcome.getTask()) + .useCase(assignOutcome.getCase()) .user(loggedUser) .build()); long finish = System.currentTimeMillis(); @@ -226,12 +227,14 @@ public void testFinishPerformance() throws IOException, MissingPetriNetMetaDataE .locale(Locale.getDefault()) .build()).getCase(); String taskId = useCase.getTasks().stream().findFirst().get().getTask(); - Task task = taskService.assignTask(TaskParams.with() + AssignTaskEventOutcome assignOutcome = taskService.assignTask(TaskParams.with() .taskId(taskId) - .build()).getTask(); + .user(loggedUser) + .build()); long start = System.currentTimeMillis(); taskService.finishTask(TaskParams.with() - .task(task) + .task(assignOutcome.getTask()) + .useCase(assignOutcome.getCase()) .user(loggedUser) .build()); long finish = System.currentTimeMillis(); @@ -258,12 +261,14 @@ public void testFinishWithActionPerformance() throws IOException, MissingPetriNe .locale(Locale.getDefault()) .build()).getCase(); String taskId = useCase.getTasks().stream().findFirst().get().getTask(); - Task task = taskService.assignTask(TaskParams.with() + AssignTaskEventOutcome assignOutcome = taskService.assignTask(TaskParams.with() .taskId(taskId) - .build()).getTask(); + .user(loggedUser) + .build()); long start = System.currentTimeMillis(); taskService.finishTask(TaskParams.with() - .task(task) + .task(assignOutcome.getTask()) + .useCase(assignOutcome.getCase()) .user(loggedUser) .build()); long finish = System.currentTimeMillis(); From 01fc5fe4c4900be17999ed065596e3a5bb6cdc52 Mon Sep 17 00:00:00 2001 From: chvostek Date: Wed, 29 Oct 2025 10:12:47 +0100 Subject: [PATCH 18/55] [NAE-2235] Improve Efficiency of Database Reads and Saves - optimize TaskService.delegateTask --- .../workflow/params/DelegateTaskParams.java | 29 ++++++ .../engine/workflow/service/TaskService.java | 88 +++++++++++++------ .../service/interfaces/ITaskService.java | 8 +- .../workflow/web/AbstractTaskController.java | 7 +- 4 files changed, 97 insertions(+), 35 deletions(-) create mode 100644 application-engine/src/main/java/com/netgrif/application/engine/workflow/params/DelegateTaskParams.java diff --git a/application-engine/src/main/java/com/netgrif/application/engine/workflow/params/DelegateTaskParams.java b/application-engine/src/main/java/com/netgrif/application/engine/workflow/params/DelegateTaskParams.java new file mode 100644 index 0000000000..6a25f62233 --- /dev/null +++ b/application-engine/src/main/java/com/netgrif/application/engine/workflow/params/DelegateTaskParams.java @@ -0,0 +1,29 @@ +package com.netgrif.application.engine.workflow.params; + +import com.netgrif.application.engine.objects.auth.domain.AbstractUser; +import com.netgrif.application.engine.objects.workflow.domain.Case; +import com.netgrif.application.engine.objects.workflow.domain.Task; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; + +import java.util.HashMap; +import java.util.Map; + +@Data +@AllArgsConstructor +@Builder(builderMethodName = "with") +public class DelegateTaskParams { + + // todo javadoc + + private String taskId; + private Task task; + private Case useCase; + private AbstractUser newAssignee; + private String newAssigneeId; + private AbstractUser delegator; + private String delegatorId; + @Builder.Default + private Map params = new HashMap<>(); +} diff --git a/application-engine/src/main/java/com/netgrif/application/engine/workflow/service/TaskService.java b/application-engine/src/main/java/com/netgrif/application/engine/workflow/service/TaskService.java index 8161107715..fcec72492d 100644 --- a/application-engine/src/main/java/com/netgrif/application/engine/workflow/service/TaskService.java +++ b/application-engine/src/main/java/com/netgrif/application/engine/workflow/service/TaskService.java @@ -30,6 +30,7 @@ import com.netgrif.application.engine.workflow.domain.repositories.TaskRepository; import com.netgrif.application.engine.objects.workflow.domain.triggers.TimeTrigger; import com.netgrif.application.engine.objects.workflow.domain.triggers.Trigger; +import com.netgrif.application.engine.workflow.params.DelegateTaskParams; import com.netgrif.application.engine.workflow.params.TaskParams; import com.netgrif.application.engine.workflow.service.interfaces.IDataService; import com.netgrif.application.engine.workflow.service.interfaces.IEventService; @@ -355,6 +356,37 @@ protected void fillMissingAttributes(TaskParams taskParams) { } } + protected void fillMissingAttributes(DelegateTaskParams taskParams) { + if (taskParams.getTask() == null) { + Task task = findOne(taskParams.getTaskId()); + taskParams.setTask(task); + } + if (taskParams.getUseCase() == null) { + Case useCase = workflowService.findOne(taskParams.getTask().getCaseId()); + taskParams.setUseCase(useCase); + } + if (taskParams.getDelegator() == null) { + if (taskParams.getDelegatorId() == null) { + throw new IllegalArgumentException("Delegate user is not specified."); + } + AbstractUser delegator = userService.findById(taskParams.getDelegatorId(), null); + if (delegator == null) { + throw new IllegalArgumentException("Such user [%s] does not exist.".formatted(taskParams.getDelegatorId())); + } + taskParams.setDelegator(delegator); + } + if (taskParams.getNewAssignee() == null) { + if (taskParams.getNewAssigneeId() == null) { + throw new IllegalArgumentException("New assignee is not specified."); + } + AbstractUser newAssignee = userService.findById(taskParams.getNewAssigneeId(), null); + if (newAssignee == null) { + throw new IllegalArgumentException("Such user [%s] does not exist.".formatted(taskParams.getNewAssigneeId())); + } + taskParams.setNewAssignee(newAssignee); + } + } + private Case returnTokens(Task task, Case useCase) { PetriNet net = useCase.getPetriNet(); Case finalUseCase = useCase; @@ -377,56 +409,56 @@ private Case returnTokens(Task task, Case useCase) { } @Override - public DelegateTaskEventOutcome delegateTask(LoggedUser loggedUser, String delegatedId, String taskId) throws TransitionNotExecutableException { - return delegateTask(loggedUser, delegatedId, taskId, new HashMap<>()); - } + public DelegateTaskEventOutcome delegateTask(DelegateTaskParams delegateTaskParams) throws TransitionNotExecutableException { + fillMissingAttributes(delegateTaskParams); - @Override - public DelegateTaskEventOutcome delegateTask(LoggedUser loggedUser, String delegatedId, String taskId, Map params) throws TransitionNotExecutableException { - AbstractUser delegatedUser = userService.findById(delegatedId, null); - AbstractUser delegateUser = getUserFromLoggedUser(loggedUser); - - Optional taskOptional = findOptionalById(taskId); - if (taskOptional.isEmpty()) { - throw new IllegalArgumentException("Could not find task with id [" + taskId + "]"); - } - Task task = taskOptional.get(); - - Case useCase = workflowService.findOne(task.getCaseId()); + AbstractUser newAssignee = delegateTaskParams.getNewAssignee(); + AbstractUser delegator = delegateTaskParams.getDelegator(); + Task task = delegateTaskParams.getTask(); + Case useCase = delegateTaskParams.getUseCase(); Transition transition = useCase.getPetriNet().getTransition(task.getTransitionId()); - log.info("[{}]: Delegating task [{}] to user [{}]", useCase.getStringId(), task.getTitle(), delegatedUser.getEmail()); + log.info("[{}]: Delegating task [{}] to user [{}]", useCase.getStringId(), task.getTitle(), newAssignee.getEmail()); + + List outcomes = new ArrayList<>(eventService.runActions(transition.getPreDelegateActions(), useCase, + task, transition, delegateTaskParams.getParams())); + if (!outcomes.isEmpty()) { + useCase = workflowService.findOne(useCase.getStringId()); + } - List outcomes = new ArrayList<>(eventService.runActions(transition.getPreDelegateActions(), useCase, task, transition, params)); - task = findOne(task.getStringId()); DelegateTaskEventOutcome outcome = new DelegateTaskEventOutcome(useCase, task, outcomes); useCase = evaluateRules(new DelegateTaskEvent(outcome, EventPhase.PRE)); - delegate(delegatedUser, task, useCase, transition); - publisher.publishEvent(new DelegateTaskEvent(outcome, EventPhase.PRE, delegateUser, delegatedUser.getStringId())); - outcomes.addAll(eventService.runActions(transition.getPostDelegateActions(), useCase, task, transition, params)); + publisher.publishEvent(new DelegateTaskEvent(outcome, EventPhase.PRE, delegator, newAssignee.getStringId())); + + useCase = delegate(newAssignee, task, useCase, transition); + + outcomes.addAll(eventService.runActions(transition.getPostDelegateActions(), useCase, task, transition, + delegateTaskParams.getParams())); useCase = evaluateRules(new DelegateTaskEvent(new DelegateTaskEventOutcome(useCase, task, outcomes), EventPhase.POST)); - useCase = workflowService.findOne(useCase.getStringId()); - reloadTasks(useCase, false); + ReloadTaskOutcome reloadTaskOutcome = reloadTasks(useCase, false); + if (reloadTaskOutcome.isAnyTaskExecuted()) { + useCase = workflowService.findOne(useCase.getStringId()); + } - outcome = new DelegateTaskEventOutcome(useCase, task, outcomes); addMessageToOutcome(transition, EventType.DELEGATE, outcome); - publisher.publishEvent(new DelegateTaskEvent(outcome, EventPhase.POST, delegateUser, delegatedUser.getStringId())); + publisher.publishEvent(new DelegateTaskEvent(outcome, EventPhase.POST, delegator, newAssignee.getStringId())); // TODO: impersonation log.info("Task [{}] in case [{}] assigned to [{}] was delegated to [{}]", task.getTitle(), useCase.getTitle(), - delegatedUser.getEmail(), delegatedUser.getEmail()); + newAssignee.getEmail(), newAssignee.getEmail()); return outcome; } - protected void delegate(AbstractUser delegated, Task task, Case useCase, Transition transition) throws TransitionNotExecutableException { + protected Case delegate(AbstractUser delegated, Task task, Case useCase, Transition transition) throws TransitionNotExecutableException { if (task.getUserId() != null) { task.setUserId(delegated.getStringId()); task.setUserRealmId(delegated.getRealmId()); task.setUser(delegated); save(task); + return useCase; } else { - assignTaskToUser(delegated, task, useCase, transition); + return assignTaskToUser(delegated, task, useCase, transition); } } diff --git a/application-engine/src/main/java/com/netgrif/application/engine/workflow/service/interfaces/ITaskService.java b/application-engine/src/main/java/com/netgrif/application/engine/workflow/service/interfaces/ITaskService.java index 3701b34980..39687d4634 100644 --- a/application-engine/src/main/java/com/netgrif/application/engine/workflow/service/interfaces/ITaskService.java +++ b/application-engine/src/main/java/com/netgrif/application/engine/workflow/service/interfaces/ITaskService.java @@ -11,6 +11,7 @@ import com.netgrif.application.engine.objects.workflow.domain.eventoutcomes.taskoutcomes.DelegateTaskEventOutcome; import com.netgrif.application.engine.objects.workflow.domain.eventoutcomes.taskoutcomes.FinishTaskEventOutcome; import com.netgrif.application.engine.workflow.domain.outcomes.ReloadTaskOutcome; +import com.netgrif.application.engine.workflow.params.DelegateTaskParams; import com.netgrif.application.engine.workflow.params.TaskParams; import com.netgrif.application.engine.workflow.web.requestbodies.TaskSearchRequest; import com.netgrif.application.engine.workflow.web.responsebodies.TaskReference; @@ -67,17 +68,12 @@ public interface ITaskService { CancelTaskEventOutcome cancelTask(TaskParams taskParams); - /** - * cancel task action - */ @SuppressWarnings("unused") void cancelTasksWithoutReload(Set transitions, String caseId); void cancelTasksWithoutReload(Set transitions, String caseId, Map params); - DelegateTaskEventOutcome delegateTask(LoggedUser loggedUser, String delegatedId, String taskId) throws TransitionNotExecutableException; - - DelegateTaskEventOutcome delegateTask(LoggedUser loggedUser, String delegatedId, String taskId, Map params) throws TransitionNotExecutableException; + DelegateTaskEventOutcome delegateTask(DelegateTaskParams delegateTaskParams) throws TransitionNotExecutableException; void resolveUserRef(Case useCase); diff --git a/application-engine/src/main/java/com/netgrif/application/engine/workflow/web/AbstractTaskController.java b/application-engine/src/main/java/com/netgrif/application/engine/workflow/web/AbstractTaskController.java index 104ecab794..46d8d40841 100644 --- a/application-engine/src/main/java/com/netgrif/application/engine/workflow/web/AbstractTaskController.java +++ b/application-engine/src/main/java/com/netgrif/application/engine/workflow/web/AbstractTaskController.java @@ -7,6 +7,7 @@ import com.netgrif.application.engine.elastic.service.interfaces.IElasticTaskService; import com.netgrif.application.engine.elastic.web.requestbodies.singleaslist.SingleElasticTaskSearchRequestAsList; import com.netgrif.application.engine.eventoutcomes.LocalisedEventOutcomeFactory; +import com.netgrif.application.engine.workflow.params.DelegateTaskParams; import com.netgrif.application.engine.workflow.params.TaskParams; import com.netgrif.application.engine.workflow.web.responsebodies.LocalisedTaskResource; import com.netgrif.application.engine.objects.petrinet.domain.throwable.TransitionNotExecutableException; @@ -117,7 +118,11 @@ public EntityModel assign(LoggedUser loggedUser, String public EntityModel delegate(LoggedUser loggedUser, String taskId, String delegatedId, Locale locale) { try { return EventOutcomeWithMessageResource.successMessage("LocalisedTask " + taskId + " assigned to [" + delegatedId + "]", - LocalisedEventOutcomeFactory.from(taskService.delegateTask(loggedUser, delegatedId, taskId), locale)); + LocalisedEventOutcomeFactory.from(taskService.delegateTask(DelegateTaskParams.with() + .delegator(loggedUser) + .newAssigneeId(delegatedId) + .taskId(taskId) + .build()), locale)); } catch (Exception e) { log.error("Delegating task [{}] failed: ", taskId, e); return EventOutcomeWithMessageResource.errorMessage("LocalisedTask " + taskId + " cannot be assigned"); From 40db1c324653ce451a8a6108c03d927d6605f4a2 Mon Sep 17 00:00:00 2001 From: chvostek Date: Wed, 29 Oct 2025 11:33:36 +0100 Subject: [PATCH 19/55] [NAE-2235] Improve Efficiency of Database Reads and Saves - update TaskService.fillMissingAttributes for delegateTask - update WorkflowPerformanceTest --- .../engine/workflow/service/TaskService.java | 8 +- .../workflow/WorkflowPerformanceTest.java | 78 ++++++++++++++++++- .../petriNets/test_task_event_with_action.xml | 8 ++ 3 files changed, 88 insertions(+), 6 deletions(-) diff --git a/application-engine/src/main/java/com/netgrif/application/engine/workflow/service/TaskService.java b/application-engine/src/main/java/com/netgrif/application/engine/workflow/service/TaskService.java index fcec72492d..8c921a90f2 100644 --- a/application-engine/src/main/java/com/netgrif/application/engine/workflow/service/TaskService.java +++ b/application-engine/src/main/java/com/netgrif/application/engine/workflow/service/TaskService.java @@ -366,12 +366,12 @@ protected void fillMissingAttributes(DelegateTaskParams taskParams) { taskParams.setUseCase(useCase); } if (taskParams.getDelegator() == null) { - if (taskParams.getDelegatorId() == null) { - throw new IllegalArgumentException("Delegate user is not specified."); + AbstractUser delegator = null; + if (taskParams.getDelegatorId() != null) { + delegator = userService.findById(taskParams.getDelegatorId(), null); } - AbstractUser delegator = userService.findById(taskParams.getDelegatorId(), null); if (delegator == null) { - throw new IllegalArgumentException("Such user [%s] does not exist.".formatted(taskParams.getDelegatorId())); + delegator = userService.getLoggedOrSystem(); } taskParams.setDelegator(delegator); } diff --git a/application-engine/src/test/java/com/netgrif/application/engine/workflow/WorkflowPerformanceTest.java b/application-engine/src/test/java/com/netgrif/application/engine/workflow/WorkflowPerformanceTest.java index 8f03a879cb..6b0d8a5aa2 100644 --- a/application-engine/src/test/java/com/netgrif/application/engine/workflow/WorkflowPerformanceTest.java +++ b/application-engine/src/test/java/com/netgrif/application/engine/workflow/WorkflowPerformanceTest.java @@ -7,12 +7,13 @@ import com.netgrif.application.engine.objects.petrinet.domain.throwable.MissingPetriNetMetaDataException; 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.taskoutcomes.AssignTaskEventOutcome; import com.netgrif.application.engine.petrinet.params.ImportPetriNetParams; import com.netgrif.application.engine.petrinet.service.interfaces.IPetriNetService; import com.netgrif.application.engine.startup.runner.SuperCreatorRunner; +import com.netgrif.application.engine.startup.runner.SystemUserRunner; import com.netgrif.application.engine.workflow.params.CreateCaseParams; +import com.netgrif.application.engine.workflow.params.DelegateTaskParams; import com.netgrif.application.engine.workflow.params.TaskParams; import com.netgrif.application.engine.workflow.service.TaskService; import com.netgrif.application.engine.workflow.service.WorkflowService; @@ -49,6 +50,9 @@ public class WorkflowPerformanceTest { @Autowired private SuperCreatorRunner superCreatorRunner; + @Autowired + private SystemUserRunner systemUserRunner; + @Autowired private TestHelper testHelper; @@ -82,7 +86,7 @@ public void testCreateWithActionPerformance() throws IOException, MissingPetriNe .petriNet(net) .loggedUser(superCreatorRunner.getLoggedSuper()) .locale(Locale.getDefault()) - .build()), 1000); + .build()), 5000); } @Test @@ -277,6 +281,76 @@ public void testFinishWithActionPerformance() throws IOException, MissingPetriNe log.info("AVG time for event [finishTaskWithAction] is [{} ms] for [{}] iterations", totalElapsedTime / iterations, iterations); } + @Test + public void testDelegatePerformance() throws IOException, MissingPetriNetMetaDataException, TransitionNotExecutableException { + PetriNet net = petriNetService.importPetriNet(ImportPetriNetParams.with() + .xmlFile(new FileInputStream("src/test/resources/petriNets/test_task_event.xml")) + .releaseType(VersionType.MAJOR) + .author(superCreatorRunner.getLoggedSuper()) + .build()).getNet(); + long totalElapsedTime = 0; + int iterations = 5000; + LoggedUser loggedUser = superCreatorRunner.getLoggedSuper(); + + for (int i = 0; i < iterations; i++) { + Case useCase = workflowService.createCase(CreateCaseParams.with() + .petriNet(net) + .loggedUser(loggedUser) + .locale(Locale.getDefault()) + .build()).getCase(); + String taskId = useCase.getTasks().stream().findFirst().get().getTask(); + AssignTaskEventOutcome assignOutcome = taskService.assignTask(TaskParams.with() + .taskId(taskId) + .user(loggedUser) + .build()); + long start = System.currentTimeMillis(); + taskService.delegateTask(DelegateTaskParams.with() + .task(assignOutcome.getTask()) + .useCase(assignOutcome.getCase()) + .newAssignee(systemUserRunner.getLoggedSystem()) + .delegator(loggedUser) + .build()); + long finish = System.currentTimeMillis(); + totalElapsedTime += finish - start; + } + log.info("AVG time for event [delegateTask] is [{} ms] for [{}] iterations", totalElapsedTime / iterations, iterations); + } + + @Test + public void testDelegateWithActionPerformance() throws IOException, MissingPetriNetMetaDataException, TransitionNotExecutableException { + PetriNet net = petriNetService.importPetriNet(ImportPetriNetParams.with() + .xmlFile(new FileInputStream("src/test/resources/petriNets/test_task_event_with_action.xml")) + .releaseType(VersionType.MAJOR) + .author(superCreatorRunner.getLoggedSuper()) + .build()).getNet(); + long totalElapsedTime = 0; + int iterations = 5000; + LoggedUser loggedUser = superCreatorRunner.getLoggedSuper(); + + for (int i = 0; i < iterations; i++) { + Case useCase = workflowService.createCase(CreateCaseParams.with() + .petriNet(net) + .loggedUser(loggedUser) + .locale(Locale.getDefault()) + .build()).getCase(); + String taskId = useCase.getTasks().stream().findFirst().get().getTask(); + AssignTaskEventOutcome assignOutcome = taskService.assignTask(TaskParams.with() + .taskId(taskId) + .user(loggedUser) + .build()); + long start = System.currentTimeMillis(); + taskService.delegateTask(DelegateTaskParams.with() + .task(assignOutcome.getTask()) + .useCase(assignOutcome.getCase()) + .newAssignee(systemUserRunner.getLoggedSystem()) + .delegator(loggedUser) + .build()); + long finish = System.currentTimeMillis(); + totalElapsedTime += finish - start; + } + log.info("AVG time for event [delegateTaskWithAction] is [{} ms] for [{}] iterations", totalElapsedTime / iterations, iterations); + } + @Test public void testSetDataPerformance() { diff --git a/application-engine/src/test/resources/petriNets/test_task_event_with_action.xml b/application-engine/src/test/resources/petriNets/test_task_event_with_action.xml index d1f4a0e72a..733110afd8 100644 --- a/application-engine/src/test/resources/petriNets/test_task_event_with_action.xml +++ b/application-engine/src/test/resources/petriNets/test_task_event_with_action.xml @@ -36,6 +36,14 @@ + + 1_delegate + + + print("testing delegate") + + + p1 From 565d17048ae3ac285718673825d354e9f05b704e Mon Sep 17 00:00:00 2001 From: chvostek Date: Wed, 29 Oct 2025 11:51:16 +0100 Subject: [PATCH 20/55] [NAE-2235] Improve Efficiency of Database Reads and Saves - small tweaks in DataService --- .../engine/workflow/service/DataService.java | 52 +++++++++---------- .../engine/workflow/service/TaskService.java | 14 ++--- 2 files changed, 29 insertions(+), 37 deletions(-) diff --git a/application-engine/src/main/java/com/netgrif/application/engine/workflow/service/DataService.java b/application-engine/src/main/java/com/netgrif/application/engine/workflow/service/DataService.java index f4f423792b..d879e32a17 100644 --- a/application-engine/src/main/java/com/netgrif/application/engine/workflow/service/DataService.java +++ b/application-engine/src/main/java/com/netgrif/application/engine/workflow/service/DataService.java @@ -17,7 +17,6 @@ import com.netgrif.application.engine.files.throwable.StorageException; import com.netgrif.application.engine.objects.event.events.data.GetDataEvent; import com.netgrif.application.engine.objects.event.events.data.SetDataEvent; -import com.netgrif.application.engine.history.service.IHistoryService; import com.netgrif.application.engine.importer.service.FieldFactory; import com.netgrif.application.engine.objects.petrinet.domain.Component; import com.netgrif.application.engine.objects.petrinet.domain.*; @@ -48,7 +47,6 @@ import org.apache.pdfbox.rendering.PDFRenderer; import org.apache.poi.util.IOUtils; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Value; import org.springframework.context.ApplicationEventPublisher; import org.springframework.context.i18n.LocaleContextHolder; import org.springframework.data.domain.Page; @@ -69,8 +67,6 @@ @Service public class DataService implements IDataService { - public static final int MONGO_ID_LENGTH = 24; - @Autowired protected ApplicationEventPublisher publisher; @@ -92,9 +88,6 @@ public class DataService implements IDataService { @Autowired protected IEventService eventService; - @Autowired - protected IHistoryService historyService; - @Autowired protected IPetriNetService petriNetService; @@ -127,7 +120,7 @@ public GetDataEventOutcome getData(Task task, Case useCase) { @Override public GetDataEventOutcome getData(Task task, Case useCase, Map params) { - log.info("[" + useCase.getStringId() + "]: Getting data of task " + task.getTransitionId() + " [" + task.getStringId() + "]"); + log.info("[{}]: Getting data of task {} [{}]", useCase.getStringId(), task.getTransitionId(), task.getStringId()); AbstractUser user = userService.getLoggedOrSystem(); Transition transition = useCase.getPetriNet().getTransition(task.getTransitionId()); @@ -223,7 +216,7 @@ public SetDataEventOutcome setData(Task task, ObjectNode values, Map resultDataGroups = new ArrayList<>(); List> data = getData(task, useCase).getData(); @@ -324,7 +317,7 @@ public GetDataGroupsEventOutcome getDataGroups(String taskId, Locale locale, Set for (DataGroup dataGroup : dataGroups) { resolveTaskRefOrderOnGrid(dataGroup, dataFieldMap); resultDataGroups.add(dataGroup); - log.debug("Setting groups of task " + taskId + " in case " + useCase.getTitle() + " level: " + level + " " + dataGroup.getImportId()); + log.debug("Setting groups of task {} in case {} level: {} {}", taskId, useCase.getTitle(), level, dataGroup.getImportId()); List> resources = new LinkedList<>(); for (String dataFieldId : dataGroup.getData()) { @@ -373,7 +366,7 @@ private List collectTaskRefDataGroups(TaskField taskRefField, Locale List groups = new ArrayList<>(); if (taskIds != null) { - taskIds = taskIds.stream().filter(id -> !collectedTaskIds.contains(id)).collect(Collectors.toList()); + taskIds = taskIds.stream().filter(id -> !collectedTaskIds.contains(id)).toList(); taskIds.forEach(id -> { collectedTaskIds.add(id); List taskRefDataGroups = getDataGroups(id, locale, collectedTaskIds, level + 1, taskRefField.getStringId()).getData(); @@ -432,7 +425,7 @@ public FileFieldInputStream getFileByTask(String taskId, String fieldId, boolean FileFieldInputStream fileFieldInputStream = getFileByCase(task.getCaseId(), task, fieldId, forPreview); if (fileFieldInputStream == null || fileFieldInputStream.getInputStream() == null) - throw new FileNotFoundException("File in field " + fieldId + " within task " + taskId + " was not found!"); + throw new FileNotFoundException("File in field %s within task %s was not found!".formatted(fieldId, taskId)); return fileFieldInputStream; } @@ -483,8 +476,8 @@ public FileFieldInputStream getFileByName(Case useCase, FileListField field, Str Optional fileFieldValue = field.getValue().getNamesPaths().stream().filter(namePath -> namePath.getName().equals(name)).findFirst(); if (fileFieldValue.isEmpty() || fileFieldValue.get().getPath() == null) { - log.error("File " + name + " not found!"); - throw new FileNotFoundException("File " + name + " not found!"); + log.error("File {} not found!", name); + throw new FileNotFoundException("File %s not found!".formatted(name)); } return new FileFieldInputStream(storageResolverService.resolve(field.getStorageType()).get(field, fileFieldValue.get().getPath()), name); } @@ -498,7 +491,7 @@ public FileFieldInputStream getFile(Case useCase, Task task, FileField field, bo public FileFieldInputStream getFile(Case useCase, Task task, FileField field, boolean forPreview, Map params) throws FileNotFoundException { runGetActionsFromFileField(field.getEvents(), useCase, params); if (useCase.getFieldValue(field.getStringId()) == null) { - throw new FileNotFoundException("Field " + field.getStringId() + " not found on case " + useCase.getStringId()); + throw new FileNotFoundException("Field %s not found on case %s".formatted(field.getStringId(), useCase.getStringId())); } workflowService.save(useCase); @@ -611,8 +604,10 @@ public SetDataEventOutcome saveFile(String taskId, String fieldId, MultipartFile field.getValue().setPath(path); storageService.save(field, path, multipartFile); } catch (StorageException e) { - log.error("File " + multipartFile.getOriginalFilename() + " in case " + useCase.getStringId() + " could not be saved to file field " + field.getStringId(), e); - throw new EventNotExecutableException("File " + multipartFile.getOriginalFilename() + " in case " + useCase.getStringId() + " could not be saved to file field " + field.getStringId(), e); + String msg = "File %s in case %s could not be saved to file field %s".formatted(multipartFile.getOriginalFilename(), + useCase.getStringId(), field.getStringId()); + log.error(msg, e); + throw new EventNotExecutableException(msg, e); } useCase.getDataSet().get(field.getStringId()).setValue(field.getValue()); @@ -644,8 +639,9 @@ public SetDataEventOutcome saveFiles(String taskId, String fieldId, MultipartFil field.addValue(multipartFile.getOriginalFilename(), path); storageService.save(field, path, multipartFile); } catch (StorageException e) { - log.error(e.getMessage()); - throw new EventNotExecutableException("File " + multipartFile.getOriginalFilename() + " in case " + useCase.getStringId() + " could not be saved to file list field " + field.getStringId(), e); + log.error(e.getMessage(), e); + throw new EventNotExecutableException("File %s in case %s could not be saved to file list field %s".formatted( + multipartFile.getOriginalFilename(), useCase.getStringId(), field.getStringId()), e); } } @@ -682,7 +678,7 @@ public SetDataEventOutcome deleteFile(String taskId, String fieldId, Map field = petriNet.getField(fieldId); if (field.isEmpty()) { - throw new IllegalArgumentException("Field with given id [" + fieldId + "] does not exists on Petri net [" + petriNet.getStringId() + " " + petriNet.getIdentifier() + "]"); + throw new IllegalArgumentException("Field with given id [%s] does not exists on Petri net [%s %s]".formatted( + fieldId, petriNet.getStringId(), petriNet.getIdentifier())); } return applyFieldConnectedChanges(useCase, field.get()); } @@ -815,13 +813,14 @@ private SetDataEventOutcome resolveComponentProperties(Component comp, Case useC useCase.getDataField(fieldId).addDataRefComponent(task.getTransitionId(), comp); } } else if (task == null) { - log.debug("Setting component on field " + fieldId + " in case [" + useCase.getTitle() + "] as default"); + log.debug("Setting component on field {} in case [{}] as default", fieldId, useCase.getTitle()); Component newComp = new Component("default", properties); useCase.getDataField(fieldId).setComponent(newComp); changedField.addAttribute("component", newComp); outcome.addChangedField(fieldId, changedField); } else { - log.warn("Setting properties on field " + fieldId + " on task [" + task.getStringId() + "] in case [" + useCase.getTitle() + "] failed, field dont have component!"); + log.warn("Setting properties on field {} on task [{}] in case [{}] failed, field dont have component!", + fieldId, task.getStringId(), useCase.getTitle()); } outcome.setCase(workflowService.save(useCase)); return outcome; @@ -1110,7 +1109,8 @@ public void validateCaseRefValue(List value, List allowedNets) t Set nets = new HashSet<>(allowedNets); cases.forEach(_case -> { if (!nets.contains(_case.getProcessIdentifier())) { - throw new IllegalArgumentException(String.format("Case '%s' with id '%s' cannot be added to case ref, since it is an instance of process with identifier '%s', which is not one of the allowed nets", _case.getTitle(), _case.getStringId(), _case.getProcessIdentifier())); + throw new IllegalArgumentException("Case '%s' with id '%s' cannot be added to case ref, since it is an instance of process with identifier '%s', which is not one of the allowed nets".formatted( + _case.getTitle(), _case.getStringId(), _case.getProcessIdentifier())); } }); } diff --git a/application-engine/src/main/java/com/netgrif/application/engine/workflow/service/TaskService.java b/application-engine/src/main/java/com/netgrif/application/engine/workflow/service/TaskService.java index 8c921a90f2..f82ddb9e27 100644 --- a/application-engine/src/main/java/com/netgrif/application/engine/workflow/service/TaskService.java +++ b/application-engine/src/main/java/com/netgrif/application/engine/workflow/service/TaskService.java @@ -726,7 +726,7 @@ public Page findByCases(Pageable pageable, List cases) { public Task findById(String id) { Optional taskOptional = findOptionalById(id); if (taskOptional.isEmpty()) { - throw new IllegalArgumentException("Could not find task with id [" + id + "]"); + throw new IllegalArgumentException("Could not find task with id [%s]".formatted(id)); } Task task = taskOptional.get(); this.setUser(task); @@ -737,7 +737,7 @@ public Task findById(String id) { public Optional findOptionalById(String id) { String[] parts = id.split(ProcessResourceId.ID_SEPARATOR); if (parts.length < 2) { - throw new IllegalArgumentException("Invalid NetgrifId format: " + id); + throw new IllegalArgumentException("Invalid NetgrifId format: %s".formatted(id)); } String objectIdPart = parts[1]; ObjectId objectId = new ObjectId(objectIdPart); @@ -781,7 +781,7 @@ public Page search(com.querydsl.core.types.Predicate predicate, Pageable p public Task searchOne(com.querydsl.core.types.Predicate predicate) { Page tasks = taskRepository.findAll(predicate, PageRequest.of(0, 1)); if (tasks.getTotalElements() > 0) - return tasks.getContent().get(0); + return tasks.getContent().getFirst(); return null; } @@ -1007,12 +1007,4 @@ public SetDataEventOutcome getMainOutcome(Map outco mainOutcome.addOutcomes(new ArrayList<>(outcomes.values())); return mainOutcome; } - - protected AbstractUser getUserFromLoggedUser(LoggedUser loggedUser) { - AbstractUser user = userService.findById(loggedUser.getStringId(), loggedUser.getRealmId()); - // TODO: impersonation -// AbstractUser fromLogged = userService.transformToUser((LoggedUserImpl) loggedUser); -// user.setImpersonated(fromLogged.getImpersonated()); - return user; - } } From 321fb225fe7f81464375e56b8c87f12f60a9207f Mon Sep 17 00:00:00 2001 From: chvostek Date: Wed, 29 Oct 2025 14:50:29 +0100 Subject: [PATCH 21/55] [NAE-2235] Improve Efficiency of Database Reads and Saves - light optimization of DataService.getData --- .../engine/workflow/service/DataService.java | 37 +++++++++++-------- 1 file changed, 21 insertions(+), 16 deletions(-) diff --git a/application-engine/src/main/java/com/netgrif/application/engine/workflow/service/DataService.java b/application-engine/src/main/java/com/netgrif/application/engine/workflow/service/DataService.java index d879e32a17..1dedd1d3fc 100644 --- a/application-engine/src/main/java/com/netgrif/application/engine/workflow/service/DataService.java +++ b/application-engine/src/main/java/com/netgrif/application/engine/workflow/service/DataService.java @@ -133,36 +133,41 @@ public GetDataEventOutcome getData(Task task, Case useCase, Map fieldsIds.forEach(fieldId -> { if (isForbidden(fieldId, transition, useCase.getDataField(fieldId))) return; - Field field = useCase.getPetriNet().getField(fieldId).get(); + Field field = useCase.getPetriNet().getField(fieldId).get(); outcome.addOutcomes(resolveDataEvents(field, DataEventType.GET, EventPhase.PRE, useCase, task, params)); publisher.publishEvent(new GetDataEvent(outcome, EventPhase.PRE, user)); if (outcome.getMessage() == null) { - Map dataSet = useCase.getPetriNet().getTransition(task.getTransitionId()).getDataSet(); if (field.getEvents().containsKey(DataEventType.GET) - && ((DataEvent) field.getEvents().get(DataEventType.GET)).getMessage() != null) { - outcome.setMessage(((DataEvent) field.getEvents().get(DataEventType.GET)).getMessage()); - } else if (dataSet.containsKey(fieldId) - && dataSet.get(fieldId).getEvents().containsKey(DataEventType.GET) - && dataSet.get(fieldId).getEvents().get(DataEventType.GET).getMessage() != null) { - outcome.setMessage(useCase.getPetriNet().getTransition(task.getTransitionId()).getDataSet().get(fieldId).getEvents().get(DataEventType.GET).getMessage()); + && field.getEvents().get(DataEventType.GET).getMessage() != null) { + outcome.setMessage(field.getEvents().get(DataEventType.GET).getMessage()); + } else { + Map dataSet = useCase.getPetriNet().getTransition(task.getTransitionId()).getDataSet(); + DataFieldLogic dataRef = dataSet.get(fieldId); + if (dataRef != null && dataRef.getEvents().containsKey(DataEventType.GET) + && dataRef.getEvents().get(DataEventType.GET).getMessage() != null) { + outcome.setMessage(dataRef.getEvents().get(DataEventType.GET).getMessage()); + } } } if (useCase.hasFieldBehavior(fieldId, transition.getStringId())) { - if (useCase.getDataSet().get(fieldId).isDisplayable(transition.getStringId())) { + DataField dataField = useCase.getDataSet().get(fieldId); + if (dataField.isDisplayable(transition.getStringId())) { Field validationField = fieldFactory.buildFieldWithValidation(useCase, fieldId, transition.getStringId()); - validationField.setBehavior(useCase.getDataSet().get(fieldId).applyBehavior(transition.getStringId())); - if (transition.getDataSet().get(fieldId).layoutExist() && transition.getDataSet().get(fieldId).getLayout().layoutFilled()) { - validationField.setLayout(transition.getDataSet().get(fieldId).getLayout().clone()); + validationField.setBehavior(dataField.applyBehavior(transition.getStringId())); + DataFieldLogic dataRef = transition.getDataSet().get(fieldId); + if (dataRef.layoutExist() && dataRef.getLayout().layoutFilled()) { + validationField.setLayout(dataRef.getLayout().clone()); } dataSetFields.add(validationField); } } else { - if (transition.getDataSet().get(fieldId).isDisplayable()) { + DataFieldLogic dataRef = transition.getDataSet().get(fieldId); + if (dataRef.isDisplayable()) { Field validationField = fieldFactory.buildFieldWithValidation(useCase, fieldId, transition.getStringId()); - validationField.setBehavior(transition.getDataSet().get(fieldId).applyBehavior()); - if (transition.getDataSet().get(fieldId).layoutExist() && transition.getDataSet().get(fieldId).getLayout().layoutFilled()) { - validationField.setLayout(transition.getDataSet().get(fieldId).getLayout().clone()); + validationField.setBehavior(dataRef.applyBehavior()); + if (dataRef.layoutExist() && dataRef.getLayout().layoutFilled()) { + validationField.setLayout(dataRef.getLayout().clone()); } dataSetFields.add(validationField); } From d5e6b99f88f335e8c940167b37d3010333f90936 Mon Sep 17 00:00:00 2001 From: chvostek Date: Wed, 29 Oct 2025 15:16:38 +0100 Subject: [PATCH 22/55] [NAE-2235] Improve Efficiency of Database Reads and Saves - light optimization of DataService.setData --- .../engine/workflow/service/DataService.java | 133 +++++++++--------- .../engine/workflow/service/EventService.java | 7 +- 2 files changed, 73 insertions(+), 67 deletions(-) diff --git a/application-engine/src/main/java/com/netgrif/application/engine/workflow/service/DataService.java b/application-engine/src/main/java/com/netgrif/application/engine/workflow/service/DataService.java index 1dedd1d3fc..5d8c93bab6 100644 --- a/application-engine/src/main/java/com/netgrif/application/engine/workflow/service/DataService.java +++ b/application-engine/src/main/java/com/netgrif/application/engine/workflow/service/DataService.java @@ -230,70 +230,74 @@ public SetDataEventOutcome setData(Task task, ObjectNode values, Map { String fieldId = entry.getKey(); DataField dataField = useCase.getDataSet().get(fieldId); - if (dataField != null) { - Field field = useCase.getPetriNet().getField(fieldId).get(); - outcome.addOutcomes(resolveDataEvents(field, DataEventType.SET, EventPhase.PRE, useCase, task, params)); - if (outcome.getMessage() == null) { + if (dataField == null) { + return; + } + + Field field = useCase.getPetriNet().getField(fieldId).get(); + outcome.addOutcomes(resolveDataEvents(field, DataEventType.SET, EventPhase.PRE, useCase, task, params)); + if (outcome.getMessage() == null) { + if (field.getEvents().containsKey(DataEventType.SET) && + field.getEvents().get(DataEventType.SET).getMessage() != null) { + outcome.setMessage(field.getEvents().get(DataEventType.SET).getMessage()); + } else { Map dataSet = useCase.getPetriNet().getTransition(task.getTransitionId()).getDataSet(); - if (field.getEvents().containsKey(DataEventType.SET) && - ((DataEvent) field.getEvents().get(DataEventType.SET)).getMessage() != null) { - outcome.setMessage(((DataEvent) field.getEvents().get(DataEventType.SET)).getMessage()); - } else if (dataSet.containsKey(fieldId) - && dataSet.get(fieldId).getEvents().containsKey(DataEventType.SET) - && dataSet.get(fieldId).getEvents().get(DataEventType.SET).getMessage() != null) { - outcome.setMessage(dataSet.get(fieldId).getEvents().get(DataEventType.SET).getMessage()); + DataFieldLogic dataRef = dataSet.get(fieldId); + if (dataRef != null && dataRef.getEvents().containsKey(DataEventType.SET) + && dataRef.getEvents().get(DataEventType.SET).getMessage() != null) { + outcome.setMessage(dataRef.getEvents().get(DataEventType.SET).getMessage()); } } - boolean modified = false; - ChangedField changedField = new ChangedField(); - changedField.setId(fieldId); - Object newValue = parseFieldsValues(entry.getValue(), dataField, task.getStringId()); - if (entry.getValue().has("value") || getFieldTypeFromNode((ObjectNode) entry.getValue()).equals("button")) { - dataField.setValue(newValue); - changedField.addAttribute("value", newValue); - modified = true; - } - List allowedNets = parseAllowedNetsValue(entry.getValue()); - if (allowedNets != null) { - dataField.setAllowedNets(allowedNets); - changedField.addAttribute("allowedNets", allowedNets); - modified = true; - } - String fieldType = getFieldTypeFromNode((ObjectNode) entry.getValue()); - Map filterMetadata = parseFilterMetadataValue((ObjectNode) entry.getValue(), fieldType); - if (filterMetadata != null) { - dataField.setFilterMetadata(filterMetadata); - changedField.addAttribute("filterMetadata", filterMetadata); - modified = true; - } - Map options = parseOptionsNode(entry.getValue(), fieldType); - if (options != null) { - setDataFieldOptions(options, dataField, changedField, fieldType); - modified = true; - } - Set choices = parseChoicesNode((ObjectNode) entry.getValue(), fieldType); - if (choices != null) { - dataField.setChoices(choices); - changedField.addAttribute("choices", choices.stream().map(i18nString -> i18nString.getTranslation(LocaleContextHolder.getLocale())).collect(Collectors.toSet())); - modified = true; - } - Map properties = parseProperties(entry.getValue()); - if (properties != null) { - outcome.addOutcome(this.changeComponentProperties(useCase, task, field.getStringId(), properties)); - modified = true; - } - if (modified) { - dataField.setLastModified(LocalDateTime.now()); - } - if (dataConfigurationProperties.getValidation().isSetDataEnabled()) { - validation.valid(useCase.getPetriNet().getDataSet().get(entry.getKey()), dataField); - } - outcome.addChangedField(fieldId, changedField); - workflowService.save(useCase); - publisher.publishEvent(new SetDataEvent(outcome, EventPhase.PRE, user)); - outcome.addOutcomes(resolveDataEvents(field, DataEventType.SET, EventPhase.POST, useCase, task, params)); - applyFieldConnectedChanges(useCase, field); } + boolean modified = false; + ChangedField changedField = new ChangedField(); + changedField.setId(fieldId); + Object newValue = parseFieldsValues(entry.getValue(), dataField, task.getStringId()); + if (entry.getValue().has("value") || getFieldTypeFromNode((ObjectNode) entry.getValue()).equals("button")) { + dataField.setValue(newValue); + changedField.addAttribute("value", newValue); + modified = true; + } + List allowedNets = parseAllowedNetsValue(entry.getValue()); + if (allowedNets != null) { + dataField.setAllowedNets(allowedNets); + changedField.addAttribute("allowedNets", allowedNets); + modified = true; + } + String fieldType = getFieldTypeFromNode((ObjectNode) entry.getValue()); + Map filterMetadata = parseFilterMetadataValue((ObjectNode) entry.getValue(), fieldType); + if (filterMetadata != null) { + dataField.setFilterMetadata(filterMetadata); + changedField.addAttribute("filterMetadata", filterMetadata); + modified = true; + } + Map options = parseOptionsNode(entry.getValue(), fieldType); + if (options != null) { + setDataFieldOptions(options, dataField, changedField, fieldType); + modified = true; + } + Set choices = parseChoicesNode((ObjectNode) entry.getValue(), fieldType); + if (choices != null) { + dataField.setChoices(choices); + changedField.addAttribute("choices", choices.stream().map(i18nString -> i18nString.getTranslation(LocaleContextHolder.getLocale())).collect(Collectors.toSet())); + modified = true; + } + Map properties = parseProperties(entry.getValue()); + if (properties != null) { + outcome.addOutcome(this.changeComponentProperties(useCase, task, field.getStringId(), properties)); + modified = true; + } + if (modified) { + dataField.setLastModified(LocalDateTime.now()); + } + if (dataConfigurationProperties.getValidation().isSetDataEnabled()) { + validation.valid(field, dataField); + } + outcome.addChangedField(fieldId, changedField); + workflowService.save(useCase); + publisher.publishEvent(new SetDataEvent(outcome, EventPhase.PRE, user)); + outcome.addOutcomes(resolveDataEvents(field, DataEventType.SET, EventPhase.POST, useCase, task, params)); + applyFieldConnectedChanges(useCase, field); }); updateDataset(useCase); outcome.setCase(workflowService.save(useCase)); @@ -831,7 +835,8 @@ private SetDataEventOutcome resolveComponentProperties(Component comp, Case useC return outcome; } - private List resolveDataEvents(Field field, DataEventType trigger, EventPhase phase, Case useCase, Task task, Map params) { + private List resolveDataEvents(Field field, DataEventType trigger, EventPhase phase, Case useCase, + Task task, Map params) { return eventService.processDataEvents(field, trigger, phase, useCase, task, params); } @@ -1025,7 +1030,7 @@ private Map parseFilterMetadataValue(ObjectNode node, String fie return null; } ObjectMapper mapper = new ObjectMapper(); - return mapper.convertValue(filterMetadata, new TypeReference>() { + return mapper.convertValue(filterMetadata, new TypeReference<>() { }); } return null; @@ -1059,7 +1064,7 @@ private Map parseOptions(JsonNode node) { SimpleModule module = new SimpleModule(); module.addDeserializer(I18nString.class, new com.netgrif.application.engine.objects.petrinet.domain.I18nStringDeserializer()); mapper.registerModule(module); - Map optionsMapped = mapper.convertValue(optionsNode, new TypeReference>() { + Map optionsMapped = mapper.convertValue(optionsNode, new TypeReference<>() { }); if (optionsMapped.isEmpty()) { return null; @@ -1101,7 +1106,7 @@ private Map parseProperties(JsonNode node) { return null; } ObjectMapper mapper = new ObjectMapper(); - Map propertiesMapped = mapper.convertValue(propertiesNode, new TypeReference>() { + Map propertiesMapped = mapper.convertValue(propertiesNode, new TypeReference<>() { }); if (propertiesMapped.isEmpty()) { return null; diff --git a/application-engine/src/main/java/com/netgrif/application/engine/workflow/service/EventService.java b/application-engine/src/main/java/com/netgrif/application/engine/workflow/service/EventService.java index edadca06cc..1593729bf7 100644 --- a/application-engine/src/main/java/com/netgrif/application/engine/workflow/service/EventService.java +++ b/application-engine/src/main/java/com/netgrif/application/engine/workflow/service/EventService.java @@ -92,8 +92,9 @@ public List processDataEvents(Field field, DataEventType actionTri } if (task != null) { Transition transition = useCase.getPetriNet().getTransition(task.getTransitionId()); - if (transition.getDataSet().containsKey(field.getStringId()) && !transition.getDataSet().get(field.getStringId()).getEvents().isEmpty()) { - fieldActions.addAll(DataFieldLogic.getEventAction(transition.getDataSet().get(field.getStringId()).getEvents().get(actionTrigger), phase)); + DataFieldLogic dataRef = transition.getDataSet().get(field.getStringId()); + if (dataRef != null && !dataRef.getEvents().isEmpty()) { + fieldActions.addAll(DataFieldLogic.getEventAction(dataRef.getEvents().get(actionTrigger), phase)); } } @@ -113,7 +114,7 @@ public void runEventActionsOnChanged(Task task, SetDataEventOutcome outcome, Dat public void runEventActionsOnChanged(Task task, SetDataEventOutcome outcome, DataEventType trigger, Map params) { outcome.getChangedFields().forEach((s, changedField) -> { if (changedField.getAttributes().containsKey("value") && trigger == DataEventType.SET) { - Field field = outcome.getCase().getField(s); + Field field = outcome.getCase().getField(s); log.info("[{}] {}: Running actions on changed field {}", outcome.getCase().getStringId(), outcome.getCase().getTitle(), s); outcome.addOutcomes(processDataEvents(field, trigger, EventPhase.PRE, outcome.getCase(), outcome.getTask(), params)); outcome.addOutcomes(processDataEvents(field, trigger, EventPhase.POST, outcome.getCase(), outcome.getTask(), params)); From 0ba39e2f5557610b3e196355e98735faf58e3f48 Mon Sep 17 00:00:00 2001 From: chvostek Date: Wed, 29 Oct 2025 15:44:20 +0100 Subject: [PATCH 23/55] [NAE-2235] Improve Efficiency of Database Reads and Saves - light optimization of DataService.getDataGroups --- .../engine/workflow/service/DataService.java | 99 ++++++++++--------- 1 file changed, 54 insertions(+), 45 deletions(-) diff --git a/application-engine/src/main/java/com/netgrif/application/engine/workflow/service/DataService.java b/application-engine/src/main/java/com/netgrif/application/engine/workflow/service/DataService.java index 5d8c93bab6..7cef22a38b 100644 --- a/application-engine/src/main/java/com/netgrif/application/engine/workflow/service/DataService.java +++ b/application-engine/src/main/java/com/netgrif/application/engine/workflow/service/DataService.java @@ -317,39 +317,44 @@ public GetDataGroupsEventOutcome getDataGroups(String taskId, Locale locale, Set PetriNet net = useCase.getPetriNet(); Transition transition = net.getTransition(task.getTransitionId()); GetDataGroupsEventOutcome outcome = new GetDataGroupsEventOutcome(useCase, task); + log.info("Getting groups of task {} in case {} level: {}", taskId, useCase.getTitle(), level); List resultDataGroups = new ArrayList<>(); List> data = getData(task, useCase).getData(); Map> dataFieldMap = data.stream().collect(Collectors.toMap(Field::getImportId, field -> field)); - List dataGroups = transition.getDataGroups().values().stream().map((dg) -> (DataGroup) new com.netgrif.application.engine.adapter.spring.workflow.domain.DataGroup((com.netgrif.application.engine.adapter.spring.workflow.domain.DataGroup) dg)).toList(); - for (DataGroup dataGroup : dataGroups) { - resolveTaskRefOrderOnGrid(dataGroup, dataFieldMap); - resultDataGroups.add(dataGroup); - log.debug("Setting groups of task {} in case {} level: {} {}", taskId, useCase.getTitle(), level, dataGroup.getImportId()); - - List> resources = new LinkedList<>(); - for (String dataFieldId : dataGroup.getData()) { - Field field = net.getDataSet().get(dataFieldId); - if (dataFieldMap.containsKey(dataFieldId)) { - Field resource = dataFieldMap.get(dataFieldId); - if (level != 0) { - dataGroup.setParentCaseId(useCase.getStringId()); - resource.setParentCaseId(useCase.getStringId()); - dataGroup.setParentTaskId(taskId); - dataGroup.setParentTransitionId(task.getTransitionId()); - dataGroup.setParentTaskRefId(parentTaskRefId); - dataGroup.setNestingLevel(level); - resource.setParentTaskId(taskId); - } - resources.add(resource); - if (field.getType() == FieldType.TASK_REF && shouldResolveTaskRefData(field, transition.getDataSet().get(field.getStringId()))) { - resultDataGroups.addAll(collectTaskRefDataGroups((TaskField) dataFieldMap.get(dataFieldId), locale, collectedTaskIds, level)); + transition.getDataGroups().values().stream() + .map((dg) -> (DataGroup) new com.netgrif.application.engine.adapter.spring.workflow.domain.DataGroup((com.netgrif.application.engine.adapter.spring.workflow.domain.DataGroup) dg)) + .forEach((dataGroup -> { + resolveTaskRefOrderOnGrid(dataGroup, dataFieldMap); + resultDataGroups.add(dataGroup); + log.debug("Setting groups of task {} in case {} level: {} {}", taskId, useCase.getTitle(), level, + dataGroup.getImportId()); + + List> resources = new LinkedList<>(); + for (String dataFieldId : dataGroup.getData()) { + Field resource = dataFieldMap.get(dataFieldId); + if (resource != null) { + if (level != 0) { + dataGroup.setParentCaseId(useCase.getStringId()); + resource.setParentCaseId(useCase.getStringId()); + dataGroup.setParentTaskId(taskId); + dataGroup.setParentTransitionId(task.getTransitionId()); + dataGroup.setParentTaskRefId(parentTaskRefId); + dataGroup.setNestingLevel(level); + resource.setParentTaskId(taskId); + } + resources.add(resource); + Field field = net.getDataSet().get(dataFieldId); + if (field.getType() == FieldType.TASK_REF + && shouldResolveTaskRefData(field, transition.getDataSet().get(field.getStringId()))) { + resultDataGroups.addAll(collectTaskRefDataGroups((TaskField) resource, locale, collectedTaskIds, level)); + } + } } - } - } - dataGroup.setFields(new DataFieldsResource(resources, locale)); - } + dataGroup.setFields(new DataFieldsResource(resources, locale)); + })); + outcome.setData(resultDataGroups); return outcome; } @@ -372,18 +377,21 @@ private boolean hasRequiredComponentProperty(Component component, String propert private List collectTaskRefDataGroups(TaskField taskRefField, Locale locale, Set collectedTaskIds, int level) { List taskIds = taskRefField.getValue(); - List groups = new ArrayList<>(); - - if (taskIds != null) { - taskIds = taskIds.stream().filter(id -> !collectedTaskIds.contains(id)).toList(); - taskIds.forEach(id -> { - collectedTaskIds.add(id); - List taskRefDataGroups = getDataGroups(id, locale, collectedTaskIds, level + 1, taskRefField.getStringId()).getData(); - resolveTaskRefBehavior(taskRefField, taskRefDataGroups); - groups.addAll(taskRefDataGroups); - }); + if (taskIds == null) { + return new ArrayList<>(); } + List groups = new ArrayList<>(); + taskIds.stream() + .filter(id -> !collectedTaskIds.contains(id)) + .forEach(id -> { + collectedTaskIds.add(id); + List taskRefDataGroups = getDataGroups(id, locale, collectedTaskIds, level + 1, + taskRefField.getStringId()).getData(); + resolveTaskRefBehavior(taskRefField, taskRefDataGroups); + groups.addAll(taskRefDataGroups); + }); + return groups; } @@ -391,8 +399,8 @@ private void resolveTaskRefOrderOnGrid(DataGroup dataGroup, Map if (dataGroup.getLayout() != null && Objects.equals(dataGroup.getLayout().getType(), "grid")) { dataGroup.setData( dataGroup.getData().stream() - .filter(dataFieldMap::containsKey) .map(dataFieldMap::get) + .filter(Objects::nonNull) .sorted(Comparator.comparingInt(a -> a.getLayout().getY())) .map(Field::getStringId) .collect(Collectors.toCollection(LinkedHashSet::new)) @@ -659,10 +667,10 @@ public SetDataEventOutcome saveFiles(String taskId, String fieldId, MultipartFil } private List getChangedFieldByFileFieldContainer(String fieldId, Task referencingTask, Case useCase, Map params) { - List outcomes = new ArrayList<>(resolveDataEvents(useCase.getPetriNet().getField(fieldId).get(), DataEventType.SET, - EventPhase.PRE, useCase, referencingTask, params)); - outcomes.addAll(resolveDataEvents(useCase.getPetriNet().getField(fieldId).get(), DataEventType.SET, - EventPhase.POST, useCase, referencingTask, params)); + Field field = useCase.getPetriNet().getField(fieldId).get(); + List outcomes = new ArrayList<>(resolveDataEvents(field, DataEventType.SET, EventPhase.PRE, + useCase, referencingTask, params)); + outcomes.addAll(resolveDataEvents(field, DataEventType.SET, EventPhase.POST, useCase, referencingTask, params)); updateDataset(useCase); workflowService.save(useCase); return outcomes; @@ -688,7 +696,8 @@ public SetDataEventOutcome deleteFile(String taskId, String fieldId, Map value, List allowedNets) t Set nets = new HashSet<>(allowedNets); cases.forEach(_case -> { if (!nets.contains(_case.getProcessIdentifier())) { - throw new IllegalArgumentException("Case '%s' with id '%s' cannot be added to case ref, since it is an instance of process with identifier '%s', which is not one of the allowed nets".formatted( - _case.getTitle(), _case.getStringId(), _case.getProcessIdentifier())); + throw new IllegalArgumentException("Case '%s' with id '%s' cannot be added to case ref, since it is an instance of process with identifier '%s', which is not one of the allowed nets" + .formatted(_case.getTitle(), _case.getStringId(), _case.getProcessIdentifier())); } }); } From f7e99cba46e4cb420275e9b26f95694f9cc0ae1c Mon Sep 17 00:00:00 2001 From: chvostek Date: Wed, 29 Oct 2025 17:34:10 +0100 Subject: [PATCH 24/55] [NAE-2235] Improve Efficiency of Database Reads and Saves - light optimizations in workflow package - optimize authorization services --- .../service/AbstractAuthorizationService.java | 30 ++-- .../workflow/service/CaseSearchService.java | 6 +- .../service/ConfigurableMenuService.java | 4 - .../engine/workflow/service/EventService.java | 29 ++-- .../service/FilterImportExportService.java | 6 +- .../service/MenuImportExportService.java | 4 - .../workflow/service/MongoSearchService.java | 2 +- .../service/TaskAuthorizationService.java | 136 ++++++++++++------ .../workflow/service/TaskSearchService.java | 4 +- .../service/WorkflowAuthorizationService.java | 44 +++--- .../service/interfaces/IEventService.java | 2 +- .../workflow/WorkflowPerformanceTest.java | 5 - 12 files changed, 160 insertions(+), 112 deletions(-) diff --git a/application-engine/src/main/java/com/netgrif/application/engine/workflow/service/AbstractAuthorizationService.java b/application-engine/src/main/java/com/netgrif/application/engine/workflow/service/AbstractAuthorizationService.java index a24222a492..3b2aa5d3ff 100644 --- a/application-engine/src/main/java/com/netgrif/application/engine/workflow/service/AbstractAuthorizationService.java +++ b/application-engine/src/main/java/com/netgrif/application/engine/workflow/service/AbstractAuthorizationService.java @@ -9,12 +9,12 @@ public abstract class AbstractAuthorizationService { - protected boolean hasPermission(Boolean hasPermission) { - return hasPermission != null && hasPermission; + protected boolean hasPermission(Boolean permissionValue) { + return permissionValue != null && permissionValue; } - protected boolean hasRestrictedPermission(Boolean hasPermission) { - return hasPermission != null && !hasPermission; + protected boolean hasRestrictedPermission(Boolean permissionValue) { + return permissionValue != null && !permissionValue; } protected Map getAggregatePermissions(AbstractUser user, Map> permissions) { @@ -22,7 +22,9 @@ protected Map getAggregatePermissions(AbstractUser user, Map userProcessRoleIDs = user.getSelfOrImpersonated().getProcessRoles().stream().map(role -> role.get_id().toString()).collect(Collectors.toSet()); // TODO: impersonation - Set userProcessRoleIDs = user.getProcessRoles().stream().map(role -> role.get_id().toString()).collect(Collectors.toSet()); + Set userProcessRoleIDs = user.getProcessRoles().stream() + .map(role -> role.get_id().toString()) + .collect(Collectors.toSet()); for (Map.Entry> role : permissions.entrySet()) { aggregatePermission(userProcessRoleIDs, role, aggregatePermissions); @@ -31,14 +33,16 @@ protected Map getAggregatePermissions(AbstractUser user, Map> role, Map aggregatePermissions) { - if (userProcessRoleIDs.contains(role.getKey())) { - for (Map.Entry permission : role.getValue().entrySet()) { - if (aggregatePermissions.containsKey(permission.getKey())) { - aggregatePermissions.put(permission.getKey(), aggregatePermissions.get(permission.getKey()) && permission.getValue()); - } else { - aggregatePermissions.put(permission.getKey(), permission.getValue()); - } + private void aggregatePermission(Set userProcessRoleIDs, Map.Entry> role, + Map aggregatePermissions) { + if (!userProcessRoleIDs.contains(role.getKey())) { + return; + } + for (Map.Entry permission : role.getValue().entrySet()) { + if (aggregatePermissions.containsKey(permission.getKey())) { + aggregatePermissions.put(permission.getKey(), aggregatePermissions.get(permission.getKey()) && permission.getValue()); + } else { + aggregatePermissions.put(permission.getKey(), permission.getValue()); } } } diff --git a/application-engine/src/main/java/com/netgrif/application/engine/workflow/service/CaseSearchService.java b/application-engine/src/main/java/com/netgrif/application/engine/workflow/service/CaseSearchService.java index 923d17bfa5..e7d80dfe57 100644 --- a/application-engine/src/main/java/com/netgrif/application/engine/workflow/service/CaseSearchService.java +++ b/application-engine/src/main/java/com/netgrif/application/engine/workflow/service/CaseSearchService.java @@ -234,7 +234,7 @@ public Predicate data(Object data) { break; } } catch (IllegalArgumentException e) { - log.error("Unrecognized Field type " + entry.getKey()); + log.error("Unrecognized Field type {}", entry.getKey()); } } else { predicates.add(QCase.case$.dataSet.get((String) k).value.eq(v)); @@ -353,7 +353,7 @@ public Predicate caseId(Object query) { } private static BooleanExpression caseIdString(String caseId) { - return caseId.equals("") ? QCase.case$._id.isNull() : QCase.case$._id.eq(new ProcessResourceId(caseId)); + return caseId.isEmpty() ? QCase.case$._id.isNull() : QCase.case$._id.eq(new ProcessResourceId(caseId)); } public Predicate group(Object query, LoggedUser user, Locale locale) { @@ -364,7 +364,7 @@ public Predicate group(Object query, LoggedUser user, Locale locale) { processQuery.setGroup(new ArrayList<>(Arrays.asList((String) query))); } List groupProcesses = this.petriNetService.search(processQuery, user, new FullPageRequest(), locale).getContent(); - if (groupProcesses.size() == 0) + if (groupProcesses.isEmpty()) return null; List processQueries = groupProcesses.stream().map(PetriNetReference::getIdentifier).map(QCase.case$.processIdentifier::eq).collect(Collectors.toList()); diff --git a/application-engine/src/main/java/com/netgrif/application/engine/workflow/service/ConfigurableMenuService.java b/application-engine/src/main/java/com/netgrif/application/engine/workflow/service/ConfigurableMenuService.java index 4ea645837c..8a73bb41a5 100644 --- a/application-engine/src/main/java/com/netgrif/application/engine/workflow/service/ConfigurableMenuService.java +++ b/application-engine/src/main/java/com/netgrif/application/engine/workflow/service/ConfigurableMenuService.java @@ -1,6 +1,5 @@ package com.netgrif.application.engine.workflow.service; -import com.netgrif.application.engine.auth.service.UserService; 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; @@ -31,9 +30,6 @@ public class ConfigurableMenuService implements IConfigurableMenuService { @Autowired private IPetriNetService petriNetService; - @Autowired - private UserService userService; - @Autowired private StringToVersionConverter converter; diff --git a/application-engine/src/main/java/com/netgrif/application/engine/workflow/service/EventService.java b/application-engine/src/main/java/com/netgrif/application/engine/workflow/service/EventService.java index 1593729bf7..e7c8549c21 100644 --- a/application-engine/src/main/java/com/netgrif/application/engine/workflow/service/EventService.java +++ b/application-engine/src/main/java/com/netgrif/application/engine/workflow/service/EventService.java @@ -1,6 +1,7 @@ package com.netgrif.application.engine.workflow.service; import com.netgrif.application.engine.objects.petrinet.domain.DataFieldLogic; +import com.netgrif.application.engine.objects.petrinet.domain.Function; import com.netgrif.application.engine.objects.petrinet.domain.Transition; import com.netgrif.application.engine.objects.petrinet.domain.dataset.Field; import com.netgrif.application.engine.objects.petrinet.domain.dataset.logic.action.Action; @@ -14,6 +15,7 @@ import com.netgrif.application.engine.objects.workflow.domain.eventoutcomes.dataoutcomes.SetDataEventOutcome; import com.netgrif.application.engine.workflow.service.interfaces.IEventService; import com.netgrif.application.engine.workflow.service.interfaces.IWorkflowService; +import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.context.annotation.Lazy; import org.springframework.stereotype.Service; @@ -23,17 +25,12 @@ @Slf4j @Lazy @Service +@RequiredArgsConstructor public class EventService implements IEventService { private final FieldActionsRunner actionsRunner; - private final IWorkflowService workflowService; - public EventService(FieldActionsRunner actionsRunner, IWorkflowService workflowService) { - this.actionsRunner = actionsRunner; - this.workflowService = workflowService; - } - @Override public List runActions(List actions, Case useCase, Task task, Transition transition, Map params) { log.info("[{}]: Running actions of transition {}", useCase.getStringId(), transition.getStringId()); @@ -51,8 +48,9 @@ public List runActions(List actions, Case useCase, Optiona if (actions.isEmpty()) { return allOutcomes; } + List functions = useCase == null ? Collections.emptyList() : useCase.getPetriNet().getFunctions(); actions.forEach(action -> { - List outcomes = actionsRunner.run(action, useCase, task, params, useCase == null ? Collections.emptyList() : useCase.getPetriNet().getFunctions()); + List outcomes = actionsRunner.run(action, useCase, task, params, functions); outcomes.stream().filter(SetDataEventOutcome.class::isInstance) .forEach(outcome -> { if (((SetDataEventOutcome) outcome).getChangedFields().isEmpty()) return; @@ -67,13 +65,16 @@ public List runActions(List actions, Case useCase, Optiona } @Override - public List runEventActions(Case useCase, Task task, List actions, DataEventType trigger, Map params) { + public List runEventActions(Case useCase, Task task, List actions, DataEventType trigger, + Map params) { List allOutcomes = new ArrayList<>(); if (actions.isEmpty()) { return allOutcomes; } + Optional taskOpt = Optional.ofNullable(task); + List functions = useCase == null ? Collections.emptyList() : useCase.getPetriNet().getFunctions(); actions.forEach(action -> { - List outcomes = actionsRunner.run(action, useCase, task == null ? Optional.empty() : Optional.of(task), params, useCase == null ? Collections.emptyList() : useCase.getPetriNet().getFunctions()); + List outcomes = actionsRunner.run(action, useCase, taskOpt, params, functions); outcomes.stream().filter(SetDataEventOutcome.class::isInstance) .forEach(outcome -> { if (((SetDataEventOutcome) outcome).getChangedFields().isEmpty()) return; @@ -85,10 +86,14 @@ public List runEventActions(Case useCase, Task task, List } @Override - public List processDataEvents(Field field, DataEventType actionTrigger, EventPhase phase, Case useCase, Task task, Map params) { + public List processDataEvents(Field field, DataEventType actionTrigger, EventPhase phase, + Case useCase, Task task, Map params) { LinkedList fieldActions = new LinkedList<>(); - if (field.getEvents() != null && field.getEvents().containsKey(actionTrigger)) { - fieldActions.addAll(DataFieldLogic.getEventAction((DataEvent) field.getEvents().get(actionTrigger), phase)); + if (field.getEvents() != null) { + DataEvent dataEvent = field.getEvents().get(actionTrigger); + if (dataEvent != null) { + fieldActions.addAll(DataFieldLogic.getEventAction(dataEvent, phase)); + } } if (task != null) { Transition transition = useCase.getPetriNet().getTransition(task.getTransitionId()); diff --git a/application-engine/src/main/java/com/netgrif/application/engine/workflow/service/FilterImportExportService.java b/application-engine/src/main/java/com/netgrif/application/engine/workflow/service/FilterImportExportService.java index 2edad2d2ed..7aab9cb0ec 100644 --- a/application-engine/src/main/java/com/netgrif/application/engine/workflow/service/FilterImportExportService.java +++ b/application-engine/src/main/java/com/netgrif/application/engine/workflow/service/FilterImportExportService.java @@ -218,12 +218,12 @@ protected Map performImport(FilterImportExportList filterList) t String parentId = null; boolean viewOrigin = false; - if (filter.getParentCaseId() != null && !filter.getParentCaseId().equals("")) { + if (filter.getParentCaseId() != null && !filter.getParentCaseId().isEmpty()) { parentId = oldToNewFilterId.get(filter.getParentCaseId()); if (parentId == null) { - log.error("Imported filter with ID '" + filter.getCaseId() + "' could not find an imported mapping of its parent case with original ID '" + filter.getParentCaseId() + "'"); + log.error("Imported filter with ID '{}' could not find an imported mapping of its parent case with original ID '{}'", filter.getCaseId(), filter.getParentCaseId()); } - } else if (filter.getParentViewId() != null && !filter.getParentViewId().equals("")) { + } else if (filter.getParentViewId() != null && !filter.getParentViewId().isEmpty()) { parentId = filter.getParentViewId(); viewOrigin = true; } diff --git a/application-engine/src/main/java/com/netgrif/application/engine/workflow/service/MenuImportExportService.java b/application-engine/src/main/java/com/netgrif/application/engine/workflow/service/MenuImportExportService.java index 47bac2e4f9..6c50ea5f3a 100644 --- a/application-engine/src/main/java/com/netgrif/application/engine/workflow/service/MenuImportExportService.java +++ b/application-engine/src/main/java/com/netgrif/application/engine/workflow/service/MenuImportExportService.java @@ -23,7 +23,6 @@ import com.netgrif.application.engine.objects.petrinet.domain.roles.ProcessRole; import com.netgrif.application.engine.objects.petrinet.domain.throwable.TransitionNotExecutableException; import com.netgrif.application.engine.petrinet.service.interfaces.IPetriNetService; -import com.netgrif.application.engine.startup.runner.DefaultFiltersRunner; import com.netgrif.application.engine.startup.ImportHelper; import com.netgrif.application.engine.utils.InputStreamToString; import com.netgrif.application.engine.objects.workflow.domain.*; @@ -71,9 +70,6 @@ public class MenuImportExportService implements IMenuImportExportService { @Autowired IPetriNetService petriNetService; - @Autowired - DefaultFiltersRunner defaultFiltersRunner; - @Autowired private ITaskService taskService; diff --git a/application-engine/src/main/java/com/netgrif/application/engine/workflow/service/MongoSearchService.java b/application-engine/src/main/java/com/netgrif/application/engine/workflow/service/MongoSearchService.java index 8e3259e239..fe9c664b17 100644 --- a/application-engine/src/main/java/com/netgrif/application/engine/workflow/service/MongoSearchService.java +++ b/application-engine/src/main/java/com/netgrif/application/engine/workflow/service/MongoSearchService.java @@ -208,7 +208,7 @@ public String buildQuery(Map queryParts) throws IllegalQueryExce protected Page executeQuery(String queryString, Pageable pageable) { Query query = new BasicQuery(queryString).with(pageable); - log.info("Executing search query: " + queryString); + log.info("Executing search query: {}", queryString); return new PageImpl<>(mongoTemplate.find(query, tClass), pageable, mongoTemplate.count(new BasicQuery(queryString, "{_id:1}"), tClass)); diff --git a/application-engine/src/main/java/com/netgrif/application/engine/workflow/service/TaskAuthorizationService.java b/application-engine/src/main/java/com/netgrif/application/engine/workflow/service/TaskAuthorizationService.java index 3ed448f14d..1fa8c8e016 100644 --- a/application-engine/src/main/java/com/netgrif/application/engine/workflow/service/TaskAuthorizationService.java +++ b/application-engine/src/main/java/com/netgrif/application/engine/workflow/service/TaskAuthorizationService.java @@ -1,7 +1,5 @@ package com.netgrif.application.engine.workflow.service; -import com.netgrif.application.engine.adapter.spring.auth.domain.LoggedUserImpl; -import com.netgrif.application.engine.auth.service.UserService; import com.netgrif.application.engine.objects.auth.domain.AbstractUser; import com.netgrif.application.engine.objects.auth.domain.LoggedUser; import com.netgrif.application.engine.objects.petrinet.domain.roles.RolePermission; @@ -19,14 +17,12 @@ public class TaskAuthorizationService extends AbstractAuthorizationService implements ITaskAuthorizationService { @Autowired - ITaskService taskService; - - @Autowired - UserService userService; + private ITaskService taskService; @Override public Boolean userHasAtLeastOneRolePermission(LoggedUser loggedUser, String taskId, RolePermission... permissions) { - return userHasAtLeastOneRolePermission(userService.transformToUser((LoggedUserImpl) loggedUser), taskService.findById(taskId), permissions); + // todo 2235 test + return userHasAtLeastOneRolePermission(loggedUser, taskService.findById(taskId), permissions); } @Override @@ -42,12 +38,14 @@ public Boolean userHasAtLeastOneRolePermission(AbstractUser user, Task task, Rol } } - return Arrays.stream(permissions).anyMatch(permission -> hasPermission(aggregatePermissions.get(permission.toString()))); + return Arrays.stream(permissions) + .anyMatch(permission -> hasPermission(aggregatePermissions.get(permission.toString()))); } @Override public Boolean userHasUserListPermission(LoggedUser loggedUser, String taskId, RolePermission... permissions) { - return userHasUserListPermission(userService.transformToUser((LoggedUserImpl) loggedUser), taskService.findById(taskId), permissions); + // todo 2235 test + return userHasUserListPermission(loggedUser, taskService.findById(taskId), permissions); } @Override @@ -55,14 +53,12 @@ public Boolean userHasUserListPermission(AbstractUser user, Task task, RolePermi if (task.getUserRefs() == null || task.getUserRefs().isEmpty()) return null; - // TODO: impersonation -// if (!task.getUsers().containsKey(user.getSelfOrImpersonated().getStringId())) { + // TODO: impersonation user.getSelfOrImpersonated().getStringId() if (!task.getUsers().containsKey(user.getStringId())) { return null; } - // TODO: impersonation -// Map userPermissions = task.getUsers().get(user.getSelfOrImpersonated().getStringId()); + // TODO: impersonation user.getSelfOrImpersonated().getStringId() Map userPermissions = task.getUsers().get(user.getStringId()); for (RolePermission permission : permissions) { @@ -71,12 +67,14 @@ public Boolean userHasUserListPermission(AbstractUser user, Task task, RolePermi return false; } } - return Arrays.stream(permissions).anyMatch(permission -> hasPermission(userPermissions.get(permission.toString()))); + return Arrays.stream(permissions) + .anyMatch(permission -> hasPermission(userPermissions.get(permission.toString()))); } @Override public boolean isAssignee(LoggedUser loggedUser, String taskId) { - return isAssignee(userService.transformToUser((LoggedUserImpl) loggedUser), taskService.findById(taskId)); + // todo 2235 test + return isAssignee(loggedUser, taskService.findById(taskId)); } @Override @@ -89,8 +87,7 @@ public boolean isAssignee(AbstractUser user, Task task) { if (!isAssigned(task)) return false; else - // TODO: impersonation -// return task.getUserId().equals(user.getSelfOrImpersonated().getStringId()) || (Boolean) user.getAttributeValue("anonymous"); + // TODO: impersonation user.getSelfOrImpersonated().getStringId() return task.getUserId().equals(user.getStringId()) || (Boolean) user.getAttributeValue("anonymous"); } @@ -104,67 +101,112 @@ private boolean isAssigned(Task task) { @Override public boolean canCallAssign(LoggedUser loggedUser, String taskId) { - Boolean rolePerm = userHasAtLeastOneRolePermission(loggedUser, taskId, RolePermission.ASSIGN); - Boolean userPerm = userHasUserListPermission(loggedUser, taskId, RolePermission.ASSIGN); + // TODO: impersonation loggedUser.getSelfOrImpersonated().isAdmin() + if (loggedUser.isAdmin()) { + return true; + } + + Task task = taskService.findById(taskId); + // TODO: impersonation + Boolean userPerm = userHasUserListPermission(loggedUser, task, RolePermission.ASSIGN); + if (userPerm != null) { + return userPerm; + } + // TODO: impersonation -// return loggedUser.getSelfOrImpersonated().isAdmin() || (userPerm == null ? (rolePerm != null && rolePerm) : userPerm); - return loggedUser.isAdmin() || (userPerm == null ? (rolePerm != null && rolePerm) : userPerm); + Boolean rolePerm = userHasAtLeastOneRolePermission(loggedUser, task, RolePermission.ASSIGN); + return rolePerm != null && rolePerm; } @Override public boolean canCallDelegate(LoggedUser loggedUser, String taskId) { - Boolean rolePerm = userHasAtLeastOneRolePermission(loggedUser, taskId, RolePermission.DELEGATE); - Boolean userPerm = userHasUserListPermission(loggedUser, taskId, RolePermission.DELEGATE); + // TODO: impersonation loggedUser.getSelfOrImpersonated().isAdmin() + if (loggedUser.isAdmin()) { + return true; + } + + Task task = taskService.findById(taskId); + // TODO: impersonation + Boolean userPerm = userHasUserListPermission(loggedUser, task, RolePermission.DELEGATE); + if (userPerm != null) { + return userPerm; + } + // TODO: impersonation -// return loggedUser.getSelfOrImpersonated().isAdmin() || (userPerm == null ? (rolePerm != null && rolePerm) : userPerm); - return loggedUser.isAdmin() || (userPerm == null ? (rolePerm != null && rolePerm) : userPerm); + Boolean rolePerm = userHasAtLeastOneRolePermission(loggedUser, taskId, RolePermission.DELEGATE); + return rolePerm != null && rolePerm; } @Override public boolean canCallFinish(LoggedUser loggedUser, String taskId) throws IllegalTaskStateException { - if (!isAssigned(taskId)) - throw new IllegalTaskStateException("Task with ID '" + taskId + "' cannot be finished, because it is not assigned!"); - - Boolean rolePerm = userHasAtLeastOneRolePermission(loggedUser, taskId, RolePermission.FINISH); - Boolean userPerm = userHasUserListPermission(loggedUser, taskId, RolePermission.FINISH); + if (!isAssigned(taskId)) { + throw new IllegalTaskStateException("Task with ID '%s' cannot be finished, because it is not assigned!".formatted(taskId)); + } // TODO: impersonation -// return loggedUser.getSelfOrImpersonated().isAdmin() || ((userPerm == null ? (rolePerm != null && rolePerm) : userPerm) && isAssignee(loggedUser, taskId)); - return loggedUser.isAdmin() || ((userPerm == null ? (rolePerm != null && rolePerm) : userPerm) && isAssignee(loggedUser, taskId)); - } + if (loggedUser.isAdmin()) { + return true; + } - private boolean canAssignedCancel(AbstractUser user, String taskId) { Task task = taskService.findById(taskId); // TODO: impersonation -// if (!isAssigned(task) || !task.getUserId().equals(user.getSelfOrImpersonated().getStringId())) { - if (!isAssigned(task) || !task.getUserId().equals(user.getStringId())) { - return true; + if (!isAssignee(loggedUser, task)) { + return false; + } + // TODO: impersonation + Boolean userPerm = userHasUserListPermission(loggedUser, task, RolePermission.FINISH); + if (userPerm != null) { + return userPerm; } - return (task.getAssignedUserPolicy() == null || task.getAssignedUserPolicy().get("cancel") == null) || task.getAssignedUserPolicy().get("cancel"); + + // TODO: impersonation + Boolean rolePerm = userHasAtLeastOneRolePermission(loggedUser, task, RolePermission.FINISH); + return rolePerm != null && rolePerm; + } + + /** + * To return true, the task should not have set up the assigned user policy for cancel to "false" + * */ + private boolean canAssignedCancel(Task task) { + return task.getAssignedUserPolicy() == null || task.getAssignedUserPolicy().get("cancel") == null + || task.getAssignedUserPolicy().get("cancel"); } @Override public boolean canCallCancel(LoggedUser loggedUser, String taskId) throws IllegalTaskStateException { - if (!isAssigned(taskId)) - throw new IllegalTaskStateException("Task with ID '" + taskId + "' cannot be canceled, because it is not assigned!"); + if (!isAssigned(taskId)) { + throw new IllegalTaskStateException("Task with ID '%s' cannot be canceled, because it is not assigned!".formatted(taskId)); + } + // TODO: impersonation + if (loggedUser.isAdmin()) { + return true; + } - Boolean rolePerm = userHasAtLeastOneRolePermission(loggedUser, taskId, RolePermission.CANCEL); + Task task = taskService.findById(taskId); + // TODO: impersonation + if (!isAssignee(loggedUser, task) || !canAssignedCancel(task)) { + return false; + } + + // TODO: impersonation Boolean userPerm = userHasUserListPermission(loggedUser, taskId, RolePermission.CANCEL); + if (userPerm != null) { + return userPerm; + } + // TODO: impersonation -// return loggedUser.getSelfOrImpersonated().isAdmin() || ((userPerm == null ? (rolePerm != null && rolePerm) : userPerm) && isAssignee(loggedUser, taskId)) && canAssignedCancel(userService.transformToUser((LoggedUserImpl) loggedUser), taskId); - return loggedUser.isAdmin() || ((userPerm == null ? (rolePerm != null && rolePerm) : userPerm) && isAssignee(loggedUser, taskId)) && canAssignedCancel(userService.transformToUser((LoggedUserImpl) loggedUser), taskId); + Boolean rolePerm = userHasAtLeastOneRolePermission(loggedUser, taskId, RolePermission.CANCEL); + return rolePerm != null && rolePerm; } @Override public boolean canCallSaveData(LoggedUser loggedUser, String taskId) { - // TODO: impersonation -// return loggedUser.getSelfOrImpersonated().isAdmin() || isAssignee(loggedUser, taskId); + // TODO: impersonation loggedUser.getSelfOrImpersonated().isAdmin() return loggedUser.isAdmin() || isAssignee(loggedUser, taskId); } @Override public boolean canCallSaveFile(LoggedUser loggedUser, String taskId) { - // TODO: impersonation -// return loggedUser.getSelfOrImpersonated().isAdmin() || isAssignee(loggedUser, taskId); + // TODO: impersonation loggedUser.getSelfOrImpersonated().isAdmin() return loggedUser.isAdmin() || isAssignee(loggedUser, taskId); } } diff --git a/application-engine/src/main/java/com/netgrif/application/engine/workflow/service/TaskSearchService.java b/application-engine/src/main/java/com/netgrif/application/engine/workflow/service/TaskSearchService.java index 486dbe6f5b..d6d8b905d4 100644 --- a/application-engine/src/main/java/com/netgrif/application/engine/workflow/service/TaskSearchService.java +++ b/application-engine/src/main/java/com/netgrif/application/engine/workflow/service/TaskSearchService.java @@ -36,7 +36,7 @@ public Predicate buildQuery(List requests, LoggedUser user, L return null; } else if (!isIntersection) { singleQueries = singleQueries.stream().filter(Objects::nonNull).collect(Collectors.toList()); - if (singleQueries.size() == 0) { + if (singleQueries.isEmpty()) { // all queries result in an empty set => the entire result is an empty set return null; } @@ -278,7 +278,7 @@ public boolean buildGroupQuery(TaskSearchRequest request, LoggedUser user, Local PetriNetSearch processQuery = new PetriNetSearch(); processQuery.setGroup(request.group); List groupProcesses = this.petriNetService.search(processQuery, user, new FullPageRequest(), locale).getContent(); - if (groupProcesses.size() == 0) + if (groupProcesses.isEmpty()) return true; query.and( diff --git a/application-engine/src/main/java/com/netgrif/application/engine/workflow/service/WorkflowAuthorizationService.java b/application-engine/src/main/java/com/netgrif/application/engine/workflow/service/WorkflowAuthorizationService.java index e4438d1b86..5299b5683e 100644 --- a/application-engine/src/main/java/com/netgrif/application/engine/workflow/service/WorkflowAuthorizationService.java +++ b/application-engine/src/main/java/com/netgrif/application/engine/workflow/service/WorkflowAuthorizationService.java @@ -1,7 +1,5 @@ package com.netgrif.application.engine.workflow.service; -import com.netgrif.application.engine.adapter.spring.auth.domain.LoggedUserImpl; -import com.netgrif.application.engine.auth.service.UserService; import com.netgrif.application.engine.objects.auth.domain.AbstractUser; import com.netgrif.application.engine.objects.auth.domain.LoggedUser; import com.netgrif.application.engine.objects.petrinet.domain.PetriNet; @@ -25,26 +23,37 @@ public class WorkflowAuthorizationService extends AbstractAuthorizationService i @Autowired private IPetriNetService petriNetService; - @Autowired - private UserService userService; - @Override public boolean canCallDelete(LoggedUser user, String caseId) { + // TODO: impersonation user.getSelfOrImpersonated().isAdmin() + if (user.isAdmin()) { + return true; + } + Case requestedCase = workflowService.findOne(caseId); - // TODO: impersonation -// Boolean rolePerm = userHasAtLeastOneRolePermission(userService.transformToUser((LoggedUserImpl) user.getSelfOrImpersonated()), requestedCase.getPetriNet(), ProcessRolePermission.DELETE); -// Boolean userPerm = userHasUserListPermission(userService.transformToUser((LoggedUserImpl) user.getSelfOrImpersonated()), requestedCase, ProcessRolePermission.DELETE); -// return user.getSelfOrImpersonated().isAdmin() || (userPerm == null ? (rolePerm != null && rolePerm) : userPerm); - Boolean rolePerm = userHasAtLeastOneRolePermission(userService.transformToUser(user), requestedCase.getPetriNet(), ProcessRolePermission.DELETE); - Boolean userPerm = userHasUserListPermission(userService.transformToUser(user), requestedCase, ProcessRolePermission.DELETE); - return user.isAdmin() || (userPerm == null ? (rolePerm != null && rolePerm) : userPerm); + // todo 2235 test if user has roles + // TODO: impersonation user.getSelfOrImpersonated() + Boolean userPerm = userHasUserListPermission(user, requestedCase, ProcessRolePermission.DELETE); + if (userPerm != null) { + return userPerm; + } + + // TODO: impersonation user.getSelfOrImpersonated() + Boolean rolePerm = userHasAtLeastOneRolePermission(user, requestedCase.getPetriNet(), ProcessRolePermission.DELETE); + return rolePerm != null && rolePerm; } @Override public boolean canCallCreate(LoggedUser user, String netId) { + // TODO: impersonation + if (user.isAdmin()) { + return true; + } + PetriNet net = petriNetService.getPetriNet(netId); // TODO: impersonation - return user.isAdmin() || userHasAtLeastOneRolePermission(userService.transformToUser(user), net, ProcessRolePermission.CREATE); + // todo 2235 test if user has roles + return userHasAtLeastOneRolePermission(user, net, ProcessRolePermission.CREATE); } @Override @@ -57,7 +66,8 @@ public Boolean userHasAtLeastOneRolePermission(AbstractUser user, PetriNet net, } } - return Arrays.stream(permissions).anyMatch(permission -> hasPermission(aggregatePermissions.get(permission.toString()))); + return Arrays.stream(permissions) + .anyMatch(permission -> hasPermission(aggregatePermissions.get(permission.toString()))); } @Override @@ -65,8 +75,7 @@ public Boolean userHasUserListPermission(AbstractUser user, Case useCase, Proces if (useCase.getUserRefs() == null || useCase.getUserRefs().isEmpty()) return null; - // TODO: impersonation -// if (!useCase.getUsers().containsKey(user.getSelfOrImpersonated().getStringId())) { + // TODO: impersonation user.getSelfOrImpersonated().getStringId() if (!useCase.getUsers().containsKey(user.getStringId())) { return null; } @@ -80,6 +89,7 @@ public Boolean userHasUserListPermission(AbstractUser user, Case useCase, Proces return false; } } - return Arrays.stream(permissions).anyMatch(permission -> hasPermission(userPermissions.get(permission.toString()))); + return Arrays.stream(permissions) + .anyMatch(permission -> hasPermission(userPermissions.get(permission.toString()))); } } diff --git a/application-engine/src/main/java/com/netgrif/application/engine/workflow/service/interfaces/IEventService.java b/application-engine/src/main/java/com/netgrif/application/engine/workflow/service/interfaces/IEventService.java index 04cb693e86..cd918dd0d3 100644 --- a/application-engine/src/main/java/com/netgrif/application/engine/workflow/service/interfaces/IEventService.java +++ b/application-engine/src/main/java/com/netgrif/application/engine/workflow/service/interfaces/IEventService.java @@ -22,7 +22,7 @@ public interface IEventService { List runActions(List actions, Map params); - List processDataEvents(Field field, DataEventType actionTrigger, EventPhase phase, Case useCase, Task task, Map params); + List processDataEvents(Field field, DataEventType actionTrigger, EventPhase phase, Case useCase, Task task, Map params); List runEventActions(Case useCase, Task task, List actions, DataEventType trigger, Map params); diff --git a/application-engine/src/test/java/com/netgrif/application/engine/workflow/WorkflowPerformanceTest.java b/application-engine/src/test/java/com/netgrif/application/engine/workflow/WorkflowPerformanceTest.java index 6b0d8a5aa2..872af8a1c0 100644 --- a/application-engine/src/test/java/com/netgrif/application/engine/workflow/WorkflowPerformanceTest.java +++ b/application-engine/src/test/java/com/netgrif/application/engine/workflow/WorkflowPerformanceTest.java @@ -351,11 +351,6 @@ public void testDelegateWithActionPerformance() throws IOException, MissingPetri log.info("AVG time for event [delegateTaskWithAction] is [{} ms] for [{}] iterations", totalElapsedTime / iterations, iterations); } - @Test - public void testSetDataPerformance() { - - } - private void iterateAndShowAvgTime(String event, Runnable callback, int iterations) { long totalElapsedTime = 0; for (int i = 0; i < iterations; i++) { From 2e9045dee0f4cd94670b9fab2064291ad276e631 Mon Sep 17 00:00:00 2001 From: chvostek Date: Thu, 30 Oct 2025 09:14:25 +0100 Subject: [PATCH 25/55] [NAE-2235] Improve Efficiency of Database Reads and Saves - begin implementation of MVC performance tests --- .../workflow/WorkflowMvcPerformanceTest.java | 142 ++++++++++++++++++ 1 file changed, 142 insertions(+) create mode 100644 application-engine/src/test/java/com/netgrif/application/engine/workflow/WorkflowMvcPerformanceTest.java diff --git a/application-engine/src/test/java/com/netgrif/application/engine/workflow/WorkflowMvcPerformanceTest.java b/application-engine/src/test/java/com/netgrif/application/engine/workflow/WorkflowMvcPerformanceTest.java new file mode 100644 index 0000000000..af3ad54600 --- /dev/null +++ b/application-engine/src/test/java/com/netgrif/application/engine/workflow/WorkflowMvcPerformanceTest.java @@ -0,0 +1,142 @@ +package com.netgrif.application.engine.workflow; + +import com.netgrif.application.engine.TestHelper; +import com.netgrif.application.engine.auth.service.UserService; +import com.netgrif.application.engine.objects.auth.domain.AbstractUser; +import com.netgrif.application.engine.objects.auth.domain.LoggedUser; +import com.netgrif.application.engine.objects.auth.domain.PasswordCredential; +import com.netgrif.application.engine.objects.auth.domain.User; +import com.netgrif.application.engine.objects.auth.domain.enums.UserState; +import com.netgrif.application.engine.objects.petrinet.domain.PetriNet; +import com.netgrif.application.engine.objects.petrinet.domain.VersionType; +import com.netgrif.application.engine.objects.petrinet.domain.throwable.MissingPetriNetMetaDataException; +import com.netgrif.application.engine.objects.workflow.domain.Case; +import com.netgrif.application.engine.petrinet.params.ImportPetriNetParams; +import com.netgrif.application.engine.petrinet.service.interfaces.IPetriNetService; +import com.netgrif.application.engine.startup.runner.SuperCreatorRunner; +import com.netgrif.application.engine.workflow.params.CreateCaseParams; +import com.netgrif.application.engine.workflow.service.WorkflowService; +import lombok.extern.slf4j.Slf4j; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Disabled; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.ActiveProfiles; +import org.springframework.test.context.junit.jupiter.SpringExtension; +import org.springframework.test.web.servlet.MockMvc; +import org.springframework.test.web.servlet.setup.MockMvcBuilders; +import org.springframework.web.context.WebApplicationContext; + +import java.io.FileInputStream; +import java.io.IOException; +import java.util.Locale; + +import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.httpBasic; +import static org.springframework.security.test.web.servlet.setup.SecurityMockMvcConfigurers.springSecurity; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; + +@Slf4j +@Disabled +@SpringBootTest +@ActiveProfiles({"test"}) +@ExtendWith(SpringExtension.class) +public class WorkflowMvcPerformanceTest { + private static final String ASSIGN_TASK_URL = "/api/task/assign/"; + private static final String DELEGATE_TASK_URL = "/api/task/delegate/"; + private static final String FINISH_TASK_URL = "/api/task/finish/"; + private static final String CANCEL_TASK_URL = "/api/task/cancel/"; + + private MockMvc mvc; + private PetriNet net; + private AbstractUser user1; + + @Autowired + private TestHelper testHelper; + + @Autowired + private WorkflowService workflowService; + + @Autowired + private IPetriNetService petriNetService; + + @Autowired + private SuperCreatorRunner superCreatorRunner; + + @Autowired + private WebApplicationContext wac; + + @Autowired + private UserService userService; + + @BeforeEach + public void beforeEach() throws IOException, MissingPetriNetMetaDataException { + testHelper.truncateDbs(); + this.net = petriNetService.importPetriNet(ImportPetriNetParams.with() + .xmlFile(new FileInputStream("src/test/resources/petriNets/test_task_event.xml")) + .releaseType(VersionType.MAJOR) + .author(superCreatorRunner.getLoggedSuper()) + .build()).getNet(); + this.mvc = MockMvcBuilders + .webAppContextSetup(wac) + .apply(springSecurity()) + .build(); + + User user = new User(); + user.setFirstName("Firstname"); + user.setLastName("Lastname"); + user.setUsername("username1"); + user.setEmail("user1@netgrif.com"); + PasswordCredential passwordCredential = new PasswordCredential("password", 0, true); + user.setCredential("password", passwordCredential); + user.setState(UserState.ACTIVE); + this.user1 = userService.createUser(user, null); + } + + @Test + void testAssignAdminPerformance() throws Exception { + long totalElapsedTime = 0; + int iterations = 1000; + LoggedUser loggedUser = superCreatorRunner.getLoggedSuper(); + + for (int i = 0; i < iterations; i++) { + Case useCase = workflowService.createCase(CreateCaseParams.with() + .petriNet(net) + .loggedUser(loggedUser) + .locale(Locale.getDefault()) + .build()).getCase(); + String taskId = useCase.getTasks().stream().findFirst().get().getTask(); + long start = System.currentTimeMillis(); + mvc.perform(get(ASSIGN_TASK_URL + taskId) + .with(httpBasic("super@netgrif.com", "password"))); + long finish = System.currentTimeMillis(); + totalElapsedTime += finish - start; + } + log.info("AVG time for event [assignTask by admin] is [{} ms] for [{}] iterations", totalElapsedTime / iterations, iterations); + } + + @Test + void testAssignPerformance() throws Exception { + long totalElapsedTime = 0; + int iterations = 1000; + LoggedUser loggedUser = superCreatorRunner.getLoggedSuper(); + + for (int i = 0; i < iterations; i++) { + Case useCase = workflowService.createCase(CreateCaseParams.with() + .petriNet(net) + .loggedUser(loggedUser) + .locale(Locale.getDefault()) + .build()).getCase(); + String taskId = useCase.getTasks().stream().findFirst().get().getTask(); + long start = System.currentTimeMillis(); + mvc.perform(get(ASSIGN_TASK_URL + taskId) + .with(httpBasic("user1@netgrif.com", "password"))); + long finish = System.currentTimeMillis(); + totalElapsedTime += finish - start; + } + log.info("AVG time for event [assignTask] is [{} ms] for [{}] iterations", totalElapsedTime / iterations, iterations); + } + + +} From b6cc6214072bd98104a4b004c1ac8ccd7fa68a98 Mon Sep 17 00:00:00 2001 From: chvostek Date: Thu, 30 Oct 2025 10:56:47 +0100 Subject: [PATCH 26/55] [NAE-2235] Improve Efficiency of Database Reads and Saves - fix nullptr in TaskAuthorizationService - update WorkflowMvcPerformanceTest --- .../service/TaskAuthorizationService.java | 9 +- .../workflow/WorkflowMvcPerformanceTest.java | 114 +++++++++++++++++- 2 files changed, 115 insertions(+), 8 deletions(-) diff --git a/application-engine/src/main/java/com/netgrif/application/engine/workflow/service/TaskAuthorizationService.java b/application-engine/src/main/java/com/netgrif/application/engine/workflow/service/TaskAuthorizationService.java index 1fa8c8e016..b6e65b0c93 100644 --- a/application-engine/src/main/java/com/netgrif/application/engine/workflow/service/TaskAuthorizationService.java +++ b/application-engine/src/main/java/com/netgrif/application/engine/workflow/service/TaskAuthorizationService.java @@ -88,7 +88,8 @@ public boolean isAssignee(AbstractUser user, Task task) { return false; else // TODO: impersonation user.getSelfOrImpersonated().getStringId() - return task.getUserId().equals(user.getStringId()) || (Boolean) user.getAttributeValue("anonymous"); + return task.getUserId().equals(user.getStringId()) + || (user.getAttributeValue("anonymous") != null && (Boolean) user.getAttributeValue("anonymous")); } private boolean isAssigned(String taskId) { @@ -133,7 +134,7 @@ public boolean canCallDelegate(LoggedUser loggedUser, String taskId) { } // TODO: impersonation - Boolean rolePerm = userHasAtLeastOneRolePermission(loggedUser, taskId, RolePermission.DELEGATE); + Boolean rolePerm = userHasAtLeastOneRolePermission(loggedUser, task, RolePermission.DELEGATE); return rolePerm != null && rolePerm; } @@ -188,13 +189,13 @@ public boolean canCallCancel(LoggedUser loggedUser, String taskId) throws Illega } // TODO: impersonation - Boolean userPerm = userHasUserListPermission(loggedUser, taskId, RolePermission.CANCEL); + Boolean userPerm = userHasUserListPermission(loggedUser, task, RolePermission.CANCEL); if (userPerm != null) { return userPerm; } // TODO: impersonation - Boolean rolePerm = userHasAtLeastOneRolePermission(loggedUser, taskId, RolePermission.CANCEL); + Boolean rolePerm = userHasAtLeastOneRolePermission(loggedUser, task, RolePermission.CANCEL); return rolePerm != null && rolePerm; } diff --git a/application-engine/src/test/java/com/netgrif/application/engine/workflow/WorkflowMvcPerformanceTest.java b/application-engine/src/test/java/com/netgrif/application/engine/workflow/WorkflowMvcPerformanceTest.java index af3ad54600..bd4c89754d 100644 --- a/application-engine/src/test/java/com/netgrif/application/engine/workflow/WorkflowMvcPerformanceTest.java +++ b/application-engine/src/test/java/com/netgrif/application/engine/workflow/WorkflowMvcPerformanceTest.java @@ -2,10 +2,7 @@ import com.netgrif.application.engine.TestHelper; import com.netgrif.application.engine.auth.service.UserService; -import com.netgrif.application.engine.objects.auth.domain.AbstractUser; -import com.netgrif.application.engine.objects.auth.domain.LoggedUser; -import com.netgrif.application.engine.objects.auth.domain.PasswordCredential; -import com.netgrif.application.engine.objects.auth.domain.User; +import com.netgrif.application.engine.objects.auth.domain.*; import com.netgrif.application.engine.objects.auth.domain.enums.UserState; import com.netgrif.application.engine.objects.petrinet.domain.PetriNet; import com.netgrif.application.engine.objects.petrinet.domain.VersionType; @@ -15,6 +12,8 @@ import com.netgrif.application.engine.petrinet.service.interfaces.IPetriNetService; import com.netgrif.application.engine.startup.runner.SuperCreatorRunner; import com.netgrif.application.engine.workflow.params.CreateCaseParams; +import com.netgrif.application.engine.workflow.params.TaskParams; +import com.netgrif.application.engine.workflow.service.TaskService; import com.netgrif.application.engine.workflow.service.WorkflowService; import lombok.extern.slf4j.Slf4j; import org.junit.jupiter.api.BeforeEach; @@ -70,6 +69,9 @@ public class WorkflowMvcPerformanceTest { @Autowired private UserService userService; + @Autowired + private TaskService taskService; + @BeforeEach public void beforeEach() throws IOException, MissingPetriNetMetaDataException { testHelper.truncateDbs(); @@ -138,5 +140,109 @@ void testAssignPerformance() throws Exception { log.info("AVG time for event [assignTask] is [{} ms] for [{}] iterations", totalElapsedTime / iterations, iterations); } + @Test + public void testCancelAdminPerformance() throws Exception { + long totalElapsedTime = 0; + int iterations = 1000; + LoggedUser loggedUser = superCreatorRunner.getLoggedSuper(); + + for (int i = 0; i < iterations; i++) { + Case useCase = workflowService.createCase(CreateCaseParams.with() + .petriNet(net) + .loggedUser(loggedUser) + .locale(Locale.getDefault()) + .build()).getCase(); + String taskId = useCase.getTasks().stream().findFirst().get().getTask(); + taskService.assignTask(TaskParams.with() + .taskId(taskId) + .user(loggedUser) + .build()); + long start = System.currentTimeMillis(); + mvc.perform(get(CANCEL_TASK_URL + taskId) + .with(httpBasic("super@netgrif.com", "password"))); + long finish = System.currentTimeMillis(); + totalElapsedTime += finish - start; + } + log.info("AVG time for event [cancelTask by admin] is [{} ms] for [{}] iterations", totalElapsedTime / iterations, iterations); + } + + @Test + public void testCancelPerformance() throws Exception { + long totalElapsedTime = 0; + int iterations = 1000; + LoggedUser loggedUser = superCreatorRunner.getLoggedSuper(); + + for (int i = 0; i < iterations; i++) { + Case useCase = workflowService.createCase(CreateCaseParams.with() + .petriNet(net) + .loggedUser(loggedUser) + .locale(Locale.getDefault()) + .build()).getCase(); + String taskId = useCase.getTasks().stream().findFirst().get().getTask(); + taskService.assignTask(TaskParams.with() + .taskId(taskId) + .user(this.user1) + .build()); + long start = System.currentTimeMillis(); + mvc.perform(get(CANCEL_TASK_URL + taskId) + .with(httpBasic("user1@netgrif.com", "password"))); + long finish = System.currentTimeMillis(); + totalElapsedTime += finish - start; + } + log.info("AVG time for event [cancelTask] is [{} ms] for [{}] iterations", totalElapsedTime / iterations, iterations); + } + + @Test + public void testFinishAdminPerformance() throws Exception { + long totalElapsedTime = 0; + int iterations = 1000; + LoggedUser loggedUser = superCreatorRunner.getLoggedSuper(); + + for (int i = 0; i < iterations; i++) { + Case useCase = workflowService.createCase(CreateCaseParams.with() + .petriNet(net) + .loggedUser(loggedUser) + .locale(Locale.getDefault()) + .build()).getCase(); + String taskId = useCase.getTasks().stream().findFirst().get().getTask(); + taskService.assignTask(TaskParams.with() + .taskId(taskId) + .user(loggedUser) + .build()); + long start = System.currentTimeMillis(); + mvc.perform(get(FINISH_TASK_URL + taskId) + .with(httpBasic("super@netgrif.com", "password"))); + long finish = System.currentTimeMillis(); + totalElapsedTime += finish - start; + } + log.info("AVG time for event [finishTask by admin] is [{} ms] for [{}] iterations", totalElapsedTime / iterations, iterations); + } + + @Test + public void testFinishPerformance() throws Exception { + long totalElapsedTime = 0; + int iterations = 1000; + LoggedUser loggedUser = superCreatorRunner.getLoggedSuper(); + + for (int i = 0; i < iterations; i++) { + Case useCase = workflowService.createCase(CreateCaseParams.with() + .petriNet(net) + .loggedUser(loggedUser) + .locale(Locale.getDefault()) + .build()).getCase(); + String taskId = useCase.getTasks().stream().findFirst().get().getTask(); + taskService.assignTask(TaskParams.with() + .taskId(taskId) + .user(this.user1) + .build()); + long start = System.currentTimeMillis(); + mvc.perform(get(FINISH_TASK_URL + taskId) + .with(httpBasic("user1@netgrif.com", "password"))); + long finish = System.currentTimeMillis(); + totalElapsedTime += finish - start; + } + log.info("AVG time for event [finishTask] is [{} ms] for [{}] iterations", totalElapsedTime / iterations, iterations); + } + } From 0ef503956a7b97e98560843a1f2ed9d8012192d6 Mon Sep 17 00:00:00 2001 From: chvostek Date: Thu, 30 Oct 2025 11:07:40 +0100 Subject: [PATCH 27/55] [NAE-2235] Improve Efficiency of Database Reads and Saves - resolve some small warnings --- .../engine/startup/ApplicationRunnerOrderResolver.java | 5 ++--- .../engine/startup/runner/AnonymousRoleRunner.java | 4 +--- .../engine/startup/runner/DefaultDashboardRunner.java | 5 ++--- .../application/engine/startup/runner/DefaultRoleRunner.java | 4 +--- 4 files changed, 6 insertions(+), 12 deletions(-) diff --git a/application-engine/src/main/java/com/netgrif/application/engine/startup/ApplicationRunnerOrderResolver.java b/application-engine/src/main/java/com/netgrif/application/engine/startup/ApplicationRunnerOrderResolver.java index 7463b1ad31..14f31d70e6 100644 --- a/application-engine/src/main/java/com/netgrif/application/engine/startup/ApplicationRunnerOrderResolver.java +++ b/application-engine/src/main/java/com/netgrif/application/engine/startup/ApplicationRunnerOrderResolver.java @@ -40,7 +40,7 @@ public SortedRunners sortByRunnerOrderAnnotation(Collection runners) { runners.forEach(runner -> { Class runnerClass = resolveClass(runner); RunnerOrder[] runnerOrders = runnerClass.getAnnotationsByType(RunnerOrder.class); - if (runnerOrders == null || runnerOrders.length == 0) { + if (runnerOrders.length == 0) { unresolved.add(runner); return; } @@ -102,8 +102,7 @@ protected void removeRunner(Class runnerClass) { } protected boolean sortUnresolvedRunners() { - boolean changed = false; - changed = changed || resolveSortingAnnotation(BeforeRunner.class, this::insertBeforeRunner); + boolean changed = resolveSortingAnnotation(BeforeRunner.class, this::insertBeforeRunner); changed = changed || resolveSortingAnnotation(AfterRunner.class, this::insertAfterRunner); changed = changed || resolveSortingAnnotation(ReplaceRunner.class, this::replaceRunner); if (unresolved.isEmpty()) return true; diff --git a/application-engine/src/main/java/com/netgrif/application/engine/startup/runner/AnonymousRoleRunner.java b/application-engine/src/main/java/com/netgrif/application/engine/startup/runner/AnonymousRoleRunner.java index 2528b5893e..64ba39948e 100644 --- a/application-engine/src/main/java/com/netgrif/application/engine/startup/runner/AnonymousRoleRunner.java +++ b/application-engine/src/main/java/com/netgrif/application/engine/startup/runner/AnonymousRoleRunner.java @@ -2,8 +2,6 @@ import com.netgrif.application.engine.adapter.spring.petrinet.service.ProcessRoleService; import com.netgrif.application.engine.objects.petrinet.domain.I18nString; -import com.netgrif.application.engine.objects.petrinet.domain.events.Event; -import com.netgrif.application.engine.objects.petrinet.domain.events.EventType; import com.netgrif.application.engine.objects.petrinet.domain.roles.ProcessRole; import com.netgrif.application.engine.startup.ApplicationEngineStartupRunner; import com.netgrif.application.engine.startup.annotation.RunnerOrder; @@ -37,7 +35,7 @@ public void run(ApplicationArguments args) throws Exception { anonymousRole.setImportId(ProcessRole.ANONYMOUS_ROLE); anonymousRole.setName(new I18nString(ProcessRole.ANONYMOUS_ROLE)); anonymousRole.setDescription("Anonymous system process role"); - anonymousRole.setEvents(new LinkedHashMap()); + anonymousRole.setEvents(new LinkedHashMap<>()); processRoleService.save(anonymousRole); } diff --git a/application-engine/src/main/java/com/netgrif/application/engine/startup/runner/DefaultDashboardRunner.java b/application-engine/src/main/java/com/netgrif/application/engine/startup/runner/DefaultDashboardRunner.java index c3e5266e41..65bcb8b004 100644 --- a/application-engine/src/main/java/com/netgrif/application/engine/startup/runner/DefaultDashboardRunner.java +++ b/application-engine/src/main/java/com/netgrif/application/engine/startup/runner/DefaultDashboardRunner.java @@ -3,7 +3,6 @@ import com.netgrif.application.engine.menu.services.interfaces.DashboardManagementService; import com.netgrif.application.engine.objects.petrinet.domain.I18nString; 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.menu.dashboard.DashboardManagementBody; import com.netgrif.application.engine.startup.ApplicationEngineStartupRunner; import com.netgrif.application.engine.startup.annotation.RunnerOrder; @@ -33,10 +32,10 @@ public void run(ApplicationArguments args) throws Exception { } } - Case createMainDashboardManagementItem() throws TransitionNotExecutableException { + private void createMainDashboardManagementItem() throws TransitionNotExecutableException { DashboardManagementBody dashboardItemBody = new DashboardManagementBody("main_dashboard", new I18nString("Main Dashboard", Map.of("sk", "Hlavný Dashboard", "de", "Haupt-Dashboard"))); dashboardItemBody.setLogoutDashboard(true); - return dashboardManagementService.createDashboardManagement(dashboardItemBody); + dashboardManagementService.createDashboardManagement(dashboardItemBody); } } diff --git a/application-engine/src/main/java/com/netgrif/application/engine/startup/runner/DefaultRoleRunner.java b/application-engine/src/main/java/com/netgrif/application/engine/startup/runner/DefaultRoleRunner.java index 50f766222b..eb60db45ed 100644 --- a/application-engine/src/main/java/com/netgrif/application/engine/startup/runner/DefaultRoleRunner.java +++ b/application-engine/src/main/java/com/netgrif/application/engine/startup/runner/DefaultRoleRunner.java @@ -2,8 +2,6 @@ import com.netgrif.application.engine.adapter.spring.petrinet.service.ProcessRoleService; import com.netgrif.application.engine.objects.petrinet.domain.I18nString; -import com.netgrif.application.engine.objects.petrinet.domain.events.Event; -import com.netgrif.application.engine.objects.petrinet.domain.events.EventType; import com.netgrif.application.engine.objects.petrinet.domain.roles.ProcessRole; import com.netgrif.application.engine.startup.ApplicationEngineStartupRunner; import com.netgrif.application.engine.startup.annotation.RunnerOrder; @@ -39,7 +37,7 @@ public void run(ApplicationArguments args) throws Exception { defaultRole.setImportId(ProcessRole.DEFAULT_ROLE); defaultRole.setName(new I18nString(ProcessRole.DEFAULT_ROLE)); defaultRole.setDescription("Default system process role"); - defaultRole.setEvents(new LinkedHashMap()); + defaultRole.setEvents(new LinkedHashMap<>()); defaultRole = processRoleService.save(defaultRole); if (defaultRole == null) { From 149c400c825f7b41cfe502ff768c13cf10f4807f Mon Sep 17 00:00:00 2001 From: chvostek Date: Thu, 30 Oct 2025 13:21:39 +0100 Subject: [PATCH 28/55] [NAE-2235] Improve Efficiency of Database Reads and Saves - introduce optimizations and fixes in ActionDelegate --- .../logic/action/ActionDelegate.groovy | 108 +++++++++++++----- 1 file changed, 80 insertions(+), 28 deletions(-) diff --git a/application-engine/src/main/groovy/com/netgrif/application/engine/petrinet/domain/dataset/logic/action/ActionDelegate.groovy b/application-engine/src/main/groovy/com/netgrif/application/engine/petrinet/domain/dataset/logic/action/ActionDelegate.groovy index e30243b7c5..8b3145b129 100644 --- a/application-engine/src/main/groovy/com/netgrif/application/engine/petrinet/domain/dataset/logic/action/ActionDelegate.groovy +++ b/application-engine/src/main/groovy/com/netgrif/application/engine/petrinet/domain/dataset/logic/action/ActionDelegate.groovy @@ -53,6 +53,7 @@ import com.netgrif.application.engine.objects.workflow.domain.eventoutcomes.case 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.FinishTaskEventOutcome import com.netgrif.application.engine.objects.workflow.domain.eventoutcomes.taskoutcomes.TaskEventOutcome import com.netgrif.application.engine.objects.workflow.domain.menu.FilterBody import com.netgrif.application.engine.objects.workflow.domain.menu.MenuItemBody @@ -70,7 +71,11 @@ import com.netgrif.application.engine.plugin.meta.PluginHolder import com.netgrif.application.engine.startup.ImportHelper import com.netgrif.application.engine.startup.runner.DefaultFiltersRunner import com.netgrif.application.engine.startup.runner.FilterRunner +import com.netgrif.application.engine.startup.runner.MenuProcessRunner import com.netgrif.application.engine.utils.FullPageRequest +import com.netgrif.application.engine.workflow.params.CreateCaseParams +import com.netgrif.application.engine.workflow.params.DeleteCaseParams +import com.netgrif.application.engine.workflow.params.TaskParams import com.netgrif.application.engine.workflow.service.FileFieldInputStream import com.netgrif.application.engine.workflow.service.InitValueExpressionEvaluator import com.netgrif.application.engine.workflow.service.TaskService @@ -627,9 +632,12 @@ class ActionDelegate { } private addTaskOutcomes(Task task, Map dataSet) { - this.outcomes.add(taskService.assignTask(task.stringId)) - this.outcomes.add(dataService.setData(task.stringId, ImportHelper.populateDataset(dataSet as Map>))) - this.outcomes.add(taskService.finishTask(task.stringId)) + AssignTaskEventOutcome assignOutcome = taskService.assignTask(new TaskParams(task.stringId)) + this.outcomes.add(assignOutcome) + SetDataEventOutcome setDataOutcome = dataService.setData(assignOutcome.getTask(), ImportHelper.populateDataset(dataSet as Map>)) + this.outcomes.add(setDataOutcome) + FinishTaskEventOutcome finishOutcome = taskService.finishTask(new TaskParams(setDataOutcome.getTask())) + this.outcomes.add(finishOutcome) } List searchCases(Closure predicates) { @@ -937,26 +945,49 @@ class ActionDelegate { return workflowService.findOne(stringId) } - Case createCase(String identifier, String title = null, String color = "", AbstractUser author = userService.loggedOrSystem, Locale locale = LocaleContextHolder.getLocale(), Map params = [:]) { - // todo 2235 - return workflowService.createCaseByIdentifier(identifier, title, color, ActorTransformer.toLoggedUser(author), locale, params).getCase() - } - - Case createCase(PetriNet net, String title = net.defaultCaseName.getTranslation(locale), String color = "", AbstractUser author = userService.loggedOrSystem, Locale locale = LocaleContextHolder.getLocale(), Map params = [:]) { - CreateCaseEventOutcome outcome = workflowService.createCase(net.stringId, title, color, ActorTransformer.toLoggedUser(author), params) + Case createCase(String identifier, String title = null, String color = "", AbstractUser author = userService.loggedOrSystem, + Locale locale = LocaleContextHolder.getLocale(), Map params = [:]) { + return workflowService.createCase(CreateCaseParams.with() + .petriNetIdentifier(identifier) + .title(title) + .color(color) + .loggedUser(ActorTransformer.toLoggedUser(author)) + .locale(locale) + .params(params) + .build()).getCase() + } + + Case createCase(PetriNet net, String title = net.defaultCaseName.getTranslation(locale), String color = "", + AbstractUser author = userService.loggedOrSystem, Locale locale = LocaleContextHolder.getLocale(), Map params = [:]) { + CreateCaseEventOutcome outcome = workflowService.createCase(CreateCaseParams.with() + .petriNet(net) + .title(title) + .color(color) + .loggedUser(ActorTransformer.toLoggedUser(author)) + .locale(locale) + .params(params) + .build()) this.outcomes.add(outcome) return outcome.getCase() } Task assignTask(String transitionId, Case aCase = useCase, AbstractUser user = userService.loggedOrSystem, Map params = [:]) { String taskId = getTaskId(transitionId, aCase) - AssignTaskEventOutcome outcome = taskService.assignTask(ActorTransformer.toLoggedUser(user), taskId, params) + AssignTaskEventOutcome outcome = taskService.assignTask(TaskParams.with() + .taskId(taskId) + .user(user) + .params(params) + .build()) this.outcomes.add(outcome) return outcome.getTask() } Task assignTask(Task task, AbstractUser user = userService.loggedOrSystem, Map params = [:]) { - return addTaskOutcomeAndReturnTask(taskService.assignTask(task, user, params)) + return addTaskOutcomeAndReturnTask(taskService.assignTask(TaskParams.with() + .task(task) + .user(user) + .params(params) + .build())) } void assignTasks(List tasks, AbstractUser assignee = userService.loggedOrSystem, Map params = [:]) { @@ -965,11 +996,19 @@ class ActionDelegate { Task cancelTask(String transitionId, Case aCase = useCase, AbstractUser user = userService.loggedOrSystem, Map params = [:]) { String taskId = getTaskId(transitionId, aCase) - return addTaskOutcomeAndReturnTask(taskService.cancelTask(ActorTransformer.toLoggedUser(user), taskId, params)) + return addTaskOutcomeAndReturnTask(taskService.cancelTask(TaskParams.with() + .taskId(taskId) + .user(user) + .params(params) + .build())) } Task cancelTask(Task task, AbstractUser user = userService.loggedOrSystem, Map params = [:]) { - return addTaskOutcomeAndReturnTask(taskService.cancelTask(task, user, params)) + return addTaskOutcomeAndReturnTask(taskService.cancelTask(TaskParams.with() + .task(task) + .user(user) + .params(params) + .build())) } void cancelTasks(List tasks, AbstractUser user = userService.loggedOrSystem, Map params = [:]) { @@ -983,11 +1022,19 @@ class ActionDelegate { void finishTask(String transitionId, Case aCase = useCase, AbstractUser user = userService.loggedOrSystem, Map params = [:]) { String taskId = getTaskId(transitionId, aCase) - addTaskOutcomeAndReturnTask(taskService.finishTask(ActorTransformer.toLoggedUser(user), taskId, params)) + addTaskOutcomeAndReturnTask(taskService.finishTask(TaskParams.with() + .taskId(taskId) + .user(user) + .params(params) + .build())) } void finishTask(Task task, AbstractUser user = userService.loggedOrSystem, Map params = [:]) { - addTaskOutcomeAndReturnTask(taskService.finishTask(task, user, params)) + addTaskOutcomeAndReturnTask(taskService.finishTask(TaskParams.with() + .task(task) + .user(user) + .params(params) + .build())) } void finishTasks(List tasks, AbstractUser finisher = userService.loggedOrSystem, Map params = [:]) { @@ -1079,6 +1126,7 @@ class ActionDelegate { return addSetDataOutcomeToOutcomes(dataService.setData(taskId, ImportHelper.populateDataset(dataSet), params)) } + // todo: remove all deprecated @Deprecated SetDataEventOutcome setDataWithPropagation(String transitionId, Case caze, Map dataSet) { Task task = taskService.findOne(caze.tasks.find { it.transition == transitionId }.task) @@ -1121,8 +1169,7 @@ class ActionDelegate { Map getData(String taskId, Map params = [:]) { Task task = taskService.findById(taskId) - def useCase = workflowService.findOne(task.caseId) - return mapData(addGetDataOutcomeToOutcomesAndReturnData(dataService.getData(task, useCase, params))) + return getData(task, params) } Map getData(Transition transition, Map params = [:]) { @@ -1322,8 +1369,11 @@ class ActionDelegate { } def changeUserByEmail(String email, String attribute, def cl) { - AbstractUser user = userService.findUserByUsername(email, null) - changeUser(user, attribute, cl) + Optional userOpt = userService.findUserByUsername(email, null) + if (userOpt.isEmpty()) { + throw new IllegalArgumentException("Such user with email %s does not exists.".formatted(email)) + } + changeUser(userOpt.get(), attribute, cl) } def changeUser(String id, String attribute, def cl) { @@ -1366,8 +1416,10 @@ class ActionDelegate { void deleteUser(String email) { AbstractUser user = userService.findByEmail(email, null) - if (user == null) + if (user == null) { log.error("Cannot find user with email [" + email + "]") + return + } deleteUser(user) } @@ -1385,12 +1437,12 @@ class ActionDelegate { } AbstractUser findUserByEmail(String email) { - AbstractUser user = userService.findUserByUsername(email, null) - if (user == null) { + Optional userOpt = userService.findUserByUsername(email, null) + if (userOpt.isEmpty()) { log.error("Cannot find user with email [" + email + "]") return null } else { - return user + return userOpt.get() } } @@ -1710,7 +1762,7 @@ class ActionDelegate { * @return */ def deleteFilter(Case filter) { - workflowService.deleteCase(filter.stringId) + workflowService.deleteCase(new DeleteCaseParams(filter.stringId)) } /** @@ -1948,7 +2000,7 @@ class ActionDelegate { */ def deleteMenuItem(Case item) { async.run { - workflowService.deleteCase(item.stringId) + workflowService.deleteCase(new DeleteCaseParams(item.stringId)) } } @@ -2736,12 +2788,12 @@ class ActionDelegate { options.putAll(splitPathList.collectEntries { [(it): new I18nString(it)] }) - Case caseByPath = findCaseElastic("processIdentifier:$FilterRunner.MENU_NET_IDENTIFIER AND dataSet.nodePath.textValue.keyword:\"$path\"") + Case caseByPath = findCaseElastic("processIdentifier:$MenuProcessRunner.MENU_NET_IDENTIFIER AND dataSet.nodePath.textValue.keyword:\"$path\"") Set childrenIds = caseByPath.dataSet[MenuItemConstants.FIELD_CHILD_ITEM_IDS].value as Set if (!childrenIds.isEmpty()) { for (String id : childrenIds) { Case childFolderCase = workflowService.findOne(id) - options.put(childFolderCase.dataSet[MenuItemConstants.FIELD_CHILD_ITEM_IDS.value].value as String, new I18nString(childFolderCase.dataSet[MenuItemConstants.PREFERENCE_ITEM_FIELD_NODE_NAME.value].value as String)) + options.put(childFolderCase.dataSet[MenuItemConstants.FIELD_CHILD_ITEM_IDS.value].value as String, new I18nString(childFolderCase.dataSet[MenuItemConstants.FIELD_NODE_NAME.value].value as String)) } } From c803e1a556ad9d7c62a346d307dbf8f425f66cb7 Mon Sep 17 00:00:00 2001 From: chvostek Date: Thu, 30 Oct 2025 13:24:32 +0100 Subject: [PATCH 29/55] [NAE-2235] Improve Efficiency of Database Reads and Saves - small update in ValidationService --- .../engine/validation/service/ValidationService.groovy | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/application-engine/src/main/groovy/com/netgrif/application/engine/validation/service/ValidationService.groovy b/application-engine/src/main/groovy/com/netgrif/application/engine/validation/service/ValidationService.groovy index a734f8e6fb..6fb727a5a7 100644 --- a/application-engine/src/main/groovy/com/netgrif/application/engine/validation/service/ValidationService.groovy +++ b/application-engine/src/main/groovy/com/netgrif/application/engine/validation/service/ValidationService.groovy @@ -17,7 +17,7 @@ import java.util.stream.Collectors class ValidationService implements IValidationService { @Override - public void valid(Field field, DataField dataField) { + void valid(Field field, DataField dataField) { if (field.getValidations() == null) { return } @@ -67,7 +67,7 @@ class ValidationService implements IValidationService { I18nString validMessage = validation.getValidationMessage() != null ? validation.getValidationMessage() : new I18nString("Invalid Field value") method.invoke(instance, new ValidationDataInput(dataField, validMessage, LocaleContextHolder.getLocale(), rules.stream().skip(1).collect(Collectors.joining(" ")))) } else { - log.warn("Method [" + rules.first() + "] in dataField " + field.getImportId() + " not found") + log.warn("Method [{}] in dataField {} not found", rules.first(), field.getImportId()) } } }) From c7ba6adb5117c9e0be3aa9b74ce61998cd553846 Mon Sep 17 00:00:00 2001 From: chvostek Date: Thu, 30 Oct 2025 13:35:17 +0100 Subject: [PATCH 30/55] [NAE-2235] Improve Efficiency of Database Reads and Saves - resolve some warning --- .../auth/service/LoginAttemptService.java | 8 +++---- .../auth/service/RegistrationService.java | 24 +++++++++---------- .../engine/auth/web/UserControllerAdvice.java | 2 +- .../security/ImpersonationRequestFilter.java | 8 +++---- .../petrinet/web/PetriNetController.java | 4 ++-- .../web/RestResponseExceptionHandler.java | 2 +- 6 files changed, 24 insertions(+), 24 deletions(-) diff --git a/application-engine/src/main/java/com/netgrif/application/engine/auth/service/LoginAttemptService.java b/application-engine/src/main/java/com/netgrif/application/engine/auth/service/LoginAttemptService.java index bf2fb7b7f1..c52ca894f7 100644 --- a/application-engine/src/main/java/com/netgrif/application/engine/auth/service/LoginAttemptService.java +++ b/application-engine/src/main/java/com/netgrif/application/engine/auth/service/LoginAttemptService.java @@ -19,7 +19,7 @@ public class LoginAttemptService implements ILoginAttemptService { @Autowired private SecurityConfigurationProperties.SecurityLimitsProperties securityLimitsProperties; - private LoadingCache attemptsCache; + private final LoadingCache attemptsCache; public LoginAttemptService(SecurityConfigurationProperties.SecurityLimitsProperties securityLimitsProperties) { super(); @@ -37,11 +37,11 @@ public void loginSucceeded(String key) { } public void loginFailed(String key) { - int attempts = 0; + int attempts; try { attempts = attemptsCache.get(key); } catch (ExecutionException e) { - log.error("Error reading login attempts cache for key " + key, e); + log.error("Error reading login attempts cache for key {}", key, e); attempts = 0; } attempts++; @@ -52,7 +52,7 @@ public boolean isBlocked(String key) { try { return attemptsCache.get(key) >= securityLimitsProperties.getLoginAttempts(); } catch (ExecutionException e) { - log.error("Error reading login attempts cache for key " + key, e); + log.error("Error reading login attempts cache for key {}", key, e); return false; } } diff --git a/application-engine/src/main/java/com/netgrif/application/engine/auth/service/RegistrationService.java b/application-engine/src/main/java/com/netgrif/application/engine/auth/service/RegistrationService.java index eeac37df89..a23b4b5564 100644 --- a/application-engine/src/main/java/com/netgrif/application/engine/auth/service/RegistrationService.java +++ b/application-engine/src/main/java/com/netgrif/application/engine/auth/service/RegistrationService.java @@ -82,7 +82,7 @@ public void resetExpiredToken() { pageable = pageable.next(); } while (users.hasNext()); - log.info("Reset " + users.getContent().size() + " expired user tokens"); + log.info("Reset {} expired user tokens", users.getContent().size()); } @Override @@ -90,13 +90,13 @@ public void changePassword(AbstractUser user, String newPassword) { user.setPassword(newPassword); encodeUserPassword(user); userService.saveUser(user, null); - log.info("Changed password for user " + user.getEmail() + "."); + log.info("Changed password for user {}.", user.getEmail()); } @Override public boolean verifyToken(String token) { try { - log.info("Verifying token:" + token); + log.info("Verifying token: {}", token); String[] tokenParts = decodeToken(token); User user = (User) userService.findByEmail(tokenParts[0], null); return user != null && Objects.equals(user.getToken(), tokenParts[1]) && user.getExpirationDate().isAfter(LocalDateTime.now()); @@ -128,12 +128,12 @@ public AbstractUser createNewUser(NewUserRequest newUser) { if (user.isActive()) { return null; } - log.info("Renewing old user [" + newUser.email + "]"); + log.info("Renewing old user [{}]", newUser.email); } else { user = new User(); user.setEmail(newUser.email); user.setUsername(newUser.email); - log.info("Creating new user [" + newUser.email + "]"); + log.info("Creating new user [{}]", newUser.email); } user.setToken(generateTokenKey()); user.setPassword(""); @@ -159,7 +159,7 @@ public AbstractUser createNewUser(NewUserRequest newUser) { @Override public AbstractUser registerUser(RegistrationRequest registrationRequest) throws InvalidUserTokenException { String email = decodeToken(registrationRequest.token)[0]; - log.info("Registering user " + email); + log.info("Registering user {}", email); User user = (User) userService.findByEmail(email, null); if (user == null) { return null; @@ -173,16 +173,16 @@ public AbstractUser registerUser(RegistrationRequest registrationRequest) throws user.setExpirationDate(null); user.setState(UserState.ACTIVE); - return (AbstractUser) userService.saveUser(user, null); + return userService.saveUser(user, null); } @Override public AbstractUser resetPassword(String email) { - log.info("Resetting password of " + email); + log.info("Resetting password of {}", email); User user = (User) userService.findByEmail(email, null); if (user == null || !user.isActive()) { String state = user == null ? "Non-existing" : "Inactive"; - log.info(state + " user [" + email + "] tried to reset his password"); + log.info("{} user [{}] tried to reset his password", state, email); return null; } @@ -190,12 +190,12 @@ public AbstractUser resetPassword(String email) { user.setPassword(null); user.setToken(generateTokenKey()); user.setExpirationDate(generateExpirationDate()); - return (AbstractUser) userService.saveUser(user, null); + return userService.saveUser(user, null); } @Override public AbstractUser recover(String email, String newPassword) { - log.info("Recovering user " + email); + log.info("Recovering user {}", email); User user = (User) userService.findByEmail(email, null); if (user == null) { return null; @@ -206,7 +206,7 @@ public AbstractUser recover(String email, String newPassword) { user.setToken(null); user.setExpirationDate(null); - return (AbstractUser) userService.saveUser(user, null); + return userService.saveUser(user, null); } @Override diff --git a/application-engine/src/main/java/com/netgrif/application/engine/auth/web/UserControllerAdvice.java b/application-engine/src/main/java/com/netgrif/application/engine/auth/web/UserControllerAdvice.java index 020df490d9..f2e7801209 100644 --- a/application-engine/src/main/java/com/netgrif/application/engine/auth/web/UserControllerAdvice.java +++ b/application-engine/src/main/java/com/netgrif/application/engine/auth/web/UserControllerAdvice.java @@ -16,7 +16,7 @@ public class UserControllerAdvice { @ResponseStatus(value = HttpStatus.BAD_REQUEST) public @ResponseBody MessageResource handleException(NumberFormatException e) { - log.error("Long could not be parsed from request. " + e.getMessage(), e); + log.error("Long could not be parsed from request. {}", e.getMessage(), e); return MessageResource.errorMessage(e.getMessage()); } } diff --git a/application-engine/src/main/java/com/netgrif/application/engine/configuration/security/ImpersonationRequestFilter.java b/application-engine/src/main/java/com/netgrif/application/engine/configuration/security/ImpersonationRequestFilter.java index 127aed8d69..a50d2b9875 100644 --- a/application-engine/src/main/java/com/netgrif/application/engine/configuration/security/ImpersonationRequestFilter.java +++ b/application-engine/src/main/java/com/netgrif/application/engine/configuration/security/ImpersonationRequestFilter.java @@ -56,16 +56,16 @@ protected void handleImpersonator(LoggedUser loggedUser, HttpServletRequest serv // logout(servletRequest, servletResponse); // } } catch (Exception e) { - log.error("ImpersonationRequestFilter error " + e.getMessage(), e); + log.error("ImpersonationRequestFilter error {}", e.getMessage(), e); } } protected void handleImpersonated(LoggedUser loggedUser, HttpServletRequest servletRequest) { try { - log.debug("Filtering request " + servletRequest.getRequestURI() + ", " + loggedUser.getUsername()); + log.debug("Filtering request {}, {}", servletRequest.getRequestURI(), loggedUser.getUsername()); impersonationService.removeImpersonatorByImpersonated(loggedUser.getStringId()); } catch (Exception e) { - log.error("Failed to resolve impersonators for " + loggedUser.getUsername() + ", " + e.getMessage(), e); + log.error("Failed to resolve impersonators for {}, {}", loggedUser.getUsername(), e.getMessage(), e); } } @@ -84,7 +84,7 @@ protected LoggedUser getPrincipal() { Object principal = auth.getPrincipal(); if (!(principal instanceof LoggedUser)) { - log.warn(principal + " is not an instance of LoggedUser"); + log.warn("{} is not an instance of LoggedUser", principal); return null; } diff --git a/application-engine/src/main/java/com/netgrif/application/engine/petrinet/web/PetriNetController.java b/application-engine/src/main/java/com/netgrif/application/engine/petrinet/web/PetriNetController.java index 200b5382f5..5c3ca66fbe 100644 --- a/application-engine/src/main/java/com/netgrif/application/engine/petrinet/web/PetriNetController.java +++ b/application-engine/src/main/java/com/netgrif/application/engine/petrinet/web/PetriNetController.java @@ -190,7 +190,7 @@ public FileSystemResource getNetFile(@PathVariable("netId") String netId, @Reque response.setContentType(MediaType.APPLICATION_OCTET_STREAM_VALUE); response.setHeader("Content-Disposition", "attachment; filename=\"" + fileResource.getFilename() + Importer.FILE_EXTENSION + "\""); response.setHeader("Content-Length", String.valueOf(fileResource.getFile().length())); - log.info("Downloading Petri net file: " + fileResource.getFilename() + " [" + netId + "]"); + log.info("Downloading Petri net file: {} [{}]", fileResource.getFilename(), netId); return fileResource; } @@ -232,7 +232,7 @@ PagedModel searchElasticPetriNets(@RequestBody PetriN public MessageResource deletePetriNet(@PathVariable("id") String processId, @RequestParam(required = false) boolean force, Authentication auth) { String decodedProcessId = decodeUrl(processId); if (Objects.equals(decodedProcessId, "")) { - log.error("Deleting Petri net [" + processId + "] failed: could not decode process ID from URL"); + log.error("Deleting Petri net [{}] failed: could not decode process ID from URL", processId); return MessageResource.errorMessage("Deleting Petri net " + processId + " failed!"); } LoggedUser user = (LoggedUser) auth.getPrincipal(); diff --git a/application-engine/src/main/java/com/netgrif/application/engine/workflow/web/RestResponseExceptionHandler.java b/application-engine/src/main/java/com/netgrif/application/engine/workflow/web/RestResponseExceptionHandler.java index b1c3fd3f40..a476b0b9f4 100644 --- a/application-engine/src/main/java/com/netgrif/application/engine/workflow/web/RestResponseExceptionHandler.java +++ b/application-engine/src/main/java/com/netgrif/application/engine/workflow/web/RestResponseExceptionHandler.java @@ -30,7 +30,7 @@ protected ResponseEntity handleHttpMessageNotWritable(HttpMessageNotWrit Field from = (Field) fieldReference.getFrom(); Case useCase = (Case) caseReference.getFrom(); - log.error("[" + useCase.getStringId() + "] Could not parse value of field [" + from.getStringId() + "], value [" + from.getValue() + "]"); + log.error("[{}] Could not parse value of field [{}], value [{}]", useCase.getStringId(), from.getStringId(), from.getValue()); } catch (Exception e) { log.warn("Unrecognized exception: ", e); } From 78b7dffd6f871ae2a39440147bc92ea067795951 Mon Sep 17 00:00:00 2001 From: chvostek Date: Thu, 30 Oct 2025 13:49:14 +0100 Subject: [PATCH 31/55] [NAE-2235] Improve Efficiency of Database Reads and Saves - resolve some warnings in UserServiceImpl --- .../application/engine/auth/service/UserServiceImpl.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/nae-user-ce/src/main/java/com/netgrif/application/engine/auth/service/UserServiceImpl.java b/nae-user-ce/src/main/java/com/netgrif/application/engine/auth/service/UserServiceImpl.java index 9820e6296b..cc1d1f7432 100644 --- a/nae-user-ce/src/main/java/com/netgrif/application/engine/auth/service/UserServiceImpl.java +++ b/nae-user-ce/src/main/java/com/netgrif/application/engine/auth/service/UserServiceImpl.java @@ -139,7 +139,7 @@ public List saveUsers(Collection users) { public Optional findUserByUsername(String username, String realmId) { log.debug("Finding user by username [{}] in realm [{}]", username, realmId); String collectionName = collectionNameProvider.getCollectionNameForRealm(realmId); - Optional userOpt = userRepository.findByUsername(username, mongoTemplate, collectionName).map(user -> (AbstractUser) user); + Optional userOpt = userRepository.findByUsername(username, mongoTemplate, collectionName).map(user -> user); if (userOpt.isPresent()) { log.debug("User [{}] found in realm [{}]", username, realmId); } else { @@ -206,7 +206,7 @@ public User createUserFromThirdParty(String username, String email, String first setDisablePassword(user); String collectionName = collectionNameProvider.getCollectionNameForRealm(realmId); userRepository.saveUser(user, mongoTemplate, collectionName); - log.info("User [{}] from third-party [{}] successfully created in realm [{}]", username, realmId); + log.info("User [{}] from third-party auth [{}] successfully created in realm [{}]", username, authMethod, realmId); return user; } From e5f99697e7a3e985544c5c8acbea321a5a22c20e Mon Sep 17 00:00:00 2001 From: chvostek Date: Thu, 30 Oct 2025 14:12:23 +0100 Subject: [PATCH 32/55] [NAE-2235] Improve Efficiency of Database Reads and Saves - resolve some warnings - update changed method calls --- .../engine/migration/ActionMigration.groovy | 4 +-- .../engine/startup/ImportHelper.groovy | 28 +++++++++++++++---- .../engine-processes/import_filters.xml | 4 +-- .../engine-processes/menu/menu_item.xml | 6 ++-- .../menu/tabbed_case_view_configuration.xml | 4 +-- .../menu/tabbed_ticket_view_configuration.xml | 4 +-- .../preference_filter_item.xml | 2 +- 7 files changed, 34 insertions(+), 18 deletions(-) diff --git a/application-engine/src/main/groovy/com/netgrif/application/engine/migration/ActionMigration.groovy b/application-engine/src/main/groovy/com/netgrif/application/engine/migration/ActionMigration.groovy index ef6e9c652f..8f22152c55 100644 --- a/application-engine/src/main/groovy/com/netgrif/application/engine/migration/ActionMigration.groovy +++ b/application-engine/src/main/groovy/com/netgrif/application/engine/migration/ActionMigration.groovy @@ -56,7 +56,7 @@ class ActionMigration { } } - private void migrateDataSetActions(PetriNet newPetriNet, PetriNet oldPetriNet) { + private static void migrateDataSetActions(PetriNet newPetriNet, PetriNet oldPetriNet) { newPetriNet.dataSet.each { key, data -> if (data.events != null && data.events.size() > 0) { oldPetriNet.dataSet[key].events = data.events @@ -64,7 +64,7 @@ class ActionMigration { } } - private void migrateDataRefActions(PetriNet newPetriNet, PetriNet oldPetriNet) { + private static void migrateDataRefActions(PetriNet newPetriNet, PetriNet oldPetriNet) { newPetriNet.transitions.each { transKey, trans -> trans.dataSet.each { dataKey, data -> if (data.events != null && data.events.size() > 0) { diff --git a/application-engine/src/main/groovy/com/netgrif/application/engine/startup/ImportHelper.groovy b/application-engine/src/main/groovy/com/netgrif/application/engine/startup/ImportHelper.groovy index 5005c9c831..a837f7951b 100644 --- a/application-engine/src/main/groovy/com/netgrif/application/engine/startup/ImportHelper.groovy +++ b/application-engine/src/main/groovy/com/netgrif/application/engine/startup/ImportHelper.groovy @@ -10,6 +10,8 @@ import com.netgrif.application.engine.petrinet.params.ImportPetriNetParams import com.netgrif.application.engine.petrinet.service.interfaces.IPetriNetService import com.netgrif.application.engine.startup.runner.SuperCreatorRunner import com.netgrif.application.engine.workflow.domain.repositories.CaseRepository +import com.netgrif.application.engine.workflow.params.CreateCaseParams +import com.netgrif.application.engine.workflow.params.TaskParams 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 @@ -158,12 +160,12 @@ class ImportHelper { // } - ProcessRole getProcessRoleByImportId(PetriNet net, String roleId) { + static ProcessRole getProcessRoleByImportId(PetriNet net, String roleId) { ProcessRole role = net.roles.values().find { it -> it.importId == roleId } return role } - Map getProcessRolesByImportId(PetriNet net, Map importId) { + static Map getProcessRolesByImportId(PetriNet net, Map importId) { HashMap roles = new HashMap<>() importId.each { it -> roles.put(it.getKey(), getProcessRoleByImportId(net, it.getValue())) @@ -190,7 +192,12 @@ class ImportHelper { } Case createCase(String title, PetriNet net, LoggedUser user) { - return workflowService.createCase(net.getStringId(), title, "", user).getCase() + return workflowService.createCase(CreateCaseParams.with() + .petriNet(net) + .title(title) + .color("") + .loggedUser(user) + .build()).getCase() } Case createCase(String title, PetriNet net) { @@ -208,7 +215,10 @@ class ImportHelper { // } AssignTaskEventOutcome assignTask(String taskTitle, String caseId, LoggedUser author) { - return taskService.assignTask(author, getTaskId(taskTitle, caseId)) + return taskService.assignTask(TaskParams.with() + .taskId(getTaskId(taskTitle, caseId)) + .user(author) + .build()) } AssignTaskEventOutcome assignTaskToSuper(String taskTitle, String caseId) { @@ -216,7 +226,10 @@ class ImportHelper { } FinishTaskEventOutcome finishTask(String taskTitle, String caseId, LoggedUser author) { - return taskService.finishTask(author, getTaskId(taskTitle, caseId)) + return taskService.finishTask(TaskParams.with() + .taskId(getTaskId(taskTitle, caseId)) + .user(author) + .build()) } FinishTaskEventOutcome finishTaskAsSuper(String taskTitle, String caseId) { @@ -224,7 +237,10 @@ class ImportHelper { } CancelTaskEventOutcome cancelTask(String taskTitle, String caseId, LoggedUser user) { - return taskService.cancelTask(user, getTaskId(taskTitle, caseId)) + return taskService.cancelTask(TaskParams.with() + .taskId(getTaskId(taskTitle, caseId)) + .user(user) + .build()) } CancelTaskEventOutcome cancelTaskAsSuper(String taskTitle, String caseId) { diff --git a/application-engine/src/main/resources/petriNets/engine-processes/import_filters.xml b/application-engine/src/main/resources/petriNets/engine-processes/import_filters.xml index ba4f173f29..d83bb6b19f 100644 --- a/application-engine/src/main/resources/petriNets/engine-processes/import_filters.xml +++ b/application-engine/src/main/resources/petriNets/engine-processes/import_filters.xml @@ -22,7 +22,7 @@ importedFilters: f.imported_filters; taskService.findAllById(importedFilters.value).forEach({filterTask -> - workflowService.deleteCase(filterTask.caseId) + deleteCase(filterTask.caseId) }) change importedFilters value { return [] } @@ -148,7 +148,7 @@ importedFilters: f.imported_filters; taskService.findAllById(importedFilters.value).forEach({filterTask -> - workflowService.deleteCase(filterTask.caseId) + deleteCase(filterTask.caseId) }) change importedFilters value { [] } diff --git a/application-engine/src/main/resources/petriNets/engine-processes/menu/menu_item.xml b/application-engine/src/main/resources/petriNets/engine-processes/menu/menu_item.xml index 74dee70993..91fbce84bd 100644 --- a/application-engine/src/main/resources/petriNets/engine-processes/menu/menu_item.xml +++ b/application-engine/src/main/resources/petriNets/engine-processes/menu/menu_item.xml @@ -63,7 +63,7 @@ def childCases = workflowService.findAllById(childCaseIds) async.run { childCases.each { - workflowService.deleteCase(it) + deleteCase(it) } } } @@ -77,7 +77,7 @@ } async.run { - workflowService.deleteCase(viewIdAsList[0]) + deleteCase(viewIdAsList[0]) } } @@ -1128,7 +1128,7 @@ view_configuration_id: f.view_configuration_id; if (view_configuration_id.value != null && !view_configuration_id.value.isEmpty()) { - workflowService.deleteCase(view_configuration_id.value[0]) + deleteCase(view_configuration_id.value[0]) } if (view_configuration_type.value == null || view_configuration_type.value == "") { diff --git a/application-engine/src/main/resources/petriNets/engine-processes/menu/tabbed_case_view_configuration.xml b/application-engine/src/main/resources/petriNets/engine-processes/menu/tabbed_case_view_configuration.xml index 8e4792479d..d4dcd2c9c1 100644 --- a/application-engine/src/main/resources/petriNets/engine-processes/menu/tabbed_case_view_configuration.xml +++ b/application-engine/src/main/resources/petriNets/engine-processes/menu/tabbed_case_view_configuration.xml @@ -84,7 +84,7 @@ } async.run { - workflowService.deleteCase(viewIdAsList[0]) + deleteCase(viewIdAsList[0]) } } @@ -879,7 +879,7 @@ view_configuration_id: f.view_configuration_id; if (view_configuration_id.value != null && !view_configuration_id.value.isEmpty()) { - workflowService.deleteCase(view_configuration_id.value[0]) + deleteCase(view_configuration_id.value[0]) } if (view_configuration_type.value == null || view_configuration_type.value == "") { diff --git a/application-engine/src/main/resources/petriNets/engine-processes/menu/tabbed_ticket_view_configuration.xml b/application-engine/src/main/resources/petriNets/engine-processes/menu/tabbed_ticket_view_configuration.xml index 8bbf0f1d2c..1f5f42476b 100644 --- a/application-engine/src/main/resources/petriNets/engine-processes/menu/tabbed_ticket_view_configuration.xml +++ b/application-engine/src/main/resources/petriNets/engine-processes/menu/tabbed_ticket_view_configuration.xml @@ -84,7 +84,7 @@ } async.run { - workflowService.deleteCase(viewIdAsList[0]) + deleteCase(viewIdAsList[0]) } } @@ -329,7 +329,7 @@ view_configuration_id: f.view_configuration_id; if (view_configuration_id.value != null && !view_configuration_id.value.isEmpty()) { - workflowService.deleteCase(view_configuration_id.value[0]) + deleteCase(view_configuration_id.value[0]) } if (view_configuration_type.value == null || view_configuration_type.value == "") { diff --git a/application-engine/src/main/resources/petriNets/engine-processes/preference_filter_item.xml b/application-engine/src/main/resources/petriNets/engine-processes/preference_filter_item.xml index bf6b837573..b30b3dc087 100644 --- a/application-engine/src/main/resources/petriNets/engine-processes/preference_filter_item.xml +++ b/application-engine/src/main/resources/petriNets/engine-processes/preference_filter_item.xml @@ -122,7 +122,7 @@ "referenced_filters": ["type": "caseRef", "value": previousCaseRefValue], ]) async.run { - workflowService.deleteCase(useCase.stringId) + deleteCase(useCase.stringId) } From aa2c1dd7449c3cb1852b2432b851003fc08264db Mon Sep 17 00:00:00 2001 From: chvostek Date: Thu, 30 Oct 2025 15:32:00 +0100 Subject: [PATCH 33/55] [NAE-2235] Improve Efficiency of Database Reads and Saves - fix some tests --- .../engine/action/AssignActionTest.groovy | 19 +- .../engine/action/MenuItemApiTest.groovy | 12 +- .../auth/TaskAuthorizationServiceTest.groovy | 116 ++++++++--- .../WorkflowAuthorizationServiceTest.groovy | 42 +++- .../elastic/DataSearchRequestTest.groovy | 7 +- .../engine/elastic/ElasticTaskTest.groovy | 7 +- .../engine/elastic/ReindexTest.groovy | 23 ++- .../export/service/ExportServiceTest.groovy | 18 +- .../filters/FilterImportExportTest.groovy | 3 +- .../PredefinedRolesPermissionsTest.groovy | 15 +- .../engine/importer/UserListTest.groovy | 7 +- .../engine/insurance/EncryptionTest.groovy | 15 +- .../ipc/AssignCancelFinishWithCaseTest.groovy | 7 +- .../application/engine/ipc/CaseApiTest.groovy | 13 +- .../application/engine/ipc/TaskApiTest.groovy | 43 +++- .../pdf/service/PdfGeneratorTest.groovy | 193 +++++++++++++++--- .../petrinet/domain/FunctionsTest.groovy | 185 ++++++++++++++--- 17 files changed, 585 insertions(+), 140 deletions(-) diff --git a/application-engine/src/test/groovy/com/netgrif/application/engine/action/AssignActionTest.groovy b/application-engine/src/test/groovy/com/netgrif/application/engine/action/AssignActionTest.groovy index 274213f87f..f55beac18b 100644 --- a/application-engine/src/test/groovy/com/netgrif/application/engine/action/AssignActionTest.groovy +++ b/application-engine/src/test/groovy/com/netgrif/application/engine/action/AssignActionTest.groovy @@ -1,19 +1,19 @@ package com.netgrif.application.engine.action +import com.netgrif.application.engine.TestHelper import com.netgrif.application.engine.adapter.spring.auth.domain.AuthorityImpl -import com.netgrif.application.engine.auth.service.RealmService import com.netgrif.application.engine.auth.service.UserService -import com.netgrif.application.engine.TestHelper +import com.netgrif.application.engine.importer.service.Importer 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.Authority import com.netgrif.application.engine.objects.auth.domain.User import com.netgrif.application.engine.objects.auth.domain.enums.UserState -import com.netgrif.application.engine.importer.service.Importer import com.netgrif.application.engine.objects.petrinet.domain.PetriNet import com.netgrif.application.engine.objects.petrinet.domain.VersionType import com.netgrif.application.engine.objects.petrinet.domain.roles.ProcessRole import com.netgrif.application.engine.petrinet.domain.roles.ProcessRoleRepository +import com.netgrif.application.engine.petrinet.params.ImportPetriNetParams import com.netgrif.application.engine.petrinet.service.interfaces.IPetriNetService import com.netgrif.application.engine.startup.ImportHelper import com.netgrif.application.engine.startup.runner.SuperCreatorRunner @@ -25,7 +25,6 @@ import org.springframework.beans.factory.annotation.Autowired import org.springframework.boot.test.context.SpringBootTest import org.springframework.data.domain.Pageable import org.springframework.data.mongodb.core.MongoTemplate -import org.springframework.hateoas.MediaTypes import org.springframework.http.MediaType import org.springframework.mock.web.MockHttpServletRequest import org.springframework.security.authentication.UsernamePasswordAuthenticationToken @@ -108,10 +107,18 @@ class AssignActionTest { } private void createMainAndSecondaryNet() { - def mainNet = petriNetService.importPetriNet(new FileInputStream("src/test/resources/assignRoleMainNet_test_.xml"), VersionType.MAJOR, superCreator.getLoggedSuper()) + def mainNet = petriNetService.importPetriNet(ImportPetriNetParams.with() + .xmlFile(new FileInputStream("src/test/resources/assignRoleMainNet_test_.xml")) + .releaseType(VersionType.MAJOR) + .author(superCreator.getLoggedSuper()) + .build()) assert mainNet.getNet() != null - def secondaryNet = petriNetService.importPetriNet(new FileInputStream("src/test/resources/assignRoleSecondaryNet_test.xml"), VersionType.MAJOR, superCreator.getLoggedSuper()) + def secondaryNet = petriNetService.importPetriNet(ImportPetriNetParams.with() + .xmlFile(new FileInputStream("src/test/resources/assignRoleSecondaryNet_test.xml")) + .releaseType(VersionType.MAJOR) + .author(superCreator.getLoggedSuper()) + .build()) assert secondaryNet.getNet() != null this.mainNet = mainNet.getNet() diff --git a/application-engine/src/test/groovy/com/netgrif/application/engine/action/MenuItemApiTest.groovy b/application-engine/src/test/groovy/com/netgrif/application/engine/action/MenuItemApiTest.groovy index 7793895f45..fcf968d930 100644 --- a/application-engine/src/test/groovy/com/netgrif/application/engine/action/MenuItemApiTest.groovy +++ b/application-engine/src/test/groovy/com/netgrif/application/engine/action/MenuItemApiTest.groovy @@ -19,6 +19,8 @@ import com.netgrif.application.engine.startup.ImportHelper import com.netgrif.application.engine.objects.workflow.domain.Case import com.netgrif.application.engine.adapter.spring.workflow.domain.QCase import com.netgrif.application.engine.startup.runner.MenuProcessRunner +import com.netgrif.application.engine.workflow.params.DeleteCaseParams +import com.netgrif.application.engine.workflow.params.TaskParams 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 @@ -256,26 +258,26 @@ class MenuItemApiTest { String newIdentifier = "new_identifier" String duplicateTaskId = testFolder.tasks.find { it.transition == "duplicate_item" }.task - taskService.assignTask(duplicateTaskId) + taskService.assignTask(new TaskParams(duplicateTaskId)) assertThrows(IllegalArgumentException.class, () -> { testFolder.dataSet[MenuItemConstants.FIELD_DUPLICATE_TITLE].value = new I18nString("") testFolder.dataSet[MenuItemConstants.FIELD_DUPLICATE_IDENTIFIER].value = newIdentifier testFolder = workflowService.save(testFolder) - taskService.finishTask(duplicateTaskId) + taskService.finishTask(new TaskParams(duplicateTaskId)) }) assertThrows(IllegalArgumentException.class, () -> { testFolder.dataSet[MenuItemConstants.FIELD_DUPLICATE_TITLE].value = new I18nString(newTitle) testFolder.dataSet[MenuItemConstants.FIELD_DUPLICATE_IDENTIFIER].value = "new_menu_item" testFolder = workflowService.save(testFolder) - taskService.finishTask(duplicateTaskId) + taskService.finishTask(new TaskParams(duplicateTaskId)) }) testFolder.dataSet[MenuItemConstants.FIELD_DUPLICATE_TITLE].value = new I18nString(newTitle) testFolder.dataSet[MenuItemConstants.FIELD_DUPLICATE_IDENTIFIER].value = newIdentifier testFolder = workflowService.save(testFolder) - taskService.finishTask(duplicateTaskId) + taskService.finishTask(new TaskParams(duplicateTaskId)) Case duplicated = workflowService.searchOne(QCase.case$.processIdentifier.eq("menu_item") .and(QCase.case$.dataSet.get(MenuItemConstants.FIELD_IDENTIFIER).value.eq(newIdentifier))) @@ -335,7 +337,7 @@ class MenuItemApiTest { String tabbedTaskViewId = MenuItemUtils.getCaseIdFromCaseRef(tabbedCaseView, TabbedCaseViewConstants.FIELD_VIEW_CONFIGURATION_ID) assert tabbedTaskViewId != null - workflowService.deleteCase(testFolder) + workflowService.deleteCase(new DeleteCaseParams(testFolder)) sleep(2000) netgrifFolder = workflowService.findOne(netgrifFolderId) assert !(netgrifFolder.dataSet[MenuItemConstants.FIELD_CHILD_ITEM_IDS].value as ArrayList).contains(testFolder.stringId) diff --git a/application-engine/src/test/groovy/com/netgrif/application/engine/auth/TaskAuthorizationServiceTest.groovy b/application-engine/src/test/groovy/com/netgrif/application/engine/auth/TaskAuthorizationServiceTest.groovy index 93934b8336..fd9b985947 100644 --- a/application-engine/src/test/groovy/com/netgrif/application/engine/auth/TaskAuthorizationServiceTest.groovy +++ b/application-engine/src/test/groovy/com/netgrif/application/engine/auth/TaskAuthorizationServiceTest.groovy @@ -4,12 +4,16 @@ import com.netgrif.application.engine.auth.service.UserService 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.User +import com.netgrif.application.engine.petrinet.params.ImportPetriNetParams import com.netgrif.application.engine.petrinet.service.interfaces.IPetriNetService import com.netgrif.application.engine.TestHelper import com.netgrif.application.engine.importer.service.Importer import com.netgrif.application.engine.startup.ImportHelper import com.netgrif.application.engine.startup.runner.SuperCreatorRunner import com.netgrif.application.engine.objects.workflow.domain.eventoutcomes.petrinetoutcomes.ImportPetriNetEventOutcome +import com.netgrif.application.engine.workflow.params.CreateCaseParams +import com.netgrif.application.engine.workflow.params.DeleteCaseParams +import com.netgrif.application.engine.workflow.params.TaskParams import com.netgrif.application.engine.workflow.service.interfaces.IDataService import com.netgrif.application.engine.workflow.service.interfaces.ITaskAuthorizationService import com.netgrif.application.engine.workflow.service.interfaces.ITaskService @@ -158,11 +162,19 @@ class TaskAuthorizationServiceTest { @BeforeEach void init() { testHelper.truncateDbs() - ImportPetriNetEventOutcome net = petriNetService.importPetriNet(new FileInputStream("src/test/resources/task_authorization_service_test.xml"), VersionType.MAJOR, superCreator.getLoggedSuper()) + ImportPetriNetEventOutcome net = petriNetService.importPetriNet(ImportPetriNetParams.with() + .xmlFile(new FileInputStream("src/test/resources/task_authorization_service_test.xml")) + .releaseType(VersionType.MAJOR) + .author(superCreator.getLoggedSuper()) + .build()) assert net.getNet() != null this.net = net.getNet() - ImportPetriNetEventOutcome netWithUserRefs = petriNetService.importPetriNet(new FileInputStream("src/test/resources/task_authorization_service_test_with_userRefs.xml"), VersionType.MAJOR, superCreator.getLoggedSuper()) + ImportPetriNetEventOutcome netWithUserRefs = petriNetService.importPetriNet(ImportPetriNetParams.with() + .xmlFile(new FileInputStream("src/test/resources/task_authorization_service_test_with_userRefs.xml")) + .releaseType(VersionType.MAJOR) + .author(superCreator.getLoggedSuper()) + .build()) assert netWithUserRefs.getNet() != null this.netWithUserRefs = netWithUserRefs.getNet() @@ -326,25 +338,40 @@ class TaskAuthorizationServiceTest { void testCanAssign() { ProcessRole positiveRole = this.net.getRoles().values().find(v -> v.getImportId() == "assign_pos_role") userService.addRole(testUser, positiveRole.get_id()) - Case case_ = workflowService.createCase(net.getStringId(), "Test assign", "", ActorTransformer.toLoggedUser(testUser)).getCase() + Case case_ = workflowService.createCase(CreateCaseParams.with() + .petriNet(net) + .title("Test assign") + .color("") + .loggedUser(ActorTransformer.toLoggedUser(testUser)) + .build()).getCase() assert taskAuthorizationService.canCallAssign(ActorTransformer.toLoggedUser(testUser), (new ArrayList<>(case_.getTasks())).get(0).task) userService.removeRole(testUser, positiveRole.get_id()) - workflowService.deleteCase(case_.stringId) + workflowService.deleteCase(new DeleteCaseParams(case_.stringId)) } @Test void testCanNotAssign() { ProcessRole negativeRole = this.net.getRoles().values().find(v -> v.getImportId() == "assign_neg_role") userService.addRole(testUser, negativeRole.get_id()) - Case case_ = workflowService.createCase(net.getStringId(), "Test assign", "", ActorTransformer.toLoggedUser(testUser)).getCase() + Case case_ = workflowService.createCase(CreateCaseParams.with() + .petriNet(net) + .title("Test assign") + .color("") + .loggedUser(ActorTransformer.toLoggedUser(testUser)) + .build()).getCase() assert !taskAuthorizationService.canCallAssign(ActorTransformer.toLoggedUser(testUser), (new ArrayList<>(case_.getTasks())).get(0).task) userService.removeRole(testUser, negativeRole.get_id()) - workflowService.deleteCase(case_.stringId) + workflowService.deleteCase(new DeleteCaseParams(case_.stringId)) } @Test void testCanAssignWithUsersRef() { - Case case_ = workflowService.createCase(netWithUserRefs.getStringId(), "Test assign", "", ActorTransformer.toLoggedUser(testUser)).getCase() + Case case_ = workflowService.createCase(CreateCaseParams.with() + .petriNet(netWithUserRefs) + .title("Test assign") + .color("") + .loggedUser(ActorTransformer.toLoggedUser(testUser)) + .build()).getCase() String taskId = (new ArrayList<>(case_.getTasks())).get(0).task case_ = dataService.setData(taskId, ImportHelper.populateDataset([ "assign_pos_ul": [ @@ -356,12 +383,17 @@ class TaskAuthorizationServiceTest { sleep(4000) assert taskAuthorizationService.canCallAssign(ActorTransformer.toLoggedUser(testUser), taskId) - workflowService.deleteCase(case_.stringId) + workflowService.deleteCase(new DeleteCaseParams(case_.stringId)) } @Test void testCannotAssignWithUsersRef() { - Case case_ = workflowService.createCase(netWithUserRefs.getStringId(), "Test assign", "", ActorTransformer.toLoggedUser(testUser)).getCase() + Case case_ = workflowService.createCase(CreateCaseParams.with() + .petriNet(netWithUserRefs) + .title("Test assign") + .color("") + .loggedUser(ActorTransformer.toLoggedUser(testUser)) + .build()).getCase() String taskId = (new ArrayList<>(case_.getTasks())).get(0).task case_ = dataService.setData(taskId, ImportHelper.populateDataset([ "assign_neg_ul": [ @@ -373,14 +405,19 @@ class TaskAuthorizationServiceTest { sleep(4000) assert !taskAuthorizationService.canCallAssign(ActorTransformer.toLoggedUser(testUser), taskId) - workflowService.deleteCase(case_.stringId) + workflowService.deleteCase(new DeleteCaseParams(case_.stringId)) } @Test void testCanAssignWithNegRoleAndPosUsersRef() { ProcessRole positiveRole = this.netWithUserRefs.getRoles().values().find(v -> v.getImportId() == "assign_pos_role") userService.addRole(testUser, positiveRole.get_id()) - Case case_ = workflowService.createCase(netWithUserRefs.getStringId(), "Test assign", "", ActorTransformer.toLoggedUser(testUser)).getCase() + Case case_ = workflowService.createCase(CreateCaseParams.with() + .petriNet(netWithUserRefs) + .title("Test assign") + .color("") + .loggedUser(ActorTransformer.toLoggedUser(testUser)) + .build()).getCase() String taskId = (new ArrayList<>(case_.getTasks())).get(0).task case_ = dataService.setData(taskId, ImportHelper.populateDataset([ "assign_pos_ul": [ @@ -393,38 +430,53 @@ class TaskAuthorizationServiceTest { assert taskAuthorizationService.canCallAssign(ActorTransformer.toLoggedUser(testUser), taskId) userService.removeRole(testUser, positiveRole.get_id()) - workflowService.deleteCase(case_.stringId) + workflowService.deleteCase(new DeleteCaseParams(case_.stringId)) } @Test void testCanFinish() { ProcessRole positiveRole = this.netWithUserRefs.getRoles().values().find(v -> v.getImportId() == "finish_pos_role") userService.addRole(testUser, positiveRole.get_id()) - Case case_ = workflowService.createCase(netWithUserRefs.getStringId(), "Test Finish", "", ActorTransformer.toLoggedUser(testUser)).getCase() + Case case_ = workflowService.createCase(CreateCaseParams.with() + .petriNet(netWithUserRefs) + .title("Test Finish") + .color("") + .loggedUser(ActorTransformer.toLoggedUser(testUser)) + .build()).getCase() String taskId = (new ArrayList<>(case_.getTasks())).get(0).task - taskService.assignTask(ActorTransformer.toLoggedUser(testUser), taskId) + taskService.assignTask(new TaskParams(taskId, ActorTransformer.toLoggedUser(testUser))) assert taskAuthorizationService.canCallFinish(ActorTransformer.toLoggedUser(testUser), taskId) userService.removeRole(testUser, positiveRole.get_id()) - workflowService.deleteCase(case_.stringId) + workflowService.deleteCase(new DeleteCaseParams(case_.stringId)) } @Test void testCanNotFinish() { ProcessRole negativeRole = this.netWithUserRefs.getRoles().values().find(v -> v.getImportId() == "finish_neg_role") userService.addRole(testUser, negativeRole.get_id()) - Case case_ = workflowService.createCase(netWithUserRefs.getStringId(), "Test Finish", "", ActorTransformer.toLoggedUser(testUser)).getCase() + Case case_ = workflowService.createCase(CreateCaseParams.with() + .petriNet(netWithUserRefs) + .title("Test Finish") + .color("") + .loggedUser(ActorTransformer.toLoggedUser(testUser)) + .build()).getCase() String taskId = (new ArrayList<>(case_.getTasks())).get(0).task - taskService.assignTask(ActorTransformer.toLoggedUser(testUser), taskId) + taskService.assignTask(new TaskParams(taskId, ActorTransformer.toLoggedUser(testUser))) assert !taskAuthorizationService.canCallFinish(ActorTransformer.toLoggedUser(testUser), taskId) userService.removeRole(testUser, negativeRole.get_id()) - workflowService.deleteCase(case_.stringId) + workflowService.deleteCase(new DeleteCaseParams(case_.stringId)) } @Test void testCanFinishWithUsersRef() { - Case case_ = workflowService.createCase(netWithUserRefs.getStringId(), "Test Finish", "", ActorTransformer.toLoggedUser(testUser)).getCase() + Case case_ = workflowService.createCase(CreateCaseParams.with() + .petriNet(netWithUserRefs) + .title("Test Finish") + .color("") + .loggedUser(ActorTransformer.toLoggedUser(testUser)) + .build()).getCase() String taskId = (new ArrayList<>(case_.getTasks())).get(0).task case_ = dataService.setData(taskId, ImportHelper.populateDataset([ "finish_pos_ul": [ @@ -435,14 +487,19 @@ class TaskAuthorizationServiceTest { workflowService.save(case_) sleep(4000) - taskService.assignTask(ActorTransformer.toLoggedUser(testUser), taskId) + taskService.assignTask(new TaskParams(taskId, ActorTransformer.toLoggedUser(testUser))) assert taskAuthorizationService.canCallFinish(ActorTransformer.toLoggedUser(testUser), taskId) - workflowService.deleteCase(case_.stringId) + workflowService.deleteCase(new DeleteCaseParams(case_.stringId)) } @Test void testCannotFinishWithUsersRef() { - Case case_ = workflowService.createCase(netWithUserRefs.getStringId(), "Test Finish", "", ActorTransformer.toLoggedUser(testUser)).getCase() + Case case_ = workflowService.createCase(CreateCaseParams.with() + .petriNet(netWithUserRefs) + .title("Test Finish") + .color("") + .loggedUser(ActorTransformer.toLoggedUser(testUser)) + .build()).getCase() String taskId = (new ArrayList<>(case_.getTasks())).get(0).task case_ = dataService.setData(taskId, ImportHelper.populateDataset([ "finish_neg_ul": [ @@ -453,16 +510,21 @@ class TaskAuthorizationServiceTest { workflowService.save(case_) sleep(4000) - taskService.assignTask(ActorTransformer.toLoggedUser(testUser), taskId) + taskService.assignTask(new TaskParams(taskId, ActorTransformer.toLoggedUser(testUser))) assert !taskAuthorizationService.canCallFinish(ActorTransformer.toLoggedUser(testUser), taskId) - workflowService.deleteCase(case_.stringId) + workflowService.deleteCase(new DeleteCaseParams(case_.stringId)) } @Test void testCanFinishWithNegRoleAndPosUsersRef() { ProcessRole positiveRole = this.netWithUserRefs.getRoles().values().find(v -> v.getImportId() == "finish_pos_role") userService.addRole(testUser, positiveRole.get_id()) - Case case_ = workflowService.createCase(netWithUserRefs.getStringId(), "Test Finish", "", ActorTransformer.toLoggedUser(testUser)).getCase() + Case case_ = workflowService.createCase(CreateCaseParams.with() + .petriNet(netWithUserRefs) + .title("Test Finish") + .color("") + .loggedUser(ActorTransformer.toLoggedUser(testUser)) + .build()).getCase() String taskId = (new ArrayList<>(case_.getTasks())).get(0).task case_ = dataService.setData(taskId, ImportHelper.populateDataset([ "finish_pos_ul": [ @@ -473,10 +535,10 @@ class TaskAuthorizationServiceTest { workflowService.save(case_) sleep(4000) - taskService.assignTask(ActorTransformer.toLoggedUser(testUser), taskId) + taskService.assignTask(new TaskParams(taskId, ActorTransformer.toLoggedUser(testUser))) assert taskAuthorizationService.canCallFinish(ActorTransformer.toLoggedUser(testUser), taskId) userService.removeRole(testUser, positiveRole.get_id()) - workflowService.deleteCase(case_.stringId) + workflowService.deleteCase(new DeleteCaseParams(case_.stringId)) } } diff --git a/application-engine/src/test/groovy/com/netgrif/application/engine/auth/WorkflowAuthorizationServiceTest.groovy b/application-engine/src/test/groovy/com/netgrif/application/engine/auth/WorkflowAuthorizationServiceTest.groovy index 6191dd7946..521a595bba 100644 --- a/application-engine/src/test/groovy/com/netgrif/application/engine/auth/WorkflowAuthorizationServiceTest.groovy +++ b/application-engine/src/test/groovy/com/netgrif/application/engine/auth/WorkflowAuthorizationServiceTest.groovy @@ -10,11 +10,13 @@ import com.netgrif.application.engine.auth.service.UserService import com.netgrif.application.engine.objects.petrinet.domain.PetriNet import com.netgrif.application.engine.objects.petrinet.domain.VersionType import com.netgrif.application.engine.objects.petrinet.domain.roles.ProcessRole +import com.netgrif.application.engine.petrinet.params.ImportPetriNetParams import com.netgrif.application.engine.petrinet.service.interfaces.IPetriNetService import com.netgrif.application.engine.startup.ImportHelper import com.netgrif.application.engine.startup.runner.SuperCreatorRunner import com.netgrif.application.engine.objects.workflow.domain.Case import com.netgrif.application.engine.objects.workflow.domain.eventoutcomes.petrinetoutcomes.ImportPetriNetEventOutcome +import com.netgrif.application.engine.workflow.params.CreateCaseParams import com.netgrif.application.engine.workflow.service.interfaces.IDataService import com.netgrif.application.engine.workflow.service.interfaces.IWorkflowAuthorizationService import com.netgrif.application.engine.workflow.service.interfaces.IWorkflowService @@ -118,11 +120,19 @@ class WorkflowAuthorizationServiceTest { @BeforeEach void init() { testHelper.truncateDbs() - ImportPetriNetEventOutcome net = petriNetService.importPetriNet(new FileInputStream("src/test/resources/workflow_authorization_service_test.xml"), VersionType.MAJOR, superCreator.getLoggedSuper()) + ImportPetriNetEventOutcome net = petriNetService.importPetriNet(ImportPetriNetParams.with() + .xmlFile(new FileInputStream("src/test/resources/workflow_authorization_service_test.xml")) + .releaseType(VersionType.MAJOR) + .author(superCreator.getLoggedSuper()) + .build()) assert net.getNet() != null this.net = net.getNet() - ImportPetriNetEventOutcome netWithUserRefs = petriNetService.importPetriNet(new FileInputStream("src/test/resources/workflow_authorization_service_test_with_userRefs.xml"), VersionType.MAJOR, superCreator.getLoggedSuper()) + ImportPetriNetEventOutcome netWithUserRefs = petriNetService.importPetriNet(ImportPetriNetParams.with() + .xmlFile(new FileInputStream("src/test/resources/workflow_authorization_service_test_with_userRefs.xml")) + .releaseType(VersionType.MAJOR) + .author(superCreator.getLoggedSuper()) + .build()) assert netWithUserRefs.getNet() != null this.netWithUserRefs = netWithUserRefs.getNet() @@ -195,7 +205,12 @@ class WorkflowAuthorizationServiceTest { void testCanCallDelete() { ProcessRole positiveDeleteRole = this.net.getRoles().values().find(v -> v.getImportId() == "delete_pos_role") userService.addRole(testUser, positiveDeleteRole.getStringId()) - Case case_ = workflowService.createCase(net.getStringId(), "Test delete", "", ActorTransformer.toLoggedUser(testUser)).getCase() + Case case_ = workflowService.createCase(CreateCaseParams.with() + .petriNet(net) + .title("Test delete") + .color("") + .loggedUser(ActorTransformer.toLoggedUser(testUser)) + .build()).getCase() assert workflowAuthorizationService.canCallDelete(ActorTransformer.toLoggedUser(testUser), case_.getStringId()) userService.removeRole(testUser, positiveDeleteRole.getStringId()) } @@ -212,7 +227,12 @@ class WorkflowAuthorizationServiceTest { void testCanCallDeleteFalse() { ProcessRole deleteRole = this.net.getRoles().values().find(v -> v.getImportId() == "delete_neg_role") userService.addRole(testUser, deleteRole.getStringId()) - Case case_ = workflowService.createCase(net.getStringId(), "Test delete", "", ActorTransformer.toLoggedUser(testUser)).getCase() + Case case_ = workflowService.createCase(CreateCaseParams.with() + .petriNet(net) + .title("Test delete") + .color("") + .loggedUser(ActorTransformer.toLoggedUser(testUser)) + .build()).getCase() assert !workflowAuthorizationService.canCallDelete(ActorTransformer.toLoggedUser(testUser), case_.getStringId()) userService.removeRole(testUser, deleteRole.getStringId()) } @@ -226,7 +246,12 @@ class WorkflowAuthorizationServiceTest { userService.addRole(testUser, posDeleteRole.getStringId()) userService.addRole(testUser, negDeleteRole.getStringId()) - Case case_ = workflowService.createCase(netWithUserRefs.getStringId(), "Test delete", "", ActorTransformer.toLoggedUser(testUser)).getCase() + Case case_ = workflowService.createCase(CreateCaseParams.with() + .petriNet(netWithUserRefs) + .title("Test delete") + .color("") + .loggedUser(ActorTransformer.toLoggedUser(testUser)) + .build()).getCase() String taskId = (new ArrayList<>(case_.getTasks())).get(0).task case_ = dataService.setData(taskId, ImportHelper.populateDataset([ "pos_user_list": [ @@ -250,7 +275,12 @@ class WorkflowAuthorizationServiceTest { userService.addRole(testUser, posDeleteRole.getStringId()) userService.addRole(testUser, negDeleteRole.getStringId()) - Case case_ = workflowService.createCase(netWithUserRefs.getStringId(), "Test delete", "", ActorTransformer.toLoggedUser(testUser)).getCase() + Case case_ = workflowService.createCase(CreateCaseParams.with() + .petriNet(netWithUserRefs) + .title("Test delete") + .color("") + .loggedUser(ActorTransformer.toLoggedUser(testUser)) + .build()).getCase() String taskId = (new ArrayList<>(case_.getTasks())).get(0).task case_ = dataService.setData(taskId, ImportHelper.populateDataset([ "pos_user_list": [ diff --git a/application-engine/src/test/groovy/com/netgrif/application/engine/elastic/DataSearchRequestTest.groovy b/application-engine/src/test/groovy/com/netgrif/application/engine/elastic/DataSearchRequestTest.groovy index 0f88aadaf8..1ecdb1e95a 100644 --- a/application-engine/src/test/groovy/com/netgrif/application/engine/elastic/DataSearchRequestTest.groovy +++ b/application-engine/src/test/groovy/com/netgrif/application/engine/elastic/DataSearchRequestTest.groovy @@ -13,6 +13,7 @@ import com.netgrif.application.engine.objects.petrinet.domain.dataset.FileFieldV import com.netgrif.application.engine.objects.petrinet.domain.dataset.FileListFieldValue import com.netgrif.application.engine.objects.petrinet.domain.dataset.UserFieldValue import com.netgrif.application.engine.objects.petrinet.domain.dataset.UserListFieldValue +import com.netgrif.application.engine.petrinet.params.ImportPetriNetParams import com.netgrif.application.engine.petrinet.service.interfaces.IPetriNetService import com.netgrif.application.engine.startup.ImportHelper import com.netgrif.application.engine.startup.runner.SuperCreatorRunner @@ -96,7 +97,11 @@ class DataSearchRequestTest { void before() { testHelper.truncateDbs() - def net = petriNetService.importPetriNet(new FileInputStream("src/test/resources/all_data.xml"), VersionType.MAJOR, superCreator.getLoggedSuper()) + def net = petriNetService.importPetriNet(ImportPetriNetParams.with() + .xmlFile(new FileInputStream("src/test/resources/all_data.xml")) + .releaseType(VersionType.MAJOR) + .author(superCreator.getLoggedSuper()) + .build()) assert net.getNet() != null def users = userService.findAllUsers(null, Pageable.ofSize(100)) diff --git a/application-engine/src/test/groovy/com/netgrif/application/engine/elastic/ElasticTaskTest.groovy b/application-engine/src/test/groovy/com/netgrif/application/engine/elastic/ElasticTaskTest.groovy index 5ff6a16f71..2ec81d7011 100644 --- a/application-engine/src/test/groovy/com/netgrif/application/engine/elastic/ElasticTaskTest.groovy +++ b/application-engine/src/test/groovy/com/netgrif/application/engine/elastic/ElasticTaskTest.groovy @@ -8,6 +8,7 @@ import com.netgrif.application.engine.elastic.service.ReindexingTask import com.netgrif.application.engine.elastic.service.interfaces.IElasticTaskService import com.netgrif.application.engine.objects.petrinet.domain.I18nString import com.netgrif.application.engine.objects.petrinet.domain.VersionType +import com.netgrif.application.engine.petrinet.params.ImportPetriNetParams import com.netgrif.application.engine.petrinet.service.interfaces.IPetriNetService import com.netgrif.application.engine.startup.ImportHelper import com.netgrif.application.engine.startup.runner.SuperCreatorRunner @@ -79,7 +80,11 @@ class ElasticTaskTest { @Test void taskReindexTest() { - def optional = petriNetService.importPetriNet(new FileInputStream("src/test/resources/all_data.xml"), VersionType.MAJOR, superCreator.getLoggedSuper()) + def optional = petriNetService.importPetriNet(ImportPetriNetParams.with() + .xmlFile(new FileInputStream("src/test/resources/all_data.xml")) + .releaseType(VersionType.MAJOR) + .author(superCreator.getLoggedSuper()) + .build()) assert optional.getNet() != null def net = optional.getNet() diff --git a/application-engine/src/test/groovy/com/netgrif/application/engine/elastic/ReindexTest.groovy b/application-engine/src/test/groovy/com/netgrif/application/engine/elastic/ReindexTest.groovy index 12d4e03878..70773d2f3e 100644 --- a/application-engine/src/test/groovy/com/netgrif/application/engine/elastic/ReindexTest.groovy +++ b/application-engine/src/test/groovy/com/netgrif/application/engine/elastic/ReindexTest.groovy @@ -4,11 +4,14 @@ import com.netgrif.application.engine.TestHelper import com.netgrif.application.engine.elastic.service.ReindexingTask import com.netgrif.application.engine.elastic.service.interfaces.IElasticCaseService import com.netgrif.application.engine.elastic.web.requestbodies.CaseSearchRequest +import com.netgrif.application.engine.objects.auth.domain.ActorTransformer import com.netgrif.application.engine.objects.petrinet.domain.VersionType +import com.netgrif.application.engine.petrinet.params.ImportPetriNetParams import com.netgrif.application.engine.petrinet.service.interfaces.IPetriNetService import com.netgrif.application.engine.startup.runner.SuperCreatorRunner import com.netgrif.application.engine.objects.workflow.domain.Case import com.netgrif.application.engine.objects.workflow.domain.eventoutcomes.petrinetoutcomes.ImportPetriNetEventOutcome +import com.netgrif.application.engine.workflow.params.CreateCaseParams import com.netgrif.application.engine.workflow.service.interfaces.IWorkflowService import org.junit.jupiter.api.BeforeEach import org.junit.jupiter.api.Test @@ -50,14 +53,23 @@ class ReindexTest { @Test void reindexTest() { - ImportPetriNetEventOutcome net = petriNetService.importPetriNet(new FileInputStream("src/test/resources/all_data.xml"), VersionType.MAJOR, superCreator.getLoggedSuper()) + ImportPetriNetEventOutcome net = petriNetService.importPetriNet(ImportPetriNetParams.with() + .xmlFile(new FileInputStream("src/test/resources/all_data.xml")) + .releaseType(VersionType.MAJOR) + .author(superCreator.getLoggedSuper()) + .build()) assert net.getNet() != null int countTread = Thread.activeCount() List threads = [] List savedCase = [] for (int i in 1..2000) { threads << Thread.start { - def useCase = workflowService.createCase(net.getNet().stringId, "Test", "color", superCreator.getLoggedSuper()).getCase() + def useCase = workflowService.createCase(CreateCaseParams.with() + .petriNet(net.getNet()) + .title("Test") + .color("color") + .loggedUser(superCreator.getLoggedSuper()) + .build()).getCase() savedCase.add(useCase) } } @@ -69,7 +81,12 @@ class ReindexTest { threads = [] for (int i in 1..4000) { threads << Thread.start { - def useCase = workflowService.createCase(net.getNet().stringId, "Test", "color", superCreator.getLoggedSuper()).getCase() + def useCase = workflowService.createCase(CreateCaseParams.with() + .petriNet(net.getNet()) + .title("Test") + .color("color") + .loggedUser(superCreator.getLoggedSuper()) + .build()).getCase() savedCase.add(useCase) } } diff --git a/application-engine/src/test/groovy/com/netgrif/application/engine/export/service/ExportServiceTest.groovy b/application-engine/src/test/groovy/com/netgrif/application/engine/export/service/ExportServiceTest.groovy index dab63cbf0f..4cf8aa191c 100644 --- a/application-engine/src/test/groovy/com/netgrif/application/engine/export/service/ExportServiceTest.groovy +++ b/application-engine/src/test/groovy/com/netgrif/application/engine/export/service/ExportServiceTest.groovy @@ -15,6 +15,7 @@ import com.netgrif.application.engine.objects.workflow.domain.Case import com.netgrif.application.engine.adapter.spring.workflow.domain.QTask import com.netgrif.application.engine.objects.workflow.domain.Task import com.netgrif.application.engine.workflow.domain.repositories.TaskRepository +import com.netgrif.application.engine.workflow.params.TaskParams import com.netgrif.application.engine.workflow.service.interfaces.ITaskService import com.netgrif.application.engine.workflow.service.interfaces.IWorkflowService import org.junit.jupiter.api.BeforeEach @@ -79,7 +80,7 @@ class ExportServiceTest { @Order(2) void testCaseMongoExport() { String exportTask = mainCase.tasks.find { it.transition == "t1" }.task - taskService.assignTask(ActorTransformer.toLoggedUser(userService.findUserByUsername(UserConstants.ADMIN_USER_USERNAME, null).get()), exportTask) + taskService.assignTask(new TaskParams(exportTask, ActorTransformer.toLoggedUser(userService.findUserByUsername(UserConstants.ADMIN_USER_USERNAME, null).get()))) File csvFile = new File("src/test/resources/csv/case_mongo_export.csv") assert csvFile.readLines().size() == 11 String[] headerSplit = csvFile.readLines()[0].split(",") @@ -87,6 +88,7 @@ class ExportServiceTest { && headerSplit.contains("immediate_number") && !headerSplit.contains("text")) taskService.cancelTask(ActorTransformer.toLoggedUser(userService.getLoggedOrSystem()), exportTask) + taskService.cancelTask(new TaskParams(exportTask, ActorTransformer.toLoggedUser(userService.getLoggedOrSystem()))) } @Test @@ -94,21 +96,21 @@ class ExportServiceTest { void testCaseElasticExport() { Thread.sleep(5000) //Elastic wait String exportTask = mainCase.tasks.find { it.transition == "t2" }.task - taskService.assignTask(ActorTransformer.toLoggedUser(userService.findByEmail(UserConstants.ADMIN_USER_EMAIL, null)), exportTask) + taskService.assignTask(new TaskParams(exportTask, ActorTransformer.toLoggedUser(userService.findByEmail(UserConstants.ADMIN_USER_EMAIL, null)))) File csvFile = new File("src/test/resources/csv/case_elastic_export.csv") assert csvFile.readLines().size() == 11 String[] headerSplit = csvFile.readLines()[0].split(",") assert (headerSplit.contains("text") && !headerSplit.contains("immediate_multichoice") && !headerSplit.contains("immediate_number")) - taskService.cancelTask(ActorTransformer.toLoggedUser(userService.getLoggedOrSystem()), exportTask) + taskService.cancelTask(new TaskParams(exportTask, ActorTransformer.toLoggedUser(userService.getLoggedOrSystem()))) } @Test @Order(4) void testTaskMongoExport() { String exportTask = mainCase.tasks.find { it.transition == "t3" }.task - taskService.assignTask(ActorTransformer.toLoggedUser(userService.findByEmail(UserConstants.ADMIN_USER_EMAIL, null)), exportTask) + taskService.assignTask(new TaskParams(exportTask, ActorTransformer.toLoggedUser(userService.findByEmail(UserConstants.ADMIN_USER_EMAIL, null)))) File csvFile = new File("src/test/resources/csv/task_mongo_export.csv") assert csvFile.readLines().size() == 11 String[] headerSplit = csvFile.readLines()[0].split(",") @@ -116,7 +118,7 @@ class ExportServiceTest { && headerSplit.contains("immediate_number") && headerSplit.contains("text") && !headerSplit.contains("no_export")) - taskService.cancelTask(ActorTransformer.toLoggedUser(userService.getLoggedOrSystem()), exportTask) + taskService.cancelTask(new TaskParams(exportTask, ActorTransformer.toLoggedUser(userService.getLoggedOrSystem()))) } @Test @@ -125,7 +127,7 @@ class ExportServiceTest { void testTaskElasticExport() { Thread.sleep(10000) //Elastic wait String exportTask = mainCase.tasks.find { it.transition == "t4" }.task - taskService.assignTask(ActorTransformer.toLoggedUser(userService.findByEmail(UserConstants.ADMIN_USER_EMAIL, null)), exportTask) + taskService.assignTask(new TaskParams(exportTask, ActorTransformer.toLoggedUser(userService.findByEmail(UserConstants.ADMIN_USER_EMAIL, null)))) Thread.sleep(20000) //Elastic wait def processId = petriNetService.getNewestVersionByIdentifier("export_test").stringId @@ -141,14 +143,14 @@ class ExportServiceTest { && headerSplit.contains("immediate_number") && !headerSplit.contains("text") && !headerSplit.contains("no_export")) - taskService.cancelTask(ActorTransformer.toLoggedUser(userService.findByEmail(UserConstants.ADMIN_USER_EMAIL, null)), exportTask) + taskService.cancelTask(new TaskParams(exportTask, ActorTransformer.toLoggedUser(userService.findByEmail(UserConstants.ADMIN_USER_EMAIL, null)))) } @Test void buildDefaultCsvTaskHeaderTest(){ def processId = petriNetService.getNewestVersionByIdentifier("export_test").stringId String exportTask = mainCase.tasks.find { it.transition == "t4" }.task - taskService.assignTask(ActorTransformer.toLoggedUser(userService.findByEmail(UserConstants.ADMIN_USER_EMAIL, null)), exportTask) + taskService.assignTask(new TaskParams(exportTask, ActorTransformer.toLoggedUser(userService.findByEmail(UserConstants.ADMIN_USER_EMAIL, null)))) List task = taskRepository.findAll(QTask.task.processId.eq(processId).and(QTask.task.transitionId.eq("t4"))) Set header = exportService.buildDefaultCsvTaskHeader(task) assert header != null diff --git a/application-engine/src/test/groovy/com/netgrif/application/engine/filters/FilterImportExportTest.groovy b/application-engine/src/test/groovy/com/netgrif/application/engine/filters/FilterImportExportTest.groovy index 81383bc8c4..ab9b9fd0ee 100644 --- a/application-engine/src/test/groovy/com/netgrif/application/engine/filters/FilterImportExportTest.groovy +++ b/application-engine/src/test/groovy/com/netgrif/application/engine/filters/FilterImportExportTest.groovy @@ -15,6 +15,7 @@ import com.netgrif.application.engine.startup.runner.FilterRunner import com.netgrif.application.engine.startup.ImportHelper import com.netgrif.application.engine.objects.workflow.domain.* import com.netgrif.application.engine.objects.workflow.domain.filter.FilterImportExportList +import com.netgrif.application.engine.workflow.params.TaskParams import com.netgrif.application.engine.workflow.service.UserFilterSearchService import com.netgrif.application.engine.workflow.service.interfaces.IDataService import com.netgrif.application.engine.workflow.service.interfaces.IFilterImportExportService @@ -165,7 +166,7 @@ class FilterImportExportTest { "value": importedTasksIds ] ])) - this.taskService.finishTask(importTask, dummyUser) + this.taskService.finishTask(new TaskParams(importTask, dummyUser)) Thread.sleep(1000) filterCases = this.userFilterSearchService.autocompleteFindFilters("") List filterCasesNames = filterCases.stream().map({ filterCase -> filterCase.title }).collect(Collectors.toList()) diff --git a/application-engine/src/test/groovy/com/netgrif/application/engine/importer/PredefinedRolesPermissionsTest.groovy b/application-engine/src/test/groovy/com/netgrif/application/engine/importer/PredefinedRolesPermissionsTest.groovy index b8df956b87..31202de920 100644 --- a/application-engine/src/test/groovy/com/netgrif/application/engine/importer/PredefinedRolesPermissionsTest.groovy +++ b/application-engine/src/test/groovy/com/netgrif/application/engine/importer/PredefinedRolesPermissionsTest.groovy @@ -6,6 +6,7 @@ import com.netgrif.application.engine.objects.petrinet.domain.PetriNet import com.netgrif.application.engine.objects.petrinet.domain.VersionType import com.netgrif.application.engine.objects.petrinet.domain.roles.ProcessRolePermission import com.netgrif.application.engine.objects.petrinet.domain.roles.RolePermission +import com.netgrif.application.engine.petrinet.params.ImportPetriNetParams import com.netgrif.application.engine.petrinet.service.interfaces.IPetriNetService import com.netgrif.application.engine.adapter.spring.petrinet.service.ProcessRoleService import com.netgrif.application.engine.startup.runner.SuperCreatorRunner @@ -14,6 +15,7 @@ import com.netgrif.application.engine.objects.workflow.domain.Task import com.netgrif.application.engine.objects.workflow.domain.TaskPair import com.netgrif.application.engine.objects.workflow.domain.eventoutcomes.caseoutcomes.CreateCaseEventOutcome import com.netgrif.application.engine.objects.workflow.domain.eventoutcomes.petrinetoutcomes.ImportPetriNetEventOutcome +import com.netgrif.application.engine.workflow.params.CreateCaseParams import com.netgrif.application.engine.workflow.service.interfaces.ITaskService import com.netgrif.application.engine.workflow.service.interfaces.IWorkflowService import org.junit.jupiter.api.BeforeEach @@ -445,13 +447,22 @@ class PredefinedRolesPermissionsTest { } private NetCaseTask importAndCreate(Resource model) { - ImportPetriNetEventOutcome importOutcome = petriNetService.importPetriNet(model.inputStream, VersionType.MAJOR, superCreator.loggedSuper) + ImportPetriNetEventOutcome importOutcome = petriNetService.importPetriNet(ImportPetriNetParams.with() + .xmlFile(model.inputStream) + .releaseType(VersionType.MAJOR) + .author(superCreator.loggedSuper) + .build()) assert importOutcome.getNet() != null PetriNet net = importOutcome.getNet() - CreateCaseEventOutcome createCaseOutcome = workflowService.createCase(net.stringId, '', '', superCreator.loggedSuper) + CreateCaseEventOutcome createCaseOutcome = workflowService.createCase(CreateCaseParams.with() + .petriNet(net) + .title('') + .color('') + .loggedUser(superCreator.loggedSuper) + .build()) assert createCaseOutcome.getCase() != null Case aCase = createCaseOutcome.getCase() diff --git a/application-engine/src/test/groovy/com/netgrif/application/engine/importer/UserListTest.groovy b/application-engine/src/test/groovy/com/netgrif/application/engine/importer/UserListTest.groovy index c9c4fe1e3b..f133804902 100644 --- a/application-engine/src/test/groovy/com/netgrif/application/engine/importer/UserListTest.groovy +++ b/application-engine/src/test/groovy/com/netgrif/application/engine/importer/UserListTest.groovy @@ -3,6 +3,7 @@ package com.netgrif.application.engine.importer import com.netgrif.application.engine.TestHelper import com.netgrif.application.engine.objects.petrinet.domain.VersionType import com.netgrif.application.engine.objects.petrinet.domain.throwable.MissingPetriNetMetaDataException +import com.netgrif.application.engine.petrinet.params.ImportPetriNetParams import com.netgrif.application.engine.petrinet.service.interfaces.IPetriNetService import com.netgrif.application.engine.startup.ImportHelper import com.netgrif.application.engine.startup.runner.SuperCreatorRunner @@ -54,7 +55,11 @@ class UserListTest { @Test void testUserList() throws MissingPetriNetMetaDataException, IOException { - ImportPetriNetEventOutcome net = petriNetService.importPetriNet(new FileInputStream("src/test/resources/user_list.xml"), VersionType.MAJOR, superCreator.getLoggedSuper()); + ImportPetriNetEventOutcome net = petriNetService.importPetriNet(ImportPetriNetParams.with() + .xmlFile(new FileInputStream("src/test/resources/user_list.xml")) + .releaseType(VersionType.MAJOR) + .author(superCreator.getLoggedSuper()) + .build()); assert net.getNet() != null; Optional caseOpt = caseRepository.findOne(QCase.case$.title.eq("User List")); diff --git a/application-engine/src/test/groovy/com/netgrif/application/engine/insurance/EncryptionTest.groovy b/application-engine/src/test/groovy/com/netgrif/application/engine/insurance/EncryptionTest.groovy index de648c1605..bea1bb7a0d 100644 --- a/application-engine/src/test/groovy/com/netgrif/application/engine/insurance/EncryptionTest.groovy +++ b/application-engine/src/test/groovy/com/netgrif/application/engine/insurance/EncryptionTest.groovy @@ -6,12 +6,14 @@ import com.netgrif.application.engine.objects.auth.domain.LoggedUser import com.netgrif.application.engine.auth.service.AuthorityService import com.netgrif.application.engine.importer.service.Importer import com.netgrif.application.engine.objects.petrinet.domain.VersionType +import com.netgrif.application.engine.petrinet.params.ImportPetriNetParams import com.netgrif.application.engine.petrinet.service.interfaces.IPetriNetService import com.netgrif.application.engine.startup.runner.SuperCreatorRunner import com.netgrif.application.engine.objects.workflow.domain.Case import com.netgrif.application.engine.objects.workflow.domain.DataField import com.netgrif.application.engine.objects.workflow.domain.eventoutcomes.petrinetoutcomes.ImportPetriNetEventOutcome import com.netgrif.application.engine.workflow.domain.repositories.CaseRepository +import com.netgrif.application.engine.workflow.params.CreateCaseParams import com.netgrif.application.engine.workflow.service.TaskService import com.netgrif.application.engine.workflow.service.interfaces.IWorkflowService import org.junit.jupiter.api.Test @@ -79,9 +81,18 @@ class EncryptionTest { } private String createCase() { - ImportPetriNetEventOutcome net = petriNetService.importPetriNet(new FileInputStream("src/test/resources/mapping_test.xml"), VersionType.MAJOR, superCreator.getLoggedSuper()) + ImportPetriNetEventOutcome net = petriNetService.importPetriNet(ImportPetriNetParams.with() + .xmlFile(new FileInputStream("src/test/resources/mapping_test.xml")) + .releaseType(VersionType.MAJOR) + .author(superCreator.getLoggedSuper()) + .build()) assert net.getNet() != null - def useCase = workflowService.createCase(net.getNet().stringId, "Encryption test", "color", mockLoggedUser()).getCase() + def useCase = workflowService.createCase(CreateCaseParams.with() + .petriNet(net.getNet()) + .title("Encryption test") + .color("color") + .loggedUser(mockLoggedUser()) + .build()).getCase() def nameField = useCase.petriNet.dataSet.values().find { v -> v.name.defaultValue == FIELD_NAME } useCase.dataSet.put(nameField.stringId, new DataField(FIELD_VALUE)) return workflowService.save(useCase).stringId diff --git a/application-engine/src/test/groovy/com/netgrif/application/engine/ipc/AssignCancelFinishWithCaseTest.groovy b/application-engine/src/test/groovy/com/netgrif/application/engine/ipc/AssignCancelFinishWithCaseTest.groovy index 15538dc2f1..659816f9bc 100644 --- a/application-engine/src/test/groovy/com/netgrif/application/engine/ipc/AssignCancelFinishWithCaseTest.groovy +++ b/application-engine/src/test/groovy/com/netgrif/application/engine/ipc/AssignCancelFinishWithCaseTest.groovy @@ -3,6 +3,7 @@ package com.netgrif.application.engine.ipc import com.netgrif.application.engine.TestHelper import com.netgrif.application.engine.importer.service.Importer import com.netgrif.application.engine.objects.petrinet.domain.VersionType +import com.netgrif.application.engine.petrinet.params.ImportPetriNetParams import com.netgrif.application.engine.petrinet.service.interfaces.IPetriNetService import com.netgrif.application.engine.startup.ImportHelper import com.netgrif.application.engine.startup.runner.SuperCreatorRunner @@ -57,7 +58,11 @@ class AssignCancelFinishWithCaseTest { @Test void testAssignCancelFinish() { - def testNet = petriNetService.importPetriNet(stream(ASSIGN_CANCEL_FINISH_NET_FILE), VersionType.MAJOR, superCreator.getLoggedSuper()) + def testNet = petriNetService.importPetriNet(ImportPetriNetParams.with() + .xmlFile(stream(ASSIGN_CANCEL_FINISH_NET_FILE)) + .releaseType(VersionType.MAJOR) + .author(superCreator.getLoggedSuper()) + .build()) assert testNet.getNet() != null diff --git a/application-engine/src/test/groovy/com/netgrif/application/engine/ipc/CaseApiTest.groovy b/application-engine/src/test/groovy/com/netgrif/application/engine/ipc/CaseApiTest.groovy index 9970a02249..a543eee023 100644 --- a/application-engine/src/test/groovy/com/netgrif/application/engine/ipc/CaseApiTest.groovy +++ b/application-engine/src/test/groovy/com/netgrif/application/engine/ipc/CaseApiTest.groovy @@ -3,6 +3,7 @@ package com.netgrif.application.engine.ipc import com.netgrif.application.engine.TestHelper import com.netgrif.application.engine.importer.service.Importer import com.netgrif.application.engine.objects.petrinet.domain.VersionType +import com.netgrif.application.engine.petrinet.params.ImportPetriNetParams import com.netgrif.application.engine.petrinet.service.interfaces.IPetriNetService import com.netgrif.application.engine.startup.ImportHelper import com.netgrif.application.engine.startup.runner.SuperCreatorRunner @@ -55,7 +56,11 @@ class CaseApiTest { @Test void testCreate() { - testNet = petriNetService.importPetriNet(stream(CREATE_NET_FILE), VersionType.MAJOR, superCreator.getLoggedSuper()) + testNet = petriNetService.importPetriNet(ImportPetriNetParams.with() + .xmlFile(stream(CREATE_NET_FILE)) + .releaseType(VersionType.MAJOR) + .author(superCreator.getLoggedSuper()) + .build()) assert testNet.getNet() != null @@ -72,7 +77,11 @@ class CaseApiTest { void testSearch() { testHelper.truncateDbs() - testNet = petriNetService.importPetriNet(stream(SEARCH_NET_FILE), VersionType.MAJOR, superCreator.getLoggedSuper()) + testNet = petriNetService.importPetriNet(ImportPetriNetParams.with() + .xmlFile(stream(SEARCH_NET_FILE)) + .releaseType(VersionType.MAJOR) + .author(superCreator.getLoggedSuper()) + .build()) assert testNet.getNet() != null diff --git a/application-engine/src/test/groovy/com/netgrif/application/engine/ipc/TaskApiTest.groovy b/application-engine/src/test/groovy/com/netgrif/application/engine/ipc/TaskApiTest.groovy index 89ea77e4dc..0708b93a2b 100644 --- a/application-engine/src/test/groovy/com/netgrif/application/engine/ipc/TaskApiTest.groovy +++ b/application-engine/src/test/groovy/com/netgrif/application/engine/ipc/TaskApiTest.groovy @@ -1,6 +1,7 @@ package com.netgrif.application.engine.ipc import com.netgrif.application.engine.auth.service.UserService +import com.netgrif.application.engine.petrinet.params.ImportPetriNetParams import com.netgrif.application.engine.petrinet.service.interfaces.IPetriNetService import com.netgrif.application.engine.adapter.spring.workflow.domain.QTask import com.netgrif.application.engine.TestHelper @@ -68,7 +69,11 @@ class TaskApiTest { @Test @Disabled("GroovyRuntime Could not find matching constructor") void testTaskSearch() { - def netOptional = petriNetService.importPetriNet(stream(TASK_SEARCH_NET_FILE), VersionType.MAJOR, superCreator.getLoggedSuper()) + def netOptional = petriNetService.importPetriNet(ImportPetriNetParams.with() + .xmlFile(stream(TASK_SEARCH_NET_FILE)) + .releaseType(VersionType.MAJOR) + .author(superCreator.getLoggedSuper()) + .build()) assert netOptional.getNet() != null @@ -99,7 +104,11 @@ class TaskApiTest { @Test @Disabled() void testTaskEventActions() { - def netOptional = petriNetService.importPetriNet(stream(TASK_EVENTS_NET_FILE), VersionType.MAJOR, superCreator.getLoggedSuper()) + def netOptional = petriNetService.importPetriNet(ImportPetriNetParams.with() + .xmlFile(stream(TASK_EVENTS_NET_FILE)) + .releaseType(VersionType.MAJOR) + .author(superCreator.getLoggedSuper()) + .build()) assert netOptional.getNet() != null @@ -121,8 +130,16 @@ class TaskApiTest { @Test @Disabled("spusta 2 krat") void testTaskExecution() { - def limitsNetOptional = petriNetService.importPetriNet(stream(LIMITS_NET_FILE), VersionType.MAJOR, superCreator.getLoggedSuper()) - def leasingNetOptional = petriNetService.importPetriNet(stream(LEASING_NET_FILE), VersionType.MAJOR, superCreator.getLoggedSuper()) + def limitsNetOptional = petriNetService.importPetriNet(ImportPetriNetParams.with() + .xmlFile(stream(LIMITS_NET_FILE)) + .releaseType(VersionType.MAJOR) + .author(superCreator.getLoggedSuper()) + .build()) + def leasingNetOptional = petriNetService.importPetriNet(ImportPetriNetParams.with() + .xmlFile(stream(LEASING_NET_FILE)) + .releaseType(VersionType.MAJOR) + .author(superCreator.getLoggedSuper()) + .build()) assert limitsNetOptional.getNet() != null assert leasingNetOptional.getNet() != null @@ -196,7 +213,11 @@ class TaskApiTest { @Test void testTaskBulkActions() { - def netOptional = petriNetService.importPetriNet(stream(TASK_BULK_NET_FILE), VersionType.MAJOR, superCreator.getLoggedSuper()) + def netOptional = petriNetService.importPetriNet(ImportPetriNetParams.with() + .xmlFile(stream(TASK_BULK_NET_FILE)) + .releaseType(VersionType.MAJOR) + .author(superCreator.getLoggedSuper()) + .build()) assert netOptional.getNet() != null PetriNet net = netOptional.getNet() @@ -221,7 +242,11 @@ class TaskApiTest { @Test void testGetData() { - def netOptional = petriNetService.importPetriNet(stream(TASK_GETTER_NET_FILE), VersionType.MAJOR, superCreator.getLoggedSuper()) + def netOptional = petriNetService.importPetriNet(ImportPetriNetParams.with() + .xmlFile(stream(TASK_GETTER_NET_FILE)) + .releaseType(VersionType.MAJOR) + .author(superCreator.getLoggedSuper()) + .build()) assert netOptional.getNet() != null PetriNet net = netOptional.getNet() @@ -256,7 +281,11 @@ class TaskApiTest { @Test void testSetData() { - def netOptional = petriNetService.importPetriNet(stream(TASK_SETTER_NET_FILE), VersionType.MAJOR, superCreator.getLoggedSuper()) + def netOptional = petriNetService.importPetriNet(ImportPetriNetParams.with() + .xmlFile(stream(TASK_SETTER_NET_FILE)) + .releaseType(VersionType.MAJOR) + .author(superCreator.getLoggedSuper()) + .build()) assert netOptional.getNet() != null PetriNet net = netOptional.getNet() diff --git a/application-engine/src/test/groovy/com/netgrif/application/engine/pdf/service/PdfGeneratorTest.groovy b/application-engine/src/test/groovy/com/netgrif/application/engine/pdf/service/PdfGeneratorTest.groovy index fbc6ec2f22..becac6ec18 100644 --- a/application-engine/src/test/groovy/com/netgrif/application/engine/pdf/service/PdfGeneratorTest.groovy +++ b/application-engine/src/test/groovy/com/netgrif/application/engine/pdf/service/PdfGeneratorTest.groovy @@ -13,10 +13,13 @@ import com.netgrif.application.engine.pdf.generator.service.interfaces.IPdfGener import com.netgrif.application.engine.objects.petrinet.domain.DataGroup import com.netgrif.application.engine.objects.petrinet.domain.VersionType import com.netgrif.application.engine.objects.petrinet.domain.dataset.FieldType +import com.netgrif.application.engine.petrinet.params.ImportPetriNetParams import com.netgrif.application.engine.petrinet.service.interfaces.IPetriNetService import com.netgrif.application.engine.objects.workflow.domain.Case import com.netgrif.application.engine.objects.workflow.domain.eventoutcomes.petrinetoutcomes.ImportPetriNetEventOutcome import com.netgrif.application.engine.objects.workflow.domain.eventoutcomes.taskoutcomes.AssignTaskEventOutcome +import com.netgrif.application.engine.workflow.params.CreateCaseParams +import com.netgrif.application.engine.workflow.params.TaskParams 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 @@ -61,10 +64,10 @@ class PdfGeneratorTest { private PdfResourceConfigurationProperties pdfResource @Autowired - private IDataService dataService; + private IDataService dataService @Autowired - private ApplicationContext applicationContext; + private ApplicationContext applicationContext @Autowired private TestHelper testHelper @@ -73,7 +76,7 @@ class PdfGeneratorTest { private ITaskService taskService @Value('${netgrif.engine.pdf.resources.output-folder}') - private String pdfOutputFolder; + private String pdfOutputFolder @Value('${netgrif.engine.pdf.resources.template-resource}') private String pdfTemplateFolder @@ -87,20 +90,38 @@ class PdfGeneratorTest { @Test void testActionDelegateFunction() { - ImportPetriNetEventOutcome net = petriNetService.importPetriNet(stream(TESTING_DATA[3]), VersionType.MAJOR, ActorTransformer.toLoggedUser(userService.getSystem())) - Case testCase = workflowService.createCase(net.getNet().getStringId(), "Test PDF", "", ActorTransformer.toLoggedUser(userService.getSystem())).getCase() + ImportPetriNetEventOutcome net = petriNetService.importPetriNet(ImportPetriNetParams.with() + .xmlFile(stream(TESTING_DATA[3])) + .releaseType(VersionType.MAJOR) + .author(ActorTransformer.toLoggedUser(userService.getSystem())) + .build()) + Case testCase = workflowService.createCase(CreateCaseParams.with() + .petriNet(net.getNet()) + .title("Test PDF") + .color("") + .loggedUser(ActorTransformer.toLoggedUser(userService.getSystem())) + .build()).getCase() testCase.getPetriNet().getTransition("1").setDataGroups(getDataGroupMap(dataService.getDataGroups(testCase.getTasks()[0].getTask(), Locale.ENGLISH).getData())) String taskId = testCase.getTasks().find(taskPair -> taskPair.transition.equals("1")).task - taskService.assignTask(taskId) - taskService.finishTask(taskId) + taskService.assignTask(new TaskParams(taskId)) + taskService.finishTask(new TaskParams(taskId)) assert workflowService.findOne(testCase.stringId).getFieldValue("file") != null } @Test void testAllData() { PdfResourceConfigurationProperties pdfResource = applicationContext.getBean(PdfResourceConfigurationProperties.class) - ImportPetriNetEventOutcome net = petriNetService.importPetriNet(stream(TESTING_DATA[3]), VersionType.MAJOR, ActorTransformer.toLoggedUser(userService.getSystem())) - Case testCase = workflowService.createCase(net.getNet().getStringId(), "Test PDF", "", ActorTransformer.toLoggedUser(userService.getSystem())).getCase() + ImportPetriNetEventOutcome net = petriNetService.importPetriNet(ImportPetriNetParams.with() + .xmlFile(stream(TESTING_DATA[3])) + .releaseType(VersionType.MAJOR) + .author(ActorTransformer.toLoggedUser(userService.getSystem())) + .build()) + Case testCase = workflowService.createCase(CreateCaseParams.with() + .petriNet(net.getNet()) + .title("Test PDF") + .color("") + .loggedUser(ActorTransformer.toLoggedUser(userService.getSystem())) + .build()).getCase() testCase.getPetriNet().getTransition("1").setDataGroups(getDataGroupMap(dataService.getDataGroups(testCase.getTasks()[0].getTask(), Locale.ENGLISH).getData())) pdfResource.setOutputResource(new ClassPathResource(pdfOutputFolder + "/out_" + TESTING_DATA[3] + "_.pdf")) pdfGenerator.setupPdfGenerator(pdfResource) @@ -113,8 +134,17 @@ class PdfGeneratorTest { @Test void testingNormal() { PdfResourceConfigurationProperties pdfResource = applicationContext.getBean(PdfResourceConfigurationProperties.class) - ImportPetriNetEventOutcome net = petriNetService.importPetriNet(stream(TESTING_DATA[0]), VersionType.MAJOR, ActorTransformer.toLoggedUser(userService.getSystem())) - Case testCase = workflowService.createCase(net.getNet().getStringId(), "Test PDF", "", ActorTransformer.toLoggedUser(userService.getSystem())).getCase() + ImportPetriNetEventOutcome net = petriNetService.importPetriNet(ImportPetriNetParams.with() + .xmlFile(stream(TESTING_DATA[0])) + .releaseType(VersionType.MAJOR) + .author(ActorTransformer.toLoggedUser(userService.getSystem())) + .build()) + Case testCase = workflowService.createCase(CreateCaseParams.with() + .petriNet(net.getNet()) + .title("Test PDF") + .color("") + .loggedUser(ActorTransformer.toLoggedUser(userService.getSystem())) + .build()).getCase() testCase.getPetriNet().getTransition("1").setDataGroups(getDataGroupMap(dataService.getDataGroups(testCase.getTasks()[0].getTask(), Locale.ENGLISH).getData())) pdfResource.setOutputResource(new ClassPathResource(pdfOutputFolder + "/out_" + TESTING_DATA[0] + "_.pdf")) pdfGenerator.setupPdfGenerator(pdfResource) @@ -127,8 +157,17 @@ class PdfGeneratorTest { @Test void testingWithTemplate() { PdfResourceConfigurationProperties pdfResource = applicationContext.getBean(PdfResourceConfigurationProperties.class) - ImportPetriNetEventOutcome net = petriNetService.importPetriNet(stream(TESTING_DATA[1]), VersionType.MAJOR, ActorTransformer.toLoggedUser(userService.getSystem())) - Case testCase = workflowService.createCase(net.getNet().getStringId(), "Test PDF", "", ActorTransformer.toLoggedUser(userService.getSystem())).getCase() + ImportPetriNetEventOutcome net = petriNetService.importPetriNet(ImportPetriNetParams.with() + .xmlFile(stream(TESTING_DATA[1])) + .releaseType(VersionType.MAJOR) + .author(ActorTransformer.toLoggedUser(userService.getSystem())) + .build()) + Case testCase = workflowService.createCase(CreateCaseParams.with() + .petriNet(net.getNet()) + .title("Test PDF") + .color("") + .loggedUser(ActorTransformer.toLoggedUser(userService.getSystem())) + .build()).getCase() testCase.getPetriNet().getTransition("1").setDataGroups(getDataGroupMap(dataService.getDataGroups(testCase.getTasks()[0].getTask(), Locale.ENGLISH).getData())) pdfResource.setOutputResource(new ClassPathResource(pdfOutputFolder + "/out_" + TESTING_DATA[1] + "_.pdf")) pdfResource.setMarginLeft(75) @@ -146,8 +185,17 @@ class PdfGeneratorTest { @Test void testingCustomFunction() { PdfResourceConfigurationProperties pdfResource = applicationContext.getBean(PdfResourceConfigurationProperties.class) - ImportPetriNetEventOutcome net = petriNetService.importPetriNet(stream(TESTING_DATA[1]), VersionType.MAJOR, ActorTransformer.toLoggedUser(userService.getSystem())) - Case testCase = workflowService.createCase(net.getNet().getStringId(), "Test PDF", "", ActorTransformer.toLoggedUser(userService.getSystem())).getCase() + ImportPetriNetEventOutcome net = petriNetService.importPetriNet(ImportPetriNetParams.with() + .xmlFile(stream(TESTING_DATA[1])) + .releaseType(VersionType.MAJOR) + .author(ActorTransformer.toLoggedUser(userService.getSystem())) + .build()) + Case testCase = workflowService.createCase(CreateCaseParams.with() + .petriNet(net.getNet()) + .title("Test PDF") + .color("") + .loggedUser(ActorTransformer.toLoggedUser(userService.getSystem())) + .build()).getCase() testCase.getPetriNet().getTransition("1").setDataGroups(getDataGroupMap(dataService.getDataGroups(testCase.getTasks()[0].getTask(), Locale.ENGLISH).getData())) String filename = pdfResource.getOutputDefaultName() String storagePath = pdfResource.getOutputFolder() + File.separator + testCase.stringId + "-" + "fileField1" + "-" + pdfResource.getOutputDefaultName() @@ -166,8 +214,17 @@ class PdfGeneratorTest { @Test void testingLongDocument() { PdfResourceConfigurationProperties pdfResource = applicationContext.getBean(PdfResourceConfigurationProperties.class) - ImportPetriNetEventOutcome net = petriNetService.importPetriNet(stream(TESTING_DATA[2]), VersionType.MAJOR, ActorTransformer.toLoggedUser(userService.getSystem())) - Case testCase = workflowService.createCase(net.getNet().getStringId(), "Test PDF", "", ActorTransformer.toLoggedUser(userService.getSystem())).getCase() + ImportPetriNetEventOutcome net = petriNetService.importPetriNet(ImportPetriNetParams.with() + .xmlFile(stream(TESTING_DATA[2])) + .releaseType(VersionType.MAJOR) + .author(ActorTransformer.toLoggedUser(userService.getSystem())) + .build()) + Case testCase = workflowService.createCase(CreateCaseParams.with() + .petriNet(net.getNet()) + .title("Test PDF") + .color("") + .loggedUser(ActorTransformer.toLoggedUser(userService.getSystem())) + .build()).getCase() testCase.getPetriNet().getTransition("1").setDataGroups(getDataGroupMap(dataService.getDataGroups(testCase.getTasks()[0].getTask(), Locale.ENGLISH).getData())) pdfResource.setOutputResource(new ClassPathResource(pdfOutputFolder + "/out_" + TESTING_DATA[2] + "_.pdf")) pdfGenerator.setupPdfGenerator(pdfResource) @@ -180,8 +237,17 @@ class PdfGeneratorTest { @Test void testingPageNumber() { PdfResourceConfigurationProperties pdfResource = applicationContext.getBean(PdfResourceConfigurationProperties.class) - ImportPetriNetEventOutcome net = petriNetService.importPetriNet(stream(TESTING_DATA[2]), VersionType.MAJOR, ActorTransformer.toLoggedUser(userService.getSystem())) - Case testCase = workflowService.createCase(net.getNet().getStringId(), "Test PDF", "", ActorTransformer.toLoggedUser(userService.getSystem())).getCase() + ImportPetriNetEventOutcome net = petriNetService.importPetriNet(ImportPetriNetParams.with() + .xmlFile(stream(TESTING_DATA[2])) + .releaseType(VersionType.MAJOR) + .author(ActorTransformer.toLoggedUser(userService.getSystem())) + .build()) + Case testCase = workflowService.createCase(CreateCaseParams.with() + .petriNet(net.getNet()) + .title("Test PDF") + .color("") + .loggedUser(ActorTransformer.toLoggedUser(userService.getSystem())) + .build()).getCase() testCase.getPetriNet().getTransition("1").setDataGroups(getDataGroupMap(dataService.getDataGroups(testCase.getTasks()[0].getTask(), Locale.ENGLISH).getData())) pdfResource.setNumberFormat(Locale.US) pdfResource.setPageNumberPosition(pdfResource.getMarginLeft()) @@ -207,8 +273,17 @@ class PdfGeneratorTest { pdfResource.getLineHeight(), pdfResource) - ImportPetriNetEventOutcome net = petriNetService.importPetriNet(stream(TESTING_DATA[2]), VersionType.MAJOR, ActorTransformer.toLoggedUser(userService.getSystem())) - Case testCase = workflowService.createCase(net.getNet().getStringId(), "Test PDF", "", ActorTransformer.toLoggedUser(userService.getSystem())).getCase() + ImportPetriNetEventOutcome net = petriNetService.importPetriNet(ImportPetriNetParams.with() + .xmlFile(stream(TESTING_DATA[2])) + .releaseType(VersionType.MAJOR) + .author(ActorTransformer.toLoggedUser(userService.getSystem())) + .build()) + Case testCase = workflowService.createCase(CreateCaseParams.with() + .petriNet(net.getNet()) + .title("Test PDF") + .color("") + .loggedUser(ActorTransformer.toLoggedUser(userService.getSystem())) + .build()).getCase() testCase.getPetriNet().getTransition("1").setDataGroups(getDataGroupMap(dataService.getDataGroups(testCase.getTasks()[0].getTask(), Locale.ENGLISH).getData())) pdfResource.setOutputResource(new ClassPathResource(pdfOutputFolder + "/out_custom_field.pdf")) pdfGenerator.setupPdfGenerator(pdfResource) @@ -222,8 +297,17 @@ class PdfGeneratorTest { @Test void testFlowLayout() { PdfResourceConfigurationProperties pdfResource = applicationContext.getBean(PdfResourceConfigurationProperties.class) - ImportPetriNetEventOutcome net = petriNetService.importPetriNet(stream(TESTING_DATA[4]), VersionType.MAJOR, ActorTransformer.toLoggedUser(userService.getSystem())) - Case testCase = workflowService.createCase(net.getNet().getStringId(), "Test PDF", "", ActorTransformer.toLoggedUser(userService.getSystem())).getCase() + ImportPetriNetEventOutcome net = petriNetService.importPetriNet(ImportPetriNetParams.with() + .xmlFile(stream(TESTING_DATA[4])) + .releaseType(VersionType.MAJOR) + .author(ActorTransformer.toLoggedUser(userService.getSystem())) + .build()) + Case testCase = workflowService.createCase(CreateCaseParams.with() + .petriNet(net.getNet()) + .title("Test PDF") + .color("") + .loggedUser(ActorTransformer.toLoggedUser(userService.getSystem())) + .build()).getCase() testCase.getPetriNet().getTransition("t1").setDataGroups(getDataGroupMap(dataService.getDataGroups(testCase.getTasks()[0].getTask(), Locale.ENGLISH).getData())) pdfResource.setOutputResource(new ClassPathResource(pdfOutputFolder + "/out_" + TESTING_DATA[4] + "_.pdf")) pdfGenerator.setupPdfGenerator(pdfResource) @@ -236,8 +320,17 @@ class PdfGeneratorTest { @Test void testDataGroup() { PdfResourceConfigurationProperties pdfResource = applicationContext.getBean(PdfResourceConfigurationProperties.class) - ImportPetriNetEventOutcome net = petriNetService.importPetriNet(stream(TESTING_DATA[5]), VersionType.MAJOR, ActorTransformer.toLoggedUser(userService.getSystem())) - Case testCase = workflowService.createCase(net.getNet().getStringId(), "Test PDF", "", ActorTransformer.toLoggedUser(userService.getSystem())).getCase() + ImportPetriNetEventOutcome net = petriNetService.importPetriNet(ImportPetriNetParams.with() + .xmlFile(stream(TESTING_DATA[5])) + .releaseType(VersionType.MAJOR) + .author(ActorTransformer.toLoggedUser(userService.getSystem())) + .build()) + Case testCase = workflowService.createCase(CreateCaseParams.with() + .petriNet(net.getNet()) + .title("Test PDF") + .color("") + .loggedUser(ActorTransformer.toLoggedUser(userService.getSystem())) + .build()).getCase() pdfResource.setOutputResource(new ClassPathResource(pdfOutputFolder + "/out_" + TESTING_DATA[5] + "_.pdf")) pdfGenerator.setupPdfGenerator(pdfResource) pdfGenerator.generatePdf(testCase, "t1", pdfResource) @@ -249,8 +342,17 @@ class PdfGeneratorTest { @Test void testTaskRef() { PdfResourceConfigurationProperties pdfResource = applicationContext.getBean(PdfResourceConfigurationProperties.class) - ImportPetriNetEventOutcome net = petriNetService.importPetriNet(stream(TESTING_DATA[6]), VersionType.MAJOR, ActorTransformer.toLoggedUser(userService.getSystem())) - Case testCase = workflowService.createCase(net.getNet().getStringId(), "Test PDF", "", ActorTransformer.toLoggedUser(userService.getSystem())).getCase() + ImportPetriNetEventOutcome net = petriNetService.importPetriNet(ImportPetriNetParams.with() + .xmlFile(stream(TESTING_DATA[6])) + .releaseType(VersionType.MAJOR) + .author(ActorTransformer.toLoggedUser(userService.getSystem())) + .build()) + Case testCase = workflowService.createCase(CreateCaseParams.with() + .petriNet(net.getNet()) + .title("Test PDF") + .color("") + .loggedUser(ActorTransformer.toLoggedUser(userService.getSystem())) + .build()).getCase() pdfResource.setOutputResource(new ClassPathResource(pdfOutputFolder + "/out_" + TESTING_DATA[6] + "_.pdf")) pdfGenerator.setupPdfGenerator(pdfResource) pdfGenerator.generatePdf(testCase, "t1", pdfResource) @@ -261,15 +363,24 @@ class PdfGeneratorTest { @Test void testRunGenerateAction() { - ImportPetriNetEventOutcome net = petriNetService.importPetriNet(stream(TESTING_DATA[7]), VersionType.MAJOR, ActorTransformer.toLoggedUser(userService.getSystem())) + ImportPetriNetEventOutcome net = petriNetService.importPetriNet(ImportPetriNetParams.with() + .xmlFile(stream(TESTING_DATA[7])) + .releaseType(VersionType.MAJOR) + .author(ActorTransformer.toLoggedUser(userService.getSystem())) + .build()) assertNotNull(net.getNet()) - Case testCase = workflowService.createCase(net.getNet().getStringId(), "Test PDF", "", ActorTransformer.toLoggedUser(userService.getSystem())).getCase() + Case testCase = workflowService.createCase(CreateCaseParams.with() + .petriNet(net.getNet()) + .title("Test PDF") + .color("") + .loggedUser(ActorTransformer.toLoggedUser(userService.getSystem())) + .build()).getCase() assertNotNull(testCase) List tasks = taskService.findAllByCase(testCase.stringId, Locale.ENGLISH) assertNotNull(tasks) assertEquals(2, tasks.size()) TaskReference task = tasks.find {it.transitionId == "1"} - AssignTaskEventOutcome outcome = taskService.assignTask(task.stringId) + AssignTaskEventOutcome outcome = taskService.assignTask(new TaskParams(task.stringId)) assertNotNull(outcome) assertEquals(task.stringId, outcome.task.stringId) assertEquals(testCase.stringId, outcome.case.stringId) @@ -280,11 +391,25 @@ class PdfGeneratorTest { @Test void testRunGenerateActionToAnotherCase() { - ImportPetriNetEventOutcome net = petriNetService.importPetriNet(stream(TESTING_DATA[7]), VersionType.MAJOR, ActorTransformer.toLoggedUser(userService.getSystem())) + ImportPetriNetEventOutcome net = petriNetService.importPetriNet(ImportPetriNetParams.with() + .xmlFile(stream(TESTING_DATA[7])) + .releaseType(VersionType.MAJOR) + .author(ActorTransformer.toLoggedUser(userService.getSystem())) + .build()) assertNotNull(net.getNet()) - Case testCase = workflowService.createCase(net.getNet().getStringId(), "Test PDF", "", ActorTransformer.toLoggedUser(userService.getSystem())).getCase() + Case testCase = workflowService.createCase(CreateCaseParams.with() + .petriNet(net.getNet()) + .title("Test PDF") + .color("") + .loggedUser(ActorTransformer.toLoggedUser(userService.getSystem())) + .build()).getCase() assertNotNull(testCase) - Case testCase2 = workflowService.createCase(net.getNet().getStringId(), "Test PDF 2", "", ActorTransformer.toLoggedUser(userService.getSystem())).getCase() + Case testCase2 = workflowService.createCase(CreateCaseParams.with() + .petriNet(net.getNet()) + .title("Test PDF 2") + .color("") + .loggedUser(ActorTransformer.toLoggedUser(userService.getSystem())) + .build()).getCase() assertNotNull(testCase2) assertNotEquals(testCase.stringId, testCase2.stringId) @@ -292,7 +417,7 @@ class PdfGeneratorTest { assertNotNull(tasks) assertEquals(2, tasks.size()) TaskReference task = tasks.find {it.transitionId == "2"} - AssignTaskEventOutcome outcome = taskService.assignTask(task.stringId) + AssignTaskEventOutcome outcome = taskService.assignTask(new TaskParams(task.stringId)) assertNotNull(outcome) assertEquals(task.stringId, outcome.task.stringId) assertEquals(testCase.stringId, outcome.case.stringId) diff --git a/application-engine/src/test/groovy/com/netgrif/application/engine/petrinet/domain/FunctionsTest.groovy b/application-engine/src/test/groovy/com/netgrif/application/engine/petrinet/domain/FunctionsTest.groovy index 35c46557f6..65c1df0af5 100644 --- a/application-engine/src/test/groovy/com/netgrif/application/engine/petrinet/domain/FunctionsTest.groovy +++ b/application-engine/src/test/groovy/com/netgrif/application/engine/petrinet/domain/FunctionsTest.groovy @@ -1,14 +1,18 @@ package com.netgrif.application.engine.petrinet.domain import com.netgrif.application.engine.TestHelper +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.User import com.netgrif.application.engine.auth.service.UserService import com.netgrif.application.engine.objects.petrinet.domain.VersionType import com.netgrif.application.engine.objects.petrinet.domain.dataset.logic.FieldBehavior +import com.netgrif.application.engine.petrinet.params.DeletePetriNetParams +import com.netgrif.application.engine.petrinet.params.ImportPetriNetParams import com.netgrif.application.engine.petrinet.service.interfaces.IPetriNetService import com.netgrif.application.engine.startup.ImportHelper import com.netgrif.application.engine.objects.workflow.domain.Case +import com.netgrif.application.engine.workflow.params.CreateCaseParams 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 @@ -89,29 +93,57 @@ class FunctionsTest { void testNamespaceFunction() { assert userService.findUserByUsername("test@test.com", null) == null - def functionResNet = petriNetService.importPetriNet(functionResNetResource.inputStream, VersionType.MAJOR, ActorTransformer.toLoggedUser(userService.getLoggedOrSystem())).getNet() - def functionTestNet = petriNetService.importPetriNet(functionTestNetResource.inputStream, VersionType.MAJOR, ActorTransformer.toLoggedUser(userService.getLoggedOrSystem())).getNet() + def functionResNet = petriNetService.importPetriNet(ImportPetriNetParams.with() + .xmlFile(functionResNetResource.inputStream) + .releaseType(VersionType.MAJOR) + .author(ActorTransformer.toLoggedUser(userService.getLoggedOrSystem())) + .build()).getNet() + def functionTestNet = petriNetService.importPetriNet(ImportPetriNetParams.with() + .xmlFile(functionTestNetResource.inputStream) + .releaseType(VersionType.MAJOR) + .author(ActorTransformer.toLoggedUser(userService.getLoggedOrSystem())) + .build()).getNet() assert functionResNet assert functionTestNet - Case aCase = workflowService.createCase(functionTestNet.stringId, "Test", "", ActorTransformer.toLoggedUser(userService.getLoggedOrSystem())) + Case aCase = workflowService.createCase(CreateCaseParams.with() + .petriNet(functionTestNet) + .title("Test") + .color("") + .loggedUser(ActorTransformer.toLoggedUser(userService.getLoggedOrSystem())) + .build()).getCase() dataService.setData(aCase.tasks.first().task, ImportHelper.populateDataset(["createUser": ["value": "true", "type": "boolean"]])) - User user = userService.findUserByUsername("test@test.com", null) - assert user - - userService.deleteUser(user) - petriNetService.deletePetriNet(functionResNet.stringId, ActorTransformer.toLoggedUser(userService.getLoggedOrSystem())) - petriNetService.deletePetriNet(functionTestNet.stringId, ActorTransformer.toLoggedUser(userService.getLoggedOrSystem())) + Optional userOpt = userService.findUserByUsername("test@test.com", null) + assert userOpt.isPresent() + + userService.deleteUser(userOpt.get()) + petriNetService.deletePetriNet(DeletePetriNetParams.with() + .petriNetId(functionResNet.stringId) + .loggedUser(ActorTransformer.toLoggedUser(userService.getLoggedOrSystem())) + .build()) + petriNetService.deletePetriNet(DeletePetriNetParams.with() + .petriNetId(functionTestNet.stringId) + .loggedUser(ActorTransformer.toLoggedUser(userService.getLoggedOrSystem())) + .build()) } @Test void testProcessFunctions() { - def functionTestNet = petriNetService.importPetriNet(functionTestNetResource.inputStream, VersionType.MAJOR, ActorTransformer.toLoggedUser(userService.getLoggedOrSystem())).getNet() + def functionTestNet = petriNetService.importPetriNet(ImportPetriNetParams.with() + .xmlFile(functionTestNetResource.inputStream) + .releaseType(VersionType.MAJOR) + .author(ActorTransformer.toLoggedUser(userService.getLoggedOrSystem())) + .build()).getNet() assert functionTestNet - Case aCase = workflowService.createCase(functionTestNet.stringId, "Test", "", ActorTransformer.toLoggedUser(userService.getLoggedOrSystem())).getCase() + Case aCase = workflowService.createCase(CreateCaseParams.with() + .petriNet(functionTestNet) + .title("Test") + .color("") + .loggedUser(ActorTransformer.toLoggedUser(userService.getLoggedOrSystem())) + .build()).getCase() dataService.setData(aCase.tasks.first().task, ImportHelper.populateDataset(["enum": ["value": "ano", "type": "enumeration"]])) aCase = workflowService.findOne(aCase.getStringId()) @@ -119,7 +151,10 @@ class FunctionsTest { def fieldBehavior = aCase.getDataField("number").behavior assert fieldBehavior.containsKey(aCase.tasks.first().transition) && fieldBehavior.get(aCase.tasks.first().transition).contains(FieldBehavior.EDITABLE) - petriNetService.deletePetriNet(functionTestNet.stringId, ActorTransformer.toLoggedUser(userService.getLoggedOrSystem())) + petriNetService.deletePetriNet(DeletePetriNetParams.with() + .petriNetId(functionTestNet.stringId) + .loggedUser(ActorTransformer.toLoggedUser(userService.getLoggedOrSystem())) + .build()) } @Test @@ -128,14 +163,26 @@ class FunctionsTest { def nets = petriNetService.getByIdentifier(FUNCTION_RES_IDENTIFIER, Pageable.unpaged()) if (nets) { nets.each { - petriNetService.deletePetriNet(it.getStringId(), ActorTransformer.toLoggedUser(userService.getLoggedOrSystem())) + petriNetService.deletePetriNet(DeletePetriNetParams.with() + .petriNetId(it.stringId) + .loggedUser(ActorTransformer.toLoggedUser(userService.getLoggedOrSystem())) + .build()) } } - def functionTestNet = petriNetService.importPetriNet(functionTestNetResource.inputStream, VersionType.MAJOR, ActorTransformer.toLoggedUser(userService.getLoggedOrSystem())).getNet() + def functionTestNet = petriNetService.importPetriNet(ImportPetriNetParams.with() + .xmlFile(functionTestNetResource.inputStream) + .releaseType(VersionType.MAJOR) + .author(ActorTransformer.toLoggedUser(userService.getLoggedOrSystem())) + .build()).getNet() assert functionTestNet - Case aCase = workflowService.createCase(functionTestNet.stringId, "Test", "", ActorTransformer.toLoggedUser(userService.getLoggedOrSystem())).getCase() + Case aCase = workflowService.createCase(CreateCaseParams.with() + .petriNet(functionTestNet) + .title("Test") + .color("") + .loggedUser(ActorTransformer.toLoggedUser(userService.getLoggedOrSystem())) + .build()).getCase() dataService.setData(aCase.tasks.first().task, ImportHelper.populateDataset(["number": ["value": "20", "type": "number"]])) }) } @@ -146,17 +193,33 @@ class FunctionsTest { def nets = petriNetService.getByIdentifier(FUNCTION_TEST_IDENTIFIER, Pageable.unpaged()) if (nets) { nets.each { - petriNetService.deletePetriNet(it.getStringId(), ActorTransformer.toLoggedUser(userService.getLoggedOrSystem())) + petriNetService.deletePetriNet(DeletePetriNetParams.with() + .petriNetId(it.stringId) + .loggedUser(ActorTransformer.toLoggedUser(userService.getLoggedOrSystem())) + .build()) } } - def functionTestNet = petriNetService.importPetriNet(functionTestNetResource.inputStream, VersionType.MAJOR, ActorTransformer.toLoggedUser(userService.getLoggedOrSystem())).getNet() + def functionTestNet = petriNetService.importPetriNet(ImportPetriNetParams.with() + .xmlFile(functionTestNetResource.inputStream) + .releaseType(VersionType.MAJOR) + .author(ActorTransformer.toLoggedUser(userService.getLoggedOrSystem())) + .build()).getNet() assert functionTestNet - Case aCase = workflowService.createCase(functionTestNet.stringId, "Test", "", ActorTransformer.toLoggedUser(userService.getLoggedOrSystem())).getCase() + Case aCase = workflowService.createCase(CreateCaseParams.with() + .petriNet(functionTestNet) + .title("Test") + .color("") + .loggedUser(ActorTransformer.toLoggedUser(userService.getLoggedOrSystem())) + .build()).getCase() dataService.setData(aCase.tasks.first().task, ImportHelper.populateDataset(["text": ["value": "20", "type": "text"]])) - functionTestNet = petriNetService.importPetriNet(functionTestNetResourceV2.inputStream, VersionType.MAJOR, ActorTransformer.toLoggedUser(userService.getLoggedOrSystem())).getNet() + functionTestNet = petriNetService.importPetriNet(ImportPetriNetParams.with() + .xmlFile(functionTestNetResourceV2.inputStream) + .releaseType(VersionType.MAJOR) + .author(ActorTransformer.toLoggedUser(userService.getLoggedOrSystem())) + .build()).getNet() assert functionTestNet dataService.setData(aCase.tasks.first().task, ImportHelper.populateDataset(["text": ["value": "20", "type": "text"]])) @@ -166,29 +229,55 @@ class FunctionsTest { @Test void testProcessFunctionException() { assertThrows(MissingMethodException.class, () -> { - def functionTestNet = petriNetService.importPetriNet(functionTestNetResource.inputStream, VersionType.MAJOR, ActorTransformer.toLoggedUser(userService.getLoggedOrSystem())).getNet() + def functionTestNet = petriNetService.importPetriNet(ImportPetriNetParams.with() + .xmlFile(functionTestNetResource.inputStream) + .releaseType(VersionType.MAJOR) + .author(ActorTransformer.toLoggedUser(userService.getLoggedOrSystem())) + .build()).getNet() assert functionTestNet - Case aCase = workflowService.createCase(functionTestNet.stringId, "Test", "", ActorTransformer.toLoggedUser(userService.getLoggedOrSystem())).getCase() + Case aCase = workflowService.createCase(CreateCaseParams.with() + .petriNet(functionTestNet) + .title("Test") + .color("") + .loggedUser(ActorTransformer.toLoggedUser(userService.getLoggedOrSystem())) + .build()).getCase() dataService.setData(aCase.tasks.first().task, ImportHelper.populateDataset(["number3": ["value": "20", "type": "number"]])) }) } @Test void testNewVersionOfNamespaceFunction() { - def functionResNet = petriNetService.importPetriNet(functionResNetResource.inputStream, VersionType.MAJOR, ActorTransformer.toLoggedUser(userService.getLoggedOrSystem())).getNet() - def functionTestNet = petriNetService.importPetriNet(functionTestNetResource.inputStream, VersionType.MAJOR, ActorTransformer.toLoggedUser(userService.getLoggedOrSystem())).getNet() + def functionResNet = petriNetService.importPetriNet(ImportPetriNetParams.with() + .xmlFile(functionResNetResource.inputStream) + .releaseType(VersionType.MAJOR) + .author(ActorTransformer.toLoggedUser(userService.getLoggedOrSystem())) + .build()).getNet() + def functionTestNet = petriNetService.importPetriNet(ImportPetriNetParams.with() + .xmlFile(functionTestNetResource.inputStream) + .releaseType(VersionType.MAJOR) + .author(ActorTransformer.toLoggedUser(userService.getLoggedOrSystem())) + .build()).getNet() assert functionResNet assert functionTestNet - Case aCase = workflowService.createCase(functionTestNet.stringId, "Test", "", ActorTransformer.toLoggedUser(userService.getLoggedOrSystem())).getCase() + Case aCase = workflowService.createCase(CreateCaseParams.with() + .petriNet(functionTestNet) + .title("Test") + .color("") + .loggedUser(ActorTransformer.toLoggedUser(userService.getLoggedOrSystem())) + .build()).getCase() dataService.setData(aCase.tasks.first().task, ImportHelper.populateDataset(["number": ["value": "20", "type": "number"]])) aCase = workflowService.findOne(aCase.getStringId()) assert aCase.getFieldValue("number2") == 20 + 20 - functionResNet = petriNetService.importPetriNet(functionResNetResourceV2.inputStream, VersionType.MAJOR, ActorTransformer.toLoggedUser(userService.getLoggedOrSystem())).getNet() + functionResNet = petriNetService.importPetriNet(ImportPetriNetParams.with() + .xmlFile(functionResNetResourceV2.inputStream) + .releaseType(VersionType.MAJOR) + .author(ActorTransformer.toLoggedUser(userService.getLoggedOrSystem())) + .build()).getNet() assert functionResNet dataService.setData(aCase.tasks.first().task, ImportHelper.populateDataset(["number": ["value": "20", "type": "number"]])) @@ -200,16 +289,33 @@ class FunctionsTest { @Test void testNamespaceMethodOverloadingFail() { assertThrows(IllegalArgumentException.class, () -> { - petriNetService.importPetriNet(functionOverloadingFailNetResource.inputStream, VersionType.MAJOR, ActorTransformer.toLoggedUser(userService.getLoggedOrSystem())) + petriNetService.importPetriNet(ImportPetriNetParams.with() + .xmlFile(functionOverloadingFailNetResource.inputStream) + .releaseType(VersionType.MAJOR) + .author(ActorTransformer.toLoggedUser(userService.getLoggedOrSystem())) + .build()) }) } @Test void testNamespaceUseCaseUpdate() { - def functionResV2Net = petriNetService.importPetriNet(functionResNetResourceV2.inputStream, VersionType.MAJOR, ActorTransformer.toLoggedUser(userService.getLoggedOrSystem())).getNet() - def functionTestV2Net = petriNetService.importPetriNet(functionTestNetResourceV2.inputStream, VersionType.MAJOR, ActorTransformer.toLoggedUser(userService.getLoggedOrSystem())).getNet() - - Case aCase = workflowService.createCase(functionTestV2Net.stringId, "Test", "", ActorTransformer.toLoggedUser(userService.getLoggedOrSystem())).getCase() + def functionResV2Net = petriNetService.importPetriNet(ImportPetriNetParams.with() + .xmlFile(functionResNetResourceV2.inputStream) + .releaseType(VersionType.MAJOR) + .author(ActorTransformer.toLoggedUser(userService.getLoggedOrSystem())) + .build()).getNet() + def functionTestV2Net = petriNetService.importPetriNet(ImportPetriNetParams.with() + .xmlFile(functionTestNetResourceV2.inputStream) + .releaseType(VersionType.MAJOR) + .author(ActorTransformer.toLoggedUser(userService.getLoggedOrSystem())) + .build()).getNet() + + Case aCase = workflowService.createCase(CreateCaseParams.with() + .petriNet(functionTestV2Net) + .title("Test") + .color("") + .loggedUser(ActorTransformer.toLoggedUser(userService.getLoggedOrSystem())) + .build()).getCase() dataService.setData(aCase.tasks.first().task, ImportHelper.populateDataset(["updateOtherField": ["value": "true", "type": "boolean"]])) aCase = workflowService.findOne(aCase.stringId) @@ -225,7 +331,11 @@ class FunctionsTest { @Test void testProcessMethodOverloadingFail() { assertThrows(IllegalArgumentException.class, () -> { - petriNetService.importPetriNet(functionOverloadingFailNetResourceV2.inputStream, VersionType.MAJOR, ActorTransformer.toLoggedUser(userService.getLoggedOrSystem())) + petriNetService.importPetriNet(ImportPetriNetParams.with() + .xmlFile(functionOverloadingFailNetResourceV2.inputStream) + .releaseType(VersionType.MAJOR) + .author(ActorTransformer.toLoggedUser(userService.getLoggedOrSystem())) + .build()) }) } @@ -235,11 +345,20 @@ class FunctionsTest { } private void testMethodOverloading(Resource resource) { - def petriNet = petriNetService.importPetriNet(resource.inputStream, VersionType.MAJOR, ActorTransformer.toLoggedUser(userService.getLoggedOrSystem())).getNet() + def petriNet = petriNetService.importPetriNet(ImportPetriNetParams.with() + .xmlFile(resource.inputStream) + .releaseType(VersionType.MAJOR) + .author(ActorTransformer.toLoggedUser(userService.getLoggedOrSystem())) + .build()).getNet() assert petriNet - Case aCase = workflowService.createCase(petriNet.stringId, "Test", "", ActorTransformer.toLoggedUser(userService.getLoggedOrSystem())).getCase() + Case aCase = workflowService.createCase(CreateCaseParams.with() + .petriNet(petriNet) + .title("Test") + .color("") + .loggedUser(ActorTransformer.toLoggedUser(userService.getLoggedOrSystem())) + .build()).getCase() dataService.setData(aCase.tasks.first().task, ImportHelper.populateDataset(["number": ["value": "20", "type": "number"]])) aCase = workflowService.findOne(aCase.getStringId()) From bb99bcccf8ef73d45fc0967299cc88b4432d58fa Mon Sep 17 00:00:00 2001 From: chvostek Date: Fri, 31 Oct 2025 10:19:21 +0100 Subject: [PATCH 34/55] [NAE-2235] Improve Efficiency of Database Reads and Saves - update tests according to changes --- .../ElasticSearchViewPermissionTest.groovy | 78 ++++++++++++--- .../QueryDSLViewPermissionTest.groovy | 98 +++++++++++++++---- .../petrinet/domain/ArcOrderTest.groovy | 7 +- .../petrinet/domain/ImporterTest.groovy | 73 ++++++++++---- .../petrinet/domain/PetriNetTest.groovy | 7 +- .../domain/dataset/CaseFieldTest.groovy | 25 ++++- .../domain/dataset/ChangeBehaviorTest.groovy | 7 +- .../dataset/ChangeCasePropertyTest.groovy | 16 ++- .../dataset/ChangeFieldValueInitTest.groovy | 12 ++- .../domain/dataset/ChoiceFieldTest.groovy | 7 +- .../domain/dataset/DynamicCaseNameTest.groovy | 22 ++++- .../domain/dataset/DynamicChoicesTest.groovy | 7 +- .../dataset/DynamicDefaultValueTest.groovy | 7 +- .../dataset/DynamicEnumerationTest.groovy | 9 +- .../DynamicValidationPerformanceTest.groovy | 13 ++- .../domain/dataset/FileFieldTest.groovy | 15 ++- .../domain/dataset/FileListFieldTest.groovy | 15 ++- .../domain/dataset/MapFieldTest.groovy | 25 ++++- .../service/CachePetriNetServiceTest.groovy | 7 +- .../web/PetriNetControllerTest.groovy | 7 +- .../engine/workflow/DataServiceTest.groovy | 25 ++++- .../engine/workflow/NewInitTest.groovy | 15 ++- .../workflow/SetDataOnButtonTest.groovy | 12 ++- .../engine/workflow/TaskRefInitTest.groovy | 13 ++- .../workflow/TaskRefPropagationTest.groovy | 13 ++- .../engine/workflow/UserRefsTest.groovy | 7 +- .../workflow/WorkflowServiceTest.groovy | 54 ++++++++-- .../change_caseref_value_action_test.xml | 6 +- 28 files changed, 482 insertions(+), 120 deletions(-) diff --git a/application-engine/src/test/groovy/com/netgrif/application/engine/permissions/ElasticSearchViewPermissionTest.groovy b/application-engine/src/test/groovy/com/netgrif/application/engine/permissions/ElasticSearchViewPermissionTest.groovy index f2e3b28043..67bf965ef2 100644 --- a/application-engine/src/test/groovy/com/netgrif/application/engine/permissions/ElasticSearchViewPermissionTest.groovy +++ b/application-engine/src/test/groovy/com/netgrif/application/engine/permissions/ElasticSearchViewPermissionTest.groovy @@ -14,11 +14,14 @@ import com.netgrif.application.engine.elastic.web.requestbodies.CaseSearchReques import com.netgrif.application.engine.objects.petrinet.domain.PetriNet import com.netgrif.application.engine.objects.petrinet.domain.VersionType import com.netgrif.application.engine.objects.petrinet.domain.roles.ProcessRole +import com.netgrif.application.engine.petrinet.params.ImportPetriNetParams import com.netgrif.application.engine.petrinet.service.interfaces.IPetriNetService import com.netgrif.application.engine.startup.ImportHelper import com.netgrif.application.engine.startup.runner.SuperCreatorRunner import com.netgrif.application.engine.objects.workflow.domain.Case import com.netgrif.application.engine.objects.workflow.domain.eventoutcomes.petrinetoutcomes.ImportPetriNetEventOutcome +import com.netgrif.application.engine.workflow.params.CreateCaseParams +import com.netgrif.application.engine.workflow.params.DeleteCaseParams 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 @@ -81,11 +84,19 @@ class ElasticSearchViewPermissionTest { @BeforeEach void inti() { testHelper.truncateDbs() - ImportPetriNetEventOutcome net = petriNetService.importPetriNet(new FileInputStream("src/test/resources/view_permission_test.xml"), VersionType.MAJOR, superCreator.getLoggedSuper()) + ImportPetriNetEventOutcome net = petriNetService.importPetriNet(ImportPetriNetParams.with() + .xmlFile(new FileInputStream("src/test/resources/view_permission_test.xml")) + .releaseType(VersionType.MAJOR) + .author(superCreator.getLoggedSuper()) + .build()) assert net.getNet() != null this.net = net.getNet() - ImportPetriNetEventOutcome netWithUserRefs = petriNetService.importPetriNet(new FileInputStream("src/test/resources/view_permission_with_userRefs_test.xml"), VersionType.MAJOR, superCreator.getLoggedSuper()) + ImportPetriNetEventOutcome netWithUserRefs = petriNetService.importPetriNet(ImportPetriNetParams.with() + .xmlFile(new FileInputStream("src/test/resources/view_permission_with_userRefs_test.xml")) + .releaseType(VersionType.MAJOR) + .author(superCreator.getLoggedSuper()) + .build()) assert netWithUserRefs.getNet() != null this.netWithUserRefs = netWithUserRefs.getNet() @@ -97,19 +108,29 @@ class ElasticSearchViewPermissionTest { @Test void testSearchElasticViewWithUserWithoutRole() { - Case case_ = workflowService.createCase(net.getStringId(), "Permission test", "", ActorTransformer.toLoggedUser(testUser)).getCase() + Case case_ = workflowService.createCase(CreateCaseParams.with() + .petriNet(net) + .title("Permission test") + .color("") + .loggedUser(ActorTransformer.toLoggedUser(testUser)) + .build()).getCase() CaseSearchRequest caseSearchRequest = new CaseSearchRequest() caseSearchRequest.process = [new CaseSearchRequest.PetriNet("vpt")] as List Page casePage = elasticCaseService.search([caseSearchRequest] as List, ActorTransformer.toLoggedUser(testUser), PageRequest.of(0, 20), LocaleContextHolder.getLocale(), false) assert casePage.getContent().size() == 0 - workflowService.deleteCase(case_.getStringId()) + workflowService.deleteCase(new DeleteCaseParams(case_.getStringId())) } @Test void testSearchElasticViewWithUserWithPosRole() { - Case case_ = workflowService.createCase(net.getStringId(), "Permission test", "", ActorTransformer.toLoggedUser(testUser)).getCase() + Case case_ = workflowService.createCase(CreateCaseParams.with() + .petriNet(net) + .title("Permission test") + .color("") + .loggedUser(ActorTransformer.toLoggedUser(testUser)) + .build()).getCase() ProcessRole posViewRole = this.net.getRoles().values().find(v -> v.getImportId() == "view_pos_role") userService.addRole(testUser, posViewRole.getStringId()) @@ -122,12 +143,17 @@ class ElasticSearchViewPermissionTest { assert casePage.getContent().size() == 1 assert casePage.getContent()[0].stringId == case_.stringId userService.removeRole(testUser, posViewRole.getStringId()) - workflowService.deleteCase(case_.getStringId()) + workflowService.deleteCase(new DeleteCaseParams(case_.getStringId())) } @Test void testSearchElasticViewWithUserWithNegRole() { - Case case_ = workflowService.createCase(net.getStringId(), "Permission test", "", ActorTransformer.toLoggedUser(testUser)).getCase() + Case case_ = workflowService.createCase(CreateCaseParams.with() + .petriNet(net) + .title("Permission test") + .color("") + .loggedUser(ActorTransformer.toLoggedUser(testUser)) + .build()).getCase() ProcessRole negViewRole = this.net.getRoles().values().find(v -> v.getImportId() == "view_neg_role") userService.addRole(testUser, negViewRole.getStringId()) @@ -137,24 +163,34 @@ class ElasticSearchViewPermissionTest { assert casePage.getContent().size() == 0 && case_.negativeViewRoles.contains(negViewRole.stringId) userService.removeRole(testUser, negViewRole.getStringId()) - workflowService.deleteCase(case_.getStringId()) + workflowService.deleteCase(new DeleteCaseParams(case_.getStringId())) } @Test void testSearchElasticViewWithUserWithoutUserRef() { - Case case_ = workflowService.createCase(netWithUserRefs.getStringId(), "Permission test", "", ActorTransformer.toLoggedUser(testUser)).getCase() + Case case_ = workflowService.createCase(CreateCaseParams.with() + .petriNet(netWithUserRefs) + .title("Permission test") + .color("") + .loggedUser(ActorTransformer.toLoggedUser(testUser)) + .build()).getCase() CaseSearchRequest caseSearchRequest = new CaseSearchRequest() caseSearchRequest.process = [new CaseSearchRequest.PetriNet(netWithUserRefs.getIdentifier())] as List Page casePage = elasticCaseService.search([caseSearchRequest] as List, ActorTransformer.toLoggedUser(testUser), PageRequest.of(0, 20), LocaleContextHolder.getLocale(), false) assert casePage.getContent().size() == 0 - workflowService.deleteCase(case_.getStringId()) + workflowService.deleteCase(new DeleteCaseParams(case_.getStringId())) } @Test void testSearchElasticViewWithUserWithPosUserRef() { - Case case_ = workflowService.createCase(netWithUserRefs.getStringId(), "Permission test", "", ActorTransformer.toLoggedUser(testUser)).getCase() + Case case_ = workflowService.createCase(CreateCaseParams.with() + .petriNet(netWithUserRefs) + .title("Permission test") + .color("") + .loggedUser(ActorTransformer.toLoggedUser(testUser)) + .build()).getCase() String taskId = (new ArrayList<>(case_.getTasks())).get(0).task case_ = dataService.setData(taskId, ImportHelper.populateDataset([ "view_ul_pos": [ @@ -170,12 +206,17 @@ class ElasticSearchViewPermissionTest { Page casePage = elasticCaseService.search([caseSearchRequest] as List, ActorTransformer.toLoggedUser(testUser), PageRequest.of(0, 20), LocaleContextHolder.getLocale(), false) assert casePage.getContent().size() == 1 && casePage.getContent()[0].stringId == case_.stringId && case_.viewUsers.contains(testUser.getStringId()) - workflowService.deleteCase(case_.getStringId()) + workflowService.deleteCase(new DeleteCaseParams(case_.getStringId())) } @Test void testSearchElasticViewWithUserWithNegUserRef() { - Case case_ = workflowService.createCase(netWithUserRefs.getStringId(), "Permission test", "", ActorTransformer.toLoggedUser(testUser)).getCase() + Case case_ = workflowService.createCase(CreateCaseParams.with() + .petriNet(netWithUserRefs) + .title("Permission test") + .color("") + .loggedUser(ActorTransformer.toLoggedUser(testUser)) + .build()).getCase() String taskId = (new ArrayList<>(case_.getTasks())).get(0).task case_ = dataService.setData(taskId, ImportHelper.populateDataset([ "view_ul_neg": [ @@ -191,12 +232,17 @@ class ElasticSearchViewPermissionTest { Page casePage = elasticCaseService.search([caseSearchRequest] as List, ActorTransformer.toLoggedUser(testUser), PageRequest.of(0, 20), LocaleContextHolder.getLocale(), false) assert casePage.getContent().size() == 0 && case_.negativeViewUsers.contains(testUser.getStringId()) - workflowService.deleteCase(case_.getStringId()) + workflowService.deleteCase(new DeleteCaseParams(case_.getStringId())) } @Test void testSearchElasticViewWithUserWithNegativeRoleAndPosUserRef() { - Case case_ = workflowService.createCase(netWithUserRefs.getStringId(), "Permission test", "", ActorTransformer.toLoggedUser(testUser)).getCase() + Case case_ = workflowService.createCase(CreateCaseParams.with() + .petriNet(netWithUserRefs) + .title("Permission test") + .color("") + .loggedUser(ActorTransformer.toLoggedUser(testUser)) + .build()).getCase() ProcessRole negViewRole = this.net.getRoles().values().find(v -> v.getImportId() == "view_neg_role") userService.addRole(testUser, negViewRole.getStringId()) String taskId = (new ArrayList<>(case_.getTasks())).get(0).task @@ -215,6 +261,6 @@ class ElasticSearchViewPermissionTest { assert casePage.getContent().size() == 1 && case_.viewUsers.contains(testUser.stringId) userService.removeRole(testUser, negViewRole.getStringId()) - workflowService.deleteCase(case_.getStringId()) + workflowService.deleteCase(new DeleteCaseParams(case_.getStringId())) } } diff --git a/application-engine/src/test/groovy/com/netgrif/application/engine/permissions/QueryDSLViewPermissionTest.groovy b/application-engine/src/test/groovy/com/netgrif/application/engine/permissions/QueryDSLViewPermissionTest.groovy index 5cf53bb05c..a47436cfce 100644 --- a/application-engine/src/test/groovy/com/netgrif/application/engine/permissions/QueryDSLViewPermissionTest.groovy +++ b/application-engine/src/test/groovy/com/netgrif/application/engine/permissions/QueryDSLViewPermissionTest.groovy @@ -5,10 +5,13 @@ import com.netgrif.application.engine.auth.service.UserService 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.User +import com.netgrif.application.engine.petrinet.params.ImportPetriNetParams import com.netgrif.application.engine.petrinet.service.interfaces.IPetriNetService import com.netgrif.application.engine.TestHelper import com.netgrif.application.engine.startup.ImportHelper import com.netgrif.application.engine.startup.runner.SuperCreatorRunner +import com.netgrif.application.engine.workflow.params.CreateCaseParams +import com.netgrif.application.engine.workflow.params.DeleteCaseParams 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 @@ -72,13 +75,21 @@ class QueryDSLViewPermissionTest { private Authority userAuthority @BeforeEach - void inti() { + void init() { testHelper.truncateDbs() - ImportPetriNetEventOutcome net = petriNetService.importPetriNet(new FileInputStream("src/test/resources/view_permission_test.xml"), VersionType.MAJOR, superCreator.getLoggedSuper()) + ImportPetriNetEventOutcome net = petriNetService.importPetriNet(ImportPetriNetParams.with() + .xmlFile(new FileInputStream("src/test/resources/view_permission_test.xml")) + .releaseType(VersionType.MAJOR) + .author(superCreator.getLoggedSuper()) + .build()) assert net.getNet() != null this.net = net.getNet() - ImportPetriNetEventOutcome netWithUserRefs = petriNetService.importPetriNet(new FileInputStream("src/test/resources/view_permission_with_userRefs_test.xml"), VersionType.MAJOR, superCreator.getLoggedSuper()) + ImportPetriNetEventOutcome netWithUserRefs = petriNetService.importPetriNet(ImportPetriNetParams.with() + .xmlFile(new FileInputStream("src/test/resources/view_permission_with_userRefs_test.xml")) + .releaseType(VersionType.MAJOR) + .author(superCreator.getLoggedSuper()) + .build()) assert netWithUserRefs.getNet() != null this.netWithUserRefs = netWithUserRefs.getNet() @@ -90,17 +101,27 @@ class QueryDSLViewPermissionTest { @Test void testSearchQueryDSLViewWithoutRole() { - Case case_ = workflowService.createCase(net.getStringId(), "Permission test", "", ActorTransformer.toLoggedUser(testUser)).getCase() + Case case_ = workflowService.createCase(CreateCaseParams.with() + .petriNet(net) + .title("Permission test") + .color("") + .loggedUser(ActorTransformer.toLoggedUser(testUser)) + .build()).getCase() Page casePage = workflowService.search(["petriNet": ["identifier": netWithUserRefs.getIdentifier()], "fullText": "VPT"] as Map, PageRequest.of(0, 20), ActorTransformer.toLoggedUser(testUser), LocaleContextHolder.getLocale()) assert casePage.getContent().size() == 0 - workflowService.deleteCase(case_.getStringId()) + workflowService.deleteCase(new DeleteCaseParams(case_.getStringId())) } @Test void testSearchQueryDSLViewWithUserWithPosRole() { - Case case_ = workflowService.createCase(net.getStringId(), "Permission test", "", ActorTransformer.toLoggedUser(testUser)).getCase() + Case case_ = workflowService.createCase(CreateCaseParams.with() + .petriNet(net) + .title("Permission test") + .color("") + .loggedUser(ActorTransformer.toLoggedUser(testUser)) + .build()).getCase() ProcessRole posViewRole = this.net.getRoles().values().find(v -> v.getImportId() == "view_pos_role") userService.addRole(testUser, posViewRole.getStringId()) @@ -109,12 +130,17 @@ class QueryDSLViewPermissionTest { assert casePage.getContent().size() == 1 && casePage.getContent()[0].stringId == case_.stringId userService.removeRole(testUser, posViewRole.getStringId()) - workflowService.deleteCase(case_.getStringId()) + workflowService.deleteCase(new DeleteCaseParams(case_.getStringId())) } @Test void testSearchQueryDSLViewWithUserWithNegRole() { - Case case_ = workflowService.createCase(net.getStringId(), "Permission test", "", ActorTransformer.toLoggedUser(testUser)).getCase() + Case case_ = workflowService.createCase(CreateCaseParams.with() + .petriNet(net) + .title("Permission test") + .color("") + .loggedUser(ActorTransformer.toLoggedUser(testUser)) + .build()).getCase() ProcessRole negViewRole = this.net.getRoles().values().find(v -> v.getImportId() == "view_neg_role") userService.addRole(testUser, negViewRole.getStringId()) @@ -123,22 +149,32 @@ class QueryDSLViewPermissionTest { assert casePage.getContent().size() == 0 && case_.negativeViewRoles.contains(negViewRole.stringId) userService.removeRole(testUser, negViewRole.getStringId()) - workflowService.deleteCase(case_.getStringId()) + workflowService.deleteCase(new DeleteCaseParams(case_.getStringId())) } @Test void testSearchQueryDSLViewWithoutUserRef() { - Case case_ = workflowService.createCase(netWithUserRefs.getStringId(), "Permission test", "", ActorTransformer.toLoggedUser(testUser)).getCase() + Case case_ = workflowService.createCase(CreateCaseParams.with() + .petriNet(netWithUserRefs) + .title("Permission test") + .color("") + .loggedUser(ActorTransformer.toLoggedUser(testUser)) + .build()).getCase() Page casePage = workflowService.search(["petriNet": ["identifier": netWithUserRefs.getIdentifier()], "fullText": "VPT"] as Map, PageRequest.of(0, 20), ActorTransformer.toLoggedUser(testUser), LocaleContextHolder.getLocale()) assert casePage.getContent().size() == 0 - workflowService.deleteCase(case_.getStringId()) + workflowService.deleteCase(new DeleteCaseParams(case_.getStringId())) } @Test void testSearchQueryDSLViewWithPosUserRef() { - Case case_ = workflowService.createCase(netWithUserRefs.getStringId(), "Permission test", "", ActorTransformer.toLoggedUser(testUser)).getCase() + Case case_ = workflowService.createCase(CreateCaseParams.with() + .petriNet(netWithUserRefs) + .title("Permission test") + .color("") + .loggedUser(ActorTransformer.toLoggedUser(testUser)) + .build()).getCase() String taskId = (new ArrayList<>(case_.getTasks())).get(0).task case_ = dataService.setData(taskId, ImportHelper.populateDataset([ "view_ul_pos": [ @@ -153,12 +189,17 @@ class QueryDSLViewPermissionTest { PageRequest.of(0, 20), ActorTransformer.toLoggedUser(testUser), LocaleContextHolder.getLocale()) assert casePage.getContent().size() == 1 && casePage.getContent()[0].stringId == case_.stringId && case_.viewUsers.contains(testUser.getStringId()) - workflowService.deleteCase(case_.getStringId()) + workflowService.deleteCase(new DeleteCaseParams(case_.getStringId())) } @Test void testSearchTaskQueryDSLViewWithPosUserRef() { - Case case_ = workflowService.createCase(netWithUserRefs.getStringId(), "Permission test", "", ActorTransformer.toLoggedUser(testUser)).getCase() + Case case_ = workflowService.createCase(CreateCaseParams.with() + .petriNet(netWithUserRefs) + .title("Permission test") + .color("") + .loggedUser(ActorTransformer.toLoggedUser(testUser)) + .build()).getCase() String taskId = (new ArrayList<>(case_.getTasks())).get(0).task case_ = dataService.setData(taskId, ImportHelper.populateDataset([ "view_ul_pos": [ @@ -175,12 +216,17 @@ class QueryDSLViewPermissionTest { PageRequest.of(0, 20), ActorTransformer.toLoggedUser(testUser), LocaleContextHolder.getLocale(), false) assert taskPage.getContent().size() == 1 && taskPage.content[0].caseId == case_.stringId && taskPage.content[0].viewUsers.contains(testUser.getStringId()) - workflowService.deleteCase(case_.getStringId()) + workflowService.deleteCase(new DeleteCaseParams(case_.getStringId())) } @Test void testSearchTaskQueryDSLViewWithUserWithPosRole() { - Case case_ = workflowService.createCase(netWithUserRefs.getStringId(), "Permission test", "", ActorTransformer.toLoggedUser(testUser)).getCase() + Case case_ = workflowService.createCase(CreateCaseParams.with() + .petriNet(netWithUserRefs) + .title("Permission test") + .color("") + .loggedUser(ActorTransformer.toLoggedUser(testUser)) + .build()).getCase() ProcessRole posViewRole = this.netWithUserRefs.getRoles().values().find(v -> v.getImportId() == "view_pos_role") userService.addRole(testUser, posViewRole.getStringId()) @@ -191,12 +237,17 @@ class QueryDSLViewPermissionTest { assert taskPage.getContent().size() == 1 && taskPage.getContent()[0].caseId == case_.stringId userService.removeRole(testUser, posViewRole.getStringId()) - workflowService.deleteCase(case_.getStringId()) + workflowService.deleteCase(new DeleteCaseParams(case_.getStringId())) } @Test void testSearchQueryDSLViewWithNegUserRef() { - Case case_ = workflowService.createCase(netWithUserRefs.getStringId(), "Permission test", "", ActorTransformer.toLoggedUser(testUser)).getCase() + Case case_ = workflowService.createCase(CreateCaseParams.with() + .petriNet(netWithUserRefs) + .title("Permission test") + .color("") + .loggedUser(ActorTransformer.toLoggedUser(testUser)) + .build()).getCase() String taskId = (new ArrayList<>(case_.getTasks())).get(0).task case_ = dataService.setData(taskId, ImportHelper.populateDataset([ "view_ul_neg": [ @@ -211,12 +262,17 @@ class QueryDSLViewPermissionTest { PageRequest.of(0, 20), ActorTransformer.toLoggedUser(testUser), LocaleContextHolder.getLocale()) assert casePage.getContent().size() == 0 && case_.negativeViewUsers.contains(testUser.getStringId()) - workflowService.deleteCase(case_.getStringId()) + workflowService.deleteCase(new DeleteCaseParams(case_.getStringId())) } @Test void testSearchQueryDSLViewWithNegRoleAndPosUserRef() { - Case case_ = workflowService.createCase(netWithUserRefs.getStringId(), "Permission test", "", ActorTransformer.toLoggedUser(testUser)).getCase() + Case case_ = workflowService.createCase(CreateCaseParams.with() + .petriNet(netWithUserRefs) + .title("Permission test") + .color("") + .loggedUser(ActorTransformer.toLoggedUser(testUser)) + .build()).getCase() String taskId = (new ArrayList<>(case_.getTasks())).get(0).task case_ = dataService.setData(taskId, ImportHelper.populateDataset([ "view_ul_pos": [ @@ -235,6 +291,6 @@ class QueryDSLViewPermissionTest { assert casePage.getContent().size() == 1 && case_.viewUsers.contains(testUser.stringId) userService.removeRole(testUser, negViewRole.getStringId()) - workflowService.deleteCase(case_.getStringId()) + workflowService.deleteCase(new DeleteCaseParams(case_.getStringId())) } } diff --git a/application-engine/src/test/groovy/com/netgrif/application/engine/petrinet/domain/ArcOrderTest.groovy b/application-engine/src/test/groovy/com/netgrif/application/engine/petrinet/domain/ArcOrderTest.groovy index 99cf689295..b3e141da89 100644 --- a/application-engine/src/test/groovy/com/netgrif/application/engine/petrinet/domain/ArcOrderTest.groovy +++ b/application-engine/src/test/groovy/com/netgrif/application/engine/petrinet/domain/ArcOrderTest.groovy @@ -5,6 +5,7 @@ import com.netgrif.application.engine.importer.service.Importer import com.netgrif.application.engine.petrinet.domain.arcs.ArcOrderComparator import com.netgrif.application.engine.objects.petrinet.domain.VersionType import com.netgrif.application.engine.objects.petrinet.domain.arcs.ResetArc +import com.netgrif.application.engine.petrinet.params.ImportPetriNetParams import com.netgrif.application.engine.petrinet.service.interfaces.IPetriNetService import com.netgrif.application.engine.startup.ImportHelper import com.netgrif.application.engine.startup.runner.SuperCreatorRunner @@ -51,7 +52,11 @@ class ArcOrderTest { @Test void testOrder() { - def net = petriNetService.importPetriNet(stream(NET_FILE), VersionType.MAJOR, superCreator.getLoggedSuper()).getNet() + def net = petriNetService.importPetriNet(ImportPetriNetParams.with() + .xmlFile(stream(NET_FILE)) + .releaseType(VersionType.MAJOR) + .author(superCreator.getLoggedSuper()) + .build()).getNet() def arcs = net.getArcsOfTransition(NET_TASK) def sorted = arcs.sort { a1, a2 -> ArcOrderComparator.getInstance().compare(a1, a2) } diff --git a/application-engine/src/test/groovy/com/netgrif/application/engine/petrinet/domain/ImporterTest.groovy b/application-engine/src/test/groovy/com/netgrif/application/engine/petrinet/domain/ImporterTest.groovy index 15e6138b78..44bbba0782 100644 --- a/application-engine/src/test/groovy/com/netgrif/application/engine/petrinet/domain/ImporterTest.groovy +++ b/application-engine/src/test/groovy/com/netgrif/application/engine/petrinet/domain/ImporterTest.groovy @@ -2,16 +2,20 @@ package com.netgrif.application.engine.petrinet.domain import com.netgrif.application.engine.TestHelper import com.netgrif.application.engine.importer.service.Importer +import com.netgrif.application.engine.objects.auth.domain.ActorTransformer import com.netgrif.application.engine.objects.petrinet.domain.PetriNet import com.netgrif.application.engine.objects.petrinet.domain.VersionType import com.netgrif.application.engine.objects.petrinet.domain.dataset.ChoiceField import com.netgrif.application.engine.objects.petrinet.domain.dataset.logic.FieldBehavior import com.netgrif.application.engine.petrinet.domain.roles.ProcessRoleRepository import com.netgrif.application.engine.objects.petrinet.domain.throwable.MissingPetriNetMetaDataException +import com.netgrif.application.engine.petrinet.params.ImportPetriNetParams import com.netgrif.application.engine.petrinet.service.interfaces.IPetriNetService import com.netgrif.application.engine.startup.ImportHelper import com.netgrif.application.engine.startup.runner.SuperCreatorRunner import com.netgrif.application.engine.objects.workflow.domain.Case +import com.netgrif.application.engine.workflow.params.CreateCaseParams +import com.netgrif.application.engine.workflow.params.TaskParams import com.netgrif.application.engine.workflow.service.interfaces.ITaskService import com.netgrif.application.engine.workflow.service.interfaces.IWorkflowService import org.junit.jupiter.api.BeforeEach @@ -82,11 +86,11 @@ class ImporterTest { @Test void importTest() { int beforeImportNet = processRoleRepository.count() - def netOptional = petriNetService.importPetriNet( - firstVersionResource.inputStream, - VersionType.MAJOR, - superCreator.loggedSuper - ) + def netOptional = petriNetService.importPetriNet(ImportPetriNetParams.with() + .xmlFile(firstVersionResource.inputStream) + .releaseType(VersionType.MAJOR) + .author(superCreator.getLoggedSuper()) + .build()) assert netOptional.getNet() != null assert processRoleRepository.count() == beforeImportNet + 2 int statusImportRole = processRoleRepository.count() @@ -168,11 +172,11 @@ class ImporterTest { } assert net.places.size() == 0 - def netOptional2 = petriNetService.importPetriNet( - secondVersionResource.inputStream, - VersionType.MAJOR, - superCreator.loggedSuper - ) + def netOptional2 = petriNetService.importPetriNet(ImportPetriNetParams.with() + .xmlFile(secondVersionResource.inputStream) + .releaseType(VersionType.MAJOR) + .author(superCreator.getLoggedSuper()) + .build()) assert processRoleRepository.count() == statusImportRole + 1 assert netOptional2.getNet() != null @@ -284,21 +288,39 @@ class ImporterTest { @Test void thisKeywordInDataEventsTest() { - PetriNet net = petriNetService.importPetriNet(new ClassPathResource("/this_kw_test.xml").getInputStream(), VersionType.MAJOR, superCreator.getLoggedSuper()).getNet() + PetriNet net = petriNetService.importPetriNet(ImportPetriNetParams.with() + .xmlFile(new ClassPathResource("/this_kw_test.xml").getInputStream()) + .releaseType(VersionType.MAJOR) + .author(superCreator.getLoggedSuper()) + .build()).getNet() assert net != null - Case testCase = workflowService.createCase(net.stringId, "Test case", "", superCreator.loggedSuper).getCase() - taskService.assignTask(testCase.getTasks().toList().get(0).getTask()) + Case testCase = workflowService.createCase(CreateCaseParams.with() + .petriNet(net) + .title("Test case") + .color("") + .loggedUser(superCreator.loggedSuper) + .build()).getCase() + taskService.assignTask(new TaskParams(testCase.getTasks().toList().get(0).getTask())) testCase = workflowService.findOne(testCase.getStringId()) assert testCase.getDataField("tester_text_field").getValue().equals("Hello world!") } @Test void initialBehaviorTest() { - PetriNet net = petriNetService.importPetriNet(new ClassPathResource("/initial_behavior.xml").getInputStream(), VersionType.MAJOR, superCreator.getLoggedSuper()).getNet() + PetriNet net = petriNetService.importPetriNet(ImportPetriNetParams.with() + .xmlFile(new ClassPathResource("/initial_behavior.xml").getInputStream()) + .releaseType(VersionType.MAJOR) + .author(superCreator.getLoggedSuper()) + .build()).getNet() assert net - Case testCase = workflowService.createCase(net.stringId, "Test case", "", superCreator.loggedSuper).getCase() + Case testCase = workflowService.createCase(CreateCaseParams.with() + .petriNet(net) + .title("Test case") + .color("") + .loggedUser(superCreator.loggedSuper) + .build()).getCase() assert testCase.dataSet.get(NUMBER_FIELD).behavior.get("1") == [FieldBehavior.FORBIDDEN] as Set assert testCase.dataSet.get(TEXT_FIELD).behavior.get("1") == [FieldBehavior.HIDDEN] as Set @@ -318,7 +340,11 @@ class ImporterTest { @Test void enumerationMultichoiceOptionsTest() throws IOException, MissingPetriNetMetaDataException { - PetriNet net = petriNetService.importPetriNet(new ClassPathResource("/enumeration_multichoice_options.xml").getInputStream(), VersionType.MAJOR, superCreator.getLoggedSuper()).getNet() + PetriNet net = petriNetService.importPetriNet(ImportPetriNetParams.with() + .xmlFile(new ClassPathResource("/enumeration_multichoice_options.xml").getInputStream()) + .releaseType(VersionType.MAJOR) + .author(superCreator.getLoggedSuper()) + .build()).getNet() assert net != null @@ -340,10 +366,11 @@ class ImporterTest { @Test void testDataGroupImportWithoutId() { - def netOutcome = petriNetService.importPetriNet( - new FileInputStream("src/test/resources/datagroup_no_id_test.xml"), - VersionType.MAJOR, - superCreator.loggedSuper) + def netOutcome = petriNetService.importPetriNet(ImportPetriNetParams.with() + .xmlFile(new FileInputStream("src/test/resources/datagroup_no_id_test.xml")) + .releaseType(VersionType.MAJOR) + .author(superCreator.getLoggedSuper()) + .build()) assert netOutcome.getNet() != null @@ -355,7 +382,11 @@ class ImporterTest { @Test void createTransitionNoLabel(){ - PetriNet net = petriNetService.importPetriNet(new FileInputStream("src/test/resources/importTest/NoLabel.xml"), VersionType.MAJOR, superCreator.getLoggedSuper()).getNet() + PetriNet net = petriNetService.importPetriNet(ImportPetriNetParams.with() + .xmlFile(new FileInputStream("src/test/resources/importTest/NoLabel.xml")) + .releaseType(VersionType.MAJOR) + .author(superCreator.getLoggedSuper()) + .build()).getNet() assert net PetriNet importNet = petriNetService.findByImportId(net.getImportId()).get() assert importNet diff --git a/application-engine/src/test/groovy/com/netgrif/application/engine/petrinet/domain/PetriNetTest.groovy b/application-engine/src/test/groovy/com/netgrif/application/engine/petrinet/domain/PetriNetTest.groovy index 19b9b76ec8..22896b8277 100644 --- a/application-engine/src/test/groovy/com/netgrif/application/engine/petrinet/domain/PetriNetTest.groovy +++ b/application-engine/src/test/groovy/com/netgrif/application/engine/petrinet/domain/PetriNetTest.groovy @@ -9,6 +9,7 @@ import com.netgrif.application.engine.objects.petrinet.domain.arcs.InhibitorArc import com.netgrif.application.engine.objects.petrinet.domain.arcs.ReadArc import com.netgrif.application.engine.objects.petrinet.domain.arcs.ResetArc import com.netgrif.application.engine.petrinet.domain.roles.ProcessRoleRepository +import com.netgrif.application.engine.petrinet.params.ImportPetriNetParams import com.netgrif.application.engine.petrinet.service.interfaces.IPetriNetService import com.netgrif.application.engine.petrinet.web.responsebodies.PetriNetReference import com.netgrif.application.engine.startup.runner.SuperCreatorRunner @@ -67,7 +68,11 @@ class PetriNetTest { void testClone() { int beforeImportNet = processRoleRepository.count() - def netOptional = petriNetService.importPetriNet(netResource.inputStream, VersionType.MAJOR, superCreator.loggedSuper) + def netOptional = petriNetService.importPetriNet(ImportPetriNetParams.with() + .xmlFile(netResource.inputStream) + .releaseType(VersionType.MAJOR) + .author(superCreator.getLoggedSuper()) + .build()) assert netOptional.getNet() != null diff --git a/application-engine/src/test/groovy/com/netgrif/application/engine/petrinet/domain/dataset/CaseFieldTest.groovy b/application-engine/src/test/groovy/com/netgrif/application/engine/petrinet/domain/dataset/CaseFieldTest.groovy index 21eaf0bf50..a9c2be28c2 100644 --- a/application-engine/src/test/groovy/com/netgrif/application/engine/petrinet/domain/dataset/CaseFieldTest.groovy +++ b/application-engine/src/test/groovy/com/netgrif/application/engine/petrinet/domain/dataset/CaseFieldTest.groovy @@ -3,6 +3,7 @@ package com.netgrif.application.engine.petrinet.domain.dataset import com.netgrif.application.engine.TestHelper import com.netgrif.application.engine.ipc.TaskApiTest import com.netgrif.application.engine.objects.petrinet.domain.VersionType +import com.netgrif.application.engine.petrinet.params.ImportPetriNetParams import com.netgrif.application.engine.petrinet.service.interfaces.IPetriNetService import com.netgrif.application.engine.startup.ImportHelper import com.netgrif.application.engine.startup.runner.SuperCreatorRunner @@ -60,7 +61,11 @@ class CaseFieldTest { @Test void testAllowedNets() { - def testNet = petriNetService.importPetriNet(stream(ALLOWED_NETS_NET_FILE), VersionType.MAJOR, superCreator.getLoggedSuper()) + def testNet = petriNetService.importPetriNet(ImportPetriNetParams.with() + .xmlFile(stream(ALLOWED_NETS_NET_FILE)) + .releaseType(VersionType.MAJOR) + .author(superCreator.getLoggedSuper()) + .build()) assert testNet.getNet() != null Case aCase = importHelper.createCase("Case 1", testNet.getNet()) @@ -114,7 +119,11 @@ class CaseFieldTest { @Test void testImmediateAllowedNets() { - def testNet = petriNetService.importPetriNet(stream(ALLOWED_NETS_NET_FILE), VersionType.MAJOR, superCreator.getLoggedSuper()) + def testNet = petriNetService.importPetriNet(ImportPetriNetParams.with() + .xmlFile(stream(ALLOWED_NETS_NET_FILE)) + .releaseType(VersionType.MAJOR) + .author(superCreator.getLoggedSuper()) + .build()) assert testNet.getNet() != null Case aCase = importHelper.createCase("Case 1", testNet.getNet()) @@ -168,10 +177,18 @@ class CaseFieldTest { @Test @Disabled("Please fix this test") void testChangeValueAction() { - def notAllowedNet = petriNetService.importPetriNet(stream(ALLOWED_NETS_NET_FILE), VersionType.MAJOR, superCreator.getLoggedSuper()) + def notAllowedNet = petriNetService.importPetriNet(ImportPetriNetParams.with() + .xmlFile(stream(ALLOWED_NETS_NET_FILE)) + .releaseType(VersionType.MAJOR) + .author(superCreator.getLoggedSuper()) + .build()) assert notAllowedNet.getNet() != null - def testNet = petriNetService.importPetriNet(stream(CHANGE_VALUE_NET_FILE), VersionType.MAJOR, superCreator.getLoggedSuper()) + def testNet = petriNetService.importPetriNet(ImportPetriNetParams.with() + .xmlFile(stream(CHANGE_VALUE_NET_FILE)) + .releaseType(VersionType.MAJOR) + .author(superCreator.getLoggedSuper()) + .build()) assert testNet.getNet() != null Case aCase = importHelper.createCase("Case 1", testNet.getNet()) diff --git a/application-engine/src/test/groovy/com/netgrif/application/engine/petrinet/domain/dataset/ChangeBehaviorTest.groovy b/application-engine/src/test/groovy/com/netgrif/application/engine/petrinet/domain/dataset/ChangeBehaviorTest.groovy index 5ac9497998..8ce11fe569 100644 --- a/application-engine/src/test/groovy/com/netgrif/application/engine/petrinet/domain/dataset/ChangeBehaviorTest.groovy +++ b/application-engine/src/test/groovy/com/netgrif/application/engine/petrinet/domain/dataset/ChangeBehaviorTest.groovy @@ -6,6 +6,7 @@ import com.netgrif.application.engine.objects.auth.domain.ActorTransformer import com.netgrif.application.engine.objects.petrinet.domain.PetriNet import com.netgrif.application.engine.objects.petrinet.domain.VersionType import com.netgrif.application.engine.objects.petrinet.domain.dataset.logic.FieldBehavior +import com.netgrif.application.engine.petrinet.params.ImportPetriNetParams import com.netgrif.application.engine.petrinet.service.interfaces.IPetriNetService import com.netgrif.application.engine.startup.ImportHelper import com.netgrif.application.engine.objects.workflow.domain.Case @@ -66,7 +67,11 @@ class ChangeBehaviorTest { @BeforeEach void initNet() { testHelper.truncateDbs() - net = petriNetService.importPetriNet(new FileInputStream(RESOURCE_PATH), VersionType.MAJOR, ActorTransformer.toLoggedUser(userService.getLoggedOrSystem())).getNet() + net = petriNetService.importPetriNet(ImportPetriNetParams.with() + .xmlFile(new FileInputStream(RESOURCE_PATH)) + .releaseType(VersionType.MAJOR) + .author(ActorTransformer.toLoggedUser(userService.getLoggedOrSystem())) + .build()).getNet() assert net != null } diff --git a/application-engine/src/test/groovy/com/netgrif/application/engine/petrinet/domain/dataset/ChangeCasePropertyTest.groovy b/application-engine/src/test/groovy/com/netgrif/application/engine/petrinet/domain/dataset/ChangeCasePropertyTest.groovy index 98b5a8a2d3..5ed8b48ceb 100644 --- a/application-engine/src/test/groovy/com/netgrif/application/engine/petrinet/domain/dataset/ChangeCasePropertyTest.groovy +++ b/application-engine/src/test/groovy/com/netgrif/application/engine/petrinet/domain/dataset/ChangeCasePropertyTest.groovy @@ -5,11 +5,13 @@ import com.netgrif.application.engine.auth.service.UserService import com.netgrif.application.engine.objects.auth.domain.ActorTransformer import com.netgrif.application.engine.objects.petrinet.domain.PetriNet import com.netgrif.application.engine.objects.petrinet.domain.VersionType +import com.netgrif.application.engine.petrinet.params.ImportPetriNetParams import com.netgrif.application.engine.petrinet.service.interfaces.IPetriNetService import com.netgrif.application.engine.startup.ImportHelper import com.netgrif.application.engine.objects.workflow.domain.Case import com.netgrif.application.engine.adapter.spring.workflow.domain.QTask import com.netgrif.application.engine.objects.workflow.domain.Task +import com.netgrif.application.engine.workflow.params.TaskParams 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 @@ -57,7 +59,11 @@ class ChangeCasePropertyTest { @BeforeEach void initNet() { testHelper.truncateDbs() - net = petriNetService.importPetriNet(new FileInputStream(RESOURCE_PATH), VersionType.MAJOR, ActorTransformer.toLoggedUser(userService.getLoggedOrSystem())).getNet() + net = petriNetService.importPetriNet(ImportPetriNetParams.with() + .xmlFile(new FileInputStream(RESOURCE_PATH)) + .releaseType(VersionType.MAJOR) + .author(ActorTransformer.toLoggedUser(userService.getLoggedOrSystem())) + .build()).getNet() assert net != null } @@ -70,8 +76,8 @@ class ChangeCasePropertyTest { Task testCaseTask = taskService.searchOne(QTask.task.caseTitle.eq(TEST_CASE_TITLE) & QTask.task.transitionId.eq(TEST_TRANSITION)) assert testCaseTask - taskService.assignTask(testCaseTask.getStringId()) - taskService.finishTask(testCaseTask.getStringId()) + taskService.assignTask(new TaskParams(testCaseTask)) + taskService.finishTask(new TaskParams(testCaseTask)) testCase = workflowService.findOne(testCase.getStringId()) testCaseTask = taskService.findOne(testCaseTask.getStringId()) @@ -89,14 +95,14 @@ class ChangeCasePropertyTest { Task testCaseTask = taskService.searchOne(QTask.task.caseTitle.eq(TEST_CASE_TITLE) & QTask.task.transitionId.eq(TEST_TRANSITION)) assert testCaseTask - taskService.assignTask(testCaseTask.getStringId()) + taskService.assignTask(new TaskParams(testCaseTask)) dataService.setData(testCaseTask.stringId, ImportHelper.populateDataset([ "bln": [ "value": "true", "type" : "boolean" ] ])) - taskService.finishTask(testCaseTask.getStringId()) + taskService.finishTask(new TaskParams(testCaseTask)) testCase = workflowService.findOne(testCase.getStringId()) testCaseTask = taskService.findOne(testCaseTask.getStringId()) diff --git a/application-engine/src/test/groovy/com/netgrif/application/engine/petrinet/domain/dataset/ChangeFieldValueInitTest.groovy b/application-engine/src/test/groovy/com/netgrif/application/engine/petrinet/domain/dataset/ChangeFieldValueInitTest.groovy index a7bdcb92fb..eda2544df1 100644 --- a/application-engine/src/test/groovy/com/netgrif/application/engine/petrinet/domain/dataset/ChangeFieldValueInitTest.groovy +++ b/application-engine/src/test/groovy/com/netgrif/application/engine/petrinet/domain/dataset/ChangeFieldValueInitTest.groovy @@ -2,6 +2,7 @@ package com.netgrif.application.engine.petrinet.domain.dataset import com.netgrif.application.engine.TestHelper import com.netgrif.application.engine.objects.petrinet.domain.VersionType +import com.netgrif.application.engine.petrinet.params.ImportPetriNetParams import com.netgrif.application.engine.petrinet.service.interfaces.IPetriNetService import com.netgrif.application.engine.startup.ImportHelper import com.netgrif.application.engine.startup.runner.SuperCreatorRunner @@ -9,6 +10,7 @@ import com.netgrif.application.engine.objects.workflow.domain.Case import com.netgrif.application.engine.adapter.spring.workflow.domain.QTask import com.netgrif.application.engine.objects.workflow.domain.Task import com.netgrif.application.engine.objects.workflow.domain.eventoutcomes.petrinetoutcomes.ImportPetriNetEventOutcome +import com.netgrif.application.engine.workflow.params.TaskParams import com.netgrif.application.engine.workflow.service.interfaces.ITaskService import com.netgrif.application.engine.workflow.service.interfaces.IWorkflowService import org.junit.jupiter.api.BeforeEach @@ -49,7 +51,11 @@ class ChangeFieldValueInitTest { @Test void testInitValues() { - ImportPetriNetEventOutcome optNet = petriNetService.importPetriNet(new FileInputStream("src/test/resources/petriNets/change_field_value_init.xml"), VersionType.MAJOR, superCreator.getLoggedSuper()); + ImportPetriNetEventOutcome optNet = petriNetService.importPetriNet(ImportPetriNetParams.with() + .xmlFile(new FileInputStream("src/test/resources/petriNets/change_field_value_init.xml")) + .releaseType(VersionType.MAJOR) + .author(superCreator.getLoggedSuper()) + .build()); Case useCase = importHelper.createCase("test", optNet.getNet()) assert useCase.dataSet["text_static"].value == "TEST VALUE" @@ -74,8 +80,8 @@ class ChangeFieldValueInitTest { Case execute(String trans, Case useCase) { Task task = taskService.searchOne(QTask.task.caseId.eq(useCase.getStringId()) & QTask.task.transitionId.eq(trans)) - taskService.assignTask(task.stringId) - taskService.finishTask(task.stringId) + taskService.assignTask(new TaskParams(task)) + taskService.finishTask(new TaskParams(task)) return reload(useCase) } diff --git a/application-engine/src/test/groovy/com/netgrif/application/engine/petrinet/domain/dataset/ChoiceFieldTest.groovy b/application-engine/src/test/groovy/com/netgrif/application/engine/petrinet/domain/dataset/ChoiceFieldTest.groovy index 066271a6f0..f7d8b9bcc3 100644 --- a/application-engine/src/test/groovy/com/netgrif/application/engine/petrinet/domain/dataset/ChoiceFieldTest.groovy +++ b/application-engine/src/test/groovy/com/netgrif/application/engine/petrinet/domain/dataset/ChoiceFieldTest.groovy @@ -5,6 +5,7 @@ import com.netgrif.application.engine.importer.service.Importer import com.netgrif.application.engine.ipc.TaskApiTest import com.netgrif.application.engine.objects.petrinet.domain.I18nString import com.netgrif.application.engine.objects.petrinet.domain.VersionType +import com.netgrif.application.engine.petrinet.params.ImportPetriNetParams import com.netgrif.application.engine.petrinet.service.interfaces.IPetriNetService import com.netgrif.application.engine.startup.ImportHelper import com.netgrif.application.engine.startup.runner.SuperCreatorRunner @@ -56,7 +57,11 @@ class ChoiceFieldTest { @Test void testChoices() { - def netOptional = petriNetService.importPetriNet(stream(LIMITS_NET_FILE), VersionType.MAJOR, superCreator.getLoggedSuper()) + def netOptional = petriNetService.importPetriNet(ImportPetriNetParams.with() + .xmlFile(stream(LIMITS_NET_FILE)) + .releaseType(VersionType.MAJOR) + .author(superCreator.getLoggedSuper()) + .build()) assert netOptional.getNet() != null def net = netOptional.getNet() diff --git a/application-engine/src/test/groovy/com/netgrif/application/engine/petrinet/domain/dataset/DynamicCaseNameTest.groovy b/application-engine/src/test/groovy/com/netgrif/application/engine/petrinet/domain/dataset/DynamicCaseNameTest.groovy index f48a81f611..8d64cee18d 100644 --- a/application-engine/src/test/groovy/com/netgrif/application/engine/petrinet/domain/dataset/DynamicCaseNameTest.groovy +++ b/application-engine/src/test/groovy/com/netgrif/application/engine/petrinet/domain/dataset/DynamicCaseNameTest.groovy @@ -2,10 +2,12 @@ package com.netgrif.application.engine.petrinet.domain.dataset import com.netgrif.application.engine.TestHelper import com.netgrif.application.engine.objects.petrinet.domain.VersionType +import com.netgrif.application.engine.petrinet.params.ImportPetriNetParams import com.netgrif.application.engine.petrinet.service.interfaces.IPetriNetService import com.netgrif.application.engine.startup.runner.SuperCreatorRunner import com.netgrif.application.engine.objects.workflow.domain.Case import com.netgrif.application.engine.objects.workflow.domain.eventoutcomes.petrinetoutcomes.ImportPetriNetEventOutcome +import com.netgrif.application.engine.workflow.params.CreateCaseParams import com.netgrif.application.engine.workflow.service.interfaces.IWorkflowService import org.junit.jupiter.api.BeforeEach import org.junit.jupiter.api.Test @@ -39,11 +41,25 @@ class DynamicCaseNameTest { @Test void testInitValues() { - ImportPetriNetEventOutcome optNet = petriNetService.importPetriNet(new FileInputStream("src/test/resources/petriNets/dynamic_case_name_test.xml"), VersionType.MAJOR, superCreator.getLoggedSuper()) - Case useCase = workflowService.createCase(optNet.getNet().stringId, null, "", superCreator.loggedSuper, Locale.forLanguageTag("sk-SK")).getCase() + ImportPetriNetEventOutcome optNet = petriNetService.importPetriNet(ImportPetriNetParams.with() + .xmlFile(new FileInputStream("src/test/resources/petriNets/dynamic_case_name_test.xml")) + .releaseType(VersionType.MAJOR) + .author(superCreator.getLoggedSuper()) + .build()) + Case useCase = workflowService.createCase(CreateCaseParams.with() + .petriNet(optNet.getNet()) + .color("") + .loggedUser(superCreator.loggedSuper) + .locale(Locale.forLanguageTag("sk-SK")) + .build()).getCase() assert useCase.title == "SK text value 6" - Case useCase2 = workflowService.createCase(optNet.getNet().stringId, null, "", superCreator.loggedSuper, Locale.ENGLISH).getCase() + Case useCase2 = workflowService.createCase(CreateCaseParams.with() + .petriNet(optNet.getNet()) + .color("") + .loggedUser(superCreator.loggedSuper) + .locale(Locale.ENGLISH) + .build()).getCase() assert useCase2.title == "EN text value 6" } } diff --git a/application-engine/src/test/groovy/com/netgrif/application/engine/petrinet/domain/dataset/DynamicChoicesTest.groovy b/application-engine/src/test/groovy/com/netgrif/application/engine/petrinet/domain/dataset/DynamicChoicesTest.groovy index a28c85311e..c622a741c5 100644 --- a/application-engine/src/test/groovy/com/netgrif/application/engine/petrinet/domain/dataset/DynamicChoicesTest.groovy +++ b/application-engine/src/test/groovy/com/netgrif/application/engine/petrinet/domain/dataset/DynamicChoicesTest.groovy @@ -2,6 +2,7 @@ package com.netgrif.application.engine.petrinet.domain.dataset import com.netgrif.application.engine.TestHelper import com.netgrif.application.engine.objects.petrinet.domain.VersionType +import com.netgrif.application.engine.petrinet.params.ImportPetriNetParams import com.netgrif.application.engine.petrinet.service.interfaces.IPetriNetService import com.netgrif.application.engine.startup.ImportHelper import com.netgrif.application.engine.startup.runner.SuperCreatorRunner @@ -50,7 +51,11 @@ class DynamicChoicesTest { @Test void testDynamicEnum() { - ImportPetriNetEventOutcome optNet = petriNetService.importPetriNet(new FileInputStream("src/test/resources/petriNets/dynamic_choices.xml"), VersionType.MAJOR, superCreator.getLoggedSuper()); + ImportPetriNetEventOutcome optNet = petriNetService.importPetriNet(ImportPetriNetParams.with() + .xmlFile(new FileInputStream("src/test/resources/petriNets/dynamic_choices.xml")) + .releaseType(VersionType.MAJOR) + .author(superCreator.getLoggedSuper()) + .build()); assert optNet.getNet() != null; def net = optNet.getNet() diff --git a/application-engine/src/test/groovy/com/netgrif/application/engine/petrinet/domain/dataset/DynamicDefaultValueTest.groovy b/application-engine/src/test/groovy/com/netgrif/application/engine/petrinet/domain/dataset/DynamicDefaultValueTest.groovy index dbb1e362ad..d18c3b1920 100644 --- a/application-engine/src/test/groovy/com/netgrif/application/engine/petrinet/domain/dataset/DynamicDefaultValueTest.groovy +++ b/application-engine/src/test/groovy/com/netgrif/application/engine/petrinet/domain/dataset/DynamicDefaultValueTest.groovy @@ -2,6 +2,7 @@ package com.netgrif.application.engine.petrinet.domain.dataset import com.netgrif.application.engine.TestHelper import com.netgrif.application.engine.objects.petrinet.domain.VersionType +import com.netgrif.application.engine.petrinet.params.ImportPetriNetParams import com.netgrif.application.engine.petrinet.service.interfaces.IPetriNetService import com.netgrif.application.engine.startup.ImportHelper import com.netgrif.application.engine.startup.runner.SuperCreatorRunner @@ -40,7 +41,11 @@ class DynamicDefaultValueTest { @Test void testInitValues() { - ImportPetriNetEventOutcome optNet = petriNetService.importPetriNet(new FileInputStream("src/test/resources/petriNets/dynamic_init.xml"), VersionType.MAJOR, superCreator.getLoggedSuper()); + ImportPetriNetEventOutcome optNet = petriNetService.importPetriNet(ImportPetriNetParams.with() + .xmlFile(new FileInputStream("src/test/resources/petriNets/dynamic_init.xml")) + .releaseType(VersionType.MAJOR) + .author(superCreator.getLoggedSuper()) + .build()); Case useCase = importHelper.createCase("test", optNet.getNet()) assert useCase.dataSet["text"].value == superCreator.superUser.name diff --git a/application-engine/src/test/groovy/com/netgrif/application/engine/petrinet/domain/dataset/DynamicEnumerationTest.groovy b/application-engine/src/test/groovy/com/netgrif/application/engine/petrinet/domain/dataset/DynamicEnumerationTest.groovy index 8eccd3493c..d8e4df8598 100644 --- a/application-engine/src/test/groovy/com/netgrif/application/engine/petrinet/domain/dataset/DynamicEnumerationTest.groovy +++ b/application-engine/src/test/groovy/com/netgrif/application/engine/petrinet/domain/dataset/DynamicEnumerationTest.groovy @@ -2,6 +2,7 @@ package com.netgrif.application.engine.petrinet.domain.dataset import com.netgrif.application.engine.TestHelper import com.netgrif.application.engine.objects.petrinet.domain.VersionType +import com.netgrif.application.engine.petrinet.params.ImportPetriNetParams import com.netgrif.application.engine.petrinet.service.interfaces.IPetriNetService import com.netgrif.application.engine.startup.ImportHelper import com.netgrif.application.engine.startup.runner.SuperCreatorRunner @@ -48,13 +49,17 @@ class DynamicEnumerationTest { private CaseRepository caseRepository; @BeforeEach - public void before() { + void before() { testHelper.truncateDbs(); } @Test void testDynamicEnum() { - ImportPetriNetEventOutcome optNet = petriNetService.importPetriNet(new FileInputStream("src/test/resources/test_autocomplete_dynamic.xml"), VersionType.MAJOR, superCreator.getLoggedSuper()); + ImportPetriNetEventOutcome optNet = petriNetService.importPetriNet(ImportPetriNetParams.with() + .xmlFile(new FileInputStream("src/test/resources/test_autocomplete_dynamic.xml")) + .releaseType(VersionType.MAJOR) + .author(superCreator.getLoggedSuper()) + .build()); assert optNet.getNet() != null; def net = optNet.getNet() diff --git a/application-engine/src/test/groovy/com/netgrif/application/engine/petrinet/domain/dataset/DynamicValidationPerformanceTest.groovy b/application-engine/src/test/groovy/com/netgrif/application/engine/petrinet/domain/dataset/DynamicValidationPerformanceTest.groovy index 9b72a7663a..374c24de03 100644 --- a/application-engine/src/test/groovy/com/netgrif/application/engine/petrinet/domain/dataset/DynamicValidationPerformanceTest.groovy +++ b/application-engine/src/test/groovy/com/netgrif/application/engine/petrinet/domain/dataset/DynamicValidationPerformanceTest.groovy @@ -2,6 +2,7 @@ package com.netgrif.application.engine.petrinet.domain.dataset import com.netgrif.application.engine.TestHelper import com.netgrif.application.engine.objects.petrinet.domain.VersionType +import com.netgrif.application.engine.petrinet.params.ImportPetriNetParams import com.netgrif.application.engine.petrinet.service.interfaces.IPetriNetService import com.netgrif.application.engine.startup.ImportHelper import com.netgrif.application.engine.startup.runner.SuperCreatorRunner @@ -61,8 +62,16 @@ class DynamicValidationPerformanceTest { @Test void testValidations() { - ImportPetriNetEventOutcome optNet1 = petriNetService.importPetriNet(new FileInputStream("src/test/resources/petriNets/dynamic_validations_performance_test.xml"), VersionType.MAJOR, superCreator.getLoggedSuper()) - ImportPetriNetEventOutcome optNet2 = petriNetService.importPetriNet(new FileInputStream("src/test/resources/petriNets/dynamic_validations_performance_test_comparison.xml"), VersionType.MAJOR, superCreator.getLoggedSuper()) + ImportPetriNetEventOutcome optNet1 = petriNetService.importPetriNet(ImportPetriNetParams.with() + .xmlFile(new FileInputStream("src/test/resources/petriNets/dynamic_validations_performance_test.xml")) + .releaseType(VersionType.MAJOR) + .author(superCreator.getLoggedSuper()) + .build()) + ImportPetriNetEventOutcome optNet2 = petriNetService.importPetriNet(ImportPetriNetParams.with() + .xmlFile(new FileInputStream("src/test/resources/petriNets/dynamic_validations_performance_test_comparison.xml")) + .releaseType(VersionType.MAJOR) + .author(superCreator.getLoggedSuper()) + .build()) def aCase1 = importHelper.createCase("Case 1", optNet1.getNet()) def aCase2 = importHelper.createCase("Case 2", optNet2.getNet()) diff --git a/application-engine/src/test/groovy/com/netgrif/application/engine/petrinet/domain/dataset/FileFieldTest.groovy b/application-engine/src/test/groovy/com/netgrif/application/engine/petrinet/domain/dataset/FileFieldTest.groovy index a4e6c1d3ff..f58166bbd6 100644 --- a/application-engine/src/test/groovy/com/netgrif/application/engine/petrinet/domain/dataset/FileFieldTest.groovy +++ b/application-engine/src/test/groovy/com/netgrif/application/engine/petrinet/domain/dataset/FileFieldTest.groovy @@ -17,10 +17,12 @@ import com.netgrif.application.engine.objects.auth.domain.enums.UserState import com.netgrif.application.engine.objects.petrinet.domain.PetriNet import com.netgrif.application.engine.objects.petrinet.domain.VersionType import com.netgrif.application.engine.objects.petrinet.domain.roles.ProcessRole +import com.netgrif.application.engine.petrinet.params.ImportPetriNetParams import com.netgrif.application.engine.petrinet.service.interfaces.IPetriNetService import com.netgrif.application.engine.startup.ImportHelper import com.netgrif.application.engine.startup.runner.SuperCreatorRunner import com.netgrif.application.engine.objects.workflow.domain.Case +import com.netgrif.application.engine.workflow.params.CreateCaseParams import com.netgrif.application.engine.workflow.service.interfaces.IWorkflowService import com.netgrif.application.engine.workflow.web.requestbodies.file.FileFieldRequest import io.minio.BucketExistsArgs @@ -144,7 +146,11 @@ class FileFieldTest { } PetriNet getNet() { - def netOptional = petriNetService.importPetriNet(new FileInputStream("src/test/resources/remoteFileField.xml"), VersionType.MAJOR, superCreator.getLoggedSuper()) + def netOptional = petriNetService.importPetriNet(ImportPetriNetParams.with() + .xmlFile(new FileInputStream("src/test/resources/remoteFileField.xml")) + .releaseType(VersionType.MAJOR) + .author(superCreator.getLoggedSuper()) + .build()) assert netOptional.getNet() != null return netOptional.getNet() } @@ -224,7 +230,12 @@ class FileFieldTest { PetriNet net = getNet() AbstractUser user = userService.findUserByUsername(UserConstants.ADMIN_USER_USERNAME, null).get() assert user != null - Case useCase = workflowService.createCase(net.getStringId(), "Test file from file list download", "black", ActorTransformer.toLoggedUser(user)).getCase() + Case useCase = workflowService.createCase(CreateCaseParams.with() + .petriNet(net) + .title("Test file from file list download") + .color("black") + .loggedUser(ActorTransformer.toLoggedUser(user)) + .build()).getCase() importHelper.assignTask(TASK_TITLE, useCase.getStringId(), ActorTransformer.toLoggedUser(user)) MockMultipartFile file diff --git a/application-engine/src/test/groovy/com/netgrif/application/engine/petrinet/domain/dataset/FileListFieldTest.groovy b/application-engine/src/test/groovy/com/netgrif/application/engine/petrinet/domain/dataset/FileListFieldTest.groovy index c015c2d380..3d00fb7b7d 100644 --- a/application-engine/src/test/groovy/com/netgrif/application/engine/petrinet/domain/dataset/FileListFieldTest.groovy +++ b/application-engine/src/test/groovy/com/netgrif/application/engine/petrinet/domain/dataset/FileListFieldTest.groovy @@ -18,9 +18,11 @@ import com.netgrif.application.engine.objects.petrinet.domain.PetriNet import com.netgrif.application.engine.objects.petrinet.domain.VersionType import com.netgrif.application.engine.objects.petrinet.domain.roles.ProcessRole import com.netgrif.application.engine.objects.workflow.domain.Case +import com.netgrif.application.engine.petrinet.params.ImportPetriNetParams import com.netgrif.application.engine.petrinet.service.interfaces.IPetriNetService import com.netgrif.application.engine.startup.ImportHelper import com.netgrif.application.engine.startup.runner.SuperCreatorRunner +import com.netgrif.application.engine.workflow.params.CreateCaseParams import com.netgrif.application.engine.workflow.service.interfaces.IWorkflowService import com.netgrif.application.engine.workflow.web.requestbodies.file.FileFieldRequest import io.minio.BucketExistsArgs @@ -213,7 +215,11 @@ class FileListFieldTest { } PetriNet getNet() { - def netOptional = petriNetService.importPetriNet(new FileInputStream("src/test/resources/remoteFileListField.xml"), VersionType.MAJOR, superCreator.getLoggedSuper()) + def netOptional = petriNetService.importPetriNet(ImportPetriNetParams.with() + .xmlFile(new FileInputStream("src/test/resources/remoteFileListField.xml")) + .releaseType(VersionType.MAJOR) + .author(superCreator.getLoggedSuper()) + .build()) assert netOptional.getNet() != null return netOptional.getNet() } @@ -222,7 +228,12 @@ class FileListFieldTest { PetriNet net = getNet() AbstractUser user = userService.findUserByUsername(UserConstants.ADMIN_USER_USERNAME, null).get() assert user != null - Case useCase = workflowService.createCase(net.getStringId(), "Test file from file list download", "black", ActorTransformer.toLoggedUser(user)).getCase() + Case useCase = workflowService.createCase(CreateCaseParams.with() + .petriNet(net) + .title("Test file from file list download") + .color("black") + .loggedUser(ActorTransformer.toLoggedUser(user)) + .build()).getCase() importHelper.assignTask(TASK_TITLE, useCase.getStringId(), ActorTransformer.toLoggedUser(user)) MockMultipartFile file diff --git a/application-engine/src/test/groovy/com/netgrif/application/engine/petrinet/domain/dataset/MapFieldTest.groovy b/application-engine/src/test/groovy/com/netgrif/application/engine/petrinet/domain/dataset/MapFieldTest.groovy index b9c0d6af68..3f49721ced 100644 --- a/application-engine/src/test/groovy/com/netgrif/application/engine/petrinet/domain/dataset/MapFieldTest.groovy +++ b/application-engine/src/test/groovy/com/netgrif/application/engine/petrinet/domain/dataset/MapFieldTest.groovy @@ -2,6 +2,7 @@ package com.netgrif.application.engine.petrinet.domain.dataset import com.netgrif.application.engine.TestHelper import com.netgrif.application.engine.objects.petrinet.domain.VersionType +import com.netgrif.application.engine.petrinet.params.ImportPetriNetParams import com.netgrif.application.engine.petrinet.service.interfaces.IPetriNetService import com.netgrif.application.engine.startup.ImportHelper import com.netgrif.application.engine.startup.runner.SuperCreatorRunner @@ -46,7 +47,11 @@ class MapFieldTest { @Test void testImport() { - def netOptional = petriNetService.importPetriNet(netResource.inputStream, VersionType.MAJOR, superCreator.loggedSuper) + def netOptional = petriNetService.importPetriNet(ImportPetriNetParams.with() + .xmlFile(netResource.inputStream) + .releaseType(VersionType.MAJOR) + .author(superCreator.getLoggedSuper()) + .build()) assert netOptional.getNet() != null def net = netOptional.getNet() @@ -70,7 +75,11 @@ class MapFieldTest { @Test void testValue() { - def netOptional = petriNetService.importPetriNet(netResource.inputStream, VersionType.MAJOR, superCreator.loggedSuper) + def netOptional = petriNetService.importPetriNet(ImportPetriNetParams.with() + .xmlFile(netResource.inputStream) + .releaseType(VersionType.MAJOR) + .author(superCreator.getLoggedSuper()) + .build()) assert netOptional.getNet() != null Case aCase = importHelper.createCase("Case", netOptional.getNet()) @@ -107,7 +116,11 @@ class MapFieldTest { @Test void testImportMultichoice() { - def netOptional = petriNetService.importPetriNet(netResource2.inputStream, VersionType.MAJOR, superCreator.loggedSuper) + def netOptional = petriNetService.importPetriNet(ImportPetriNetParams.with() + .xmlFile(netResource2.inputStream) + .releaseType(VersionType.MAJOR) + .author(superCreator.getLoggedSuper()) + .build()) assert netOptional.getNet() != null def net = netOptional.getNet() @@ -131,7 +144,11 @@ class MapFieldTest { @Test void testValueMultichoice() { - def netOptional = petriNetService.importPetriNet(netResource2.inputStream, VersionType.MAJOR, superCreator.loggedSuper) + def netOptional = petriNetService.importPetriNet(ImportPetriNetParams.with() + .xmlFile(netResource2.inputStream) + .releaseType(VersionType.MAJOR) + .author(superCreator.getLoggedSuper()) + .build()) assert netOptional.getNet() != null Case aCase = importHelper.createCase("Case", netOptional.getNet()) diff --git a/application-engine/src/test/groovy/com/netgrif/application/engine/petrinet/service/CachePetriNetServiceTest.groovy b/application-engine/src/test/groovy/com/netgrif/application/engine/petrinet/service/CachePetriNetServiceTest.groovy index 1c4a7d430a..9957e4072a 100644 --- a/application-engine/src/test/groovy/com/netgrif/application/engine/petrinet/service/CachePetriNetServiceTest.groovy +++ b/application-engine/src/test/groovy/com/netgrif/application/engine/petrinet/service/CachePetriNetServiceTest.groovy @@ -9,6 +9,7 @@ import com.netgrif.application.engine.configuration.properties.CacheConfiguratio import com.netgrif.application.engine.ipc.TaskApiTest import com.netgrif.application.engine.objects.petrinet.domain.PetriNet import com.netgrif.application.engine.objects.petrinet.domain.VersionType +import com.netgrif.application.engine.petrinet.params.ImportPetriNetParams import com.netgrif.application.engine.petrinet.service.interfaces.IPetriNetService import com.netgrif.application.engine.startup.ImportHelper import com.netgrif.application.engine.startup.runner.SuperCreatorRunner @@ -68,7 +69,11 @@ class CachePetriNetServiceTest { @Test void cacheTest() { assert cacheManager.getCache(cacheProperties.getPetriNetNewest()).get("processDeleteTest") == null - ImportPetriNetEventOutcome testNetOptional = petriNetService.importPetriNet(stream(NET_FILE), VersionType.MAJOR, superCreator.getLoggedSuper()) + ImportPetriNetEventOutcome testNetOptional = petriNetService.importPetriNet(ImportPetriNetParams.with() + .xmlFile(stream(NET_FILE)) + .releaseType(VersionType.MAJOR) + .author(superCreator.getLoggedSuper()) + .build()) assert testNetOptional.getNet() != null PetriNet testNet = testNetOptional.getNet() diff --git a/application-engine/src/test/groovy/com/netgrif/application/engine/petrinet/web/PetriNetControllerTest.groovy b/application-engine/src/test/groovy/com/netgrif/application/engine/petrinet/web/PetriNetControllerTest.groovy index d8e270522a..5477dcf487 100644 --- a/application-engine/src/test/groovy/com/netgrif/application/engine/petrinet/web/PetriNetControllerTest.groovy +++ b/application-engine/src/test/groovy/com/netgrif/application/engine/petrinet/web/PetriNetControllerTest.groovy @@ -11,6 +11,7 @@ import com.netgrif.application.engine.ipc.TaskApiTest import com.netgrif.application.engine.objects.petrinet.domain.PetriNet import com.netgrif.application.engine.objects.petrinet.domain.VersionType import com.netgrif.application.engine.objects.petrinet.domain.roles.ProcessRole +import com.netgrif.application.engine.petrinet.params.ImportPetriNetParams import com.netgrif.application.engine.petrinet.service.interfaces.IPetriNetService import com.netgrif.application.engine.startup.ImportHelper import com.netgrif.application.engine.startup.runner.SuperCreatorRunner @@ -82,7 +83,11 @@ class PetriNetControllerTest { void before() { testHelper.truncateDbs() - def net = petriNetService.importPetriNet(stream(NET_FILE), VersionType.MAJOR, superCreator.getLoggedSuper()) + def net = petriNetService.importPetriNet(ImportPetriNetParams.with() + .xmlFile(stream(NET_FILE)) + .releaseType(VersionType.MAJOR) + .author(superCreator.getLoggedSuper()) + .build()) assert net.getNet() != null this.net = net.getNet() diff --git a/application-engine/src/test/groovy/com/netgrif/application/engine/workflow/DataServiceTest.groovy b/application-engine/src/test/groovy/com/netgrif/application/engine/workflow/DataServiceTest.groovy index d00307f629..4da1826b08 100644 --- a/application-engine/src/test/groovy/com/netgrif/application/engine/workflow/DataServiceTest.groovy +++ b/application-engine/src/test/groovy/com/netgrif/application/engine/workflow/DataServiceTest.groovy @@ -8,6 +8,7 @@ import com.netgrif.application.engine.objects.petrinet.domain.I18nString import com.netgrif.application.engine.objects.petrinet.domain.PetriNet import com.netgrif.application.engine.objects.petrinet.domain.VersionType import com.netgrif.application.engine.objects.petrinet.domain.dataset.logic.ChangedFieldByFileFieldContainer +import com.netgrif.application.engine.petrinet.params.ImportPetriNetParams import com.netgrif.application.engine.petrinet.service.interfaces.IPetriNetService import com.netgrif.application.engine.startup.ImportHelper import com.netgrif.application.engine.startup.runner.SuperCreatorRunner @@ -61,18 +62,34 @@ class DataServiceTest { @BeforeEach void beforeAll() { testHelper.truncateDbs() - ImportPetriNetEventOutcome net = petriNetService.importPetriNet(new FileInputStream("src/test/resources/data_service_referenced.xml"), VersionType.MAJOR, superCreator.getLoggedSuper()) + ImportPetriNetEventOutcome net = petriNetService.importPetriNet(ImportPetriNetParams.with() + .xmlFile(new FileInputStream("src/test/resources/data_service_referenced.xml")) + .releaseType(VersionType.MAJOR) + .author(superCreator.getLoggedSuper()) + .build()) assert net.getNet() != null - net = petriNetService.importPetriNet(new FileInputStream("src/test/resources/data_service_taskref.xml"), VersionType.MAJOR, superCreator.getLoggedSuper()) + net = petriNetService.importPetriNet(ImportPetriNetParams.with() + .xmlFile(new FileInputStream("src/test/resources/data_service_taskref.xml")) + .releaseType(VersionType.MAJOR) + .author(superCreator.getLoggedSuper()) + .build()) assert net.getNet() != null this.net = net.getNet() - ImportPetriNetEventOutcome agreementNet = petriNetService.importPetriNet(new FileInputStream("src/test/resources/agreement.xml"), VersionType.MAJOR, superCreator.getLoggedSuper()) + ImportPetriNetEventOutcome agreementNet = petriNetService.importPetriNet(ImportPetriNetParams.with() + .xmlFile(new FileInputStream("src/test/resources/agreement.xml")) + .releaseType(VersionType.MAJOR) + .author(superCreator.getLoggedSuper()) + .build()) assert agreementNet.getNet() != null this.agreementNet = agreementNet.getNet() - ImportPetriNetEventOutcome netoutcome = petriNetService.importPetriNet(new FileInputStream("src/test/resources/test_setData.xml"), VersionType.MAJOR, superCreator.getLoggedSuper()); + ImportPetriNetEventOutcome netoutcome = petriNetService.importPetriNet(ImportPetriNetParams.with() + .xmlFile(new FileInputStream("src/test/resources/test_setData.xml")) + .releaseType(VersionType.MAJOR) + .author(superCreator.getLoggedSuper()) + .build()); assert netoutcome.getNet() != null; this.setDataNet = netoutcome.getNet(); } diff --git a/application-engine/src/test/groovy/com/netgrif/application/engine/workflow/NewInitTest.groovy b/application-engine/src/test/groovy/com/netgrif/application/engine/workflow/NewInitTest.groovy index 3e7f28bd4d..2de0e7f2ae 100644 --- a/application-engine/src/test/groovy/com/netgrif/application/engine/workflow/NewInitTest.groovy +++ b/application-engine/src/test/groovy/com/netgrif/application/engine/workflow/NewInitTest.groovy @@ -6,9 +6,11 @@ import com.netgrif.application.engine.objects.petrinet.domain.I18nString import com.netgrif.application.engine.objects.petrinet.domain.VersionType import com.netgrif.application.engine.objects.petrinet.domain.dataset.FileListFieldValue import com.netgrif.application.engine.objects.petrinet.domain.throwable.MissingPetriNetMetaDataException +import com.netgrif.application.engine.petrinet.params.ImportPetriNetParams import com.netgrif.application.engine.petrinet.service.interfaces.IPetriNetService import com.netgrif.application.engine.startup.runner.SuperCreatorRunner import com.netgrif.application.engine.objects.workflow.domain.Case +import com.netgrif.application.engine.workflow.params.CreateCaseParams import com.netgrif.application.engine.workflow.service.interfaces.IWorkflowService import org.junit.jupiter.api.BeforeEach import org.junit.jupiter.api.Test @@ -44,8 +46,17 @@ class NewInitTest { @Test void newInitTest() throws IOException, MissingIconKeyException, MissingPetriNetMetaDataException { - petriNetService.importPetriNet(new FileInputStream("src/test/resources/petriNets/nae_1276_Init_value_as_choice.xml"), VersionType.MAJOR, superCreator.getLoggedSuper()) - Case initTestCase = workflowService.createCase(petriNetService.getNewestVersionByIdentifier("new_init_test").stringId, "New init test", "", superCreator.getLoggedSuper()).getCase() + petriNetService.importPetriNet(ImportPetriNetParams.with() + .xmlFile(new FileInputStream("src/test/resources/petriNets/nae_1276_Init_value_as_choice.xml")) + .releaseType(VersionType.MAJOR) + .author(superCreator.getLoggedSuper()) + .build()) + Case initTestCase = workflowService.createCase(CreateCaseParams.with() + .petriNet(petriNetService.getNewestVersionByIdentifier("new_init_test")) + .title("New init test") + .color("") + .loggedUser(superCreator.loggedSuper) + .build()).getCase() assert (initTestCase.dataSet["new_init_multichoice"].value as List).stream().any { it.defaultValue == "Bob" } assert (initTestCase.dataSet["new_init_multichoice"].value as List).stream().any { it.defaultValue == "Alice" } assert (initTestCase.dataSet["old_init_multichoice"].value as List).stream().any { it.defaultValue == "Bob" } diff --git a/application-engine/src/test/groovy/com/netgrif/application/engine/workflow/SetDataOnButtonTest.groovy b/application-engine/src/test/groovy/com/netgrif/application/engine/workflow/SetDataOnButtonTest.groovy index cb01b2d098..e9ce551b98 100644 --- a/application-engine/src/test/groovy/com/netgrif/application/engine/workflow/SetDataOnButtonTest.groovy +++ b/application-engine/src/test/groovy/com/netgrif/application/engine/workflow/SetDataOnButtonTest.groovy @@ -5,11 +5,13 @@ import com.netgrif.application.engine.auth.service.UserService import com.netgrif.application.engine.objects.auth.domain.ActorTransformer import com.netgrif.application.engine.objects.petrinet.domain.PetriNet import com.netgrif.application.engine.objects.petrinet.domain.VersionType +import com.netgrif.application.engine.petrinet.params.ImportPetriNetParams import com.netgrif.application.engine.petrinet.service.interfaces.IPetriNetService import com.netgrif.application.engine.startup.ImportHelper import com.netgrif.application.engine.objects.workflow.domain.Case import com.netgrif.application.engine.adapter.spring.workflow.domain.QTask import com.netgrif.application.engine.objects.workflow.domain.Task +import com.netgrif.application.engine.workflow.params.TaskParams 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 @@ -67,7 +69,11 @@ class SetDataOnButtonTest { @BeforeEach void initNet() { testHelper.truncateDbs() - net = petriNetService.importPetriNet(new FileInputStream(RESOURCE_PATH), VersionType.MAJOR, ActorTransformer.toLoggedUser(userService.getLoggedOrSystem())).getNet() + net = petriNetService.importPetriNet(ImportPetriNetParams.with() + .xmlFile(new FileInputStream(RESOURCE_PATH)) + .releaseType(VersionType.MAJOR) + .author(ActorTransformer.toLoggedUser(userService.getLoggedOrSystem())) + .build()).getNet() assert net != null } @@ -83,8 +89,8 @@ class SetDataOnButtonTest { Task parentTask = taskService.searchOne(QTask.task.caseTitle.eq(PARENT_CASE) & QTask.task.transitionId.eq(TEST_TRANSITION)) assert parentTask != null - taskService.assignTask(parentTask.getStringId()) - taskService.finishTask(parentTask.getStringId()) + taskService.assignTask(new TaskParams(parentTask)) + taskService.finishTask(new TaskParams(parentTask)) childCase = workflowService.findOne(childCase.getStringId()) diff --git a/application-engine/src/test/groovy/com/netgrif/application/engine/workflow/TaskRefInitTest.groovy b/application-engine/src/test/groovy/com/netgrif/application/engine/workflow/TaskRefInitTest.groovy index 6e9089fa89..dfc6b443de 100644 --- a/application-engine/src/test/groovy/com/netgrif/application/engine/workflow/TaskRefInitTest.groovy +++ b/application-engine/src/test/groovy/com/netgrif/application/engine/workflow/TaskRefInitTest.groovy @@ -5,6 +5,7 @@ import com.netgrif.application.engine.auth.service.UserService import com.netgrif.application.engine.objects.auth.domain.ActorTransformer import com.netgrif.application.engine.objects.petrinet.domain.PetriNet import com.netgrif.application.engine.objects.petrinet.domain.VersionType +import com.netgrif.application.engine.petrinet.params.ImportPetriNetParams import com.netgrif.application.engine.petrinet.service.interfaces.IPetriNetService import com.netgrif.application.engine.startup.ImportHelper import com.netgrif.application.engine.objects.workflow.domain.Case @@ -45,8 +46,16 @@ class TaskRefInitTest { @BeforeEach void initNet() { testHelper.truncateDbs() - net = petriNetService.importPetriNet(new FileInputStream("src/test/resources/taskref_init.xml"), VersionType.MAJOR, ActorTransformer.toLoggedUser(userService.getLoggedOrSystem())).getNet() - autoTrigger = petriNetService.importPetriNet(new FileInputStream("src/test/resources/autotrigger_taskref.xml"), VersionType.MAJOR, ActorTransformer.toLoggedUser(userService.getLoggedOrSystem())).getNet() + net = petriNetService.importPetriNet(ImportPetriNetParams.with() + .xmlFile(new FileInputStream("src/test/resources/taskref_init.xml")) + .releaseType(VersionType.MAJOR) + .author(ActorTransformer.toLoggedUser(userService.getLoggedOrSystem())) + .build()).getNet() + autoTrigger = petriNetService.importPetriNet(ImportPetriNetParams.with() + .xmlFile(new FileInputStream("src/test/resources/taskref_init.xml")) + .releaseType(VersionType.MAJOR) + .author(ActorTransformer.toLoggedUser(userService.getLoggedOrSystem())) + .build()).getNet() assert net != null } diff --git a/application-engine/src/test/groovy/com/netgrif/application/engine/workflow/TaskRefPropagationTest.groovy b/application-engine/src/test/groovy/com/netgrif/application/engine/workflow/TaskRefPropagationTest.groovy index 95a0e753ff..f039286f70 100644 --- a/application-engine/src/test/groovy/com/netgrif/application/engine/workflow/TaskRefPropagationTest.groovy +++ b/application-engine/src/test/groovy/com/netgrif/application/engine/workflow/TaskRefPropagationTest.groovy @@ -3,6 +3,7 @@ package com.netgrif.application.engine.workflow import com.netgrif.application.engine.objects.petrinet.domain.DataGroup import com.netgrif.application.engine.objects.petrinet.domain.PetriNet import com.netgrif.application.engine.objects.petrinet.domain.VersionType +import com.netgrif.application.engine.petrinet.params.ImportPetriNetParams import com.netgrif.application.engine.petrinet.service.interfaces.IPetriNetService import com.netgrif.application.engine.startup.ImportHelper import com.netgrif.application.engine.startup.runner.SuperCreatorRunner @@ -47,8 +48,16 @@ class TaskRefPropagationTest { @BeforeEach void beforeAll() { - def parent = petriNetService.importPetriNet(new FileInputStream("src/test/resources/taskRef_propagation_test_parent.xml"), VersionType.MAJOR, superCreator.getLoggedSuper()) - def child = petriNetService.importPetriNet(new FileInputStream("src/test/resources/taskRef_propagation_test_child.xml"), VersionType.MAJOR, superCreator.getLoggedSuper()) + def parent = petriNetService.importPetriNet(ImportPetriNetParams.with() + .xmlFile(new FileInputStream("src/test/resources/taskRef_propagation_test_parent.xml")) + .releaseType(VersionType.MAJOR) + .author(superCreator.getLoggedSuper()) + .build()) + def child = petriNetService.importPetriNet(ImportPetriNetParams.with() + .xmlFile(new FileInputStream("src/test/resources/taskRef_propagation_test_child.xml")) + .releaseType(VersionType.MAJOR) + .author(superCreator.getLoggedSuper()) + .build()) assert parent.getNet() != null assert child.getNet() != null diff --git a/application-engine/src/test/groovy/com/netgrif/application/engine/workflow/UserRefsTest.groovy b/application-engine/src/test/groovy/com/netgrif/application/engine/workflow/UserRefsTest.groovy index 6f6b6aa44c..9f25a00c3a 100644 --- a/application-engine/src/test/groovy/com/netgrif/application/engine/workflow/UserRefsTest.groovy +++ b/application-engine/src/test/groovy/com/netgrif/application/engine/workflow/UserRefsTest.groovy @@ -5,6 +5,7 @@ import com.netgrif.application.engine.auth.service.UserService import com.netgrif.application.engine.elastic.service.interfaces.IElasticCaseService import com.netgrif.application.engine.objects.auth.domain.ActorTransformer import com.netgrif.application.engine.objects.petrinet.domain.VersionType +import com.netgrif.application.engine.petrinet.params.ImportPetriNetParams import com.netgrif.application.engine.petrinet.service.interfaces.IPetriNetService import com.netgrif.application.engine.startup.ImportHelper import com.netgrif.application.engine.objects.workflow.domain.Case @@ -55,7 +56,11 @@ class UserRefsTest { @BeforeEach void before() { helper.truncateDbs() - def net = petriNetService.importPetriNet(new FileInputStream("src/test/resources/userrefs_test.xml"), VersionType.MAJOR, ActorTransformer.toLoggedUser(userService.getLoggedOrSystem())).getNet() + def net = petriNetService.importPetriNet(ImportPetriNetParams.with() + .xmlFile(new FileInputStream("src/test/resources/userrefs_test.xml")) + .releaseType(VersionType.MAJOR) + .author(ActorTransformer.toLoggedUser(userService.getLoggedOrSystem())) + .build()).getNet() assert net netId = net.getStringId() def userEmails = ["super@netgrif.com", "engine@netgrif.com"] diff --git a/application-engine/src/test/groovy/com/netgrif/application/engine/workflow/WorkflowServiceTest.groovy b/application-engine/src/test/groovy/com/netgrif/application/engine/workflow/WorkflowServiceTest.groovy index c009207af1..c0444c2cff 100644 --- a/application-engine/src/test/groovy/com/netgrif/application/engine/workflow/WorkflowServiceTest.groovy +++ b/application-engine/src/test/groovy/com/netgrif/application/engine/workflow/WorkflowServiceTest.groovy @@ -3,10 +3,12 @@ package com.netgrif.application.engine.workflow import com.netgrif.application.engine.TestHelper import com.netgrif.application.engine.ipc.TaskApiTest import com.netgrif.application.engine.objects.petrinet.domain.VersionType +import com.netgrif.application.engine.petrinet.params.ImportPetriNetParams import com.netgrif.application.engine.petrinet.service.interfaces.IPetriNetService import com.netgrif.application.engine.startup.ImportHelper import com.netgrif.application.engine.startup.runner.SuperCreatorRunner import com.netgrif.application.engine.objects.workflow.domain.Case +import com.netgrif.application.engine.workflow.params.CreateCaseParams import com.netgrif.application.engine.workflow.service.interfaces.IWorkflowService import org.junit.jupiter.api.BeforeEach import org.junit.jupiter.api.Test @@ -52,7 +54,11 @@ class WorkflowServiceTest { @Test void testFindOneImmediateData() { - def testNet = petriNetService.importPetriNet(stream(NET_FILE), VersionType.MAJOR, superCreator.getLoggedSuper()) + def testNet = petriNetService.importPetriNet(ImportPetriNetParams.with() + .xmlFile(stream(NET_FILE)) + .releaseType(VersionType.MAJOR) + .author(superCreator.getLoggedSuper()) + .build()) assert testNet.getNet() != null Case aCase = importHelper.createCase("Case 1", testNet.getNet()) @@ -66,11 +72,20 @@ class WorkflowServiceTest { @Test void testFirstTransitionAuto() { - def testNet = petriNetService.importPetriNet(stream(FIRST_AUTO_NET_FILE), VersionType.MAJOR, superCreator.getLoggedSuper()).getNet() + def testNet = petriNetService.importPetriNet(ImportPetriNetParams.with() + .xmlFile(stream(FIRST_AUTO_NET_FILE)) + .releaseType(VersionType.MAJOR) + .author(superCreator.getLoggedSuper()) + .build()).getNet() assert testNet def net = testNet - Case aCase = workflowService.createCase(net.stringId, "autoErr", "red", superCreator.getLoggedSuper()).getCase() + Case aCase = workflowService.createCase(CreateCaseParams.with() + .petriNet(net) + .title("autoErr") + .color("red") + .loggedUser(superCreator.loggedSuper) + .build()).getCase() importHelper.assignTask("Manual", aCase.getStringId(), superCreator.getLoggedSuper()) importHelper.finishTask("Manual", aCase.getStringId(), superCreator.getLoggedSuper()) @@ -80,9 +95,18 @@ class WorkflowServiceTest { @Test void testSecondTransitionAuto() { - def net = petriNetService.importPetriNet(stream(SECOND_AUTO_NET_FILE), VersionType.MAJOR, superCreator.getLoggedSuper()).getNet() - - Case aCase = workflowService.createCase(net.stringId, "autoErr", "red", superCreator.getLoggedSuper()).getCase() + def net = petriNetService.importPetriNet(ImportPetriNetParams.with() + .xmlFile(stream(SECOND_AUTO_NET_FILE)) + .releaseType(VersionType.MAJOR) + .author(superCreator.getLoggedSuper()) + .build()).getNet() + + Case aCase = workflowService.createCase(CreateCaseParams.with() + .petriNet(net) + .title("autoErr") + .color("red") + .loggedUser(superCreator.loggedSuper) + .build()).getCase() importHelper.assignTask("Manual", aCase.getStringId(), superCreator.getLoggedSuper()) importHelper.finishTask("Manual", aCase.getStringId(), superCreator.getLoggedSuper()) @@ -96,14 +120,26 @@ class WorkflowServiceTest { @Test void createCaseWithLocale() { - def testNet = petriNetService.importPetriNet(stream(CASE_LOCALE_NET_FILE), VersionType.MAJOR, superCreator.getLoggedSuper()) + def testNet = petriNetService.importPetriNet(ImportPetriNetParams.with() + .xmlFile(stream(CASE_LOCALE_NET_FILE)) + .releaseType(VersionType.MAJOR) + .author(superCreator.getLoggedSuper()) + .build()) assert testNet.getNet() != null def net = testNet.getNet() - Case aCase = workflowService.createCase(net.stringId, null, null, superCreator.getLoggedSuper(), new Locale('sk')).getCase() + Case aCase = workflowService.createCase(CreateCaseParams.with() + .petriNet(net) + .loggedUser(superCreator.loggedSuper) + .locale(new Locale('sk')) + .build()).getCase() assert aCase.title.equals("Slovenský preklad") - Case enCase = workflowService.createCase(net.stringId, null, null, superCreator.getLoggedSuper(), new Locale('en')).getCase() + Case enCase = workflowService.createCase(CreateCaseParams.with() + .petriNet(net) + .loggedUser(superCreator.loggedSuper) + .locale(new Locale('en')) + .build()).getCase() assert enCase.title.equals("English translation") } } diff --git a/application-engine/src/test/resources/change_caseref_value_action_test.xml b/application-engine/src/test/resources/change_caseref_value_action_test.xml index cf908b29fe..1010587824 100644 --- a/application-engine/src/test/resources/change_caseref_value_action_test.xml +++ b/application-engine/src/test/resources/change_caseref_value_action_test.xml @@ -29,8 +29,7 @@ caseref: f.caseref; - def net = petriNetService.getNewestVersionByIdentifier("change_value"); - def newCase = workflowService.createCase(net.stringId, "", "", userService.transformToLoggedUser(userService.getLoggedOrSystem())).getACase() + def newCase = createCase("change_value") def newValue = new ArrayList(caseref.value) newValue.add(newCase) change caseref value {return newValue} @@ -43,8 +42,7 @@ caseref: f.caseref; - def net = petriNetService.getNewestVersionByIdentifier("test"); - def newCase = workflowService.createCase(net.stringId, "", "", userService.transformToLoggedUser(userService.getLoggedOrSystem())).getACase() + def newCase = createCase("test") def newValue = new ArrayList(caseref.value) newValue.add(newCase) try { From b97f5a780e293ab4329a29c13e9347f7f3352661 Mon Sep 17 00:00:00 2001 From: chvostek Date: Fri, 31 Oct 2025 11:37:35 +0100 Subject: [PATCH 35/55] [NAE-2235] Improve Efficiency of Database Reads and Saves - fixes according to tests - fix tests --- .../logic/action/ActionDelegate.groovy | 8 +++ .../export/service/ExportServiceTest.groovy | 2 +- .../petrinet/domain/PetriNetTest.groovy | 60 +++++++++++++++---- .../engine/workflow/TaskRefInitTest.groovy | 2 +- .../engine/objects/workflow/domain/Case.java | 29 +++++---- 5 files changed, 77 insertions(+), 24 deletions(-) diff --git a/application-engine/src/main/groovy/com/netgrif/application/engine/petrinet/domain/dataset/logic/action/ActionDelegate.groovy b/application-engine/src/main/groovy/com/netgrif/application/engine/petrinet/domain/dataset/logic/action/ActionDelegate.groovy index 8b3145b129..808e9d7ad5 100644 --- a/application-engine/src/main/groovy/com/netgrif/application/engine/petrinet/domain/dataset/logic/action/ActionDelegate.groovy +++ b/application-engine/src/main/groovy/com/netgrif/application/engine/petrinet/domain/dataset/logic/action/ActionDelegate.groovy @@ -971,6 +971,14 @@ class ActionDelegate { return outcome.getCase() } + Case deleteCase(Case useCase) { + return workflowService.deleteCase(new DeleteCaseParams(useCase)).case + } + + Case deleteCase(String caseId) { + return workflowService.deleteCase(new DeleteCaseParams(caseId)).case + } + Task assignTask(String transitionId, Case aCase = useCase, AbstractUser user = userService.loggedOrSystem, Map params = [:]) { String taskId = getTaskId(transitionId, aCase) AssignTaskEventOutcome outcome = taskService.assignTask(TaskParams.with() diff --git a/application-engine/src/test/groovy/com/netgrif/application/engine/export/service/ExportServiceTest.groovy b/application-engine/src/test/groovy/com/netgrif/application/engine/export/service/ExportServiceTest.groovy index 4cf8aa191c..df5f92fbb5 100644 --- a/application-engine/src/test/groovy/com/netgrif/application/engine/export/service/ExportServiceTest.groovy +++ b/application-engine/src/test/groovy/com/netgrif/application/engine/export/service/ExportServiceTest.groovy @@ -87,7 +87,7 @@ class ExportServiceTest { assert (headerSplit.contains("immediate_multichoice") && headerSplit.contains("immediate_number") && !headerSplit.contains("text")) - taskService.cancelTask(ActorTransformer.toLoggedUser(userService.getLoggedOrSystem()), exportTask) + taskService.cancelTask(new TaskParams(exportTask, ActorTransformer.toLoggedUser(userService.getLoggedOrSystem()))) taskService.cancelTask(new TaskParams(exportTask, ActorTransformer.toLoggedUser(userService.getLoggedOrSystem()))) } diff --git a/application-engine/src/test/groovy/com/netgrif/application/engine/petrinet/domain/PetriNetTest.groovy b/application-engine/src/test/groovy/com/netgrif/application/engine/petrinet/domain/PetriNetTest.groovy index 22896b8277..1f405b2c7c 100644 --- a/application-engine/src/test/groovy/com/netgrif/application/engine/petrinet/domain/PetriNetTest.groovy +++ b/application-engine/src/test/groovy/com/netgrif/application/engine/petrinet/domain/PetriNetTest.groovy @@ -93,13 +93,25 @@ class PetriNetTest { @Test void testVersioning() { - def netOptional = petriNetService.importPetriNet(netResource.inputStream, VersionType.MAJOR, superCreator.loggedSuper) + def netOptional = petriNetService.importPetriNet(ImportPetriNetParams.with() + .xmlFile(netResource.inputStream) + .releaseType(VersionType.MAJOR) + .author(superCreator.getLoggedSuper()) + .build()) assert netOptional.getNet() != null - def netOptional2 = petriNetService.importPetriNet(netResource.inputStream, VersionType.MAJOR, superCreator.loggedSuper) + def netOptional2 = petriNetService.importPetriNet(ImportPetriNetParams.with() + .xmlFile(netResource.inputStream) + .releaseType(VersionType.MAJOR) + .author(superCreator.getLoggedSuper()) + .build()) assert netOptional2.getNet() != null - def netOptional3 = petriNetService.importPetriNet(netResource2.inputStream, VersionType.MAJOR, superCreator.loggedSuper) + def netOptional3 = petriNetService.importPetriNet(ImportPetriNetParams.with() + .xmlFile(netResource2.inputStream) + .releaseType(VersionType.MAJOR) + .author(superCreator.getLoggedSuper()) + .build()) assert netOptional3.getNet() != null Page nets = petriNetService.getReferencesByVersion(null, superCreator.loggedSuper, Locale.UK, Pageable.unpaged()) @@ -110,21 +122,41 @@ class PetriNetTest { @Test void testVersion() { - def zeroImport = petriNetService.importPetriNet(netResource3.inputStream, VersionType.PATCH, superCreator.loggedSuper) + def zeroImport = petriNetService.importPetriNet(ImportPetriNetParams.with() + .xmlFile(netResource3.inputStream) + .releaseType(VersionType.PATCH) + .author(superCreator.getLoggedSuper()) + .build()) assert zeroImport.getNet() != null assert zeroImport.getNet().version.toString() == "0.0.1" - def firstImport = petriNetService.importPetriNet(netResource.inputStream, VersionType.MAJOR, superCreator.loggedSuper) + def firstImport = petriNetService.importPetriNet(ImportPetriNetParams.with() + .xmlFile(netResource.inputStream) + .releaseType(VersionType.MAJOR) + .author(superCreator.getLoggedSuper()) + .build()) assert firstImport.getNet() != null assert firstImport.getNet().version.toString() == "1.0.0" - def secondImport = petriNetService.importPetriNet(netResource.inputStream, VersionType.MINOR, superCreator.loggedSuper) + def secondImport = petriNetService.importPetriNet(ImportPetriNetParams.with() + .xmlFile(netResource.inputStream) + .releaseType(VersionType.MINOR) + .author(superCreator.getLoggedSuper()) + .build()) assert secondImport.getNet().version.toString() == "1.1.0" - def thirdImport = petriNetService.importPetriNet(netResource.inputStream, VersionType.PATCH, superCreator.loggedSuper) + def thirdImport = petriNetService.importPetriNet(ImportPetriNetParams.with() + .xmlFile(netResource.inputStream) + .releaseType(VersionType.PATCH) + .author(superCreator.getLoggedSuper()) + .build()) assert thirdImport.getNet().version.toString() == "1.1.1" - def lastImport = petriNetService.importPetriNet(netResource4.inputStream, VersionType.PATCH, superCreator.loggedSuper) + def lastImport = petriNetService.importPetriNet(ImportPetriNetParams.with() + .xmlFile(netResource4.inputStream) + .releaseType(VersionType.PATCH) + .author(superCreator.getLoggedSuper()) + .build()) assert lastImport.getNet().version.toString() == "3.1.1" Page nets = petriNetService.getByIdentifier(zeroImport.getNet().identifier, Pageable.unpaged()) @@ -134,12 +166,20 @@ class PetriNetTest { @Test void testVersioningConflicts() { - def zeroImport = petriNetService.importPetriNet(netResource3.inputStream, VersionType.PATCH, superCreator.loggedSuper) + def zeroImport = petriNetService.importPetriNet(ImportPetriNetParams.with() + .xmlFile(netResource3.inputStream) + .releaseType(VersionType.PATCH) + .author(superCreator.getLoggedSuper()) + .build()) assert zeroImport.getNet() != null assert zeroImport.getNet().version.toString() == "0.0.1" try { - petriNetService.importPetriNet(netResource3.inputStream, VersionType.MAJOR, superCreator.loggedSuper) + petriNetService.importPetriNet(ImportPetriNetParams.with() + .xmlFile(netResource3.inputStream) + .releaseType(VersionType.MAJOR) + .author(superCreator.getLoggedSuper()) + .build()) } catch (Exception e) { assert e.getMessage() == "Provided Petri net version is already present in the system" } diff --git a/application-engine/src/test/groovy/com/netgrif/application/engine/workflow/TaskRefInitTest.groovy b/application-engine/src/test/groovy/com/netgrif/application/engine/workflow/TaskRefInitTest.groovy index dfc6b443de..1ece7803a2 100644 --- a/application-engine/src/test/groovy/com/netgrif/application/engine/workflow/TaskRefInitTest.groovy +++ b/application-engine/src/test/groovy/com/netgrif/application/engine/workflow/TaskRefInitTest.groovy @@ -52,7 +52,7 @@ class TaskRefInitTest { .author(ActorTransformer.toLoggedUser(userService.getLoggedOrSystem())) .build()).getNet() autoTrigger = petriNetService.importPetriNet(ImportPetriNetParams.with() - .xmlFile(new FileInputStream("src/test/resources/taskref_init.xml")) + .xmlFile(new FileInputStream("src/test/resources/autotrigger_taskref.xml")) .releaseType(VersionType.MAJOR) .author(ActorTransformer.toLoggedUser(userService.getLoggedOrSystem())) .build()).getNet() diff --git a/nae-object-library/src/main/java/com/netgrif/application/engine/objects/workflow/domain/Case.java b/nae-object-library/src/main/java/com/netgrif/application/engine/objects/workflow/domain/Case.java index 1a90ba49a7..9461eb832e 100644 --- a/nae-object-library/src/main/java/com/netgrif/application/engine/objects/workflow/domain/Case.java +++ b/nae-object-library/src/main/java/com/netgrif/application/engine/objects/workflow/domain/Case.java @@ -202,18 +202,23 @@ public void populateDataSet(InitValueExpressionEvaluator initValueExpressionEval if (field.getComponent() != null) { dataField.setComponent(field.getComponent()); } - switch (field) { - case UserField userField -> - dataField.setChoices(userField.getRoles().stream().map(I18nString::new).collect(Collectors.toSet())); - case UserListField userListField -> - dataField.setChoices(userListField.getRoles().stream().map(I18nString::new).collect(Collectors.toSet())); - case FilterField filterField -> dataField.setFilterMetadata(filterField.getFilterMetadata()); - case FieldWithAllowedNets fieldWithAllowedNets -> - dataField.setAllowedNets(fieldWithAllowedNets.getAllowedNets()); - case MapOptionsField mapOptionsField when mapOptionsField.isDynamic() -> - dynamicOptionsFields.add((MapOptionsField) field); - case ChoiceField choiceField when choiceField.isDynamic() -> dynamicChoicesFields.add(choiceField); - default -> {} + if (field instanceof UserField) { + dataField.setChoices(((UserField) field).getRoles().stream().map(I18nString::new).collect(Collectors.toSet())); + } + if (field instanceof UserListField) { + dataField.setChoices(((UserListField) field).getRoles().stream().map(I18nString::new).collect(Collectors.toSet())); + } + if (field instanceof FieldWithAllowedNets) { + dataField.setAllowedNets(((FieldWithAllowedNets) field).getAllowedNets()); + } + if (field instanceof FilterField) { + dataField.setFilterMetadata(((FilterField) field).getFilterMetadata()); + } + if (field instanceof MapOptionsField && ((MapOptionsField) field).isDynamic()) { + dynamicOptionsFields.add((MapOptionsField) field); + } + if (field instanceof ChoiceField && ((ChoiceField) field).isDynamic()) { + dynamicChoicesFields.add((ChoiceField) field); } }); dynamicInitFields.forEach(field -> this.dataSet.get(field.getImportId()).setValue(initValueExpressionEvaluator.evaluate(this, field, params))); From 2b272ecc6a7a4f8fc9274a7fc1fe51f51cd3181c Mon Sep 17 00:00:00 2001 From: chvostek Date: Fri, 31 Oct 2025 12:59:27 +0100 Subject: [PATCH 36/55] [NAE-2235] Improve Efficiency of Database Reads and Saves - fixes according to tests - fix tests --- .../logic/action/ActionDelegate.groovy | 3 ++ .../engine/workflow/service/TaskService.java | 8 ++--- .../filters/FilterImportExportTest.groovy | 2 +- .../dataset/ChangeCasePropertyTest.groovy | 8 ++--- .../dataset/ChangeFieldValueInitTest.groovy | 4 +-- .../workflow/SetDataOnButtonTest.groovy | 4 +-- .../petriNets/test_task_event_with_action.xml | 16 +++++++--- .../ChangeCasePropertyOutcome.java | 30 +++++++++++++++++++ 8 files changed, 58 insertions(+), 17 deletions(-) create mode 100644 nae-object-library/src/main/java/com/netgrif/application/engine/objects/workflow/domain/eventoutcomes/caseoutcomes/ChangeCasePropertyOutcome.java diff --git a/application-engine/src/main/groovy/com/netgrif/application/engine/petrinet/domain/dataset/logic/action/ActionDelegate.groovy b/application-engine/src/main/groovy/com/netgrif/application/engine/petrinet/domain/dataset/logic/action/ActionDelegate.groovy index 808e9d7ad5..9d2c656ded 100644 --- a/application-engine/src/main/groovy/com/netgrif/application/engine/petrinet/domain/dataset/logic/action/ActionDelegate.groovy +++ b/application-engine/src/main/groovy/com/netgrif/application/engine/petrinet/domain/dataset/logic/action/ActionDelegate.groovy @@ -49,6 +49,7 @@ import com.netgrif.application.engine.objects.utils.MenuItemUtils 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.EventOutcome +import com.netgrif.application.engine.objects.workflow.domain.eventoutcomes.caseoutcomes.ChangeCasePropertyOutcome import com.netgrif.application.engine.objects.workflow.domain.eventoutcomes.caseoutcomes.CreateCaseEventOutcome import com.netgrif.application.engine.objects.workflow.domain.eventoutcomes.dataoutcomes.GetDataEventOutcome import com.netgrif.application.engine.objects.workflow.domain.eventoutcomes.dataoutcomes.SetDataEventOutcome @@ -877,6 +878,8 @@ class ActionDelegate { } taskService.save(tasks) } + + outcomes.add(new ChangeCasePropertyOutcome(useCase)) }] } diff --git a/application-engine/src/main/java/com/netgrif/application/engine/workflow/service/TaskService.java b/application-engine/src/main/java/com/netgrif/application/engine/workflow/service/TaskService.java index f82ddb9e27..b54531df6a 100644 --- a/application-engine/src/main/java/com/netgrif/application/engine/workflow/service/TaskService.java +++ b/application-engine/src/main/java/com/netgrif/application/engine/workflow/service/TaskService.java @@ -139,7 +139,7 @@ public AssignTaskEventOutcome assignTask(TaskParams taskParams) throws Transitio List outcomes = new ArrayList<>(eventService.runActions(transition.getPreAssignActions(), useCase, task, transition, taskParams.getParams())); if (!outcomes.isEmpty()) { - useCase = workflowService.findOne(useCase.getStringId()); + task = findOne(task.getStringId()); } AssignTaskEventOutcome outcome = new AssignTaskEventOutcome(useCase, task, outcomes); useCase = evaluateRules(new AssignTaskEvent(outcome, EventPhase.PRE)); @@ -223,7 +223,7 @@ public FinishTaskEventOutcome finishTask(TaskParams taskParams) throws Transitio List outcomes = new ArrayList<>(eventService.runActions(transition.getPreFinishActions(), useCase, task, transition, taskParams.getParams())); if (!outcomes.isEmpty()) { - useCase = workflowService.findOne(useCase.getStringId()); + task = findOne(task.getStringId()); } FinishTaskEventOutcome outcome = new FinishTaskEventOutcome(useCase, task, outcomes); useCase = evaluateRules(new FinishTaskEvent(outcome, EventPhase.PRE)); @@ -281,7 +281,7 @@ public CancelTaskEventOutcome cancelTask(TaskParams taskParams) { List outcomes = new ArrayList<>(eventService.runActions(transition.getPreCancelActions(), useCase, task, transition, taskParams.getParams())); if (!outcomes.isEmpty()) { - useCase = workflowService.findOne(useCase.getStringId()); + task = findOne(task.getStringId()); } CancelTaskEventOutcome outcome = new CancelTaskEventOutcome(useCase, task, outcomes); useCase = evaluateRules(new CancelTaskEvent(outcome, EventPhase.PRE)); @@ -423,7 +423,7 @@ public DelegateTaskEventOutcome delegateTask(DelegateTaskParams delegateTaskPara List outcomes = new ArrayList<>(eventService.runActions(transition.getPreDelegateActions(), useCase, task, transition, delegateTaskParams.getParams())); if (!outcomes.isEmpty()) { - useCase = workflowService.findOne(useCase.getStringId()); + task = findOne(task.getStringId()); } DelegateTaskEventOutcome outcome = new DelegateTaskEventOutcome(useCase, task, outcomes); diff --git a/application-engine/src/test/groovy/com/netgrif/application/engine/filters/FilterImportExportTest.groovy b/application-engine/src/test/groovy/com/netgrif/application/engine/filters/FilterImportExportTest.groovy index ab9b9fd0ee..db5235cb06 100644 --- a/application-engine/src/test/groovy/com/netgrif/application/engine/filters/FilterImportExportTest.groovy +++ b/application-engine/src/test/groovy/com/netgrif/application/engine/filters/FilterImportExportTest.groovy @@ -166,7 +166,7 @@ class FilterImportExportTest { "value": importedTasksIds ] ])) - this.taskService.finishTask(new TaskParams(importTask, dummyUser)) + this.taskService.finishTask(new TaskParams(importTask.getStringId(), dummyUser)) Thread.sleep(1000) filterCases = this.userFilterSearchService.autocompleteFindFilters("") List filterCasesNames = filterCases.stream().map({ filterCase -> filterCase.title }).collect(Collectors.toList()) diff --git a/application-engine/src/test/groovy/com/netgrif/application/engine/petrinet/domain/dataset/ChangeCasePropertyTest.groovy b/application-engine/src/test/groovy/com/netgrif/application/engine/petrinet/domain/dataset/ChangeCasePropertyTest.groovy index 5ed8b48ceb..7748ce3da8 100644 --- a/application-engine/src/test/groovy/com/netgrif/application/engine/petrinet/domain/dataset/ChangeCasePropertyTest.groovy +++ b/application-engine/src/test/groovy/com/netgrif/application/engine/petrinet/domain/dataset/ChangeCasePropertyTest.groovy @@ -76,8 +76,8 @@ class ChangeCasePropertyTest { Task testCaseTask = taskService.searchOne(QTask.task.caseTitle.eq(TEST_CASE_TITLE) & QTask.task.transitionId.eq(TEST_TRANSITION)) assert testCaseTask - taskService.assignTask(new TaskParams(testCaseTask)) - taskService.finishTask(new TaskParams(testCaseTask)) + taskService.assignTask(new TaskParams(testCaseTask.getStringId())) + taskService.finishTask(new TaskParams(testCaseTask.getStringId())) testCase = workflowService.findOne(testCase.getStringId()) testCaseTask = taskService.findOne(testCaseTask.getStringId()) @@ -95,14 +95,14 @@ class ChangeCasePropertyTest { Task testCaseTask = taskService.searchOne(QTask.task.caseTitle.eq(TEST_CASE_TITLE) & QTask.task.transitionId.eq(TEST_TRANSITION)) assert testCaseTask - taskService.assignTask(new TaskParams(testCaseTask)) + taskService.assignTask(new TaskParams(testCaseTask.getStringId())) dataService.setData(testCaseTask.stringId, ImportHelper.populateDataset([ "bln": [ "value": "true", "type" : "boolean" ] ])) - taskService.finishTask(new TaskParams(testCaseTask)) + taskService.finishTask(new TaskParams(testCaseTask.getStringId())) testCase = workflowService.findOne(testCase.getStringId()) testCaseTask = taskService.findOne(testCaseTask.getStringId()) diff --git a/application-engine/src/test/groovy/com/netgrif/application/engine/petrinet/domain/dataset/ChangeFieldValueInitTest.groovy b/application-engine/src/test/groovy/com/netgrif/application/engine/petrinet/domain/dataset/ChangeFieldValueInitTest.groovy index eda2544df1..80828f6bd6 100644 --- a/application-engine/src/test/groovy/com/netgrif/application/engine/petrinet/domain/dataset/ChangeFieldValueInitTest.groovy +++ b/application-engine/src/test/groovy/com/netgrif/application/engine/petrinet/domain/dataset/ChangeFieldValueInitTest.groovy @@ -80,8 +80,8 @@ class ChangeFieldValueInitTest { Case execute(String trans, Case useCase) { Task task = taskService.searchOne(QTask.task.caseId.eq(useCase.getStringId()) & QTask.task.transitionId.eq(trans)) - taskService.assignTask(new TaskParams(task)) - taskService.finishTask(new TaskParams(task)) + taskService.assignTask(new TaskParams(task.getStringId())) + taskService.finishTask(new TaskParams(task.getStringId())) return reload(useCase) } diff --git a/application-engine/src/test/groovy/com/netgrif/application/engine/workflow/SetDataOnButtonTest.groovy b/application-engine/src/test/groovy/com/netgrif/application/engine/workflow/SetDataOnButtonTest.groovy index e9ce551b98..e554670d6b 100644 --- a/application-engine/src/test/groovy/com/netgrif/application/engine/workflow/SetDataOnButtonTest.groovy +++ b/application-engine/src/test/groovy/com/netgrif/application/engine/workflow/SetDataOnButtonTest.groovy @@ -89,8 +89,8 @@ class SetDataOnButtonTest { Task parentTask = taskService.searchOne(QTask.task.caseTitle.eq(PARENT_CASE) & QTask.task.transitionId.eq(TEST_TRANSITION)) assert parentTask != null - taskService.assignTask(new TaskParams(parentTask)) - taskService.finishTask(new TaskParams(parentTask)) + taskService.assignTask(new TaskParams(parentTask.getStringId())) + taskService.finishTask(new TaskParams(parentTask.getStringId())) childCase = workflowService.findOne(childCase.getStringId()) diff --git a/application-engine/src/test/resources/petriNets/test_task_event_with_action.xml b/application-engine/src/test/resources/petriNets/test_task_event_with_action.xml index 733110afd8..e418b42588 100644 --- a/application-engine/src/test/resources/petriNets/test_task_event_with_action.xml +++ b/application-engine/src/test/resources/petriNets/test_task_event_with_action.xml @@ -7,6 +7,10 @@ true true false + + data1 + + </data> <transition> <id>t1</id> <x>368</x> @@ -16,7 +20,8 @@ <id>1_assign</id> <actions phase="post"> <action> - print("testing assign") + data1:f.data1; + change data1 value { "test" } </action> </actions> </event> @@ -24,7 +29,8 @@ <id>1_cancel</id> <actions phase="post"> <action> - print("testing cancel") + data1:f.data1; + change data1 value { "test" } </action> </actions> </event> @@ -32,7 +38,8 @@ <id>1_finish</id> <actions phase="post"> <action> - print("testing finish") + data1:f.data1; + change data1 value { "test" } </action> </actions> </event> @@ -40,7 +47,8 @@ <id>1_delegate</id> <actions phase="post"> <action> - print("testing delegate") + data1:f.data1; + change data1 value { "test" } </action> </actions> </event> diff --git a/nae-object-library/src/main/java/com/netgrif/application/engine/objects/workflow/domain/eventoutcomes/caseoutcomes/ChangeCasePropertyOutcome.java b/nae-object-library/src/main/java/com/netgrif/application/engine/objects/workflow/domain/eventoutcomes/caseoutcomes/ChangeCasePropertyOutcome.java new file mode 100644 index 0000000000..159ec51c10 --- /dev/null +++ b/nae-object-library/src/main/java/com/netgrif/application/engine/objects/workflow/domain/eventoutcomes/caseoutcomes/ChangeCasePropertyOutcome.java @@ -0,0 +1,30 @@ +package com.netgrif.application.engine.objects.workflow.domain.eventoutcomes.caseoutcomes; + +import com.netgrif.application.engine.objects.petrinet.domain.I18nString; +import com.netgrif.application.engine.objects.workflow.domain.Case; +import com.netgrif.application.engine.objects.workflow.domain.eventoutcomes.EventOutcome; + +import java.util.List; + +public class ChangeCasePropertyOutcome extends CaseEventOutcome { + + public ChangeCasePropertyOutcome() { + super(); + } + + public ChangeCasePropertyOutcome(Case aCase) { + super(aCase); + } + + public ChangeCasePropertyOutcome(Case aCase, List<EventOutcome> outcomes) { + super(aCase, outcomes); + } + + public ChangeCasePropertyOutcome(I18nString message, Case aCase) { + super(message, aCase); + } + + public ChangeCasePropertyOutcome(I18nString message, List<EventOutcome> outcomes, Case aCase) { + super(message, outcomes, aCase); + } +} From a3cc876fecfbec070034c5b5318a16b86662e431 Mon Sep 17 00:00:00 2001 From: chvostek <chvostek@netgrif.com> Date: Fri, 31 Oct 2025 15:09:50 +0100 Subject: [PATCH 37/55] [NAE-2235] Improve Efficiency of Database Reads and Saves - remove todos --- .../engine/workflow/service/TaskAuthorizationService.java | 3 --- .../engine/workflow/service/WorkflowAuthorizationService.java | 2 -- 2 files changed, 5 deletions(-) diff --git a/application-engine/src/main/java/com/netgrif/application/engine/workflow/service/TaskAuthorizationService.java b/application-engine/src/main/java/com/netgrif/application/engine/workflow/service/TaskAuthorizationService.java index b6e65b0c93..d565d0cace 100644 --- a/application-engine/src/main/java/com/netgrif/application/engine/workflow/service/TaskAuthorizationService.java +++ b/application-engine/src/main/java/com/netgrif/application/engine/workflow/service/TaskAuthorizationService.java @@ -21,7 +21,6 @@ public class TaskAuthorizationService extends AbstractAuthorizationService imple @Override public Boolean userHasAtLeastOneRolePermission(LoggedUser loggedUser, String taskId, RolePermission... permissions) { - // todo 2235 test return userHasAtLeastOneRolePermission(loggedUser, taskService.findById(taskId), permissions); } @@ -44,7 +43,6 @@ public Boolean userHasAtLeastOneRolePermission(AbstractUser user, Task task, Rol @Override public Boolean userHasUserListPermission(LoggedUser loggedUser, String taskId, RolePermission... permissions) { - // todo 2235 test return userHasUserListPermission(loggedUser, taskService.findById(taskId), permissions); } @@ -73,7 +71,6 @@ public Boolean userHasUserListPermission(AbstractUser user, Task task, RolePermi @Override public boolean isAssignee(LoggedUser loggedUser, String taskId) { - // todo 2235 test return isAssignee(loggedUser, taskService.findById(taskId)); } diff --git a/application-engine/src/main/java/com/netgrif/application/engine/workflow/service/WorkflowAuthorizationService.java b/application-engine/src/main/java/com/netgrif/application/engine/workflow/service/WorkflowAuthorizationService.java index 5299b5683e..a38e66e5e6 100644 --- a/application-engine/src/main/java/com/netgrif/application/engine/workflow/service/WorkflowAuthorizationService.java +++ b/application-engine/src/main/java/com/netgrif/application/engine/workflow/service/WorkflowAuthorizationService.java @@ -31,7 +31,6 @@ public boolean canCallDelete(LoggedUser user, String caseId) { } Case requestedCase = workflowService.findOne(caseId); - // todo 2235 test if user has roles // TODO: impersonation user.getSelfOrImpersonated() Boolean userPerm = userHasUserListPermission(user, requestedCase, ProcessRolePermission.DELETE); if (userPerm != null) { @@ -52,7 +51,6 @@ public boolean canCallCreate(LoggedUser user, String netId) { PetriNet net = petriNetService.getPetriNet(netId); // TODO: impersonation - // todo 2235 test if user has roles return userHasAtLeastOneRolePermission(user, net, ProcessRolePermission.CREATE); } From c442350a004d331e39f78f80e047b737a5cf8a1c Mon Sep 17 00:00:00 2001 From: chvostek <chvostek@netgrif.com> Date: Mon, 3 Nov 2025 09:12:15 +0100 Subject: [PATCH 38/55] [NAE-2235] Improve Efficiency of Database Reads and Saves - add and update fill and validate methods --- .../engine/petrinet/service/PetriNetService.java | 11 +++++++++++ .../engine/workflow/service/TaskService.java | 12 ++++++------ .../engine/workflow/service/WorkflowService.java | 8 ++++---- 3 files changed, 21 insertions(+), 10 deletions(-) diff --git a/application-engine/src/main/java/com/netgrif/application/engine/petrinet/service/PetriNetService.java b/application-engine/src/main/java/com/netgrif/application/engine/petrinet/service/PetriNetService.java index 7b6098a7bd..8a59f46ef0 100644 --- a/application-engine/src/main/java/com/netgrif/application/engine/petrinet/service/PetriNetService.java +++ b/application-engine/src/main/java/com/netgrif/application/engine/petrinet/service/PetriNetService.java @@ -524,6 +524,8 @@ protected void addValueCriteria(Query query, Query queryTotal, Criteria criteria @Override @Transactional public void deletePetriNet(DeletePetriNetParams deletePetriNetParams) { + fillAndValidateAttributes(deletePetriNetParams); + Optional<PetriNet> petriNetOptional = repository.findById(deletePetriNetParams.getPetriNetId()); if (petriNetOptional.isEmpty()) { throw new IllegalArgumentException("Could not find process with id [" + deletePetriNetParams.getPetriNetId() + "]"); @@ -581,4 +583,13 @@ protected void fillAndValidateAttributes(ImportPetriNetParams importPetriNetPara throw new IllegalArgumentException("Version type is null."); } } + + protected void fillAndValidateAttributes(DeletePetriNetParams deletePetriNetParams) throws IllegalArgumentException { + if (deletePetriNetParams.getPetriNetId() == null) { + throw new IllegalArgumentException("No petriNet identifier was provided."); + } + if (deletePetriNetParams.getLoggedUser() == null) { + deletePetriNetParams.setLoggedUser(ActorTransformer.toLoggedUser(userService.getLoggedOrSystem())); + } + } } diff --git a/application-engine/src/main/java/com/netgrif/application/engine/workflow/service/TaskService.java b/application-engine/src/main/java/com/netgrif/application/engine/workflow/service/TaskService.java index b54531df6a..1fe600378b 100644 --- a/application-engine/src/main/java/com/netgrif/application/engine/workflow/service/TaskService.java +++ b/application-engine/src/main/java/com/netgrif/application/engine/workflow/service/TaskService.java @@ -130,7 +130,7 @@ public List<AssignTaskEventOutcome> assignTasks(List<Task> tasks, AbstractUser u @Override public AssignTaskEventOutcome assignTask(TaskParams taskParams) throws TransitionNotExecutableException { - fillMissingAttributes(taskParams); + fillAndValidateAttributes(taskParams); Case useCase = taskParams.getUseCase(); Task task = taskParams.getTask(); @@ -201,7 +201,7 @@ public List<FinishTaskEventOutcome> finishTasks(List<Task> tasks, AbstractUser u @Override public FinishTaskEventOutcome finishTask(TaskParams taskParams) throws TransitionNotExecutableException { - fillMissingAttributes(taskParams); + fillAndValidateAttributes(taskParams); Task task = taskParams.getTask(); Case useCase = taskParams.getUseCase(); @@ -268,7 +268,7 @@ public List<CancelTaskEventOutcome> cancelTasks(List<Task> tasks, AbstractUser u @Override public CancelTaskEventOutcome cancelTask(TaskParams taskParams) { - fillMissingAttributes(taskParams); + fillAndValidateAttributes(taskParams); Task task = taskParams.getTask(); Case useCase = taskParams.getUseCase(); @@ -341,7 +341,7 @@ public void cancelTasksWithoutReload(Set<String> transitions, String caseId, Map } } - protected void fillMissingAttributes(TaskParams taskParams) { + protected void fillAndValidateAttributes(TaskParams taskParams) { if (taskParams.getTask() == null) { Task task = findOne(taskParams.getTaskId()); taskParams.setTask(task); @@ -356,7 +356,7 @@ protected void fillMissingAttributes(TaskParams taskParams) { } } - protected void fillMissingAttributes(DelegateTaskParams taskParams) { + protected void fillAndValidateAttributes(DelegateTaskParams taskParams) { if (taskParams.getTask() == null) { Task task = findOne(taskParams.getTaskId()); taskParams.setTask(task); @@ -410,7 +410,7 @@ private Case returnTokens(Task task, Case useCase) { @Override public DelegateTaskEventOutcome delegateTask(DelegateTaskParams delegateTaskParams) throws TransitionNotExecutableException { - fillMissingAttributes(delegateTaskParams); + fillAndValidateAttributes(delegateTaskParams); AbstractUser newAssignee = delegateTaskParams.getNewAssignee(); AbstractUser delegator = delegateTaskParams.getDelegator(); diff --git a/application-engine/src/main/java/com/netgrif/application/engine/workflow/service/WorkflowService.java b/application-engine/src/main/java/com/netgrif/application/engine/workflow/service/WorkflowService.java index fc4045549f..ebedde52ec 100644 --- a/application-engine/src/main/java/com/netgrif/application/engine/workflow/service/WorkflowService.java +++ b/application-engine/src/main/java/com/netgrif/application/engine/workflow/service/WorkflowService.java @@ -274,7 +274,7 @@ private List<String> getExistingUsers(UserListFieldValue userListValue) { } public CreateCaseEventOutcome createCase(CreateCaseParams createCaseParams) { - fillMissingAttributes(createCaseParams); + fillAndValidateAttributes(createCaseParams); PetriNet petriNet = createCaseParams.getPetriNet(); CreateCaseEventOutcome outcome = new CreateCaseEventOutcome(); @@ -328,7 +328,7 @@ private Case createCaseObject(CreateCaseParams createCaseParams) { return useCase; } - private void fillMissingAttributes(CreateCaseParams createCaseParams) throws IllegalArgumentException { + private void fillAndValidateAttributes(CreateCaseParams createCaseParams) throws IllegalArgumentException { if (createCaseParams.getLoggedUser() == null) { throw new IllegalArgumentException("Logged user cannot be null on Case creation."); } @@ -374,7 +374,7 @@ public Page<Case> findAllByAuthor(String authorId, String petriNet, Pageable pag @Override public DeleteCaseEventOutcome deleteCase(DeleteCaseParams deleteCaseParams) { - fillMissingAttributes(deleteCaseParams); + fillAndValidateAttributes(deleteCaseParams); DeleteCaseEventOutcome outcome = null; Case useCase = deleteCaseParams.getUseCase(); @@ -402,7 +402,7 @@ public DeleteCaseEventOutcome deleteCase(DeleteCaseParams deleteCaseParams) { return outcome; } - protected void fillMissingAttributes(DeleteCaseParams deleteCaseParams) throws IllegalArgumentException { + protected void fillAndValidateAttributes(DeleteCaseParams deleteCaseParams) throws IllegalArgumentException { if (deleteCaseParams.getUseCase() == null) { if (deleteCaseParams.getUseCaseId() != null) { deleteCaseParams.setUseCase(findOne(deleteCaseParams.getUseCaseId())); From 8ada786e3876bdb052ce76a835f95f6ec13e2c63 Mon Sep 17 00:00:00 2001 From: chvostek <chvostek@netgrif.com> Date: Mon, 3 Nov 2025 09:18:57 +0100 Subject: [PATCH 39/55] [NAE-2235] Improve Efficiency of Database Reads and Saves - rollback PetriNetService.evaluateRules --- .../engine/petrinet/service/PetriNetService.java | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/application-engine/src/main/java/com/netgrif/application/engine/petrinet/service/PetriNetService.java b/application-engine/src/main/java/com/netgrif/application/engine/petrinet/service/PetriNetService.java index 8a59f46ef0..0cacdee201 100644 --- a/application-engine/src/main/java/com/netgrif/application/engine/petrinet/service/PetriNetService.java +++ b/application-engine/src/main/java/com/netgrif/application/engine/petrinet/service/PetriNetService.java @@ -5,6 +5,7 @@ import com.netgrif.application.engine.objects.auth.domain.ActorTransformer; import com.netgrif.application.engine.configuration.properties.CacheConfigurationProperties; import com.netgrif.application.engine.files.minio.StorageConfigurationProperties; +import com.netgrif.application.engine.objects.event.events.Event; import com.netgrif.application.engine.petrinet.params.DeletePetriNetParams; import com.netgrif.application.engine.petrinet.params.ImportPetriNetParams; import com.netgrif.application.engine.petrinet.service.interfaces.IPetriNetService; @@ -572,6 +573,11 @@ protected <T> T requireNonNull(T obj, Object... item) { return obj; } + protected void evaluateRules(Event event) { + publisher.publishEvent(event); + + } + protected void fillAndValidateAttributes(ImportPetriNetParams importPetriNetParams) throws IllegalArgumentException { if (importPetriNetParams.getXmlFile() == null) { throw new IllegalArgumentException("No Petriflow source file provided."); From f870c04bd99734d6ef02e60ae98a8f229ec6d424 Mon Sep 17 00:00:00 2001 From: chvostek <chvostek@netgrif.com> Date: Mon, 3 Nov 2025 10:22:49 +0100 Subject: [PATCH 40/55] [NAE-2235] Improve Efficiency of Database Reads and Saves - ensure initialization of taskId in TaskParams --- .../engine/workflow/params/TaskParams.java | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/application-engine/src/main/java/com/netgrif/application/engine/workflow/params/TaskParams.java b/application-engine/src/main/java/com/netgrif/application/engine/workflow/params/TaskParams.java index 6f31ca0b31..fc176c2d0e 100644 --- a/application-engine/src/main/java/com/netgrif/application/engine/workflow/params/TaskParams.java +++ b/application-engine/src/main/java/com/netgrif/application/engine/workflow/params/TaskParams.java @@ -30,6 +30,9 @@ public TaskParams(Task task) { public TaskParams(Task task, AbstractUser user) { this.task = task; + if (task != null) { + this.taskId = task.getStringId(); + } this.user = user; } @@ -41,4 +44,17 @@ public TaskParams(String taskId, AbstractUser user) { this.taskId = taskId; this.user = user; } + + public static class TaskParamsBuilder { + /** + * Sets the {@link #task} and {@link #taskId} + * */ + public TaskParams.TaskParamsBuilder task(Task task) { + this.task = task; + if (task != null) { + this.taskId = task.getStringId(); + } + return this; + } + } } From 6514393c0bbbf4702cb31825251760d562d8fdea Mon Sep 17 00:00:00 2001 From: chvostek <chvostek@netgrif.com> Date: Mon, 3 Nov 2025 16:27:51 +0100 Subject: [PATCH 41/55] [NAE-2235] Improve Efficiency of Database Reads and Saves - rename some CreateCaseParams attributes --- .../logic/action/ActionDelegate.groovy | 8 +-- .../engine/startup/ImportHelper.groovy | 4 +- .../services/DashboardItemServiceImpl.java | 4 +- .../DashboardManagementServiceImpl.java | 4 +- .../engine/menu/services/MenuItemService.java | 4 +- .../petrinet/params/ImportPetriNetParams.java | 7 ++- .../startup/runner/DefaultFiltersRunner.java | 4 +- .../workflow/params/CreateCaseParams.java | 20 +++---- .../service/FilterImportExportService.java | 8 +-- .../service/MenuImportExportService.java | 4 +- .../workflow/service/WorkflowService.java | 28 +++++----- .../web/PublicWorkflowController.java | 4 +- .../workflow/web/WorkflowController.java | 5 +- .../auth/TaskAuthorizationServiceTest.groovy | 40 ++++++------- .../WorkflowAuthorizationServiceTest.groovy | 16 +++--- .../engine/elastic/ReindexTest.groovy | 9 ++- .../PredefinedRolesPermissionsTest.groovy | 4 +- .../engine/insurance/EncryptionTest.groovy | 4 +- .../pdf/service/PdfGeneratorTest.groovy | 56 +++++++++---------- .../ElasticSearchViewPermissionTest.groovy | 28 +++++----- .../QueryDSLViewPermissionTest.groovy | 36 ++++++------ .../petrinet/domain/FunctionsTest.groovy | 33 ++++++----- .../petrinet/domain/ImporterTest.groovy | 9 ++- .../domain/dataset/DynamicCaseNameTest.groovy | 8 +-- .../domain/dataset/FileFieldTest.groovy | 5 +- .../domain/dataset/FileListFieldTest.groovy | 5 +- .../engine/workflow/NewInitTest.groovy | 4 +- .../workflow/WorkflowServiceTest.groovy | 16 +++--- .../engine/importer/ImporterTest.java | 4 +- .../workflow/WorkflowMvcPerformanceTest.java | 24 ++++---- .../workflow/WorkflowPerformanceTest.java | 40 ++++++------- .../workflow/service/TaskServiceTest.java | 16 ++---- .../engine/workflow/web/VariableArcsTest.java | 4 +- 33 files changed, 226 insertions(+), 239 deletions(-) diff --git a/application-engine/src/main/groovy/com/netgrif/application/engine/petrinet/domain/dataset/logic/action/ActionDelegate.groovy b/application-engine/src/main/groovy/com/netgrif/application/engine/petrinet/domain/dataset/logic/action/ActionDelegate.groovy index 57d1dc990c..15cc8b4678 100644 --- a/application-engine/src/main/groovy/com/netgrif/application/engine/petrinet/domain/dataset/logic/action/ActionDelegate.groovy +++ b/application-engine/src/main/groovy/com/netgrif/application/engine/petrinet/domain/dataset/logic/action/ActionDelegate.groovy @@ -951,10 +951,10 @@ class ActionDelegate { Case createCase(String identifier, String title = null, String color = "", AbstractUser author = userService.loggedOrSystem, Locale locale = LocaleContextHolder.getLocale(), Map<String, String> params = [:]) { return workflowService.createCase(CreateCaseParams.with() - .petriNetIdentifier(identifier) + .processIdentifier(identifier) .title(title) .color(color) - .loggedUser(ActorTransformer.toLoggedUser(author)) + .author(ActorTransformer.toLoggedUser(author)) .locale(locale) .params(params) .build()).getCase() @@ -963,10 +963,10 @@ class ActionDelegate { Case createCase(PetriNet net, String title = net.defaultCaseName.getTranslation(locale), String color = "", AbstractUser author = userService.loggedOrSystem, Locale locale = LocaleContextHolder.getLocale(), Map<String, String> params = [:]) { CreateCaseEventOutcome outcome = workflowService.createCase(CreateCaseParams.with() - .petriNet(net) + .process(net) .title(title) .color(color) - .loggedUser(ActorTransformer.toLoggedUser(author)) + .author(ActorTransformer.toLoggedUser(author)) .locale(locale) .params(params) .build()) diff --git a/application-engine/src/main/groovy/com/netgrif/application/engine/startup/ImportHelper.groovy b/application-engine/src/main/groovy/com/netgrif/application/engine/startup/ImportHelper.groovy index a837f7951b..17b141895c 100644 --- a/application-engine/src/main/groovy/com/netgrif/application/engine/startup/ImportHelper.groovy +++ b/application-engine/src/main/groovy/com/netgrif/application/engine/startup/ImportHelper.groovy @@ -193,10 +193,10 @@ class ImportHelper { Case createCase(String title, PetriNet net, LoggedUser user) { return workflowService.createCase(CreateCaseParams.with() - .petriNet(net) + .process(net) .title(title) .color("") - .loggedUser(user) + .author(user) .build()).getCase() } diff --git a/application-engine/src/main/java/com/netgrif/application/engine/menu/services/DashboardItemServiceImpl.java b/application-engine/src/main/java/com/netgrif/application/engine/menu/services/DashboardItemServiceImpl.java index fe88113cc1..019ebbf03d 100644 --- a/application-engine/src/main/java/com/netgrif/application/engine/menu/services/DashboardItemServiceImpl.java +++ b/application-engine/src/main/java/com/netgrif/application/engine/menu/services/DashboardItemServiceImpl.java @@ -65,10 +65,10 @@ public Case getOrCreate(DashboardItemBody body) throws TransitionNotExecutableEx LoggedUser loggedUser = ActorTransformer.toLoggedUser(userService.getLoggedOrSystem()); itemCase = workflowService.createCase(CreateCaseParams.with() - .petriNetIdentifier(DashboardItemConstants.PROCESS_IDENTIFIER) + .processIdentifier(DashboardItemConstants.PROCESS_IDENTIFIER) .title(body.getName().getDefaultValue()) .color("") - .loggedUser(loggedUser) + .author(loggedUser) .build()).getCase(); ToDataSetOutcome outcome = body.toDataSet(); itemCase = setDataWithExecute(itemCase, DashboardItemConstants.TASK_CONFIGURE, outcome.getDataSet()); diff --git a/application-engine/src/main/java/com/netgrif/application/engine/menu/services/DashboardManagementServiceImpl.java b/application-engine/src/main/java/com/netgrif/application/engine/menu/services/DashboardManagementServiceImpl.java index e0c14d3b58..239e364709 100644 --- a/application-engine/src/main/java/com/netgrif/application/engine/menu/services/DashboardManagementServiceImpl.java +++ b/application-engine/src/main/java/com/netgrif/application/engine/menu/services/DashboardManagementServiceImpl.java @@ -67,10 +67,10 @@ public Case createDashboardManagement(DashboardManagementBody body) throws Trans addReferencedMenuItems(body); LoggedUser loggedUser = ActorTransformer.toLoggedUser(userService.getLoggedOrSystem()); managementCase = workflowService.createCase(CreateCaseParams.with() - .petriNetIdentifier(DashboardManagementConstants.PROCESS_IDENTIFIER) + .processIdentifier(DashboardManagementConstants.PROCESS_IDENTIFIER) .title(body.getName().getDefaultValue()) .color("") - .loggedUser(loggedUser) + .author(loggedUser) .build()).getCase(); ToDataSetOutcome outcome = body.toDataSet(); managementCase = setDataWithExecute(managementCase, DashboardItemConstants.TASK_CONFIGURE, outcome.getDataSet()); diff --git a/application-engine/src/main/java/com/netgrif/application/engine/menu/services/MenuItemService.java b/application-engine/src/main/java/com/netgrif/application/engine/menu/services/MenuItemService.java index 25227d0db6..90283ee4d2 100644 --- a/application-engine/src/main/java/com/netgrif/application/engine/menu/services/MenuItemService.java +++ b/application-engine/src/main/java/com/netgrif/application/engine/menu/services/MenuItemService.java @@ -673,10 +673,10 @@ protected void addConfigurationIntoDataSet(Case configurationCase, Map<String, M protected Case createCase(String identifier, String title, LoggedUser loggedUser) { return workflowService.createCase(CreateCaseParams.with() - .petriNetIdentifier(identifier) + .processIdentifier(identifier) .title(title) .color("") - .loggedUser(loggedUser) + .author(loggedUser) .build()).getCase(); } diff --git a/application-engine/src/main/java/com/netgrif/application/engine/petrinet/params/ImportPetriNetParams.java b/application-engine/src/main/java/com/netgrif/application/engine/petrinet/params/ImportPetriNetParams.java index 11bc1996ee..cc7a0c68dc 100644 --- a/application-engine/src/main/java/com/netgrif/application/engine/petrinet/params/ImportPetriNetParams.java +++ b/application-engine/src/main/java/com/netgrif/application/engine/petrinet/params/ImportPetriNetParams.java @@ -1,5 +1,6 @@ package com.netgrif.application.engine.petrinet.params; +import com.netgrif.application.engine.objects.auth.domain.AbstractUser; import com.netgrif.application.engine.objects.auth.domain.LoggedUser; import com.netgrif.application.engine.objects.petrinet.domain.VersionType; import lombok.AllArgsConstructor; @@ -20,18 +21,18 @@ public class ImportPetriNetParams { private InputStream xmlFile; private String uriNodeId; private VersionType releaseType; - private LoggedUser author; + private AbstractUser author; @Builder.Default private Map<String, String> params = new HashMap<>(); - public ImportPetriNetParams(InputStream xmlFile, VersionType releaseType, LoggedUser author, String uriNodeId) { + public ImportPetriNetParams(InputStream xmlFile, VersionType releaseType, AbstractUser author, String uriNodeId) { this.xmlFile = xmlFile; this.releaseType = releaseType; this.author = author; this.uriNodeId = uriNodeId; } - public ImportPetriNetParams(InputStream xmlFile, VersionType releaseType, LoggedUser author) { + public ImportPetriNetParams(InputStream xmlFile, VersionType releaseType, AbstractUser author) { this(xmlFile, releaseType, author, null); } } diff --git a/application-engine/src/main/java/com/netgrif/application/engine/startup/runner/DefaultFiltersRunner.java b/application-engine/src/main/java/com/netgrif/application/engine/startup/runner/DefaultFiltersRunner.java index 0bd0873334..9bfe3ed6c2 100644 --- a/application-engine/src/main/java/com/netgrif/application/engine/startup/runner/DefaultFiltersRunner.java +++ b/application-engine/src/main/java/com/netgrif/application/engine/startup/runner/DefaultFiltersRunner.java @@ -439,10 +439,10 @@ private Optional<Case> createFilterCase(String title, String icon, String filter try { Case filterCase = this.workflowService.createCase(CreateCaseParams.with() - .petriNet(filterNet) + .process(filterNet) .title(title) .color(null) - .loggedUser(ActorTransformer.toLoggedUser(loggedUser)) + .author(ActorTransformer.toLoggedUser(loggedUser)) .build()).getCase(); filterCase.setIcon(icon); filterCase = this.workflowService.save(filterCase); diff --git a/application-engine/src/main/java/com/netgrif/application/engine/workflow/params/CreateCaseParams.java b/application-engine/src/main/java/com/netgrif/application/engine/workflow/params/CreateCaseParams.java index 1c210b4434..d18cdfd9c9 100644 --- a/application-engine/src/main/java/com/netgrif/application/engine/workflow/params/CreateCaseParams.java +++ b/application-engine/src/main/java/com/netgrif/application/engine/workflow/params/CreateCaseParams.java @@ -1,6 +1,6 @@ package com.netgrif.application.engine.workflow.params; -import com.netgrif.application.engine.objects.auth.domain.LoggedUser; +import com.netgrif.application.engine.objects.auth.domain.AbstractUser; import com.netgrif.application.engine.objects.petrinet.domain.PetriNet; import com.netgrif.application.engine.objects.workflow.domain.Case; import lombok.Builder; @@ -17,13 +17,13 @@ public class CreateCaseParams { // todo javadoc - private String petriNetId; - private String petriNetIdentifier; - private PetriNet petriNet; + private String processId; + private String processIdentifier; + private PetriNet process; private String title; private Function<Case, String> makeTitle; private String color; - private LoggedUser loggedUser; + private AbstractUser author; @Builder.Default private Locale locale = LocaleContextHolder.getLocale(); @Builder.Default @@ -44,12 +44,12 @@ public CreateCaseParams.CreateCaseParamsBuilder title(String title) { } /** - * Sets the {@link #petriNet} as clone, {@link #petriNetIdentifier} and {@link #petriNetId} + * Sets the {@link #process} as clone, {@link #processIdentifier} and {@link #processId} * */ - public CreateCaseParams.CreateCaseParamsBuilder petriNet(PetriNet petriNet) { - this.petriNet = new com.netgrif.application.engine.adapter.spring.petrinet.domain.PetriNet((com.netgrif.application.engine.adapter.spring.petrinet.domain.PetriNet) petriNet); - this.petriNetIdentifier = petriNet.getIdentifier(); - this.petriNetId = petriNet.getStringId(); + public CreateCaseParams.CreateCaseParamsBuilder process(PetriNet petriNet) { + this.process = new com.netgrif.application.engine.adapter.spring.petrinet.domain.PetriNet((com.netgrif.application.engine.adapter.spring.petrinet.domain.PetriNet) petriNet); + this.processIdentifier = petriNet.getIdentifier(); + this.processId = petriNet.getStringId(); return this; } } diff --git a/application-engine/src/main/java/com/netgrif/application/engine/workflow/service/FilterImportExportService.java b/application-engine/src/main/java/com/netgrif/application/engine/workflow/service/FilterImportExportService.java index 7aab9cb0ec..bf59555ad6 100644 --- a/application-engine/src/main/java/com/netgrif/application/engine/workflow/service/FilterImportExportService.java +++ b/application-engine/src/main/java/com/netgrif/application/engine/workflow/service/FilterImportExportService.java @@ -102,20 +102,20 @@ public class FilterImportExportService implements IFilterImportExportService { @Override public void createFilterImport(AbstractUser author) { workflowService.createCase(CreateCaseParams.with() - .petriNetIdentifier(IMPORT_NET_IDENTIFIER) + .processIdentifier(IMPORT_NET_IDENTIFIER) .title("Import filters %s".formatted(author.getName())) .color("") - .loggedUser(ActorTransformer.toLoggedUser(author)) + .author(ActorTransformer.toLoggedUser(author)) .build()); } @Override public void createFilterExport(AbstractUser author) { workflowService.createCase(CreateCaseParams.with() - .petriNetIdentifier(EXPORT_NET_IDENTIFIER) + .processIdentifier(EXPORT_NET_IDENTIFIER) .title("Export filters %s".formatted(author.getName())) .color("") - .loggedUser(ActorTransformer.toLoggedUser(author)) + .author(ActorTransformer.toLoggedUser(author)) .build()); } diff --git a/application-engine/src/main/java/com/netgrif/application/engine/workflow/service/MenuImportExportService.java b/application-engine/src/main/java/com/netgrif/application/engine/workflow/service/MenuImportExportService.java index 6c50ea5f3a..4e889f7d19 100644 --- a/application-engine/src/main/java/com/netgrif/application/engine/workflow/service/MenuImportExportService.java +++ b/application-engine/src/main/java/com/netgrif/application/engine/workflow/service/MenuImportExportService.java @@ -263,10 +263,10 @@ public String createMenuItemCase(StringBuilder resultMessage, MenuEntry item, St } //Creating new Case of preference_filter_item net and setting its data... Case menuItemCase = workflowService.createCase(CreateCaseParams.with() - .petriNetIdentifier("preference_filter_item") + .processIdentifier("preference_filter_item") .title("%s_%s".formatted(item.getEntryName(), menuIdentifier)) .color("") - .loggedUser(ActorTransformer.toLoggedUser(userService.getSystem())) + .author(ActorTransformer.toLoggedUser(userService.getSystem())) .build()).getCase(); QTask qTask = new QTask("task"); diff --git a/application-engine/src/main/java/com/netgrif/application/engine/workflow/service/WorkflowService.java b/application-engine/src/main/java/com/netgrif/application/engine/workflow/service/WorkflowService.java index ebedde52ec..aa2c99a8de 100644 --- a/application-engine/src/main/java/com/netgrif/application/engine/workflow/service/WorkflowService.java +++ b/application-engine/src/main/java/com/netgrif/application/engine/workflow/service/WorkflowService.java @@ -275,7 +275,7 @@ private List<String> getExistingUsers(UserListFieldValue userListValue) { public CreateCaseEventOutcome createCase(CreateCaseParams createCaseParams) { fillAndValidateAttributes(createCaseParams); - PetriNet petriNet = createCaseParams.getPetriNet(); + PetriNet petriNet = createCaseParams.getProcess(); CreateCaseEventOutcome outcome = new CreateCaseEventOutcome(); outcome.addOutcomes(eventService.runActions(petriNet.getPreCreateActions(), null, Optional.empty(), @@ -315,11 +315,11 @@ public CreateCaseEventOutcome createCase(CreateCaseParams createCaseParams) { * @return created {@link Case} object * */ private Case createCaseObject(CreateCaseParams createCaseParams) { - PetriNet petriNet = new com.netgrif.application.engine.adapter.spring.petrinet.domain.PetriNet((com.netgrif.application.engine.adapter.spring.petrinet.domain.PetriNet) createCaseParams.getPetriNet()); + PetriNet petriNet = new com.netgrif.application.engine.adapter.spring.petrinet.domain.PetriNet((com.netgrif.application.engine.adapter.spring.petrinet.domain.PetriNet) createCaseParams.getProcess()); Case useCase = new com.netgrif.application.engine.adapter.spring.workflow.domain.Case(petriNet); useCase.populateDataSet(initValueExpressionEvaluator, createCaseParams.getParams()); useCase.setColor(createCaseParams.getColor()); - useCase.setAuthor(ActorTransformer.toActorRef(createCaseParams.getLoggedUser())); // TODO: impersonation + useCase.setAuthor(ActorTransformer.toActorRef(createCaseParams.getAuthor())); // TODO: impersonation useCase.setCreationDate(LocalDateTime.now()); useCase.setTitle(createCaseParams.getMakeTitle().apply(useCase)); @@ -329,28 +329,28 @@ private Case createCaseObject(CreateCaseParams createCaseParams) { } private void fillAndValidateAttributes(CreateCaseParams createCaseParams) throws IllegalArgumentException { - if (createCaseParams.getLoggedUser() == null) { - throw new IllegalArgumentException("Logged user cannot be null on Case creation."); + if (createCaseParams.getAuthor() == null) { + throw new IllegalArgumentException("Author cannot be null on Case creation."); } - if (createCaseParams.getPetriNet() == null) { + if (createCaseParams.getProcess() == null) { PetriNet petriNet; - if (createCaseParams.getPetriNetId() != null) { - petriNet = new com.netgrif.application.engine.adapter.spring.petrinet.domain.PetriNet((com.netgrif.application.engine.adapter.spring.petrinet.domain.PetriNet) petriNetService.get(new ObjectId(createCaseParams.getPetriNetId()))); - } else if (createCaseParams.getPetriNetIdentifier() != null) { - petriNet = new com.netgrif.application.engine.adapter.spring.petrinet.domain.PetriNet((com.netgrif.application.engine.adapter.spring.petrinet.domain.PetriNet) petriNetService.getNewestVersionByIdentifier(createCaseParams.getPetriNetIdentifier())); + if (createCaseParams.getProcessId() != null) { + petriNet = new com.netgrif.application.engine.adapter.spring.petrinet.domain.PetriNet((com.netgrif.application.engine.adapter.spring.petrinet.domain.PetriNet) petriNetService.get(new ObjectId(createCaseParams.getProcessId()))); + } else if (createCaseParams.getProcessIdentifier() != null) { + petriNet = new com.netgrif.application.engine.adapter.spring.petrinet.domain.PetriNet((com.netgrif.application.engine.adapter.spring.petrinet.domain.PetriNet) petriNetService.getNewestVersionByIdentifier(createCaseParams.getProcessIdentifier())); } else { - throw new IllegalArgumentException("Could not find the PetriNet for the Case from provided inputs on case creation."); + throw new IllegalArgumentException("Could not find the process for the Case from provided inputs on case creation."); } - createCaseParams.setPetriNet(petriNet); + createCaseParams.setProcess(petriNet); } - if (createCaseParams.getMakeTitle() == null && createCaseParams.getPetriNet() != null) { + if (createCaseParams.getMakeTitle() == null && createCaseParams.getProcess() != null) { createCaseParams.setMakeTitle(resolveDefaultCaseTitle(createCaseParams)); } } private Function<Case, String> resolveDefaultCaseTitle(CreateCaseParams createCaseParams) { Locale locale = createCaseParams.getLocale(); - PetriNet petriNet = createCaseParams.getPetriNet(); + PetriNet petriNet = createCaseParams.getProcess(); Function<Case, String> makeTitle; if (petriNet.hasDynamicCaseName()) { makeTitle = (u) -> initValueExpressionEvaluator.evaluateCaseName(u, petriNet.getDefaultCaseNameExpression(), diff --git a/application-engine/src/main/java/com/netgrif/application/engine/workflow/web/PublicWorkflowController.java b/application-engine/src/main/java/com/netgrif/application/engine/workflow/web/PublicWorkflowController.java index ec13682427..f25d6a3a7e 100644 --- a/application-engine/src/main/java/com/netgrif/application/engine/workflow/web/PublicWorkflowController.java +++ b/application-engine/src/main/java/com/netgrif/application/engine/workflow/web/PublicWorkflowController.java @@ -51,10 +51,10 @@ public EntityModel<EventOutcomeWithMessage> createCase(@RequestBody CreateCaseBo LoggedUser loggedUser = ActorTransformer.toLoggedUser(userService.getLoggedUser()); try { CreateCaseEventOutcome outcome = this.workflowService.createCase(CreateCaseParams.with() - .petriNetId(body.netId) + .processId(body.netId) .title(body.title) .color(body.color) - .loggedUser(loggedUser) + .author(loggedUser) .locale(locale) .build()); return EventOutcomeWithMessageResource.successMessage("Case created successfully", diff --git a/application-engine/src/main/java/com/netgrif/application/engine/workflow/web/WorkflowController.java b/application-engine/src/main/java/com/netgrif/application/engine/workflow/web/WorkflowController.java index afd6c94d65..eeb7edbd7a 100644 --- a/application-engine/src/main/java/com/netgrif/application/engine/workflow/web/WorkflowController.java +++ b/application-engine/src/main/java/com/netgrif/application/engine/workflow/web/WorkflowController.java @@ -52,7 +52,6 @@ import java.io.UnsupportedEncodingException; import java.net.URLDecoder; import java.nio.charset.StandardCharsets; -import java.util.ArrayList; import java.util.Locale; import java.util.Map; @@ -88,10 +87,10 @@ public EntityModel<EventOutcomeWithMessage> createCase(@RequestBody CreateCaseBo LoggedUser loggedUser = (LoggedUser) auth.getPrincipal(); try { CreateCaseEventOutcome outcome = workflowService.createCase(CreateCaseParams.with() - .petriNetId(body.netId) + .processId(body.netId) .title(body.title) .color(body.color) - .loggedUser(loggedUser) + .author(loggedUser) .locale(locale) .build()); return EventOutcomeWithMessageResource.successMessage("Case with id " + outcome.getCase().getStringId() + " was created succesfully", diff --git a/application-engine/src/test/groovy/com/netgrif/application/engine/auth/TaskAuthorizationServiceTest.groovy b/application-engine/src/test/groovy/com/netgrif/application/engine/auth/TaskAuthorizationServiceTest.groovy index fd9b985947..93d4a00122 100644 --- a/application-engine/src/test/groovy/com/netgrif/application/engine/auth/TaskAuthorizationServiceTest.groovy +++ b/application-engine/src/test/groovy/com/netgrif/application/engine/auth/TaskAuthorizationServiceTest.groovy @@ -339,10 +339,10 @@ class TaskAuthorizationServiceTest { ProcessRole positiveRole = this.net.getRoles().values().find(v -> v.getImportId() == "assign_pos_role") userService.addRole(testUser, positiveRole.get_id()) Case case_ = workflowService.createCase(CreateCaseParams.with() - .petriNet(net) + .process(net) .title("Test assign") .color("") - .loggedUser(ActorTransformer.toLoggedUser(testUser)) + .author(ActorTransformer.toLoggedUser(testUser)) .build()).getCase() assert taskAuthorizationService.canCallAssign(ActorTransformer.toLoggedUser(testUser), (new ArrayList<>(case_.getTasks())).get(0).task) userService.removeRole(testUser, positiveRole.get_id()) @@ -354,10 +354,10 @@ class TaskAuthorizationServiceTest { ProcessRole negativeRole = this.net.getRoles().values().find(v -> v.getImportId() == "assign_neg_role") userService.addRole(testUser, negativeRole.get_id()) Case case_ = workflowService.createCase(CreateCaseParams.with() - .petriNet(net) + .process(net) .title("Test assign") .color("") - .loggedUser(ActorTransformer.toLoggedUser(testUser)) + .author(ActorTransformer.toLoggedUser(testUser)) .build()).getCase() assert !taskAuthorizationService.canCallAssign(ActorTransformer.toLoggedUser(testUser), (new ArrayList<>(case_.getTasks())).get(0).task) userService.removeRole(testUser, negativeRole.get_id()) @@ -367,10 +367,10 @@ class TaskAuthorizationServiceTest { @Test void testCanAssignWithUsersRef() { Case case_ = workflowService.createCase(CreateCaseParams.with() - .petriNet(netWithUserRefs) + .process(netWithUserRefs) .title("Test assign") .color("") - .loggedUser(ActorTransformer.toLoggedUser(testUser)) + .author(ActorTransformer.toLoggedUser(testUser)) .build()).getCase() String taskId = (new ArrayList<>(case_.getTasks())).get(0).task case_ = dataService.setData(taskId, ImportHelper.populateDataset([ @@ -389,10 +389,10 @@ class TaskAuthorizationServiceTest { @Test void testCannotAssignWithUsersRef() { Case case_ = workflowService.createCase(CreateCaseParams.with() - .petriNet(netWithUserRefs) + .process(netWithUserRefs) .title("Test assign") .color("") - .loggedUser(ActorTransformer.toLoggedUser(testUser)) + .author(ActorTransformer.toLoggedUser(testUser)) .build()).getCase() String taskId = (new ArrayList<>(case_.getTasks())).get(0).task case_ = dataService.setData(taskId, ImportHelper.populateDataset([ @@ -413,10 +413,10 @@ class TaskAuthorizationServiceTest { ProcessRole positiveRole = this.netWithUserRefs.getRoles().values().find(v -> v.getImportId() == "assign_pos_role") userService.addRole(testUser, positiveRole.get_id()) Case case_ = workflowService.createCase(CreateCaseParams.with() - .petriNet(netWithUserRefs) + .process(netWithUserRefs) .title("Test assign") .color("") - .loggedUser(ActorTransformer.toLoggedUser(testUser)) + .author(ActorTransformer.toLoggedUser(testUser)) .build()).getCase() String taskId = (new ArrayList<>(case_.getTasks())).get(0).task case_ = dataService.setData(taskId, ImportHelper.populateDataset([ @@ -438,10 +438,10 @@ class TaskAuthorizationServiceTest { ProcessRole positiveRole = this.netWithUserRefs.getRoles().values().find(v -> v.getImportId() == "finish_pos_role") userService.addRole(testUser, positiveRole.get_id()) Case case_ = workflowService.createCase(CreateCaseParams.with() - .petriNet(netWithUserRefs) + .process(netWithUserRefs) .title("Test Finish") .color("") - .loggedUser(ActorTransformer.toLoggedUser(testUser)) + .author(ActorTransformer.toLoggedUser(testUser)) .build()).getCase() String taskId = (new ArrayList<>(case_.getTasks())).get(0).task @@ -456,10 +456,10 @@ class TaskAuthorizationServiceTest { ProcessRole negativeRole = this.netWithUserRefs.getRoles().values().find(v -> v.getImportId() == "finish_neg_role") userService.addRole(testUser, negativeRole.get_id()) Case case_ = workflowService.createCase(CreateCaseParams.with() - .petriNet(netWithUserRefs) + .process(netWithUserRefs) .title("Test Finish") .color("") - .loggedUser(ActorTransformer.toLoggedUser(testUser)) + .author(ActorTransformer.toLoggedUser(testUser)) .build()).getCase() String taskId = (new ArrayList<>(case_.getTasks())).get(0).task @@ -472,10 +472,10 @@ class TaskAuthorizationServiceTest { @Test void testCanFinishWithUsersRef() { Case case_ = workflowService.createCase(CreateCaseParams.with() - .petriNet(netWithUserRefs) + .process(netWithUserRefs) .title("Test Finish") .color("") - .loggedUser(ActorTransformer.toLoggedUser(testUser)) + .author(ActorTransformer.toLoggedUser(testUser)) .build()).getCase() String taskId = (new ArrayList<>(case_.getTasks())).get(0).task case_ = dataService.setData(taskId, ImportHelper.populateDataset([ @@ -495,10 +495,10 @@ class TaskAuthorizationServiceTest { @Test void testCannotFinishWithUsersRef() { Case case_ = workflowService.createCase(CreateCaseParams.with() - .petriNet(netWithUserRefs) + .process(netWithUserRefs) .title("Test Finish") .color("") - .loggedUser(ActorTransformer.toLoggedUser(testUser)) + .author(ActorTransformer.toLoggedUser(testUser)) .build()).getCase() String taskId = (new ArrayList<>(case_.getTasks())).get(0).task case_ = dataService.setData(taskId, ImportHelper.populateDataset([ @@ -520,10 +520,10 @@ class TaskAuthorizationServiceTest { ProcessRole positiveRole = this.netWithUserRefs.getRoles().values().find(v -> v.getImportId() == "finish_pos_role") userService.addRole(testUser, positiveRole.get_id()) Case case_ = workflowService.createCase(CreateCaseParams.with() - .petriNet(netWithUserRefs) + .process(netWithUserRefs) .title("Test Finish") .color("") - .loggedUser(ActorTransformer.toLoggedUser(testUser)) + .author(ActorTransformer.toLoggedUser(testUser)) .build()).getCase() String taskId = (new ArrayList<>(case_.getTasks())).get(0).task case_ = dataService.setData(taskId, ImportHelper.populateDataset([ diff --git a/application-engine/src/test/groovy/com/netgrif/application/engine/auth/WorkflowAuthorizationServiceTest.groovy b/application-engine/src/test/groovy/com/netgrif/application/engine/auth/WorkflowAuthorizationServiceTest.groovy index 521a595bba..391cf68378 100644 --- a/application-engine/src/test/groovy/com/netgrif/application/engine/auth/WorkflowAuthorizationServiceTest.groovy +++ b/application-engine/src/test/groovy/com/netgrif/application/engine/auth/WorkflowAuthorizationServiceTest.groovy @@ -206,10 +206,10 @@ class WorkflowAuthorizationServiceTest { ProcessRole positiveDeleteRole = this.net.getRoles().values().find(v -> v.getImportId() == "delete_pos_role") userService.addRole(testUser, positiveDeleteRole.getStringId()) Case case_ = workflowService.createCase(CreateCaseParams.with() - .petriNet(net) + .process(net) .title("Test delete") .color("") - .loggedUser(ActorTransformer.toLoggedUser(testUser)) + .author(ActorTransformer.toLoggedUser(testUser)) .build()).getCase() assert workflowAuthorizationService.canCallDelete(ActorTransformer.toLoggedUser(testUser), case_.getStringId()) userService.removeRole(testUser, positiveDeleteRole.getStringId()) @@ -228,10 +228,10 @@ class WorkflowAuthorizationServiceTest { ProcessRole deleteRole = this.net.getRoles().values().find(v -> v.getImportId() == "delete_neg_role") userService.addRole(testUser, deleteRole.getStringId()) Case case_ = workflowService.createCase(CreateCaseParams.with() - .petriNet(net) + .process(net) .title("Test delete") .color("") - .loggedUser(ActorTransformer.toLoggedUser(testUser)) + .author(ActorTransformer.toLoggedUser(testUser)) .build()).getCase() assert !workflowAuthorizationService.canCallDelete(ActorTransformer.toLoggedUser(testUser), case_.getStringId()) userService.removeRole(testUser, deleteRole.getStringId()) @@ -247,10 +247,10 @@ class WorkflowAuthorizationServiceTest { userService.addRole(testUser, negDeleteRole.getStringId()) Case case_ = workflowService.createCase(CreateCaseParams.with() - .petriNet(netWithUserRefs) + .process(netWithUserRefs) .title("Test delete") .color("") - .loggedUser(ActorTransformer.toLoggedUser(testUser)) + .author(ActorTransformer.toLoggedUser(testUser)) .build()).getCase() String taskId = (new ArrayList<>(case_.getTasks())).get(0).task case_ = dataService.setData(taskId, ImportHelper.populateDataset([ @@ -276,10 +276,10 @@ class WorkflowAuthorizationServiceTest { userService.addRole(testUser, negDeleteRole.getStringId()) Case case_ = workflowService.createCase(CreateCaseParams.with() - .petriNet(netWithUserRefs) + .process(netWithUserRefs) .title("Test delete") .color("") - .loggedUser(ActorTransformer.toLoggedUser(testUser)) + .author(ActorTransformer.toLoggedUser(testUser)) .build()).getCase() String taskId = (new ArrayList<>(case_.getTasks())).get(0).task case_ = dataService.setData(taskId, ImportHelper.populateDataset([ diff --git a/application-engine/src/test/groovy/com/netgrif/application/engine/elastic/ReindexTest.groovy b/application-engine/src/test/groovy/com/netgrif/application/engine/elastic/ReindexTest.groovy index 70773d2f3e..271b79b57e 100644 --- a/application-engine/src/test/groovy/com/netgrif/application/engine/elastic/ReindexTest.groovy +++ b/application-engine/src/test/groovy/com/netgrif/application/engine/elastic/ReindexTest.groovy @@ -4,7 +4,6 @@ import com.netgrif.application.engine.TestHelper import com.netgrif.application.engine.elastic.service.ReindexingTask import com.netgrif.application.engine.elastic.service.interfaces.IElasticCaseService import com.netgrif.application.engine.elastic.web.requestbodies.CaseSearchRequest -import com.netgrif.application.engine.objects.auth.domain.ActorTransformer import com.netgrif.application.engine.objects.petrinet.domain.VersionType import com.netgrif.application.engine.petrinet.params.ImportPetriNetParams import com.netgrif.application.engine.petrinet.service.interfaces.IPetriNetService @@ -65,10 +64,10 @@ class ReindexTest { for (int i in 1..2000) { threads << Thread.start { def useCase = workflowService.createCase(CreateCaseParams.with() - .petriNet(net.getNet()) + .process(net.getNet()) .title("Test") .color("color") - .loggedUser(superCreator.getLoggedSuper()) + .author(superCreator.getLoggedSuper()) .build()).getCase() savedCase.add(useCase) } @@ -82,10 +81,10 @@ class ReindexTest { for (int i in 1..4000) { threads << Thread.start { def useCase = workflowService.createCase(CreateCaseParams.with() - .petriNet(net.getNet()) + .process(net.getNet()) .title("Test") .color("color") - .loggedUser(superCreator.getLoggedSuper()) + .author(superCreator.getLoggedSuper()) .build()).getCase() savedCase.add(useCase) } diff --git a/application-engine/src/test/groovy/com/netgrif/application/engine/importer/PredefinedRolesPermissionsTest.groovy b/application-engine/src/test/groovy/com/netgrif/application/engine/importer/PredefinedRolesPermissionsTest.groovy index 31202de920..66c77dc328 100644 --- a/application-engine/src/test/groovy/com/netgrif/application/engine/importer/PredefinedRolesPermissionsTest.groovy +++ b/application-engine/src/test/groovy/com/netgrif/application/engine/importer/PredefinedRolesPermissionsTest.groovy @@ -458,10 +458,10 @@ class PredefinedRolesPermissionsTest { PetriNet net = importOutcome.getNet() CreateCaseEventOutcome createCaseOutcome = workflowService.createCase(CreateCaseParams.with() - .petriNet(net) + .process(net) .title('') .color('') - .loggedUser(superCreator.loggedSuper) + .author(superCreator.loggedSuper) .build()) assert createCaseOutcome.getCase() != null Case aCase = createCaseOutcome.getCase() diff --git a/application-engine/src/test/groovy/com/netgrif/application/engine/insurance/EncryptionTest.groovy b/application-engine/src/test/groovy/com/netgrif/application/engine/insurance/EncryptionTest.groovy index bea1bb7a0d..4e89241718 100644 --- a/application-engine/src/test/groovy/com/netgrif/application/engine/insurance/EncryptionTest.groovy +++ b/application-engine/src/test/groovy/com/netgrif/application/engine/insurance/EncryptionTest.groovy @@ -88,10 +88,10 @@ class EncryptionTest { .build()) assert net.getNet() != null def useCase = workflowService.createCase(CreateCaseParams.with() - .petriNet(net.getNet()) + .process(net.getNet()) .title("Encryption test") .color("color") - .loggedUser(mockLoggedUser()) + .author(mockLoggedUser()) .build()).getCase() def nameField = useCase.petriNet.dataSet.values().find { v -> v.name.defaultValue == FIELD_NAME } useCase.dataSet.put(nameField.stringId, new DataField(FIELD_VALUE)) diff --git a/application-engine/src/test/groovy/com/netgrif/application/engine/pdf/service/PdfGeneratorTest.groovy b/application-engine/src/test/groovy/com/netgrif/application/engine/pdf/service/PdfGeneratorTest.groovy index becac6ec18..914e47e484 100644 --- a/application-engine/src/test/groovy/com/netgrif/application/engine/pdf/service/PdfGeneratorTest.groovy +++ b/application-engine/src/test/groovy/com/netgrif/application/engine/pdf/service/PdfGeneratorTest.groovy @@ -96,10 +96,10 @@ class PdfGeneratorTest { .author(ActorTransformer.toLoggedUser(userService.getSystem())) .build()) Case testCase = workflowService.createCase(CreateCaseParams.with() - .petriNet(net.getNet()) + .process(net.getNet()) .title("Test PDF") .color("") - .loggedUser(ActorTransformer.toLoggedUser(userService.getSystem())) + .author(ActorTransformer.toLoggedUser(userService.getSystem())) .build()).getCase() testCase.getPetriNet().getTransition("1").setDataGroups(getDataGroupMap(dataService.getDataGroups(testCase.getTasks()[0].getTask(), Locale.ENGLISH).getData())) String taskId = testCase.getTasks().find(taskPair -> taskPair.transition.equals("1")).task @@ -117,10 +117,10 @@ class PdfGeneratorTest { .author(ActorTransformer.toLoggedUser(userService.getSystem())) .build()) Case testCase = workflowService.createCase(CreateCaseParams.with() - .petriNet(net.getNet()) + .process(net.getNet()) .title("Test PDF") .color("") - .loggedUser(ActorTransformer.toLoggedUser(userService.getSystem())) + .author(ActorTransformer.toLoggedUser(userService.getSystem())) .build()).getCase() testCase.getPetriNet().getTransition("1").setDataGroups(getDataGroupMap(dataService.getDataGroups(testCase.getTasks()[0].getTask(), Locale.ENGLISH).getData())) pdfResource.setOutputResource(new ClassPathResource(pdfOutputFolder + "/out_" + TESTING_DATA[3] + "_.pdf")) @@ -140,10 +140,10 @@ class PdfGeneratorTest { .author(ActorTransformer.toLoggedUser(userService.getSystem())) .build()) Case testCase = workflowService.createCase(CreateCaseParams.with() - .petriNet(net.getNet()) + .process(net.getNet()) .title("Test PDF") .color("") - .loggedUser(ActorTransformer.toLoggedUser(userService.getSystem())) + .author(ActorTransformer.toLoggedUser(userService.getSystem())) .build()).getCase() testCase.getPetriNet().getTransition("1").setDataGroups(getDataGroupMap(dataService.getDataGroups(testCase.getTasks()[0].getTask(), Locale.ENGLISH).getData())) pdfResource.setOutputResource(new ClassPathResource(pdfOutputFolder + "/out_" + TESTING_DATA[0] + "_.pdf")) @@ -163,10 +163,10 @@ class PdfGeneratorTest { .author(ActorTransformer.toLoggedUser(userService.getSystem())) .build()) Case testCase = workflowService.createCase(CreateCaseParams.with() - .petriNet(net.getNet()) + .process(net.getNet()) .title("Test PDF") .color("") - .loggedUser(ActorTransformer.toLoggedUser(userService.getSystem())) + .author(ActorTransformer.toLoggedUser(userService.getSystem())) .build()).getCase() testCase.getPetriNet().getTransition("1").setDataGroups(getDataGroupMap(dataService.getDataGroups(testCase.getTasks()[0].getTask(), Locale.ENGLISH).getData())) pdfResource.setOutputResource(new ClassPathResource(pdfOutputFolder + "/out_" + TESTING_DATA[1] + "_.pdf")) @@ -191,10 +191,10 @@ class PdfGeneratorTest { .author(ActorTransformer.toLoggedUser(userService.getSystem())) .build()) Case testCase = workflowService.createCase(CreateCaseParams.with() - .petriNet(net.getNet()) + .process(net.getNet()) .title("Test PDF") .color("") - .loggedUser(ActorTransformer.toLoggedUser(userService.getSystem())) + .author(ActorTransformer.toLoggedUser(userService.getSystem())) .build()).getCase() testCase.getPetriNet().getTransition("1").setDataGroups(getDataGroupMap(dataService.getDataGroups(testCase.getTasks()[0].getTask(), Locale.ENGLISH).getData())) String filename = pdfResource.getOutputDefaultName() @@ -220,10 +220,10 @@ class PdfGeneratorTest { .author(ActorTransformer.toLoggedUser(userService.getSystem())) .build()) Case testCase = workflowService.createCase(CreateCaseParams.with() - .petriNet(net.getNet()) + .process(net.getNet()) .title("Test PDF") .color("") - .loggedUser(ActorTransformer.toLoggedUser(userService.getSystem())) + .author(ActorTransformer.toLoggedUser(userService.getSystem())) .build()).getCase() testCase.getPetriNet().getTransition("1").setDataGroups(getDataGroupMap(dataService.getDataGroups(testCase.getTasks()[0].getTask(), Locale.ENGLISH).getData())) pdfResource.setOutputResource(new ClassPathResource(pdfOutputFolder + "/out_" + TESTING_DATA[2] + "_.pdf")) @@ -243,10 +243,10 @@ class PdfGeneratorTest { .author(ActorTransformer.toLoggedUser(userService.getSystem())) .build()) Case testCase = workflowService.createCase(CreateCaseParams.with() - .petriNet(net.getNet()) + .process(net.getNet()) .title("Test PDF") .color("") - .loggedUser(ActorTransformer.toLoggedUser(userService.getSystem())) + .author(ActorTransformer.toLoggedUser(userService.getSystem())) .build()).getCase() testCase.getPetriNet().getTransition("1").setDataGroups(getDataGroupMap(dataService.getDataGroups(testCase.getTasks()[0].getTask(), Locale.ENGLISH).getData())) pdfResource.setNumberFormat(Locale.US) @@ -279,10 +279,10 @@ class PdfGeneratorTest { .author(ActorTransformer.toLoggedUser(userService.getSystem())) .build()) Case testCase = workflowService.createCase(CreateCaseParams.with() - .petriNet(net.getNet()) + .process(net.getNet()) .title("Test PDF") .color("") - .loggedUser(ActorTransformer.toLoggedUser(userService.getSystem())) + .author(ActorTransformer.toLoggedUser(userService.getSystem())) .build()).getCase() testCase.getPetriNet().getTransition("1").setDataGroups(getDataGroupMap(dataService.getDataGroups(testCase.getTasks()[0].getTask(), Locale.ENGLISH).getData())) pdfResource.setOutputResource(new ClassPathResource(pdfOutputFolder + "/out_custom_field.pdf")) @@ -303,10 +303,10 @@ class PdfGeneratorTest { .author(ActorTransformer.toLoggedUser(userService.getSystem())) .build()) Case testCase = workflowService.createCase(CreateCaseParams.with() - .petriNet(net.getNet()) + .process(net.getNet()) .title("Test PDF") .color("") - .loggedUser(ActorTransformer.toLoggedUser(userService.getSystem())) + .author(ActorTransformer.toLoggedUser(userService.getSystem())) .build()).getCase() testCase.getPetriNet().getTransition("t1").setDataGroups(getDataGroupMap(dataService.getDataGroups(testCase.getTasks()[0].getTask(), Locale.ENGLISH).getData())) pdfResource.setOutputResource(new ClassPathResource(pdfOutputFolder + "/out_" + TESTING_DATA[4] + "_.pdf")) @@ -326,10 +326,10 @@ class PdfGeneratorTest { .author(ActorTransformer.toLoggedUser(userService.getSystem())) .build()) Case testCase = workflowService.createCase(CreateCaseParams.with() - .petriNet(net.getNet()) + .process(net.getNet()) .title("Test PDF") .color("") - .loggedUser(ActorTransformer.toLoggedUser(userService.getSystem())) + .author(ActorTransformer.toLoggedUser(userService.getSystem())) .build()).getCase() pdfResource.setOutputResource(new ClassPathResource(pdfOutputFolder + "/out_" + TESTING_DATA[5] + "_.pdf")) pdfGenerator.setupPdfGenerator(pdfResource) @@ -348,10 +348,10 @@ class PdfGeneratorTest { .author(ActorTransformer.toLoggedUser(userService.getSystem())) .build()) Case testCase = workflowService.createCase(CreateCaseParams.with() - .petriNet(net.getNet()) + .process(net.getNet()) .title("Test PDF") .color("") - .loggedUser(ActorTransformer.toLoggedUser(userService.getSystem())) + .author(ActorTransformer.toLoggedUser(userService.getSystem())) .build()).getCase() pdfResource.setOutputResource(new ClassPathResource(pdfOutputFolder + "/out_" + TESTING_DATA[6] + "_.pdf")) pdfGenerator.setupPdfGenerator(pdfResource) @@ -370,10 +370,10 @@ class PdfGeneratorTest { .build()) assertNotNull(net.getNet()) Case testCase = workflowService.createCase(CreateCaseParams.with() - .petriNet(net.getNet()) + .process(net.getNet()) .title("Test PDF") .color("") - .loggedUser(ActorTransformer.toLoggedUser(userService.getSystem())) + .author(ActorTransformer.toLoggedUser(userService.getSystem())) .build()).getCase() assertNotNull(testCase) List<TaskReference> tasks = taskService.findAllByCase(testCase.stringId, Locale.ENGLISH) @@ -398,17 +398,17 @@ class PdfGeneratorTest { .build()) assertNotNull(net.getNet()) Case testCase = workflowService.createCase(CreateCaseParams.with() - .petriNet(net.getNet()) + .process(net.getNet()) .title("Test PDF") .color("") - .loggedUser(ActorTransformer.toLoggedUser(userService.getSystem())) + .author(ActorTransformer.toLoggedUser(userService.getSystem())) .build()).getCase() assertNotNull(testCase) Case testCase2 = workflowService.createCase(CreateCaseParams.with() - .petriNet(net.getNet()) + .process(net.getNet()) .title("Test PDF 2") .color("") - .loggedUser(ActorTransformer.toLoggedUser(userService.getSystem())) + .author(ActorTransformer.toLoggedUser(userService.getSystem())) .build()).getCase() assertNotNull(testCase2) assertNotEquals(testCase.stringId, testCase2.stringId) diff --git a/application-engine/src/test/groovy/com/netgrif/application/engine/permissions/ElasticSearchViewPermissionTest.groovy b/application-engine/src/test/groovy/com/netgrif/application/engine/permissions/ElasticSearchViewPermissionTest.groovy index 67bf965ef2..f85b01230e 100644 --- a/application-engine/src/test/groovy/com/netgrif/application/engine/permissions/ElasticSearchViewPermissionTest.groovy +++ b/application-engine/src/test/groovy/com/netgrif/application/engine/permissions/ElasticSearchViewPermissionTest.groovy @@ -109,10 +109,10 @@ class ElasticSearchViewPermissionTest { @Test void testSearchElasticViewWithUserWithoutRole() { Case case_ = workflowService.createCase(CreateCaseParams.with() - .petriNet(net) + .process(net) .title("Permission test") .color("") - .loggedUser(ActorTransformer.toLoggedUser(testUser)) + .author(ActorTransformer.toLoggedUser(testUser)) .build()).getCase() CaseSearchRequest caseSearchRequest = new CaseSearchRequest() @@ -126,10 +126,10 @@ class ElasticSearchViewPermissionTest { @Test void testSearchElasticViewWithUserWithPosRole() { Case case_ = workflowService.createCase(CreateCaseParams.with() - .petriNet(net) + .process(net) .title("Permission test") .color("") - .loggedUser(ActorTransformer.toLoggedUser(testUser)) + .author(ActorTransformer.toLoggedUser(testUser)) .build()).getCase() ProcessRole posViewRole = this.net.getRoles().values().find(v -> v.getImportId() == "view_pos_role") userService.addRole(testUser, posViewRole.getStringId()) @@ -149,10 +149,10 @@ class ElasticSearchViewPermissionTest { @Test void testSearchElasticViewWithUserWithNegRole() { Case case_ = workflowService.createCase(CreateCaseParams.with() - .petriNet(net) + .process(net) .title("Permission test") .color("") - .loggedUser(ActorTransformer.toLoggedUser(testUser)) + .author(ActorTransformer.toLoggedUser(testUser)) .build()).getCase() ProcessRole negViewRole = this.net.getRoles().values().find(v -> v.getImportId() == "view_neg_role") userService.addRole(testUser, negViewRole.getStringId()) @@ -169,10 +169,10 @@ class ElasticSearchViewPermissionTest { @Test void testSearchElasticViewWithUserWithoutUserRef() { Case case_ = workflowService.createCase(CreateCaseParams.with() - .petriNet(netWithUserRefs) + .process(netWithUserRefs) .title("Permission test") .color("") - .loggedUser(ActorTransformer.toLoggedUser(testUser)) + .author(ActorTransformer.toLoggedUser(testUser)) .build()).getCase() CaseSearchRequest caseSearchRequest = new CaseSearchRequest() @@ -186,10 +186,10 @@ class ElasticSearchViewPermissionTest { @Test void testSearchElasticViewWithUserWithPosUserRef() { Case case_ = workflowService.createCase(CreateCaseParams.with() - .petriNet(netWithUserRefs) + .process(netWithUserRefs) .title("Permission test") .color("") - .loggedUser(ActorTransformer.toLoggedUser(testUser)) + .author(ActorTransformer.toLoggedUser(testUser)) .build()).getCase() String taskId = (new ArrayList<>(case_.getTasks())).get(0).task case_ = dataService.setData(taskId, ImportHelper.populateDataset([ @@ -212,10 +212,10 @@ class ElasticSearchViewPermissionTest { @Test void testSearchElasticViewWithUserWithNegUserRef() { Case case_ = workflowService.createCase(CreateCaseParams.with() - .petriNet(netWithUserRefs) + .process(netWithUserRefs) .title("Permission test") .color("") - .loggedUser(ActorTransformer.toLoggedUser(testUser)) + .author(ActorTransformer.toLoggedUser(testUser)) .build()).getCase() String taskId = (new ArrayList<>(case_.getTasks())).get(0).task case_ = dataService.setData(taskId, ImportHelper.populateDataset([ @@ -238,10 +238,10 @@ class ElasticSearchViewPermissionTest { @Test void testSearchElasticViewWithUserWithNegativeRoleAndPosUserRef() { Case case_ = workflowService.createCase(CreateCaseParams.with() - .petriNet(netWithUserRefs) + .process(netWithUserRefs) .title("Permission test") .color("") - .loggedUser(ActorTransformer.toLoggedUser(testUser)) + .author(ActorTransformer.toLoggedUser(testUser)) .build()).getCase() ProcessRole negViewRole = this.net.getRoles().values().find(v -> v.getImportId() == "view_neg_role") userService.addRole(testUser, negViewRole.getStringId()) diff --git a/application-engine/src/test/groovy/com/netgrif/application/engine/permissions/QueryDSLViewPermissionTest.groovy b/application-engine/src/test/groovy/com/netgrif/application/engine/permissions/QueryDSLViewPermissionTest.groovy index a47436cfce..2a47f6b0d6 100644 --- a/application-engine/src/test/groovy/com/netgrif/application/engine/permissions/QueryDSLViewPermissionTest.groovy +++ b/application-engine/src/test/groovy/com/netgrif/application/engine/permissions/QueryDSLViewPermissionTest.groovy @@ -102,10 +102,10 @@ class QueryDSLViewPermissionTest { @Test void testSearchQueryDSLViewWithoutRole() { Case case_ = workflowService.createCase(CreateCaseParams.with() - .petriNet(net) + .process(net) .title("Permission test") .color("") - .loggedUser(ActorTransformer.toLoggedUser(testUser)) + .author(ActorTransformer.toLoggedUser(testUser)) .build()).getCase() Page<Case> casePage = workflowService.search(["petriNet": ["identifier": netWithUserRefs.getIdentifier()], "fullText": "VPT"] as Map, PageRequest.of(0, 20), ActorTransformer.toLoggedUser(testUser), LocaleContextHolder.getLocale()) @@ -117,10 +117,10 @@ class QueryDSLViewPermissionTest { @Test void testSearchQueryDSLViewWithUserWithPosRole() { Case case_ = workflowService.createCase(CreateCaseParams.with() - .petriNet(net) + .process(net) .title("Permission test") .color("") - .loggedUser(ActorTransformer.toLoggedUser(testUser)) + .author(ActorTransformer.toLoggedUser(testUser)) .build()).getCase() ProcessRole posViewRole = this.net.getRoles().values().find(v -> v.getImportId() == "view_pos_role") userService.addRole(testUser, posViewRole.getStringId()) @@ -136,10 +136,10 @@ class QueryDSLViewPermissionTest { @Test void testSearchQueryDSLViewWithUserWithNegRole() { Case case_ = workflowService.createCase(CreateCaseParams.with() - .petriNet(net) + .process(net) .title("Permission test") .color("") - .loggedUser(ActorTransformer.toLoggedUser(testUser)) + .author(ActorTransformer.toLoggedUser(testUser)) .build()).getCase() ProcessRole negViewRole = this.net.getRoles().values().find(v -> v.getImportId() == "view_neg_role") userService.addRole(testUser, negViewRole.getStringId()) @@ -155,10 +155,10 @@ class QueryDSLViewPermissionTest { @Test void testSearchQueryDSLViewWithoutUserRef() { Case case_ = workflowService.createCase(CreateCaseParams.with() - .petriNet(netWithUserRefs) + .process(netWithUserRefs) .title("Permission test") .color("") - .loggedUser(ActorTransformer.toLoggedUser(testUser)) + .author(ActorTransformer.toLoggedUser(testUser)) .build()).getCase() Page<Case> casePage = workflowService.search(["petriNet": ["identifier": netWithUserRefs.getIdentifier()], "fullText": "VPT"] as Map, PageRequest.of(0, 20), ActorTransformer.toLoggedUser(testUser), LocaleContextHolder.getLocale()) @@ -170,10 +170,10 @@ class QueryDSLViewPermissionTest { @Test void testSearchQueryDSLViewWithPosUserRef() { Case case_ = workflowService.createCase(CreateCaseParams.with() - .petriNet(netWithUserRefs) + .process(netWithUserRefs) .title("Permission test") .color("") - .loggedUser(ActorTransformer.toLoggedUser(testUser)) + .author(ActorTransformer.toLoggedUser(testUser)) .build()).getCase() String taskId = (new ArrayList<>(case_.getTasks())).get(0).task case_ = dataService.setData(taskId, ImportHelper.populateDataset([ @@ -195,10 +195,10 @@ class QueryDSLViewPermissionTest { @Test void testSearchTaskQueryDSLViewWithPosUserRef() { Case case_ = workflowService.createCase(CreateCaseParams.with() - .petriNet(netWithUserRefs) + .process(netWithUserRefs) .title("Permission test") .color("") - .loggedUser(ActorTransformer.toLoggedUser(testUser)) + .author(ActorTransformer.toLoggedUser(testUser)) .build()).getCase() String taskId = (new ArrayList<>(case_.getTasks())).get(0).task case_ = dataService.setData(taskId, ImportHelper.populateDataset([ @@ -222,10 +222,10 @@ class QueryDSLViewPermissionTest { @Test void testSearchTaskQueryDSLViewWithUserWithPosRole() { Case case_ = workflowService.createCase(CreateCaseParams.with() - .petriNet(netWithUserRefs) + .process(netWithUserRefs) .title("Permission test") .color("") - .loggedUser(ActorTransformer.toLoggedUser(testUser)) + .author(ActorTransformer.toLoggedUser(testUser)) .build()).getCase() ProcessRole posViewRole = this.netWithUserRefs.getRoles().values().find(v -> v.getImportId() == "view_pos_role") userService.addRole(testUser, posViewRole.getStringId()) @@ -243,10 +243,10 @@ class QueryDSLViewPermissionTest { @Test void testSearchQueryDSLViewWithNegUserRef() { Case case_ = workflowService.createCase(CreateCaseParams.with() - .petriNet(netWithUserRefs) + .process(netWithUserRefs) .title("Permission test") .color("") - .loggedUser(ActorTransformer.toLoggedUser(testUser)) + .author(ActorTransformer.toLoggedUser(testUser)) .build()).getCase() String taskId = (new ArrayList<>(case_.getTasks())).get(0).task case_ = dataService.setData(taskId, ImportHelper.populateDataset([ @@ -268,10 +268,10 @@ class QueryDSLViewPermissionTest { @Test void testSearchQueryDSLViewWithNegRoleAndPosUserRef() { Case case_ = workflowService.createCase(CreateCaseParams.with() - .petriNet(netWithUserRefs) + .process(netWithUserRefs) .title("Permission test") .color("") - .loggedUser(ActorTransformer.toLoggedUser(testUser)) + .author(ActorTransformer.toLoggedUser(testUser)) .build()).getCase() String taskId = (new ArrayList<>(case_.getTasks())).get(0).task case_ = dataService.setData(taskId, ImportHelper.populateDataset([ diff --git a/application-engine/src/test/groovy/com/netgrif/application/engine/petrinet/domain/FunctionsTest.groovy b/application-engine/src/test/groovy/com/netgrif/application/engine/petrinet/domain/FunctionsTest.groovy index 65c1df0af5..1f3ff5ed69 100644 --- a/application-engine/src/test/groovy/com/netgrif/application/engine/petrinet/domain/FunctionsTest.groovy +++ b/application-engine/src/test/groovy/com/netgrif/application/engine/petrinet/domain/FunctionsTest.groovy @@ -3,7 +3,6 @@ package com.netgrif.application.engine.petrinet.domain import com.netgrif.application.engine.TestHelper 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.User import com.netgrif.application.engine.auth.service.UserService import com.netgrif.application.engine.objects.petrinet.domain.VersionType import com.netgrif.application.engine.objects.petrinet.domain.dataset.logic.FieldBehavior @@ -108,10 +107,10 @@ class FunctionsTest { assert functionTestNet Case aCase = workflowService.createCase(CreateCaseParams.with() - .petriNet(functionTestNet) + .process(functionTestNet) .title("Test") .color("") - .loggedUser(ActorTransformer.toLoggedUser(userService.getLoggedOrSystem())) + .author(ActorTransformer.toLoggedUser(userService.getLoggedOrSystem())) .build()).getCase() dataService.setData(aCase.tasks.first().task, ImportHelper.populateDataset(["createUser": ["value": "true", "type": "boolean"]])) @@ -139,10 +138,10 @@ class FunctionsTest { assert functionTestNet Case aCase = workflowService.createCase(CreateCaseParams.with() - .petriNet(functionTestNet) + .process(functionTestNet) .title("Test") .color("") - .loggedUser(ActorTransformer.toLoggedUser(userService.getLoggedOrSystem())) + .author(ActorTransformer.toLoggedUser(userService.getLoggedOrSystem())) .build()).getCase() dataService.setData(aCase.tasks.first().task, ImportHelper.populateDataset(["enum": ["value": "ano", "type": "enumeration"]])) aCase = workflowService.findOne(aCase.getStringId()) @@ -178,10 +177,10 @@ class FunctionsTest { assert functionTestNet Case aCase = workflowService.createCase(CreateCaseParams.with() - .petriNet(functionTestNet) + .process(functionTestNet) .title("Test") .color("") - .loggedUser(ActorTransformer.toLoggedUser(userService.getLoggedOrSystem())) + .author(ActorTransformer.toLoggedUser(userService.getLoggedOrSystem())) .build()).getCase() dataService.setData(aCase.tasks.first().task, ImportHelper.populateDataset(["number": ["value": "20", "type": "number"]])) }) @@ -208,10 +207,10 @@ class FunctionsTest { assert functionTestNet Case aCase = workflowService.createCase(CreateCaseParams.with() - .petriNet(functionTestNet) + .process(functionTestNet) .title("Test") .color("") - .loggedUser(ActorTransformer.toLoggedUser(userService.getLoggedOrSystem())) + .author(ActorTransformer.toLoggedUser(userService.getLoggedOrSystem())) .build()).getCase() dataService.setData(aCase.tasks.first().task, ImportHelper.populateDataset(["text": ["value": "20", "type": "text"]])) @@ -237,10 +236,10 @@ class FunctionsTest { assert functionTestNet Case aCase = workflowService.createCase(CreateCaseParams.with() - .petriNet(functionTestNet) + .process(functionTestNet) .title("Test") .color("") - .loggedUser(ActorTransformer.toLoggedUser(userService.getLoggedOrSystem())) + .author(ActorTransformer.toLoggedUser(userService.getLoggedOrSystem())) .build()).getCase() dataService.setData(aCase.tasks.first().task, ImportHelper.populateDataset(["number3": ["value": "20", "type": "number"]])) }) @@ -263,10 +262,10 @@ class FunctionsTest { assert functionTestNet Case aCase = workflowService.createCase(CreateCaseParams.with() - .petriNet(functionTestNet) + .process(functionTestNet) .title("Test") .color("") - .loggedUser(ActorTransformer.toLoggedUser(userService.getLoggedOrSystem())) + .author(ActorTransformer.toLoggedUser(userService.getLoggedOrSystem())) .build()).getCase() dataService.setData(aCase.tasks.first().task, ImportHelper.populateDataset(["number": ["value": "20", "type": "number"]])) aCase = workflowService.findOne(aCase.getStringId()) @@ -311,10 +310,10 @@ class FunctionsTest { .build()).getNet() Case aCase = workflowService.createCase(CreateCaseParams.with() - .petriNet(functionTestV2Net) + .process(functionTestV2Net) .title("Test") .color("") - .loggedUser(ActorTransformer.toLoggedUser(userService.getLoggedOrSystem())) + .author(ActorTransformer.toLoggedUser(userService.getLoggedOrSystem())) .build()).getCase() dataService.setData(aCase.tasks.first().task, ImportHelper.populateDataset(["updateOtherField": ["value": "true", "type": "boolean"]])) @@ -354,10 +353,10 @@ class FunctionsTest { assert petriNet Case aCase = workflowService.createCase(CreateCaseParams.with() - .petriNet(petriNet) + .process(petriNet) .title("Test") .color("") - .loggedUser(ActorTransformer.toLoggedUser(userService.getLoggedOrSystem())) + .author(ActorTransformer.toLoggedUser(userService.getLoggedOrSystem())) .build()).getCase() dataService.setData(aCase.tasks.first().task, ImportHelper.populateDataset(["number": ["value": "20", "type": "number"]])) aCase = workflowService.findOne(aCase.getStringId()) diff --git a/application-engine/src/test/groovy/com/netgrif/application/engine/petrinet/domain/ImporterTest.groovy b/application-engine/src/test/groovy/com/netgrif/application/engine/petrinet/domain/ImporterTest.groovy index 44bbba0782..bbeca1efc1 100644 --- a/application-engine/src/test/groovy/com/netgrif/application/engine/petrinet/domain/ImporterTest.groovy +++ b/application-engine/src/test/groovy/com/netgrif/application/engine/petrinet/domain/ImporterTest.groovy @@ -2,7 +2,6 @@ package com.netgrif.application.engine.petrinet.domain import com.netgrif.application.engine.TestHelper import com.netgrif.application.engine.importer.service.Importer -import com.netgrif.application.engine.objects.auth.domain.ActorTransformer import com.netgrif.application.engine.objects.petrinet.domain.PetriNet import com.netgrif.application.engine.objects.petrinet.domain.VersionType import com.netgrif.application.engine.objects.petrinet.domain.dataset.ChoiceField @@ -296,10 +295,10 @@ class ImporterTest { assert net != null Case testCase = workflowService.createCase(CreateCaseParams.with() - .petriNet(net) + .process(net) .title("Test case") .color("") - .loggedUser(superCreator.loggedSuper) + .author(superCreator.loggedSuper) .build()).getCase() taskService.assignTask(new TaskParams(testCase.getTasks().toList().get(0).getTask())) testCase = workflowService.findOne(testCase.getStringId()) @@ -316,10 +315,10 @@ class ImporterTest { assert net Case testCase = workflowService.createCase(CreateCaseParams.with() - .petriNet(net) + .process(net) .title("Test case") .color("") - .loggedUser(superCreator.loggedSuper) + .author(superCreator.loggedSuper) .build()).getCase() assert testCase.dataSet.get(NUMBER_FIELD).behavior.get("1") == [FieldBehavior.FORBIDDEN] as Set<FieldBehavior> diff --git a/application-engine/src/test/groovy/com/netgrif/application/engine/petrinet/domain/dataset/DynamicCaseNameTest.groovy b/application-engine/src/test/groovy/com/netgrif/application/engine/petrinet/domain/dataset/DynamicCaseNameTest.groovy index 8d64cee18d..bf2a677bd2 100644 --- a/application-engine/src/test/groovy/com/netgrif/application/engine/petrinet/domain/dataset/DynamicCaseNameTest.groovy +++ b/application-engine/src/test/groovy/com/netgrif/application/engine/petrinet/domain/dataset/DynamicCaseNameTest.groovy @@ -47,17 +47,17 @@ class DynamicCaseNameTest { .author(superCreator.getLoggedSuper()) .build()) Case useCase = workflowService.createCase(CreateCaseParams.with() - .petriNet(optNet.getNet()) + .process(optNet.getNet()) .color("") - .loggedUser(superCreator.loggedSuper) + .author(superCreator.loggedSuper) .locale(Locale.forLanguageTag("sk-SK")) .build()).getCase() assert useCase.title == "SK text value 6" Case useCase2 = workflowService.createCase(CreateCaseParams.with() - .petriNet(optNet.getNet()) + .process(optNet.getNet()) .color("") - .loggedUser(superCreator.loggedSuper) + .author(superCreator.loggedSuper) .locale(Locale.ENGLISH) .build()).getCase() assert useCase2.title == "EN text value 6" diff --git a/application-engine/src/test/groovy/com/netgrif/application/engine/petrinet/domain/dataset/FileFieldTest.groovy b/application-engine/src/test/groovy/com/netgrif/application/engine/petrinet/domain/dataset/FileFieldTest.groovy index f58166bbd6..a7195dc810 100644 --- a/application-engine/src/test/groovy/com/netgrif/application/engine/petrinet/domain/dataset/FileFieldTest.groovy +++ b/application-engine/src/test/groovy/com/netgrif/application/engine/petrinet/domain/dataset/FileFieldTest.groovy @@ -1,7 +1,6 @@ package com.netgrif.application.engine.petrinet.domain.dataset import com.fasterxml.jackson.databind.ObjectMapper -import com.netgrif.application.engine.ApplicationEngine import com.netgrif.application.engine.TestHelper import com.netgrif.application.engine.adapter.spring.auth.domain.AuthorityImpl import com.netgrif.application.engine.auth.service.UserService @@ -231,10 +230,10 @@ class FileFieldTest { AbstractUser user = userService.findUserByUsername(UserConstants.ADMIN_USER_USERNAME, null).get() assert user != null Case useCase = workflowService.createCase(CreateCaseParams.with() - .petriNet(net) + .process(net) .title("Test file from file list download") .color("black") - .loggedUser(ActorTransformer.toLoggedUser(user)) + .author(ActorTransformer.toLoggedUser(user)) .build()).getCase() importHelper.assignTask(TASK_TITLE, useCase.getStringId(), ActorTransformer.toLoggedUser(user)) diff --git a/application-engine/src/test/groovy/com/netgrif/application/engine/petrinet/domain/dataset/FileListFieldTest.groovy b/application-engine/src/test/groovy/com/netgrif/application/engine/petrinet/domain/dataset/FileListFieldTest.groovy index 3d00fb7b7d..75fcf2f448 100644 --- a/application-engine/src/test/groovy/com/netgrif/application/engine/petrinet/domain/dataset/FileListFieldTest.groovy +++ b/application-engine/src/test/groovy/com/netgrif/application/engine/petrinet/domain/dataset/FileListFieldTest.groovy @@ -1,7 +1,6 @@ package com.netgrif.application.engine.petrinet.domain.dataset import com.fasterxml.jackson.databind.ObjectMapper -import com.netgrif.application.engine.ApplicationEngine import com.netgrif.application.engine.TestHelper import com.netgrif.application.engine.adapter.spring.auth.domain.AuthorityImpl import com.netgrif.application.engine.auth.service.UserService @@ -229,10 +228,10 @@ class FileListFieldTest { AbstractUser user = userService.findUserByUsername(UserConstants.ADMIN_USER_USERNAME, null).get() assert user != null Case useCase = workflowService.createCase(CreateCaseParams.with() - .petriNet(net) + .process(net) .title("Test file from file list download") .color("black") - .loggedUser(ActorTransformer.toLoggedUser(user)) + .author(ActorTransformer.toLoggedUser(user)) .build()).getCase() importHelper.assignTask(TASK_TITLE, useCase.getStringId(), ActorTransformer.toLoggedUser(user)) diff --git a/application-engine/src/test/groovy/com/netgrif/application/engine/workflow/NewInitTest.groovy b/application-engine/src/test/groovy/com/netgrif/application/engine/workflow/NewInitTest.groovy index 2de0e7f2ae..84095cba1e 100644 --- a/application-engine/src/test/groovy/com/netgrif/application/engine/workflow/NewInitTest.groovy +++ b/application-engine/src/test/groovy/com/netgrif/application/engine/workflow/NewInitTest.groovy @@ -52,10 +52,10 @@ class NewInitTest { .author(superCreator.getLoggedSuper()) .build()) Case initTestCase = workflowService.createCase(CreateCaseParams.with() - .petriNet(petriNetService.getNewestVersionByIdentifier("new_init_test")) + .process(petriNetService.getNewestVersionByIdentifier("new_init_test")) .title("New init test") .color("") - .loggedUser(superCreator.loggedSuper) + .author(superCreator.loggedSuper) .build()).getCase() assert (initTestCase.dataSet["new_init_multichoice"].value as List<I18nString>).stream().any { it.defaultValue == "Bob" } assert (initTestCase.dataSet["new_init_multichoice"].value as List<I18nString>).stream().any { it.defaultValue == "Alice" } diff --git a/application-engine/src/test/groovy/com/netgrif/application/engine/workflow/WorkflowServiceTest.groovy b/application-engine/src/test/groovy/com/netgrif/application/engine/workflow/WorkflowServiceTest.groovy index c0444c2cff..072c93a25c 100644 --- a/application-engine/src/test/groovy/com/netgrif/application/engine/workflow/WorkflowServiceTest.groovy +++ b/application-engine/src/test/groovy/com/netgrif/application/engine/workflow/WorkflowServiceTest.groovy @@ -81,10 +81,10 @@ class WorkflowServiceTest { def net = testNet Case aCase = workflowService.createCase(CreateCaseParams.with() - .petriNet(net) + .process(net) .title("autoErr") .color("red") - .loggedUser(superCreator.loggedSuper) + .author(superCreator.loggedSuper) .build()).getCase() importHelper.assignTask("Manual", aCase.getStringId(), superCreator.getLoggedSuper()) importHelper.finishTask("Manual", aCase.getStringId(), superCreator.getLoggedSuper()) @@ -102,10 +102,10 @@ class WorkflowServiceTest { .build()).getNet() Case aCase = workflowService.createCase(CreateCaseParams.with() - .petriNet(net) + .process(net) .title("autoErr") .color("red") - .loggedUser(superCreator.loggedSuper) + .author(superCreator.loggedSuper) .build()).getCase() importHelper.assignTask("Manual", aCase.getStringId(), superCreator.getLoggedSuper()) importHelper.finishTask("Manual", aCase.getStringId(), superCreator.getLoggedSuper()) @@ -129,15 +129,15 @@ class WorkflowServiceTest { def net = testNet.getNet() Case aCase = workflowService.createCase(CreateCaseParams.with() - .petriNet(net) - .loggedUser(superCreator.loggedSuper) + .process(net) + .author(superCreator.loggedSuper) .locale(new Locale('sk')) .build()).getCase() assert aCase.title.equals("Slovenský preklad") Case enCase = workflowService.createCase(CreateCaseParams.with() - .petriNet(net) - .loggedUser(superCreator.loggedSuper) + .process(net) + .author(superCreator.loggedSuper) .locale(new Locale('en')) .build()).getCase() assert enCase.title.equals("English translation") diff --git a/application-engine/src/test/java/com/netgrif/application/engine/importer/ImporterTest.java b/application-engine/src/test/java/com/netgrif/application/engine/importer/ImporterTest.java index 58870e97e7..68df92264a 100644 --- a/application-engine/src/test/java/com/netgrif/application/engine/importer/ImporterTest.java +++ b/application-engine/src/test/java/com/netgrif/application/engine/importer/ImporterTest.java @@ -82,10 +82,10 @@ public void priorityTest() throws MissingPetriNetMetaDataException, IOException, assert outcome.getNet() != null; CreateCaseEventOutcome caseOutcome = workflowService.createCase(CreateCaseParams.with() - .petriNet(outcome.getNet()) + .process(outcome.getNet()) .title(outcome.getNet().getTitle().getDefaultValue()) .color("color") - .loggedUser(superCreator.getLoggedSuper()) + .author(superCreator.getLoggedSuper()) .build()); assert caseOutcome.getCase() != null; diff --git a/application-engine/src/test/java/com/netgrif/application/engine/workflow/WorkflowMvcPerformanceTest.java b/application-engine/src/test/java/com/netgrif/application/engine/workflow/WorkflowMvcPerformanceTest.java index bd4c89754d..b952430ff4 100644 --- a/application-engine/src/test/java/com/netgrif/application/engine/workflow/WorkflowMvcPerformanceTest.java +++ b/application-engine/src/test/java/com/netgrif/application/engine/workflow/WorkflowMvcPerformanceTest.java @@ -104,8 +104,8 @@ void testAssignAdminPerformance() throws Exception { for (int i = 0; i < iterations; i++) { Case useCase = workflowService.createCase(CreateCaseParams.with() - .petriNet(net) - .loggedUser(loggedUser) + .process(net) + .author(loggedUser) .locale(Locale.getDefault()) .build()).getCase(); String taskId = useCase.getTasks().stream().findFirst().get().getTask(); @@ -126,8 +126,8 @@ void testAssignPerformance() throws Exception { for (int i = 0; i < iterations; i++) { Case useCase = workflowService.createCase(CreateCaseParams.with() - .petriNet(net) - .loggedUser(loggedUser) + .process(net) + .author(loggedUser) .locale(Locale.getDefault()) .build()).getCase(); String taskId = useCase.getTasks().stream().findFirst().get().getTask(); @@ -148,8 +148,8 @@ public void testCancelAdminPerformance() throws Exception { for (int i = 0; i < iterations; i++) { Case useCase = workflowService.createCase(CreateCaseParams.with() - .petriNet(net) - .loggedUser(loggedUser) + .process(net) + .author(loggedUser) .locale(Locale.getDefault()) .build()).getCase(); String taskId = useCase.getTasks().stream().findFirst().get().getTask(); @@ -174,8 +174,8 @@ public void testCancelPerformance() throws Exception { for (int i = 0; i < iterations; i++) { Case useCase = workflowService.createCase(CreateCaseParams.with() - .petriNet(net) - .loggedUser(loggedUser) + .process(net) + .author(loggedUser) .locale(Locale.getDefault()) .build()).getCase(); String taskId = useCase.getTasks().stream().findFirst().get().getTask(); @@ -200,8 +200,8 @@ public void testFinishAdminPerformance() throws Exception { for (int i = 0; i < iterations; i++) { Case useCase = workflowService.createCase(CreateCaseParams.with() - .petriNet(net) - .loggedUser(loggedUser) + .process(net) + .author(loggedUser) .locale(Locale.getDefault()) .build()).getCase(); String taskId = useCase.getTasks().stream().findFirst().get().getTask(); @@ -226,8 +226,8 @@ public void testFinishPerformance() throws Exception { for (int i = 0; i < iterations; i++) { Case useCase = workflowService.createCase(CreateCaseParams.with() - .petriNet(net) - .loggedUser(loggedUser) + .process(net) + .author(loggedUser) .locale(Locale.getDefault()) .build()).getCase(); String taskId = useCase.getTasks().stream().findFirst().get().getTask(); diff --git a/application-engine/src/test/java/com/netgrif/application/engine/workflow/WorkflowPerformanceTest.java b/application-engine/src/test/java/com/netgrif/application/engine/workflow/WorkflowPerformanceTest.java index 872af8a1c0..d50de54b89 100644 --- a/application-engine/src/test/java/com/netgrif/application/engine/workflow/WorkflowPerformanceTest.java +++ b/application-engine/src/test/java/com/netgrif/application/engine/workflow/WorkflowPerformanceTest.java @@ -69,8 +69,8 @@ public void testCreatePerformance() throws IOException, MissingPetriNetMetaDataE .author(superCreatorRunner.getLoggedSuper()) .build()).getNet(); iterateAndShowAvgTime("createCase", () -> workflowService.createCase(CreateCaseParams.with() - .petriNet(net) - .loggedUser(superCreatorRunner.getLoggedSuper()) + .process(net) + .author(superCreatorRunner.getLoggedSuper()) .locale(Locale.getDefault()) .build()), 1000); } @@ -83,8 +83,8 @@ public void testCreateWithActionPerformance() throws IOException, MissingPetriNe .author(superCreatorRunner.getLoggedSuper()) .build()).getNet(); iterateAndShowAvgTime("createCaseWithAction", () -> workflowService.createCase(CreateCaseParams.with() - .petriNet(net) - .loggedUser(superCreatorRunner.getLoggedSuper()) + .process(net) + .author(superCreatorRunner.getLoggedSuper()) .locale(Locale.getDefault()) .build()), 5000); } @@ -102,8 +102,8 @@ public void testAssignPerformance() throws IOException, MissingPetriNetMetaDataE for (int i = 0; i < iterations; i++) { Case useCase = workflowService.createCase(CreateCaseParams.with() - .petriNet(net) - .loggedUser(loggedUser) + .process(net) + .author(loggedUser) .locale(Locale.getDefault()) .build()).getCase(); String taskId = useCase.getTasks().stream().findFirst().get().getTask(); @@ -131,8 +131,8 @@ public void testAssignWithActionPerformance() throws IOException, MissingPetriNe for (int i = 0; i < iterations; i++) { Case useCase = workflowService.createCase(CreateCaseParams.with() - .petriNet(net) - .loggedUser(loggedUser) + .process(net) + .author(loggedUser) .locale(Locale.getDefault()) .build()).getCase(); String taskId = useCase.getTasks().stream().findFirst().get().getTask(); @@ -160,8 +160,8 @@ public void testCancelPerformance() throws IOException, MissingPetriNetMetaDataE for (int i = 0; i < iterations; i++) { Case useCase = workflowService.createCase(CreateCaseParams.with() - .petriNet(net) - .loggedUser(loggedUser) + .process(net) + .author(loggedUser) .locale(Locale.getDefault()) .build()).getCase(); String taskId = useCase.getTasks().stream().findFirst().get().getTask(); @@ -193,8 +193,8 @@ public void testCancelWithActionPerformance() throws IOException, MissingPetriNe for (int i = 0; i < iterations; i++) { Case useCase = workflowService.createCase(CreateCaseParams.with() - .petriNet(net) - .loggedUser(loggedUser) + .process(net) + .author(loggedUser) .locale(Locale.getDefault()) .build()).getCase(); String taskId = useCase.getTasks().stream().findFirst().get().getTask(); @@ -226,8 +226,8 @@ public void testFinishPerformance() throws IOException, MissingPetriNetMetaDataE for (int i = 0; i < iterations; i++) { Case useCase = workflowService.createCase(CreateCaseParams.with() - .petriNet(net) - .loggedUser(loggedUser) + .process(net) + .author(loggedUser) .locale(Locale.getDefault()) .build()).getCase(); String taskId = useCase.getTasks().stream().findFirst().get().getTask(); @@ -260,8 +260,8 @@ public void testFinishWithActionPerformance() throws IOException, MissingPetriNe for (int i = 0; i < iterations; i++) { Case useCase = workflowService.createCase(CreateCaseParams.with() - .petriNet(net) - .loggedUser(loggedUser) + .process(net) + .author(loggedUser) .locale(Locale.getDefault()) .build()).getCase(); String taskId = useCase.getTasks().stream().findFirst().get().getTask(); @@ -294,8 +294,8 @@ public void testDelegatePerformance() throws IOException, MissingPetriNetMetaDat for (int i = 0; i < iterations; i++) { Case useCase = workflowService.createCase(CreateCaseParams.with() - .petriNet(net) - .loggedUser(loggedUser) + .process(net) + .author(loggedUser) .locale(Locale.getDefault()) .build()).getCase(); String taskId = useCase.getTasks().stream().findFirst().get().getTask(); @@ -329,8 +329,8 @@ public void testDelegateWithActionPerformance() throws IOException, MissingPetri for (int i = 0; i < iterations; i++) { Case useCase = workflowService.createCase(CreateCaseParams.with() - .petriNet(net) - .loggedUser(loggedUser) + .process(net) + .author(loggedUser) .locale(Locale.getDefault()) .build()).getCase(); String taskId = useCase.getTasks().stream().findFirst().get().getTask(); diff --git a/application-engine/src/test/java/com/netgrif/application/engine/workflow/service/TaskServiceTest.java b/application-engine/src/test/java/com/netgrif/application/engine/workflow/service/TaskServiceTest.java index 4da77f5e5f..046bf7fd11 100644 --- a/application-engine/src/test/java/com/netgrif/application/engine/workflow/service/TaskServiceTest.java +++ b/application-engine/src/test/java/com/netgrif/application/engine/workflow/service/TaskServiceTest.java @@ -1,12 +1,9 @@ package com.netgrif.application.engine.workflow.service; import com.netgrif.application.engine.MockService; -import com.netgrif.application.engine.adapter.spring.auth.domain.LoggedUserImpl; import com.netgrif.application.engine.auth.service.AuthorityService; import com.netgrif.application.engine.auth.service.UserService; import com.netgrif.application.engine.importer.service.throwable.MissingIconKeyException; -import com.netgrif.application.engine.objects.auth.domain.ActorTransformer; -import com.netgrif.application.engine.objects.auth.domain.Authority; 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.domain.enums.UserState; @@ -23,16 +20,12 @@ import com.netgrif.application.engine.startup.runner.DefaultRealmRunner; import com.netgrif.application.engine.startup.runner.SuperCreatorRunner; import com.netgrif.application.engine.startup.runner.SystemUserRunner; -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.workflow.domain.repositories.CaseRepository; import com.netgrif.application.engine.workflow.domain.repositories.TaskRepository; import com.netgrif.application.engine.workflow.params.CreateCaseParams; import com.netgrif.application.engine.workflow.params.TaskParams; import com.netgrif.application.engine.workflow.service.interfaces.ITaskService; import com.netgrif.application.engine.workflow.service.interfaces.IWorkflowService; -import org.bson.types.ObjectId; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; @@ -44,7 +37,6 @@ import java.io.FileInputStream; import java.io.IOException; -import java.util.Set; @SpringBootTest @ActiveProfiles({"test"}) @@ -104,10 +96,10 @@ public void setUp() throws Exception { .build()); PetriNet net = petriNetRepository.findAll().get(0); workflowService.createCase(CreateCaseParams.with() - .petriNet(net) + .process(net) .title("Storage Unit") .color("color") - .loggedUser(mock.mockLoggedUser()) + .author(mock.mockLoggedUser()) .build()); } @@ -120,10 +112,10 @@ public void resetArcTest() throws TransitionNotExecutableException, MissingPetri .build()).getNet(); LoggedUser loggedUser = mock.mockLoggedUser(); CreateCaseEventOutcome outcome = workflowService.createCase(CreateCaseParams.with() - .petriNet(net) + .process(net) .title("Reset test") .color("color") - .loggedUser(loggedUser) + .author(loggedUser) .build()); User user = new User(); user.setFirstName("name"); diff --git a/application-engine/src/test/java/com/netgrif/application/engine/workflow/web/VariableArcsTest.java b/application-engine/src/test/java/com/netgrif/application/engine/workflow/web/VariableArcsTest.java index 427ac54678..a1f61c2029 100644 --- a/application-engine/src/test/java/com/netgrif/application/engine/workflow/web/VariableArcsTest.java +++ b/application-engine/src/test/java/com/netgrif/application/engine/workflow/web/VariableArcsTest.java @@ -144,10 +144,10 @@ public void importTest() throws MissingIconKeyException { List<Arc> arcs = this.loaded.getArcs().values().stream().flatMap(List::stream).collect(Collectors.toList()); assert arcs.size() > 0; CreateCaseEventOutcome caseOutcome = workflowService.createCase(CreateCaseParams.with() - .petriNet(this.loaded) + .process(this.loaded) .title("VARTEST") .color("red") - .loggedUser(mock.mockLoggedUser()) + .author(mock.mockLoggedUser()) .build()); assert caseOutcome.getCase().getPetriNet().getArcs() From a16849f52657765a5a65f0da9e451b3501f6b316 Mon Sep 17 00:00:00 2001 From: chvostek <chvostek@netgrif.com> Date: Thu, 13 Nov 2025 09:54:29 +0100 Subject: [PATCH 42/55] [NAE-2235] Improve Efficiency of Database Reads and Saves - fix initialization of default values in params classes --- .../application/engine/workflow/params/DeleteCaseParams.java | 2 ++ .../netgrif/application/engine/workflow/params/TaskParams.java | 2 ++ 2 files changed, 4 insertions(+) diff --git a/application-engine/src/main/java/com/netgrif/application/engine/workflow/params/DeleteCaseParams.java b/application-engine/src/main/java/com/netgrif/application/engine/workflow/params/DeleteCaseParams.java index fa8aad92f7..803c837d44 100644 --- a/application-engine/src/main/java/com/netgrif/application/engine/workflow/params/DeleteCaseParams.java +++ b/application-engine/src/main/java/com/netgrif/application/engine/workflow/params/DeleteCaseParams.java @@ -26,10 +26,12 @@ public DeleteCaseParams(Case useCase) { if (useCase != null) { this.useCaseId = useCase.getStringId(); } + this.params = new HashMap<>(); } public DeleteCaseParams(String useCaseId) { this.useCaseId = useCaseId; + this.params = new HashMap<>(); } public static class DeleteCaseParamsBuilder { diff --git a/application-engine/src/main/java/com/netgrif/application/engine/workflow/params/TaskParams.java b/application-engine/src/main/java/com/netgrif/application/engine/workflow/params/TaskParams.java index fc176c2d0e..29086dcbb6 100644 --- a/application-engine/src/main/java/com/netgrif/application/engine/workflow/params/TaskParams.java +++ b/application-engine/src/main/java/com/netgrif/application/engine/workflow/params/TaskParams.java @@ -34,6 +34,7 @@ public TaskParams(Task task, AbstractUser user) { this.taskId = task.getStringId(); } this.user = user; + this.params = new HashMap<>(); } public TaskParams(String taskId) { @@ -43,6 +44,7 @@ public TaskParams(String taskId) { public TaskParams(String taskId, AbstractUser user) { this.taskId = taskId; this.user = user; + this.params = new HashMap<>(); } public static class TaskParamsBuilder { From 406cafbf3033d7411adeea2982a5222f4cf8f35d Mon Sep 17 00:00:00 2001 From: chvostek <chvostek@netgrif.com> Date: Thu, 13 Nov 2025 10:49:16 +0100 Subject: [PATCH 43/55] [NAE-2235] Improve Efficiency of Database Reads and Saves - rollback ProcessRoleService.isRoleReferenced --- .../petrinet/domain/repositories/PetriNetRepository.java | 2 -- .../engine/petrinet/service/PetriNetService.java | 9 --------- .../engine/petrinet/service/ProcessRoleService.java | 4 +++- .../petrinet/service/interfaces/IPetriNetService.java | 4 ---- 4 files changed, 3 insertions(+), 16 deletions(-) diff --git a/application-engine/src/main/java/com/netgrif/application/engine/petrinet/domain/repositories/PetriNetRepository.java b/application-engine/src/main/java/com/netgrif/application/engine/petrinet/domain/repositories/PetriNetRepository.java index de3310bc60..38f38a7a5e 100644 --- a/application-engine/src/main/java/com/netgrif/application/engine/petrinet/domain/repositories/PetriNetRepository.java +++ b/application-engine/src/main/java/com/netgrif/application/engine/petrinet/domain/repositories/PetriNetRepository.java @@ -69,6 +69,4 @@ public interface PetriNetRepository extends MongoRepository<PetriNet, String>, Q @Query("{ 'roles.?0' : { $exists: true } }") Page<PetriNet> findAllByRoleId(String roleId, Pageable pageable); - @Query("{ 'roles.?0' : { $exists: true } }") - boolean existsByRoleId(String roleId); } \ No newline at end of file diff --git a/application-engine/src/main/java/com/netgrif/application/engine/petrinet/service/PetriNetService.java b/application-engine/src/main/java/com/netgrif/application/engine/petrinet/service/PetriNetService.java index 0cacdee201..20db3bb6b0 100644 --- a/application-engine/src/main/java/com/netgrif/application/engine/petrinet/service/PetriNetService.java +++ b/application-engine/src/main/java/com/netgrif/application/engine/petrinet/service/PetriNetService.java @@ -316,15 +316,6 @@ public Page<PetriNet> findAllByRoleId(String roleId, Pageable pageable) { return nets; } - @Override - public boolean existsByRoleId(String roleId) { - // todo test - if (roleId == null) { - return false; - } - return repository.existsByRoleId(roleId); - } - @Override public Page<PetriNet> getAll(Pageable pageable) { Page<PetriNet> nets = repository.findAll(pageable); diff --git a/application-engine/src/main/java/com/netgrif/application/engine/petrinet/service/ProcessRoleService.java b/application-engine/src/main/java/com/netgrif/application/engine/petrinet/service/ProcessRoleService.java index 89a887380e..7aa94b80a1 100644 --- a/application-engine/src/main/java/com/netgrif/application/engine/petrinet/service/ProcessRoleService.java +++ b/application-engine/src/main/java/com/netgrif/application/engine/petrinet/service/ProcessRoleService.java @@ -503,7 +503,9 @@ public void deleteGlobalRole(String roleId, LoggedUser loggedUser) { } protected boolean isRoleReferenced(ProcessRole processRole) { - return petriNetService.existsByRoleId(processRole.getStringId()); + Pageable pageable = PageRequest.of(0, 1); + Page<PetriNet> petriNetPage = petriNetService.findAllByRoleId(processRole.getStringId(), pageable); + return petriNetPage.getTotalElements() > 0; } private void removeRoleFromUser(AbstractUser user, ProcessRole processRole, LoggedUser loggedUser) { diff --git a/application-engine/src/main/java/com/netgrif/application/engine/petrinet/service/interfaces/IPetriNetService.java b/application-engine/src/main/java/com/netgrif/application/engine/petrinet/service/interfaces/IPetriNetService.java index 3fce2f414b..bc9fa80ab1 100644 --- a/application-engine/src/main/java/com/netgrif/application/engine/petrinet/service/interfaces/IPetriNetService.java +++ b/application-engine/src/main/java/com/netgrif/application/engine/petrinet/service/interfaces/IPetriNetService.java @@ -314,8 +314,4 @@ ImportPetriNetEventOutcome importPetriNet(ImportPetriNetParams importPetriNetPar */ Page<PetriNet> findAllByRoleId(String roleId, Pageable pageable); - /** - * todo javadoc - */ - boolean existsByRoleId(String roleId); } \ No newline at end of file From b9616a955775cef45356b12d0fad00f0169b62ce Mon Sep 17 00:00:00 2001 From: chvostek <chvostek@netgrif.com> Date: Thu, 13 Nov 2025 11:08:13 +0100 Subject: [PATCH 44/55] [NAE-2235] Improve Efficiency of Database Reads and Saves - rollback ProcessRoleService.delete --- .../domain/roles/ProcessRoleRepository.java | 26 ------------------- .../petrinet/service/ProcessRoleService.java | 4 +-- 2 files changed, 2 insertions(+), 28 deletions(-) diff --git a/application-engine/src/main/java/com/netgrif/application/engine/petrinet/domain/roles/ProcessRoleRepository.java b/application-engine/src/main/java/com/netgrif/application/engine/petrinet/domain/roles/ProcessRoleRepository.java index b18654d04c..87c6d92884 100755 --- a/application-engine/src/main/java/com/netgrif/application/engine/petrinet/domain/roles/ProcessRoleRepository.java +++ b/application-engine/src/main/java/com/netgrif/application/engine/petrinet/domain/roles/ProcessRoleRepository.java @@ -73,12 +73,6 @@ public interface ProcessRoleRepository extends MongoRepository<ProcessRole, Stri @Query("{ '_id.objectId': ?0 }") Optional<ProcessRole> findByIdObjectId(ObjectId objectId); - /** - * todo javadoc - */ - @Query("{ '_id.objectId': ?0 }") - void deleteByObjectId(ObjectId objectId); - /** * Finds all {@link ProcessRole} entities by their object IDs. * @@ -138,20 +132,6 @@ default Optional<ProcessRole> findByCompositeId(String compositeId) { } } - /** - * todo javadoc - */ - default void deleteByCompositeId(String compositeId) { - String[] parts = compositeId.split(ProcessResourceId.ID_SEPARATOR); - if (parts.length == 2) { - String networkId = parts[0]; - ObjectId objectId = new ObjectId(parts[1]); - deleteByNetworkIdAndObjectId(networkId, objectId); - } else { - deleteByObjectId(new ObjectId(compositeId)); - } - } - /** * Finds a {@link ProcessRole} by a network ID and object ID. * @@ -162,12 +142,6 @@ default void deleteByCompositeId(String compositeId) { @Query("{ '_id.shortProcessId': ?0, '_id.objectId': ?1 }") Optional<ProcessRole> findByNetworkIdAndObjectId(String networkId, ObjectId objectId); - /** - * todo javadoc - */ - @Query("{ '_id.shortProcessId': ?0, '_id.objectId': ?1 }") - void deleteByNetworkIdAndObjectId(String networkId, ObjectId objectId); - /** * Finds all {@link ProcessRole} entities by a collection of composite resource IDs. * diff --git a/application-engine/src/main/java/com/netgrif/application/engine/petrinet/service/ProcessRoleService.java b/application-engine/src/main/java/com/netgrif/application/engine/petrinet/service/ProcessRoleService.java index 7aa94b80a1..89f7dcebda 100644 --- a/application-engine/src/main/java/com/netgrif/application/engine/petrinet/service/ProcessRoleService.java +++ b/application-engine/src/main/java/com/netgrif/application/engine/petrinet/service/ProcessRoleService.java @@ -100,11 +100,11 @@ public Optional<ProcessRole> get(ProcessResourceId processResourceId) { @Override public void delete(String compositeId) { - // todo test if (compositeId == null) { return; } - processRoleRepository.deleteByCompositeId(compositeId); + Optional<ProcessRole> processRole = processRoleRepository.findByCompositeId(compositeId); + processRole.ifPresent(processRoleRepository::delete); } @Override From c97efa08b16e52c201fb2164832be0cb8a012a02 Mon Sep 17 00:00:00 2001 From: chvostek <chvostek@netgrif.com> Date: Thu, 13 Nov 2025 15:03:02 +0100 Subject: [PATCH 45/55] [NAE-2235] Improve Efficiency of Database Reads and Saves - add javadoc - fix variable initialization in ImportPetriNetParams --- .../petrinet/params/DeletePetriNetParams.java | 12 ++++++-- .../petrinet/params/ImportPetriNetParams.java | 19 +++++++++++-- .../service/interfaces/IPetriNetService.java | 21 +++++++++----- .../workflow/params/CreateCaseParams.java | 28 ++++++++++++++----- .../workflow/params/DelegateTaskParams.java | 20 +++++++++++-- .../workflow/params/DeleteCaseParams.java | 16 +++++++---- .../engine/workflow/params/TaskParams.java | 18 ++++++++---- .../engine/workflow/service/TaskService.java | 7 ++++- .../workflow/service/WorkflowService.java | 18 +++++++++--- .../engine/objects/workflow/domain/Case.java | 7 +++-- .../engine/objects/workflow/domain/Task.java | 7 +++-- 11 files changed, 133 insertions(+), 40 deletions(-) diff --git a/application-engine/src/main/java/com/netgrif/application/engine/petrinet/params/DeletePetriNetParams.java b/application-engine/src/main/java/com/netgrif/application/engine/petrinet/params/DeletePetriNetParams.java index 4183661804..e42e84e5b1 100644 --- a/application-engine/src/main/java/com/netgrif/application/engine/petrinet/params/DeletePetriNetParams.java +++ b/application-engine/src/main/java/com/netgrif/application/engine/petrinet/params/DeletePetriNetParams.java @@ -1,17 +1,25 @@ package com.netgrif.application.engine.petrinet.params; import com.netgrif.application.engine.objects.auth.domain.LoggedUser; +import com.netgrif.application.engine.petrinet.service.PetriNetService; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; +/** + * A parameter class for the {@link PetriNetService#deletePetriNet(DeletePetriNetParams)} method. + */ @Data @AllArgsConstructor @Builder(builderMethodName = "with") public class DeletePetriNetParams { - // todo javadoc + + /// String id of the process to be deleted private String petriNetId; + + /// User, who performs the process removal private LoggedUser loggedUser; -// * @param force whether to force the deletion without running events + + /// whether to force the removal without running events private boolean force; } diff --git a/application-engine/src/main/java/com/netgrif/application/engine/petrinet/params/ImportPetriNetParams.java b/application-engine/src/main/java/com/netgrif/application/engine/petrinet/params/ImportPetriNetParams.java index cc7a0c68dc..c6eac84847 100644 --- a/application-engine/src/main/java/com/netgrif/application/engine/petrinet/params/ImportPetriNetParams.java +++ b/application-engine/src/main/java/com/netgrif/application/engine/petrinet/params/ImportPetriNetParams.java @@ -1,7 +1,7 @@ package com.netgrif.application.engine.petrinet.params; import com.netgrif.application.engine.objects.auth.domain.AbstractUser; -import com.netgrif.application.engine.objects.auth.domain.LoggedUser; +import com.netgrif.application.engine.petrinet.service.PetriNetService; import com.netgrif.application.engine.objects.petrinet.domain.VersionType; import lombok.AllArgsConstructor; import lombok.Builder; @@ -11,17 +11,29 @@ import java.util.HashMap; import java.util.Map; +/** + * A parameter class for the {@link PetriNetService#importPetriNet(ImportPetriNetParams)} method. + */ @Data @AllArgsConstructor @Builder(builderMethodName = "with") public class ImportPetriNetParams { - // todo javadoc - + /// Input stream of the process XML file. private InputStream xmlFile; + + /// uri node id for the process private String uriNodeId; + + /** + * Release type of the process + * @see VersionType + */ private VersionType releaseType; + + /// Author of the process private AbstractUser author; + @Builder.Default private Map<String, String> params = new HashMap<>(); @@ -30,6 +42,7 @@ public ImportPetriNetParams(InputStream xmlFile, VersionType releaseType, Abstra this.releaseType = releaseType; this.author = author; this.uriNodeId = uriNodeId; + this.params = new HashMap<>(); } public ImportPetriNetParams(InputStream xmlFile, VersionType releaseType, AbstractUser author) { diff --git a/application-engine/src/main/java/com/netgrif/application/engine/petrinet/service/interfaces/IPetriNetService.java b/application-engine/src/main/java/com/netgrif/application/engine/petrinet/service/interfaces/IPetriNetService.java index bc9fa80ab1..69d502d27b 100644 --- a/application-engine/src/main/java/com/netgrif/application/engine/petrinet/service/interfaces/IPetriNetService.java +++ b/application-engine/src/main/java/com/netgrif/application/engine/petrinet/service/interfaces/IPetriNetService.java @@ -69,13 +69,15 @@ static DataFieldReference transformToReference(PetriNet net, Transition transiti /** * Imports a PetriNet from XML input. - * todo javadoc * - * @param importPetriNetParams additional parameters + * @param importPetriNetParams parameters for PetriNet import + * <br> + * <b>Required parameters: xmlFile, releaseType, author</b> + * * @return an {@link ImportPetriNetEventOutcome} representing the result - * @throws IOException if an I/O error occurs - * @throws MissingPetriNetMetaDataException if metadata is incomplete - * @throws MissingIconKeyException if an icon key is missing + * @throws IOException if an error occurs while processing the XML file + * @throws MissingPetriNetMetaDataException if metadata is missing from the PetriNet + * @throws MissingIconKeyException if an icon key is missing */ ImportPetriNetEventOutcome importPetriNet(ImportPetriNetParams importPetriNetParams) throws IOException, MissingPetriNetMetaDataException, MissingIconKeyException; @@ -274,8 +276,13 @@ ImportPetriNetEventOutcome importPetriNet(ImportPetriNetParams importPetriNetPar List<PetriNet> get(List<String> petriNetIds); /** - * Deletes a PetriNet by its ID. - * todo javadoc + * Deletes a PetriNet instance by its process ID. + * + * @param deletePetriNetParams parameters for petriNet removal + * <br> + * <b>Required parameters: petriNetId</b> + * + * @throws IllegalArgumentException if the PetriNet doesn't exist */ void deletePetriNet(DeletePetriNetParams deletePetriNetParams); diff --git a/application-engine/src/main/java/com/netgrif/application/engine/workflow/params/CreateCaseParams.java b/application-engine/src/main/java/com/netgrif/application/engine/workflow/params/CreateCaseParams.java index d18cdfd9c9..5edb1679b3 100644 --- a/application-engine/src/main/java/com/netgrif/application/engine/workflow/params/CreateCaseParams.java +++ b/application-engine/src/main/java/com/netgrif/application/engine/workflow/params/CreateCaseParams.java @@ -3,6 +3,7 @@ import com.netgrif.application.engine.objects.auth.domain.AbstractUser; import com.netgrif.application.engine.objects.petrinet.domain.PetriNet; import com.netgrif.application.engine.objects.workflow.domain.Case; +import com.netgrif.application.engine.workflow.service.WorkflowService; import lombok.Builder; import lombok.Data; import org.springframework.context.i18n.LocaleContextHolder; @@ -12,27 +13,42 @@ import java.util.Map; import java.util.function.Function; +/** + * A parameter class for the {@link WorkflowService#createCase(CreateCaseParams)} method + */ @Data @Builder(builderMethodName = "with") public class CreateCaseParams { - // todo javadoc + /// String id of the process to be used for creation private String processId; + + /// Identifier of the process to be used for creation private String processIdentifier; + + /// Process object to be used for creation private PetriNet process; + + /// Title of the new Case private String title; + + /// Function for the title initialization private Function<Case, String> makeTitle; + + /// Color of the new Case private String color; + + /// Author of the Case private AbstractUser author; + @Builder.Default private Locale locale = LocaleContextHolder.getLocale(); + @Builder.Default private Map<String, String> params = new HashMap<>(); public static class CreateCaseParamsBuilder { - /** - * Sets the {@link #title} and {@link #makeTitle} as well - * */ + /// Sets the {@link #title} and {@link #makeTitle} as well public CreateCaseParams.CreateCaseParamsBuilder title(String title) { this.title = title; if (title != null) { @@ -43,9 +59,7 @@ public CreateCaseParams.CreateCaseParamsBuilder title(String title) { return this; } - /** - * Sets the {@link #process} as clone, {@link #processIdentifier} and {@link #processId} - * */ + /// Sets the {@link #process} as clone, {@link #processIdentifier} and {@link #processId} public CreateCaseParams.CreateCaseParamsBuilder process(PetriNet petriNet) { this.process = new com.netgrif.application.engine.adapter.spring.petrinet.domain.PetriNet((com.netgrif.application.engine.adapter.spring.petrinet.domain.PetriNet) petriNet); this.processIdentifier = petriNet.getIdentifier(); diff --git a/application-engine/src/main/java/com/netgrif/application/engine/workflow/params/DelegateTaskParams.java b/application-engine/src/main/java/com/netgrif/application/engine/workflow/params/DelegateTaskParams.java index 6a25f62233..b3ced7dbeb 100644 --- a/application-engine/src/main/java/com/netgrif/application/engine/workflow/params/DelegateTaskParams.java +++ b/application-engine/src/main/java/com/netgrif/application/engine/workflow/params/DelegateTaskParams.java @@ -2,6 +2,7 @@ import com.netgrif.application.engine.objects.auth.domain.AbstractUser; import com.netgrif.application.engine.objects.workflow.domain.Case; +import com.netgrif.application.engine.workflow.service.TaskService; import com.netgrif.application.engine.objects.workflow.domain.Task; import lombok.AllArgsConstructor; import lombok.Builder; @@ -10,20 +11,35 @@ import java.util.HashMap; import java.util.Map; +/** + * A parameter class for the {@link TaskService#delegateTask(DelegateTaskParams)} method. + */ @Data @AllArgsConstructor @Builder(builderMethodName = "with") public class DelegateTaskParams { - // todo javadoc - + /// String id of the task to be delegated private String taskId; + + /// Task object to be delegated. The state of task must be up to date. private Task task; + + /// Case of the subject task. The state of useCase must be up to date. private Case useCase; + + /// The user, who is going to be a new assignee. private AbstractUser newAssignee; + + /// The user's string id, who is going to be a new assignee. private String newAssigneeId; + + /// The user, who is performing the delegation private AbstractUser delegator; + + /// The user's string id, who is performing the delegation private String delegatorId; + @Builder.Default private Map<String, String> params = new HashMap<>(); } diff --git a/application-engine/src/main/java/com/netgrif/application/engine/workflow/params/DeleteCaseParams.java b/application-engine/src/main/java/com/netgrif/application/engine/workflow/params/DeleteCaseParams.java index 803c837d44..9b0e12d80a 100644 --- a/application-engine/src/main/java/com/netgrif/application/engine/workflow/params/DeleteCaseParams.java +++ b/application-engine/src/main/java/com/netgrif/application/engine/workflow/params/DeleteCaseParams.java @@ -1,6 +1,7 @@ package com.netgrif.application.engine.workflow.params; import com.netgrif.application.engine.objects.workflow.domain.Case; +import com.netgrif.application.engine.workflow.service.WorkflowService; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; @@ -8,16 +9,23 @@ import java.util.HashMap; import java.util.Map; +/** + * A parameter class for the {@link WorkflowService#deleteCase(DeleteCaseParams)} method. + */ @Data @AllArgsConstructor @Builder(builderMethodName = "with") public class DeleteCaseParams { - // todo javadoc - + /// String id of the useCase to be deleted private String useCaseId; + + /// useCase to be deleted private Case useCase; + + /// If set to true, no event will be triggered. private boolean force; + @Builder.Default private Map<String, String> params = new HashMap<>(); @@ -35,9 +43,7 @@ public DeleteCaseParams(String useCaseId) { } public static class DeleteCaseParamsBuilder { - /** - * Sets the {@link #useCase} and {@link #useCaseId} - * */ + /// Sets the {@link #useCase} and {@link #useCaseId} public DeleteCaseParams.DeleteCaseParamsBuilder useCase(Case useCase) { this.useCase = useCase; if (useCase != null) { diff --git a/application-engine/src/main/java/com/netgrif/application/engine/workflow/params/TaskParams.java b/application-engine/src/main/java/com/netgrif/application/engine/workflow/params/TaskParams.java index 29086dcbb6..5bb5434629 100644 --- a/application-engine/src/main/java/com/netgrif/application/engine/workflow/params/TaskParams.java +++ b/application-engine/src/main/java/com/netgrif/application/engine/workflow/params/TaskParams.java @@ -3,6 +3,7 @@ import com.netgrif.application.engine.objects.auth.domain.AbstractUser; import com.netgrif.application.engine.objects.workflow.domain.Case; import com.netgrif.application.engine.objects.workflow.domain.Task; +import com.netgrif.application.engine.workflow.service.TaskService; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; @@ -10,17 +11,26 @@ import java.util.HashMap; import java.util.Map; +/** + * A parameter class for the {@link TaskService} interface's methods + */ @Data @AllArgsConstructor @Builder(builderMethodName = "with") public class TaskParams { - // todo javadoc - + /// String id of the subject task private String taskId; + + /// Subject task object. The state of task must be up to date. private Task task; + + /// Case of the subject task. The state of useCase must be up to date. private Case useCase; + + /// Subject user for the specific task event (new assignee or current assignee) private AbstractUser user; + @Builder.Default private Map<String, String> params = new HashMap<>(); @@ -48,9 +58,7 @@ public TaskParams(String taskId, AbstractUser user) { } public static class TaskParamsBuilder { - /** - * Sets the {@link #task} and {@link #taskId} - * */ + /// Sets the {@link #task} and {@link #taskId} public TaskParams.TaskParamsBuilder task(Task task) { this.task = task; if (task != null) { diff --git a/application-engine/src/main/java/com/netgrif/application/engine/workflow/service/TaskService.java b/application-engine/src/main/java/com/netgrif/application/engine/workflow/service/TaskService.java index 1fe600378b..f4cbaf14d5 100644 --- a/application-engine/src/main/java/com/netgrif/application/engine/workflow/service/TaskService.java +++ b/application-engine/src/main/java/com/netgrif/application/engine/workflow/service/TaskService.java @@ -480,7 +480,12 @@ protected Case evaluateRules(TaskEvent taskEvent) { * <td>Transition not executable</td><td>destroy task</td><td>no action</td> * </tr> * </table> - * todo javadoc + * + * @param useCase useCase for which to reload tasks + * @param lazyCaseSave if set to true, the useCase is saved only if any task is about to be executed. If set to false + * the useCase is saved every time this method is called. + * + * @return {@link ReloadTaskOutcome}, which holds the information if any task was executed and if the useCase was saved */ @SuppressWarnings("StatementWithEmptyBody") @Override diff --git a/application-engine/src/main/java/com/netgrif/application/engine/workflow/service/WorkflowService.java b/application-engine/src/main/java/com/netgrif/application/engine/workflow/service/WorkflowService.java index aa2c99a8de..632d4d7793 100644 --- a/application-engine/src/main/java/com/netgrif/application/engine/workflow/service/WorkflowService.java +++ b/application-engine/src/main/java/com/netgrif/application/engine/workflow/service/WorkflowService.java @@ -250,8 +250,14 @@ public Case resolveUserRef(Case useCase, boolean canSaveUseCase) { } /** - * todo javadoc - * */ + * Resolves user permissions for the useCase based on the user list data field. + * + * @param useCase useCase where to resolve user permissions + * @param userListId field id of the user list + * @param permission permission associated with the useCase and user list + * + * @return true if the useCase was modified, false otherwise + */ private boolean resolveUserRefPermissions(Case useCase, String userListId, Map<String, Boolean> permission) { List<String> userIds = getExistingUsers((UserListFieldValue) useCase.getDataSet().get(userListId).getValue()); if (userIds != null && !userIds.isEmpty()) { @@ -501,8 +507,12 @@ public void setPetriNet(Case useCase) { } /** - * todo javadoc - * */ + * Initializes task ref data fields with the task ids based on field definition in petriNet + * + * @param useCase useCase where to initialize task ref data fields + * + * @return true if useCase was modified, false otherwise + */ protected boolean resolveTaskRefs(Case useCase) { AtomicBoolean anyDataFieldChanged = new AtomicBoolean(false); useCase.getPetriNet().getDataSet().values().stream() diff --git a/nae-object-library/src/main/java/com/netgrif/application/engine/objects/workflow/domain/Case.java b/nae-object-library/src/main/java/com/netgrif/application/engine/objects/workflow/domain/Case.java index 9461eb832e..e79505791e 100644 --- a/nae-object-library/src/main/java/com/netgrif/application/engine/objects/workflow/domain/Case.java +++ b/nae-object-library/src/main/java/com/netgrif/application/engine/objects/workflow/domain/Case.java @@ -310,8 +310,11 @@ public void resolveViewUserRefs() { } /** - * todo javadoc - * */ + * Initializes {@link #viewUsers} collection. Any user defined in {@link #users} with permission {@link RolePermission#VIEW} + * of true value is added to the {@link #viewUsers} collection. + * + * @return true if the {@link #viewUsers} was modified, false otherwise + */ public boolean resolveViewUsers() { AtomicBoolean isModified = new AtomicBoolean(!this.viewUsers.isEmpty()); this.viewUsers.clear(); diff --git a/nae-object-library/src/main/java/com/netgrif/application/engine/objects/workflow/domain/Task.java b/nae-object-library/src/main/java/com/netgrif/application/engine/objects/workflow/domain/Task.java index a2f9c4c7bd..5f94bb9e7d 100644 --- a/nae-object-library/src/main/java/com/netgrif/application/engine/objects/workflow/domain/Task.java +++ b/nae-object-library/src/main/java/com/netgrif/application/engine/objects/workflow/domain/Task.java @@ -314,8 +314,11 @@ public void resolveViewUserRefs() { } /** - * todo javadoc - * */ + * Initializes {@link #viewUsers} collection. Any user defined in {@link #users} with permission {@link RolePermission#VIEW} + * of true value is added to the {@link #viewUsers} collection. + * + * @return true if the {@link #viewUsers} was modified, false otherwise + */ public boolean resolveViewUsers() { getViewUsers(); AtomicBoolean isModified = new AtomicBoolean(!this.viewUsers.isEmpty()); From 449051b037952a254e4f1e7c1d8c1f2ca648ad6e Mon Sep 17 00:00:00 2001 From: chvostek <chvostek@netgrif.com> Date: Fri, 14 Nov 2025 10:16:28 +0100 Subject: [PATCH 46/55] [NAE-2235] Improve Efficiency of Database Reads and Saves - fix possible leak with try-with-resources --- .../engine/migration/ActionMigration.groovy | 51 ++++++++++--------- 1 file changed, 26 insertions(+), 25 deletions(-) diff --git a/application-engine/src/main/groovy/com/netgrif/application/engine/migration/ActionMigration.groovy b/application-engine/src/main/groovy/com/netgrif/application/engine/migration/ActionMigration.groovy index 8f22152c55..37b1832339 100644 --- a/application-engine/src/main/groovy/com/netgrif/application/engine/migration/ActionMigration.groovy +++ b/application-engine/src/main/groovy/com/netgrif/application/engine/migration/ActionMigration.groovy @@ -25,33 +25,34 @@ class ActionMigration { private UserService userService; void migrateActions(String petriNetPath) { - InputStream netStream = new ClassPathResource(petriNetPath).inputStream - ImportPetriNetEventOutcome newPetriNet = petriNetService.importPetriNet(ImportPetriNetParams.with() - .xmlFile(netStream) - .releaseType(VersionType.MAJOR) - .author(ActorTransformer.toLoggedUser(userService.getLoggedOrSystem())) - .build()) - List<PetriNet> oldPetriNets + try (InputStream netStream = new ClassPathResource(petriNetPath).inputStream) { + ImportPetriNetEventOutcome newPetriNet = petriNetService.importPetriNet(ImportPetriNetParams.with() + .xmlFile(netStream) + .releaseType(VersionType.MAJOR) + .author(ActorTransformer.toLoggedUser(userService.getLoggedOrSystem())) + .build()) + List<PetriNet> oldPetriNets - if(newPetriNet.getNet() != null) { - String message = "Petri net from file [" + petriNetPath + "] was not imported" - log.error(message) - throw new IllegalArgumentException(message) - } else { - oldPetriNets = petriNetService.getByIdentifier(newPetriNet.getNet().importId) - .stream().filter({ net -> (net.version != newPetriNet.getNet().version)}) - .collect(Collectors.toList()) - } + if (newPetriNet.getNet() != null) { + String message = "Petri net from file [" + petriNetPath + "] was not imported" + log.error(message) + throw new IllegalArgumentException(message) + } else { + oldPetriNets = petriNetService.getByIdentifier(newPetriNet.getNet().importId) + .stream().filter({ net -> (net.version != newPetriNet.getNet().version)}) + .collect(Collectors.toList()) + } - if(oldPetriNets.size() == 0){ - String message = "Older version of Petri net with ID [" + newPetriNet.getNet().importId + "] is not present in MongoDB." - log.error(message) - throw new IllegalArgumentException(message) - } else { - oldPetriNets.each {net -> - migrateDataSetActions(newPetriNet.getNet(), net) - migrateDataRefActions(newPetriNet.getNet(), net) - petriNetService.save(net) + if (oldPetriNets.size() == 0){ + String message = "Older version of Petri net with ID [" + newPetriNet.getNet().importId + "] is not present in MongoDB." + log.error(message) + throw new IllegalArgumentException(message) + } else { + oldPetriNets.each {net -> + migrateDataSetActions(newPetriNet.getNet(), net) + migrateDataRefActions(newPetriNet.getNet(), net) + petriNetService.save(net) + } } } } From 7263d4eb37a8fa51e923109217ce2fd637c61288 Mon Sep 17 00:00:00 2001 From: chvostek <chvostek@netgrif.com> Date: Fri, 14 Nov 2025 10:21:53 +0100 Subject: [PATCH 47/55] [NAE-2235] Improve Efficiency of Database Reads and Saves - fix incorrect counter in a log message --- .../application/engine/auth/service/RegistrationService.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/application-engine/src/main/java/com/netgrif/application/engine/auth/service/RegistrationService.java b/application-engine/src/main/java/com/netgrif/application/engine/auth/service/RegistrationService.java index a23b4b5564..f85cab460b 100644 --- a/application-engine/src/main/java/com/netgrif/application/engine/auth/service/RegistrationService.java +++ b/application-engine/src/main/java/com/netgrif/application/engine/auth/service/RegistrationService.java @@ -66,6 +66,7 @@ public void resetExpiredToken() { Pageable pageable = PageRequest.of(0, paginationProperties.getBackendPageSize()); Page<User> users; + int totalReset = 0; do { users = userService.findAllByStateAndExpirationDateBefore(UserState.BLOCKED, LocalDateTime.now(), null, pageable); if (users == null || users.isEmpty()) { @@ -78,11 +79,12 @@ public void resetExpiredToken() { user.setExpirationDate(null); }); userService.saveUsers(users.getContent().stream().map(AbstractUser.class::cast).toList()); + totalReset += users.getContent().size(); pageable = pageable.next(); } while (users.hasNext()); - log.info("Reset {} expired user tokens", users.getContent().size()); + log.info("Reset {} expired user tokens", totalReset); } @Override From 51b200b3bea7d7e9aadda18ded2f52c00db94742 Mon Sep 17 00:00:00 2001 From: chvostek <chvostek@netgrif.com> Date: Fri, 14 Nov 2025 10:29:31 +0100 Subject: [PATCH 48/55] [NAE-2235] Improve Efficiency of Database Reads and Saves - change logging level info --- .../application/engine/auth/service/RegistrationService.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/application-engine/src/main/java/com/netgrif/application/engine/auth/service/RegistrationService.java b/application-engine/src/main/java/com/netgrif/application/engine/auth/service/RegistrationService.java index f85cab460b..1583db825f 100644 --- a/application-engine/src/main/java/com/netgrif/application/engine/auth/service/RegistrationService.java +++ b/application-engine/src/main/java/com/netgrif/application/engine/auth/service/RegistrationService.java @@ -98,7 +98,7 @@ public void changePassword(AbstractUser user, String newPassword) { @Override public boolean verifyToken(String token) { try { - log.info("Verifying token: {}", token); + log.debug("Verifying token: {}", token); String[] tokenParts = decodeToken(token); User user = (User) userService.findByEmail(tokenParts[0], null); return user != null && Objects.equals(user.getToken(), tokenParts[1]) && user.getExpirationDate().isAfter(LocalDateTime.now()); From d163493329fc16c3d762ec7039abda32b2161768 Mon Sep 17 00:00:00 2001 From: chvostek <chvostek@netgrif.com> Date: Fri, 14 Nov 2025 10:55:39 +0100 Subject: [PATCH 49/55] [NAE-2235] Improve Efficiency of Database Reads and Saves - add stack trace in an error message --- .../engine/elastic/service/ElasticTaskQueueManager.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/application-engine/src/main/java/com/netgrif/application/engine/elastic/service/ElasticTaskQueueManager.java b/application-engine/src/main/java/com/netgrif/application/engine/elastic/service/ElasticTaskQueueManager.java index cc869a3911..94f6d0bfe5 100644 --- a/application-engine/src/main/java/com/netgrif/application/engine/elastic/service/ElasticTaskQueueManager.java +++ b/application-engine/src/main/java/com/netgrif/application/engine/elastic/service/ElasticTaskQueueManager.java @@ -56,7 +56,7 @@ public Future<ElasticTask> scheduleOperation(ElasticTaskJob task) { try { queue.add(taskWrapper); } catch (Exception e) { - log.error("Queue error: {}", e.getMessage()); + log.error("Queue error: {}", e.getMessage(), e); throw e; } From 10f6aa9fb9ef7b4a87655b6e4ef8b7494f4cd0a3 Mon Sep 17 00:00:00 2001 From: chvostek <chvostek@netgrif.com> Date: Fri, 14 Nov 2025 11:07:06 +0100 Subject: [PATCH 50/55] [NAE-2235] Improve Efficiency of Database Reads and Saves - remove token from log messages to reduce security risk --- .../java/com/netgrif/application/engine/mail/MailService.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/application-engine/src/main/java/com/netgrif/application/engine/mail/MailService.java b/application-engine/src/main/java/com/netgrif/application/engine/mail/MailService.java index e43b98d9ab..3eba895847 100644 --- a/application-engine/src/main/java/com/netgrif/application/engine/mail/MailService.java +++ b/application-engine/src/main/java/com/netgrif/application/engine/mail/MailService.java @@ -74,7 +74,7 @@ public void sendRegistrationEmail(AbstractUser user) throws IOException, Templat MimeMessage email = buildEmail(mailDraft); mailSender.send(email); - log.info("Registration email sent to [{}] with token [{}], expiring on [{}]", user.getEmail(), model.get(TOKEN), model.get(EXPIRATION)); + log.info("Registration email sent to [{}] with a token expiring on [{}]", user.getEmail(), model.get(EXPIRATION)); } @Override @@ -94,7 +94,7 @@ public void sendPasswordResetEmail(AbstractUser user) throws IOException, Templa MimeMessage email = buildEmail(mailDraft); mailSender.send(email); - log.info("Reset email sent to [{}] with token [{}], expiring on [{}]", user.getEmail(), model.get(TOKEN), model.get(EXPIRATION)); + log.info("Reset email sent to [{}] with a token expiring on [{}]", user.getEmail(), model.get(EXPIRATION)); } @Override From 2a0d30588016b7f3c2b921a2f1f4ee52136f0423 Mon Sep 17 00:00:00 2001 From: chvostek <chvostek@netgrif.com> Date: Fri, 14 Nov 2025 12:01:40 +0100 Subject: [PATCH 51/55] [NAE-2235] Improve Efficiency of Database Reads and Saves - override builder methods in DelegateTaskParams --- .../workflow/params/DelegateTaskParams.java | 29 +++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/application-engine/src/main/java/com/netgrif/application/engine/workflow/params/DelegateTaskParams.java b/application-engine/src/main/java/com/netgrif/application/engine/workflow/params/DelegateTaskParams.java index b3ced7dbeb..c1c8ad177b 100644 --- a/application-engine/src/main/java/com/netgrif/application/engine/workflow/params/DelegateTaskParams.java +++ b/application-engine/src/main/java/com/netgrif/application/engine/workflow/params/DelegateTaskParams.java @@ -42,4 +42,33 @@ public class DelegateTaskParams { @Builder.Default private Map<String, String> params = new HashMap<>(); + + public static class DelegateTaskParamsBuilder { + /// Sets the {@link #task} and {@link #taskId} + public DelegateTaskParamsBuilder task(Task task) { + this.task = task; + if (task != null) { + this.taskId = task.getStringId(); + } + return this; + } + + /// Sets the {@link #newAssignee} and {@link #newAssigneeId} + public DelegateTaskParamsBuilder newAssignee(AbstractUser newAssignee) { + this.newAssignee = newAssignee; + if (newAssignee != null) { + this.newAssigneeId = newAssignee.getStringId(); + } + return this; + } + + /// Sets the {@link #delegator} and {@link #delegatorId} + public DelegateTaskParamsBuilder delegator(AbstractUser delegator) { + this.delegator = delegator; + if (delegator != null) { + this.delegatorId = delegator.getStringId(); + } + return this; + } + } } From ab50f49d1b06f6d3dfb79a861319fc15dfb44f3e Mon Sep 17 00:00:00 2001 From: chvostek <chvostek@netgrif.com> Date: Fri, 14 Nov 2025 12:13:30 +0100 Subject: [PATCH 52/55] [NAE-2235] Improve Efficiency of Database Reads and Saves - fix stale useCase problem --- .../application/engine/workflow/service/TaskService.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/application-engine/src/main/java/com/netgrif/application/engine/workflow/service/TaskService.java b/application-engine/src/main/java/com/netgrif/application/engine/workflow/service/TaskService.java index f4cbaf14d5..d3933d8efb 100644 --- a/application-engine/src/main/java/com/netgrif/application/engine/workflow/service/TaskService.java +++ b/application-engine/src/main/java/com/netgrif/application/engine/workflow/service/TaskService.java @@ -331,7 +331,7 @@ public void cancelTasksWithoutReload(Set<String> transitions, String caseId, Map } Transition transition = useCase.getPetriNet().getTransition(task.getTransitionId()); - boolean anyActionExecuted = eventService.runActions(transition.getPreCancelActions(), useCase, task, + boolean anyActionExecuted = !eventService.runActions(transition.getPreCancelActions(), useCase, task, transition, params).isEmpty(); if (anyActionExecuted) { useCase = workflowService.findOne(useCase.getStringId()); From 2deef9c7476a8a9108428b854d00a31d9f7bb664 Mon Sep 17 00:00:00 2001 From: chvostek <chvostek@netgrif.com> Date: Fri, 14 Nov 2025 12:46:16 +0100 Subject: [PATCH 53/55] [NAE-2235] Improve Efficiency of Database Reads and Saves - improve consistency in WorkflowController --- .../application/engine/workflow/web/WorkflowController.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/application-engine/src/main/java/com/netgrif/application/engine/workflow/web/WorkflowController.java b/application-engine/src/main/java/com/netgrif/application/engine/workflow/web/WorkflowController.java index eeb7edbd7a..7222b4ae96 100644 --- a/application-engine/src/main/java/com/netgrif/application/engine/workflow/web/WorkflowController.java +++ b/application-engine/src/main/java/com/netgrif/application/engine/workflow/web/WorkflowController.java @@ -217,7 +217,7 @@ public MessageResource reloadTasks(@PathVariable("id") String caseId) { @DeleteMapping(value = "/case/{id}", produces = MediaTypes.HAL_JSON_VALUE) public EntityModel<EventOutcomeWithMessage> deleteCase(Authentication auth, @PathVariable("id") String caseId, @RequestParam(defaultValue = "false") boolean deleteSubtree) { try { - caseId = URLDecoder.decode(caseId, StandardCharsets.UTF_8.name()); + caseId = URLDecoder.decode(caseId, StandardCharsets.UTF_8); DeleteCaseEventOutcome outcome; if (deleteSubtree) { outcome = workflowService.deleteSubtreeRootedAt(caseId); @@ -228,7 +228,7 @@ public EntityModel<EventOutcomeWithMessage> deleteCase(Authentication auth, @Pat } return EventOutcomeWithMessageResource.successMessage("Case " + caseId + " was deleted", LocalisedEventOutcomeFactory.from(outcome, LocaleContextHolder.getLocale())); - } catch (UnsupportedEncodingException e) { + } catch (Exception e) { log.error("Deleting case [{}] failed:", caseId, e); return EventOutcomeWithMessageResource.errorMessage("Deleting case " + caseId + " has failed!"); } From a86d7d967dc2673849dfb0b71cfbfc0f5e606db4 Mon Sep 17 00:00:00 2001 From: chvostek <chvostek@netgrif.com> Date: Fri, 14 Nov 2025 12:54:06 +0100 Subject: [PATCH 54/55] [NAE-2235] Improve Efficiency of Database Reads and Saves - fix possible input stream leak in test files --- .../elastic/DataSearchRequestTest.groovy | 25 +++++++++---------- .../domain/dataset/DynamicChoicesTest.groovy | 17 +++++++------ .../workflow/SetDataOnButtonTest.groovy | 12 +++++---- 3 files changed, 29 insertions(+), 25 deletions(-) diff --git a/application-engine/src/test/groovy/com/netgrif/application/engine/elastic/DataSearchRequestTest.groovy b/application-engine/src/test/groovy/com/netgrif/application/engine/elastic/DataSearchRequestTest.groovy index 1ecdb1e95a..8c93488d8d 100644 --- a/application-engine/src/test/groovy/com/netgrif/application/engine/elastic/DataSearchRequestTest.groovy +++ b/application-engine/src/test/groovy/com/netgrif/application/engine/elastic/DataSearchRequestTest.groovy @@ -2,24 +2,20 @@ package com.netgrif.application.engine.elastic import com.netgrif.application.engine.MockService import com.netgrif.application.engine.TestHelper +import com.netgrif.application.engine.adapter.spring.workflow.domain.QTask import com.netgrif.application.engine.auth.service.UserService import com.netgrif.application.engine.elastic.domain.ElasticCaseRepository import com.netgrif.application.engine.elastic.service.interfaces.IElasticCaseService import com.netgrif.application.engine.elastic.service.interfaces.IElasticIndexService import com.netgrif.application.engine.elastic.web.requestbodies.CaseSearchRequest import com.netgrif.application.engine.objects.petrinet.domain.VersionType -import com.netgrif.application.engine.objects.petrinet.domain.dataset.ChoiceField -import com.netgrif.application.engine.objects.petrinet.domain.dataset.FileFieldValue -import com.netgrif.application.engine.objects.petrinet.domain.dataset.FileListFieldValue -import com.netgrif.application.engine.objects.petrinet.domain.dataset.UserFieldValue -import com.netgrif.application.engine.objects.petrinet.domain.dataset.UserListFieldValue +import com.netgrif.application.engine.objects.petrinet.domain.dataset.* +import com.netgrif.application.engine.objects.workflow.domain.Case +import com.netgrif.application.engine.objects.workflow.domain.Task import com.netgrif.application.engine.petrinet.params.ImportPetriNetParams import com.netgrif.application.engine.petrinet.service.interfaces.IPetriNetService import com.netgrif.application.engine.startup.ImportHelper import com.netgrif.application.engine.startup.runner.SuperCreatorRunner -import com.netgrif.application.engine.objects.workflow.domain.Case -import com.netgrif.application.engine.adapter.spring.workflow.domain.QTask -import com.netgrif.application.engine.objects.workflow.domain.Task 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 @@ -97,11 +93,14 @@ class DataSearchRequestTest { void before() { testHelper.truncateDbs() - def net = petriNetService.importPetriNet(ImportPetriNetParams.with() - .xmlFile(new FileInputStream("src/test/resources/all_data.xml")) - .releaseType(VersionType.MAJOR) - .author(superCreator.getLoggedSuper()) - .build()) + def net = null + new FileInputStream("src/test/resources/all_data.xml").withCloseable {inputStream -> + net = petriNetService.importPetriNet(ImportPetriNetParams.with() + .xmlFile(inputStream) + .releaseType(VersionType.MAJOR) + .author(superCreator.getLoggedSuper()) + .build()) + } assert net.getNet() != null def users = userService.findAllUsers(null, Pageable.ofSize(100)) diff --git a/application-engine/src/test/groovy/com/netgrif/application/engine/petrinet/domain/dataset/DynamicChoicesTest.groovy b/application-engine/src/test/groovy/com/netgrif/application/engine/petrinet/domain/dataset/DynamicChoicesTest.groovy index c622a741c5..0d38f11709 100644 --- a/application-engine/src/test/groovy/com/netgrif/application/engine/petrinet/domain/dataset/DynamicChoicesTest.groovy +++ b/application-engine/src/test/groovy/com/netgrif/application/engine/petrinet/domain/dataset/DynamicChoicesTest.groovy @@ -51,13 +51,16 @@ class DynamicChoicesTest { @Test void testDynamicEnum() { - ImportPetriNetEventOutcome optNet = petriNetService.importPetriNet(ImportPetriNetParams.with() - .xmlFile(new FileInputStream("src/test/resources/petriNets/dynamic_choices.xml")) - .releaseType(VersionType.MAJOR) - .author(superCreator.getLoggedSuper()) - .build()); - - assert optNet.getNet() != null; + ImportPetriNetEventOutcome optNet = null + new FileInputStream("src/test/resources/petriNets/dynamic_choices.xml").withCloseable { inputStream -> + optNet = petriNetService.importPetriNet(ImportPetriNetParams.with() + .xmlFile(inputStream) + .releaseType(VersionType.MAJOR) + .author(superCreator.getLoggedSuper()) + .build()) + } + + assert optNet.getNet() != null def net = optNet.getNet() def aCase = importHelper.createCase("Case", net) diff --git a/application-engine/src/test/groovy/com/netgrif/application/engine/workflow/SetDataOnButtonTest.groovy b/application-engine/src/test/groovy/com/netgrif/application/engine/workflow/SetDataOnButtonTest.groovy index e554670d6b..8c291b4684 100644 --- a/application-engine/src/test/groovy/com/netgrif/application/engine/workflow/SetDataOnButtonTest.groovy +++ b/application-engine/src/test/groovy/com/netgrif/application/engine/workflow/SetDataOnButtonTest.groovy @@ -69,11 +69,13 @@ class SetDataOnButtonTest { @BeforeEach void initNet() { testHelper.truncateDbs() - net = petriNetService.importPetriNet(ImportPetriNetParams.with() - .xmlFile(new FileInputStream(RESOURCE_PATH)) - .releaseType(VersionType.MAJOR) - .author(ActorTransformer.toLoggedUser(userService.getLoggedOrSystem())) - .build()).getNet() + new FileInputStream(RESOURCE_PATH).withCloseable { inputStream -> + net = petriNetService.importPetriNet(ImportPetriNetParams.with() + .xmlFile(inputStream) + .releaseType(VersionType.MAJOR) + .author(ActorTransformer.toLoggedUser(userService.getLoggedOrSystem())) + .build()).getNet() + } assert net != null } From a0eb9f2470065574d575a60370e879dffbc1649c Mon Sep 17 00:00:00 2001 From: chvostek <chvostek@netgrif.com> Date: Fri, 14 Nov 2025 13:10:16 +0100 Subject: [PATCH 55/55] [NAE-2235] Improve Efficiency of Database Reads and Saves - fix ActionMigration.migrateActions to fail on every successful import --- .../netgrif/application/engine/migration/ActionMigration.groovy | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/application-engine/src/main/groovy/com/netgrif/application/engine/migration/ActionMigration.groovy b/application-engine/src/main/groovy/com/netgrif/application/engine/migration/ActionMigration.groovy index 37b1832339..b9529bd23d 100644 --- a/application-engine/src/main/groovy/com/netgrif/application/engine/migration/ActionMigration.groovy +++ b/application-engine/src/main/groovy/com/netgrif/application/engine/migration/ActionMigration.groovy @@ -33,7 +33,7 @@ class ActionMigration { .build()) List<PetriNet> oldPetriNets - if (newPetriNet.getNet() != null) { + if (newPetriNet.getNet() == null) { String message = "Petri net from file [" + petriNetPath + "] was not imported" log.error(message) throw new IllegalArgumentException(message)