Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
37 commits
Select commit Hold shift + click to select a range
a002636
NAE-2212 - added method that will cache all petriNets functions
dominikvozr Sep 24, 2025
e6e8dac
NAE-2212 - added prevention of cache namespaceFunctions deletion from…
dominikvozr Sep 25, 2025
6e09ba1
NAE-2212 - repair of PR, rework to use petriNetService and other
dominikvozr Sep 25, 2025
790659b
- test fix
renczesstefan Sep 29, 2025
dd80913
- test fix
renczesstefan Sep 30, 2025
7dc7947
[NAE-2212] Change list to set, remove CacheMapKeys, use copyOf for sa…
dominikvozr Sep 30, 2025
eb56f99
Merge remote-tracking branch 'origin/release/7.0.0-rev8' into NAE-2212
machacjozef Sep 30, 2025
93921f9
fix
machacjozef Sep 30, 2025
cf3dc8c
Merge remote-tracking branch 'origin/release/7.0.0-rev8' into NAE-2212
machacjozef Sep 30, 2025
fc76808
[NAE-2266] Introduce active version of process
Retoocs Nov 19, 2025
b5bd5b5
[NAE-2266] Introduce active version of process
Retoocs Nov 19, 2025
9059bec
[NAE-2266] Introduce active version of process
Retoocs Nov 19, 2025
dfd7afd
[NAE-2266] Introduce active version of process
Retoocs Nov 20, 2025
e8441cb
[NAE-2266] Introduce active version of process
Retoocs Nov 20, 2025
0c1c914
[NAE-2266] Introduce active version of process
Retoocs Nov 20, 2025
53fb4e6
[NAE-2266] Introduce active version of process
Retoocs Nov 21, 2025
1cdfbc4
[NAE-2266] Introduce active version of process
Retoocs Nov 21, 2025
47ba662
[NAE-2266] Introduce active version of process
Retoocs Nov 21, 2025
7e0c9b8
[NAE-2266] Introduce active version of process
Retoocs Nov 21, 2025
4670f33
[NAE-2266] Introduce active version of process
Retoocs Nov 21, 2025
cf0651a
[NAE-2266] Introduce active version of process
Retoocs Nov 24, 2025
48e1411
[NAE-2266] Introduce active version of process
Retoocs Nov 25, 2025
b30c884
[NAE-2266] Introduce active version of process
Retoocs Nov 25, 2025
d7705b2
[NAE-2266] Introduce active version of process
Retoocs Nov 27, 2025
2654b7d
[NAE-2266] Introduce active version of process
Retoocs Nov 27, 2025
d457145
Merge remote-tracking branch 'origin/release/7.0.0-rev9' into NAE-2266
Retoocs Nov 27, 2025
61f9b2e
[NAE-2266] Introduce active version of process
Retoocs Nov 28, 2025
289de0f
[NAE-2266] Introduce active version of process
Retoocs Nov 28, 2025
e9ef494
[NAE-2266] Introduce active version of process
Retoocs Nov 28, 2025
2274d62
[NAE-2266] Introduce active version of process
Retoocs Nov 28, 2025
39da22c
Merge remote-tracking branch 'origin/release/7.0.0-rev9' into NAE-2266
Retoocs Dec 8, 2025
d82fc67
Merge branch 'release/7.0.0-rev9' into NAE-2212
renczesstefan Dec 12, 2025
174c7ee
[NAE-2212] Global scope process function caches
renczesstefan Dec 16, 2025
faa99d7
Merge remote-tracking branch 'refs/remotes/origin/NAE-2266' into NAE-…
renczesstefan Dec 18, 2025
44c6ed7
[NAE-2212] Global scope process function caches
renczesstefan Dec 18, 2025
fc637ee
[NAE-2212] Global scope process function caches
renczesstefan Dec 18, 2025
6d84f5b
Remove redundant dependencies and fix scope comparison logic.
renczesstefan Dec 18, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 0 additions & 12 deletions application-engine/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -270,18 +270,6 @@
<version>${junit-jupiter.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-api</artifactId>
<version>${junit-jupiter.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-engine</artifactId>
<version>${junit-jupiter.version}</version>
<scope>test</scope>
</dependency>
<!-- Groovy -->
<!-- https://mvnrepository.com/artifact/org.codehaus.groovy/groovy-all -->
<dependency>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2444,9 +2444,13 @@ class ActionDelegate {
return [(role.importId + ":" + GLOBAL_ROLE), ("$role.name (🌍 Global role)" as String)]
} else {
if (!temp.containsKey(entry.value)) {
temp.put(entry.value, petriNetService.getNewestVersionByIdentifier(entry.value))
temp.put(entry.value, petriNetService.getActiveVersionByIdentifier(entry.value))
}
PetriNet net = temp[entry.value]
if (net == null) {
throw new IllegalArgumentException("The process with identifier [%s] could not be found when collecting roles."
.formatted(entry.value))
}
ProcessRole role = net.roles.find { it.value.importId == entry.key }.value
return [(role.importId + ":" + net.identifier), ("$role.name ($net.title)" as String)]
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ abstract class FieldActionsRunner {
actionsCacheService.getCachedFunctions(functions).each {
actionDelegate.metaClass."${it.function.name}" << it.code
}
actionsCacheService.getNamespaceFunctionCache().each { entry ->
actionsCacheService.getGlobalFunctionsCache().each { entry ->
def namespace = [:]
entry.getValue().each {
namespace["${it.function.name}"] = it.code.rehydrate(actionDelegate, it.code.owner, it.code.thisObject)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,10 @@ class RoleActionDelegate extends AbstractActionDelegate<RoleContext> {
}

AbstractUser assignRole(String roleImportId, String petriNetIdentifier, AbstractUser user = affectedUser) {
PetriNet petriNet = petriNetService.getNewestVersionByIdentifier(petriNetIdentifier)
PetriNet petriNet = petriNetService.getActiveVersionByIdentifier(petriNetIdentifier)
if (petriNet == null) {
throw new IllegalArgumentException("The process with identifier [%s] could not be found".formatted(petriNetIdentifier))
}
assignRole(roleImportId, user, petriNet)
}

Expand All @@ -75,7 +78,10 @@ class RoleActionDelegate extends AbstractActionDelegate<RoleContext> {
}

AbstractUser removeRole(String roleImportId, String petriNetIdentifier, AbstractUser user = affectedUser) {
PetriNet petriNet = petriNetService.getNewestVersionByIdentifier(petriNetIdentifier)
PetriNet petriNet = petriNetService.getActiveVersionByIdentifier(petriNetIdentifier)
if (petriNet == null) {
throw new IllegalArgumentException("The process with identifier [%s] could not be found".formatted(petriNetIdentifier))
}
removeRole(roleImportId, user, petriNet)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,7 @@ class ImportHelper {
}

Optional<PetriNet> upsertNet(String filename, String identifier, VersionType release = VersionType.MAJOR, LoggedUser author = ActorTransformer.toLoggedUser(userService.getSystem())) {
PetriNet petriNet = petriNetService.getNewestVersionByIdentifier(identifier)
PetriNet petriNet = petriNetService.getActiveVersionByIdentifier(identifier)
if (!petriNet) {
return createNet(filename, release, author)
}
Expand Down Expand Up @@ -249,7 +249,7 @@ class ImportHelper {
}

Optional<PetriNet> importProcessOnce(String message, String netIdentifier, String netFileName) {
PetriNet filter = petriNetService.getNewestVersionByIdentifier(netIdentifier)
PetriNet filter = petriNetService.getActiveVersionByIdentifier(netIdentifier)
if (filter != null) {
log.info("${message} has already been imported.")
return Optional.of(filter)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;


@Configuration
@EnableCaching
public class CacheConfiguration extends CachingConfigurerSupport {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,14 @@ public class CacheConfigurationProperties {
private String petriNetByIdentifier = "petriNetByIdentifier";

/**
* Default cache name for caching the newest versions of Petri nets.
* Default cache name for caching the active versions of Petri nets.
*/
private String petriNetNewest = "petriNetNewest";
private String petriNetActive = "petriNetActive";

/**
* Default cache name for caching the latest versions of Petri nets.
*/
private String petriNetLatest = "petriNetLatest";
Comment on lines +30 to +37
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

cat application-engine/src/main/java/com/netgrif/application/engine/configuration/properties/CacheConfigurationProperties.java

Repository: netgrif/application-engine

Length of output: 2263


🏁 Script executed:

rg "petriNetNewest" --type java

Repository: netgrif/application-engine

Length of output: 178


🏁 Script executed:

rg -i "migration" application-engine/src/main/java/com/netgrif/application/engine/configuration/properties/ --type java

Repository: netgrif/application-engine

Length of output: 52


🏁 Script executed:

find . -name "*MIGRAT*" -o -name "*CHANGELOG*" -o -name "*RELEASE*" 2>/dev/null | head -20

Repository: netgrif/application-engine

Length of output: 234


🏁 Script executed:

rg "petriNetNewest|cache|breaking" ./application-engine/CHANGELOG.md -A 2 -B 2

Repository: netgrif/application-engine

Length of output: 1241


🏁 Script executed:

rg "@Deprecated" application-engine/src/main/java/com/netgrif/application/engine/configuration/properties/CacheConfigurationProperties.java

Repository: netgrif/application-engine

Length of output: 52


🏁 Script executed:

git log --oneline --all --grep="petriNetNewest\|cache\|CacheConfiguration" 2>/dev/null | head -20

Repository: netgrif/application-engine

Length of output: 127


🏁 Script executed:

git show fc637ee7e --stat

Repository: netgrif/application-engine

Length of output: 50383


🏁 Script executed:

rg "petriNetNewest" application-engine/src/main --type java -B 2 -A 2

Repository: netgrif/application-engine

Length of output: 581


🏁 Script executed:

find . -name "*.properties" -o -name "*.yml" -o -name "*.yaml" | xargs grep -l "petriNetNewest" 2>/dev/null | head -10

Repository: netgrif/application-engine

Length of output: 140


Document the breaking change for users overriding petriNetNewest.

The removal of petriNetNewest (replaced by petriNetActive and petriNetLatest) is a breaking change for users who have customized this property in their configuration files. Ensure that migration documentation is provided to guide users in updating their configurations, or consider adding a deprecated petriNetNewest property temporarily with a warning that maps to one of the new properties.

🤖 Prompt for AI Agents
In
application-engine/src/main/java/com/netgrif/application/engine/configuration/properties/CacheConfigurationProperties.java
around lines 30 to 37, the removal of petriNetNewest is a breaking change for
users who set that property; add a deprecated compatibility property named
petriNetNewest (annotated @Deprecated and exposed for deserialization) whose
setter maps the incoming value to the new petriNetActive and/or petriNetLatest
fields (or to the most appropriate single field per your migration decision) and
emits a clear warning log message when used, and also update the project
configuration docs and release notes to document the breaking change and show
example replacements for existing configs.


/**
* Default cache name for general Petri net caching.
Expand All @@ -41,6 +46,11 @@ public class CacheConfigurationProperties {
*/
private String loadedModules = "loadedModules";

/**
* Default cache name for caching namespace functions.
*/
private String globalFunctions = "globalFunctions";
Comment on lines +49 to +52
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick | 🔵 Trivial

Clarify the comment to reflect the global scope.

The comment describes "caching namespace functions" while the field is named globalFunctions. Consider updating the comment to clarify that these are functions from Petri net namespaces cached in a global (cluster-wide) scope, e.g., "Default cache name for globally caching Petri net namespace functions."

🤖 Prompt for AI Agents
In
application-engine/src/main/java/com/netgrif/application/engine/configuration/properties/CacheConfigurationProperties.java
around lines 49 to 52, the Javadoc incorrectly or ambiguously refers to "caching
namespace functions" while the field name is globalFunctions; update the Javadoc
to explicitly state this is the default cache name for globally (cluster-wide)
caching Petri net namespace functions so the comment matches the field intent
and scope.


/**
* A list of additional custom cache names.
* Allows users to define their own cache names for specific use cases.
Expand All @@ -54,7 +64,8 @@ public class CacheConfigurationProperties {
* @return a {@link Set} of all cache names.
*/
public Set<String> getAllCaches() {
Set<String> caches = new LinkedHashSet<>(Arrays.asList(petriNetById, petriNetByIdentifier, petriNetNewest, petriNetCache, loadedModules));
Set<String> caches = new LinkedHashSet<>(Arrays.asList(petriNetById, petriNetByIdentifier, petriNetActive,
petriNetLatest, petriNetCache, loadedModules, globalFunctions));
caches.addAll(additional);
return caches;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ public static class FieldRunnerProperties {
/**
* The size of the cache used for maintaining field runner namespaces.
*/
Comment on lines 56 to 58
Copy link

@coderabbitai coderabbitai bot Dec 16, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Update the JavaDoc comment to reflect the global functions cache.

The comment still references "maintaining field runner namespaces" but the property has been renamed to globalFunctionsCacheSize and serves a different purpose (global functions caching).

Apply this diff to update the comment:

-        /**
-         * The size of the cache used for maintaining field runner namespaces.
-         */
+        /**
+         * The size of the cache used for managing global Petri net namespace functions.
+         */
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
/**
* The size of the cache used for maintaining field runner namespaces.
*/
/**
* The size of the cache used for managing global Petri net namespace functions.
*/
🤖 Prompt for AI Agents
In
application-engine/src/main/java/com/netgrif/application/engine/configuration/properties/RunnerConfigurationProperties.java
around lines 56 to 58, the JavaDoc still refers to "maintaining field runner
namespaces" but the property is now named globalFunctionsCacheSize and is used
for caching global functions; update the JavaDoc to reference
globalFunctionsCacheSize and describe that it controls the size of the cache for
global functions (e.g., "The size of the cache used for storing global
functions"), ensuring the comment matches the renamed property and its purpose.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@dominikvozr please update the java doc

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seems like the humans are having a chat. I'll hop back into my burrow for now. If you need me again, just tag @coderabbitai in a new comment, and I'll come hopping out!

private int namespaceCacheSize = 500;
private int globalFunctionsCacheSize = 500;
}

/**
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.netgrif.application.engine.importer.service;

import com.netgrif.application.engine.objects.importer.model.Scope;
import com.netgrif.application.engine.objects.petrinet.domain.Function;
import com.netgrif.application.engine.objects.petrinet.domain.FunctionScope;
import lombok.extern.slf4j.Slf4j;
Expand All @@ -9,7 +10,10 @@
@Slf4j
public final class FunctionFactory {

private static final String NAMESPACE = "namespace";

public Function getFunction(com.netgrif.application.engine.objects.importer.model.Function function) {
checkDeprecatedAttributes(function);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For deprecated attributes we already use interface IModelValidator. Please implement this interface for functions and use it

Function function1 = new Function();

function1.setDefinition(function.getValue());
Expand All @@ -18,4 +22,11 @@ public Function getFunction(com.netgrif.application.engine.objects.importer.mode

return function1;
}

private void checkDeprecatedAttributes(com.netgrif.application.engine.objects.importer.model.Function function) {
if (function.getScope() != null && function.getScope().value().equals(NAMESPACE)) {
log.warn("Function scope [NAMESPACE] is deprecated. Replacing with [GLOBAL].]");
function.setScope(Scope.GLOBAL);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import com.netgrif.application.engine.objects.auth.domain.AbstractUser;
import com.netgrif.application.engine.objects.auth.domain.ActorTransformer;
import com.netgrif.application.engine.objects.auth.domain.LoggedUser;
import com.netgrif.application.engine.objects.petrinet.domain.PetriNet;
import com.netgrif.application.engine.objects.petrinet.domain.throwable.TransitionNotExecutableException;
import com.netgrif.application.engine.objects.utils.MenuItemUtils;
import com.netgrif.application.engine.objects.workflow.domain.Case;
Expand Down Expand Up @@ -62,7 +63,11 @@ 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();
PetriNet petriNet = petriNetService.getActiveVersionByIdentifier(DashboardItemConstants.PROCESS_IDENTIFIER);
if (petriNet == null) {
throw new IllegalStateException("Dashboard item process not found or not active");
}
itemCase = workflowService.createCase(petriNet.getStringId(), body.getName().getDefaultValue(), "", loggedUser).getCase();
ToDataSetOutcome outcome = body.toDataSet();
itemCase = setDataWithExecute(itemCase, DashboardItemConstants.TASK_CONFIGURE, outcome.getDataSet());
return itemCase;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import com.netgrif.application.engine.objects.auth.domain.ActorTransformer;
import com.netgrif.application.engine.objects.auth.domain.LoggedUser;
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.throwable.TransitionNotExecutableException;
import com.netgrif.application.engine.objects.utils.MenuItemUtils;
import com.netgrif.application.engine.objects.workflow.domain.Case;
Expand Down Expand Up @@ -64,7 +65,11 @@ 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();
PetriNet petriNet = petriNetService.getActiveVersionByIdentifier(DashboardManagementConstants.PROCESS_IDENTIFIER);
if (petriNet == null) {
throw new IllegalStateException("Dashboard management process not found or not active");
}
managementCase = workflowService.createCase(petriNet.getStringId(), body.getName().getDefaultValue(), "", loggedUser).getCase();
ToDataSetOutcome outcome = body.toDataSet();
managementCase = setDataWithExecute(managementCase, DashboardItemConstants.TASK_CONFIGURE, outcome.getDataSet());
return managementCase;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,15 @@ public interface PetriNetRepository extends MongoRepository<PetriNet, String>, Q
*/
PetriNet findByIdentifierAndVersion(String identifier, Version version);

/**
* Finds a {@link PetriNet} entity by its identifier and versionActive attribute
*
* @param identifier the unique identifier of the PetriNet.
* @param versionActive if true, the active version will be found, otherwise the inactive version
* @return the {@link PetriNet} entity matching the given identifier and versionActive attribute, or {@code null} if none found.
*/
PetriNet findByIdentifierAndVersionActive(String identifier, boolean versionActive);
Comment on lines +36 to +43
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Search for how findByIdentifierAndVersionActive is used
echo "=== Usage of findByIdentifierAndVersionActive ==="
rg -n "findByIdentifierAndVersionActive" --type java -B 2 -A 5

echo -e "\n=== PetriNet entity definition ==="
fd "PetriNet.java" --type f | head -1 | xargs cat | head -200

echo -e "\n=== Database constraints or schema annotations ==="
fd "PetriNet.java" --type f | head -1 | xargs rg -n "@.*Unique|@.*Constraint|@.*Index" | head -20

echo -e "\n=== How versionActive is defined ==="
fd "PetriNet.java" --type f | head -1 | xargs rg -n "versionActive" -B 2 -A 2 | head -50

Repository: netgrif/application-engine

Length of output: 3009


🏁 Script executed:

#!/bin/bash
# Find the actual PetriNet entity (not SearchPetriNet)
echo "=== Finding PetriNet entity ==="
fd "PetriNet\.java" -x sh -c 'wc -l {} && echo "File: {}"' | sort -rn | head -20

echo -e "\n=== PetriNet entity with @Entity annotation ==="
fd "\.java" -x grep -l "class PetriNet" | grep -v Search | head -5

echo -e "\n=== Searching for PetriNet class definition ==="
rg "class PetriNet" --type java -A 100 | head -150

echo -e "\n=== Looking for unique constraints ==="
rg "UniqueConstraint|@Index.*unique|@Unique" -B 2 -A 2 --type java | grep -A 5 -B 5 PetriNet | head -50

Repository: netgrif/application-engine

Length of output: 24594


🏁 Script executed:

#!/bin/bash
# Read the actual PetriNet entity
echo "=== PetriNet Entity Definition ==="
head -300 "./nae-object-library/src/main/java/com/netgrif/application/engine/objects/petrinet/domain/PetriNet.java"

echo -e "\n=== Searching for constraints and versionActive ==="
grep -n "@\|versionActive\|UniqueConstraint\|@Index" "./nae-object-library/src/main/java/com/netgrif/application/engine/objects/petrinet/domain/PetriNet.java" | head -60

Repository: netgrif/application-engine

Length of output: 11098


Implement the planned compound index for identifier and version uniqueness.

The TODO comment on line 34 indicates this is a known limitation: a compound unique constraint on (identifier, version) should be added. Currently, only versionActive is indexed individually. While the method is presently only invoked with versionActive=true (ensuring single active version per identifier), the lack of a compound constraint creates a gap if inactive version queries are introduced later. Implement the @CompoundIndex annotation as noted in the TODO to enforce this constraint at the database level.


/**
* Finds a paginated list of {@link PetriNet} entities by their identifier.
*
Expand Down
Loading
Loading