Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
73 commits
Select commit Hold shift + click to select a range
dd58002
NAE-2182 - Implementation of an endpoint for clearing the action cache
dominikvozr Sep 1, 2025
5b98ca4
NAE-2182 - Implementation of custom cache wrapper to use in cacheManager
dominikvozr Sep 1, 2025
e917f76
NAE-2182 - Implementation of generic map cache and created actuator c…
dominikvozr Sep 2, 2025
bd719b5
NAE-2182 - cache FunctionsNamespace and functions if not found
dominikvozr Sep 3, 2025
e976081
NAE-2182 - prevent multi thread unexpected behaviour and prevent cach…
dominikvozr Sep 4, 2025
8323adb
NAE-2182 - Implementation of generic map cache and changed store for …
dominikvozr Sep 16, 2025
f9796d6
NAE-2182 - removal of unused methods, correction of several issues du…
dominikvozr Sep 16, 2025
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
d2227d0
NAE-2182 - optimized imports, added helper and refactor code
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
cb1505f
Merge remote-tracking branch 'origin/release/7.0.0-rev8' into NAE-2182
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
6f57b74
Release/7.0.0-RC10
machacjozef Dec 15, 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
c18561f
Merge branch 'NAE-2212' into NAE-2182
renczesstefan Dec 18, 2025
f7b61be
Refactor caching logic in FieldActionsCacheService and improve annota…
renczesstefan Dec 18, 2025
c039509
Refactor function validation and enhance PetriNet handling
renczesstefan Jan 7, 2026
df89aac
Merge remote-tracking branch 'origin/release/7.0.0-rev10' into NAE-2266
Retoocs Jan 7, 2026
3241eed
[NAE-2266] Introduce active version of process
Retoocs Jan 7, 2026
b92ba07
[NAE-2266] Introduce active version of process
Retoocs Jan 7, 2026
eb377cc
[NAE-2266] Introduce active version of process
Retoocs Jan 7, 2026
4ca7fd4
[NAE-2266] Introduce active version of process
Retoocs Jan 8, 2026
8028b98
[NAE-2266] Introduce active version of process
Retoocs Jan 8, 2026
1d7d175
[NAE-2266] Introduce active version of process
Retoocs Jan 8, 2026
9cdd0b9
Merge branch 'NAE-2266' into NAE-2212
renczesstefan Jan 8, 2026
d614cf9
- corrected according to PR
renczesstefan Jan 8, 2026
e82c400
- returned petriflow_schema.xsd
renczesstefan Jan 8, 2026
f7c8583
- cached functions after doSaveInternal
renczesstefan Jan 8, 2026
5d72517
- added thread safe maps to cache service
renczesstefan Jan 8, 2026
a1e93de
Add documentation for new PetriNet functions in NAE 5.6.0
renczesstefan Jan 8, 2026
5ce552c
Fix typos and improve formatting in functions documentation
renczesstefan Jan 8, 2026
59299c5
[NAE-2266] Introduce active version of process
Retoocs Jan 8, 2026
f2cf540
Synchronize access to cache instances
renczesstefan Jan 8, 2026
75b903d
Merge branch 'NAE-2266' into NAE-2182
renczesstefan Jan 9, 2026
749db25
Update function to use the default Petri net version
renczesstefan Jan 9, 2026
94724c5
Merge branch 'NAE-2212' into NAE-2182
renczesstefan Jan 9, 2026
0f7bb9b
Merge branch 'NAE-2212' into NAE-2182
renczesstefan Jan 9, 2026
ebaa5a9
Merge remote-tracking branch 'origin/NAE-2182' into NAE-2182
renczesstefan Jan 9, 2026
d573cf2
Refactor function caching property configuration
renczesstefan Jan 9, 2026
4c1cf75
[NAE-2182] Refactor GenericMapCache to use ConcurrentHashMap.computeI…
dominikvozr Jan 9, 2026
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.getDefaultVersionByIdentifier(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.getDefaultVersionByIdentifier(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.getDefaultVersionByIdentifier(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.getDefaultVersionByIdentifier(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.getDefaultVersionByIdentifier(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
@@ -1,30 +1,55 @@
package com.netgrif.application.engine.configuration;

import com.netgrif.application.engine.configuration.properties.CacheConfigurationProperties;
import com.netgrif.application.engine.configuration.properties.RunnerConfigurationProperties;
import com.netgrif.application.engine.workflow.domain.CachedFunction;
import groovy.lang.Closure;
import lombok.RequiredArgsConstructor;
import org.springframework.cache.Cache;
import org.springframework.cache.CacheManager;
import org.springframework.cache.annotation.CachingConfigurerSupport;
import org.springframework.cache.annotation.CachingConfigurer;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.cache.concurrent.ConcurrentMapCacheManager;
import org.springframework.cache.concurrent.ConcurrentMapCache;
import org.springframework.cache.interceptor.CacheResolver;
import org.springframework.cache.support.SimpleCacheManager;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;


import java.util.*;
import java.util.stream.Collectors;

@Configuration
@EnableCaching
public class CacheConfiguration extends CachingConfigurerSupport {

@RequiredArgsConstructor
public class CacheConfiguration implements CachingConfigurer {
private final RunnerConfigurationProperties.FieldRunnerProperties fieldRunnerProperties;
private final CacheConfigurationProperties properties;

public CacheConfiguration(CacheConfigurationProperties properties) {
this.properties = properties;
}

@Bean
@Primary
@Override
public CacheManager cacheManager() {
return new ConcurrentMapCacheManager(properties.getAllCaches().toArray(String[]::new));
Set<String> cacheNames = properties.getAllCaches();
List<Cache> caches = cacheNames.stream()
.map(ConcurrentMapCache::new)
.collect(Collectors.toCollection(ArrayList::new));

caches.add(new GenericMapCache<>(
CacheMapKeys.ACTIONS,
Closure.class,
fieldRunnerProperties.getActionCacheSize()
));
caches.add(new GenericMapCache<>(
CacheMapKeys.FUNCTIONS,
CachedFunction.class,
fieldRunnerProperties.getFunctionsCacheSize()
));

SimpleCacheManager cacheManager = new SimpleCacheManager();
cacheManager.setCaches(caches);
return cacheManager;
}

@Bean
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package com.netgrif.application.engine.configuration;

public final class CacheMapKeys {
private CacheMapKeys() {}
public static final String ACTIONS = "actions";
public static final String FUNCTIONS = "functions";
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
package com.netgrif.application.engine.configuration;

import lombok.extern.slf4j.Slf4j;
import org.jetbrains.annotations.NotNull;
import org.springframework.cache.Cache;
import org.springframework.cache.support.SimpleValueWrapper;

import java.util.Map;
import java.util.concurrent.Callable;
import java.util.concurrent.ConcurrentHashMap;

@Slf4j
public class GenericMapCache<V> implements Cache {
private final String name;
private final Class<V> valueType;
private final ConcurrentHashMap<String, V> map;

public GenericMapCache(String name, Class<V> valueType, int cacheSize) {
this.name = name;
this.valueType = valueType;
this.map = new ConcurrentHashMap<>(cacheSize);
}
Comment on lines +18 to +22
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

Cache is unbounded despite cacheSize parameter name.

The cacheSize parameter is only passed to ConcurrentHashMap as initial capacity, not as a maximum bound. The cache can grow indefinitely, potentially causing memory exhaustion under load. This contradicts the AI summary mentioning "bounded generic caches."

Consider using a bounded cache implementation like Caffeine or implementing LRU eviction:

Option 1: Use Caffeine for bounded caching
import com.github.benmanes.caffeine.cache.Cache;
import com.github.benmanes.caffeine.cache.Caffeine;

// In constructor:
this.map = Caffeine.newBuilder()
    .maximumSize(cacheSize)
    .build();
Option 2: Use LinkedHashMap with access-order eviction
private final Map<String, V> map;

public GenericMapCache(String name, Class<V> valueType, int cacheSize) {
    this.name = name;
    this.valueType = valueType;
    this.map = Collections.synchronizedMap(new LinkedHashMap<>(cacheSize, 0.75f, true) {
        @Override
        protected boolean removeEldestEntry(Map.Entry<String, V> eldest) {
            return size() > cacheSize;
        }
    });
}
🤖 Prompt for AI Agents
In
@application-engine/src/main/java/com/netgrif/application/engine/configuration/GenericMapCache.java
around lines 18 - 22, The constructor GenericMapCache(String name, Class<V>
valueType, int cacheSize) only uses cacheSize as the initial capacity for the
ConcurrentHashMap backing field map, so the cache is unbounded; change the
backing implementation to enforce a maximum size (e.g., replace map with a
Caffeine Cache built with maximumSize(cacheSize) or with a synchronized
LinkedHashMap/ConcurrentLinkedHashMap using access-order eviction and
removeEldestEntry to cap size) and update usages of map in the class to interact
with the chosen cache API (put/get/remove) instead of assuming a raw
ConcurrentHashMap.


@Override public @NotNull String getName() { return name; }

@Override public @NotNull Object getNativeCache() { return Map.copyOf(map); }

@Override
public <T> T get(Object key, Callable<T> loader) {
final String stringKey = String.valueOf(key);
try {
V value = map.computeIfAbsent(stringKey, cacheValue -> {
try {
T computed = loader.call();
if (computed == null) return null;
return safeCast(computed);
}
catch (Exception e) {
throw new RuntimeException(e);
}
});
return (T) value;
} catch (RuntimeException e) {
Throwable cause = (e.getCause() != null) ? e.getCause() : e;
throw new Cache.ValueRetrievalException(stringKey, loader, cause);
}
}
Comment on lines +29 to +47
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

Null values are not cached, causing repeated loader invocations.

When loader.call() returns null (line 35), computeIfAbsent does not store the mapping. Subsequent calls with the same key will repeatedly invoke the loader, which may be expensive.

If caching null results is intentional behavior, document it. Otherwise, consider using a sentinel value or Optional<V> internally to distinguish "cached null" from "not cached."

Additionally, line 42 has an unchecked cast from V to T. While safeCast ensures the value is of type V, there's no guarantee T is assignable from V. Consider adding @SuppressWarnings("unchecked") with a comment explaining why this is safe in practice.


@Override
public ValueWrapper get(Object key) {
String stringKey = String.valueOf(key);
Object valueObject = map.get(stringKey);
return valueObject != null ? new SimpleValueWrapper(valueObject) : null;
}

@Override
public <T> T get(Object key, Class<T> type) {
String stringKey = String.valueOf(key);
Object valueObject = map.get(stringKey);
return valueObject != null ? type.cast(valueObject) : null;
}

@Override
public void put(Object key, Object value) {
map.put(String.valueOf(key), safeCast(value));
}

@Override
public void evict(Object key) {
map.remove(String.valueOf(key));
}

@Override
public void clear() {
map.clear();
}

@SuppressWarnings("unchecked")
private V safeCast(Object object) {
if (object == null) {
return null;
}

if (!valueType.isInstance(object)) {
throw new ClassCastException("Expected " + valueType.getName() + " but was " + object.getClass().getName());
}

return (V) object;
}
}
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 default versions of Petri nets.
*/
private String petriNetNewest = "petriNetNewest";
private String petriNetDefault = "petriNetDefault";

/**
* Default cache name for caching the latest versions of Petri nets.
*/
private String petriNetLatest = "petriNetLatest";

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

/**
* Default cache name for caching global functions of PetriNet global scoped 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 documentation wording.

The phrase "caching global functions of PetriNet global scoped functions" is redundant. Consider simplifying to:

  • "Default cache name for caching PetriNet global-scoped functions." or
  • "Default cache name for caching global functions for PetriNets."
📝 Suggested documentation improvement
     /**
-     * Default cache name for caching global functions of PetriNet global scoped functions.
+     * Default cache name for caching PetriNet global-scoped functions.
      */
     private String globalFunctions = "globalFunctions";

Based on learnings, the property name globalFunctions is correct.

🤖 Prompt for AI Agents
In
@application-engine/src/main/java/com/netgrif/application/engine/configuration/properties/CacheConfigurationProperties.java
around lines 49 - 52, Update the Javadoc for the CacheConfigurationProperties
field globalFunctions to remove the redundant wording; replace "Default cache
name for caching global functions of PetriNet global scoped functions." with a
simpler sentence such as "Default cache name for caching PetriNet global-scoped
functions." (keep field name globalFunctions unchanged).


/**
* A list of additional custom cache names.
* Allows users to define their own cache names for specific use cases.
*/
private List<String> additional = new ArrayList<>();

/**
* The size of pages used for caching functions when processing large sets of data.
* This property determines the maximum number of functions to include in a single page during caching operations.
* Default value is 500.
*/
private int functionCachingPageSize = 500;

/**
* Retrieves a set of all configured cache names.
* Includes the default caches and any additional user-defined cache names.
*
* @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, petriNetDefault,
petriNetLatest, petriNetCache, loadedModules, globalFunctions));
caches.addAll(additional);
return caches;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,9 +54,9 @@ public static class FieldRunnerProperties {
private int functionsCacheSize = 500;

/**
* The size of the cache used for maintaining field runner namespaces.
* The size of the cache used for managing global Petri net functions.
*/
private int namespaceCacheSize = 500;
private int globalFunctionsCacheSize = 500;
Comment on lines +57 to +59
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:

#!/bin/bash
# Search for references to the old namespaceCacheSize property name

echo "=== Searching for Java references to namespaceCacheSize ==="
rg -n --type=java 'namespaceCacheSize|getNamespaceCacheSize|setNamespaceCacheSize'

echo -e "\n=== Searching for property file references ==="
rg -n --type=yaml --type=properties 'namespaceCacheSize|namespace-cache-size|namespace_cache_size'

echo -e "\n=== Searching for test file references ==="
rg -n --type=java 'namespaceCacheSize' -- '**/*.java'

echo -e "\n=== Checking for migration guides or deprecation notes ==="
rg -n -i 'migration|deprecat|namespace.*cache|namespaceCacheSize'

Repository: netgrif/application-engine

Length of output: 50486


🏁 Script executed:

#!/bin/bash
# Verify the current state of RunnerConfigurationProperties.java around lines 57-59

echo "=== Reading RunnerConfigurationProperties.java lines 50-65 ==="
sed -n '50,65p' application-engine/src/main/java/com/netgrif/application/engine/configuration/properties/RunnerConfigurationProperties.java

echo -e "\n=== Checking for getter/setter methods for globalFunctionsCacheSize ==="
rg -n -A5 -B5 'globalFunctionsCacheSize' application-engine/src/main/java/com/netgrif/application/engine/configuration/properties/RunnerConfigurationProperties.java

Repository: netgrif/application-engine

Length of output: 932


🏁 Script executed:

#!/bin/bash
# Search for all property definitions in CacheConfigurationProperties and FieldRunnerProperties

echo "=== Checking CacheConfigurationProperties for related properties ==="
find . -name 'CacheConfigurationProperties.java' -exec cat -n {} \;

echo -e "\n=== Searching for uses of globalFunctionsCacheSize in codebase ==="
rg -n 'globalFunctionsCacheSize' --type=java

Repository: netgrif/application-engine

Length of output: 3469


🏁 Script executed:

#!/bin/bash
# Search for usage of cache size properties in implementation code

echo "=== Searching for functionsCacheSize usage ==="
rg -n 'functionsCacheSize' --type=java | head -20

echo -e "\n=== Searching for globalFunctionsCacheSize usage outside property definition ==="
rg -n 'globalFunctionsCacheSize' --type=java

echo -e "\n=== Searching for references to FieldRunnerProperties or cache configuration ==="
rg -n 'FieldRunnerProperties|getGlobalFunctionsCacheSize|getFunctionsCacheSize' --type=java | head -30

echo -e "\n=== Checking if property is actually wired/injected ==="
rg -n 'RunnerConfigurationProperties|FieldRunnerProperties' --type=java -B2 -A2 | head -50

Repository: netgrif/application-engine

Length of output: 8490


🏁 Script executed:

#!/bin/bash
# Check where the cache sizes are actually used

echo "=== Searching for cache configuration usage in runner/function classes ==="
fd -t f -name '*.java' -path '*runner*' -o -path '*function*' | xargs rg -l 'cache|Cache' 2>/dev/null | head -10

echo -e "\n=== Check FunctionValidator for cache usage ==="
rg -n 'FunctionValidator' --type=java -A5 -B5 | head -40

echo -e "\n=== Search for any property getter usage pattern ==="
rg -n '\.get[A-Z]' application-engine/src/main/java/com/netgrif/application/engine/configuration/properties/RunnerConfigurationProperties.java

Repository: netgrif/application-engine

Length of output: 5343


🏁 Script executed:

#!/bin/bash
# Verify the cache configuration wiring to understand the integration gap

echo "=== Reading CacheConfiguration.java around line 52 ==="
sed -n '20,65p' application-engine/src/main/java/com/netgrif/application/engine/configuration/CacheConfiguration.java

echo -e "\n=== Search for any cache setup for global functions ==="
rg -n 'globalFunctions|GlobalFunctions' --type=java -B3 -A3

echo -e "\n=== Check if there are TODOs or incomplete implementation markers ==="
rg -n 'TODO|FIXME|XXX' application-engine/src/main/java/com/netgrif/application/engine/configuration/CacheConfiguration.java

Repository: netgrif/application-engine

Length of output: 11223


Wire the globalFunctionsCacheSize property into cache configuration.

The globalFunctionsCacheSize property is defined in FieldRunnerProperties but not used in CacheConfiguration. The cache named "globalFunctions" is currently created as a standard ConcurrentMapCache without a size limit, unlike the "functions" cache which respects functionsCacheSize.

Update CacheConfiguration.cacheManager() to create the global functions cache using GenericMapCache with a supplier that applies fieldRunnerProperties.getGlobalFunctionsCacheSize(), similar to how the functions cache is configured (line 52).

🤖 Prompt for AI Agents
In
@application-engine/src/main/java/com/netgrif/application/engine/configuration/properties/RunnerConfigurationProperties.java
around lines 57 - 59, CacheConfiguration.cacheManager() currently registers the
"globalFunctions" cache as a plain ConcurrentMapCache and ignores the
FieldRunnerProperties.globalFunctionsCacheSize; change the registration to
construct the "globalFunctions" cache using GenericMapCache with a supplier that
reads fieldRunnerProperties.getGlobalFunctionsCacheSize(), mirroring how the
"functions" cache is created, so the globalFunctions cache is bounded by the
configured size (update the cacheManager() method to replace the
ConcurrentMapCache instantiation for "globalFunctions" with a GenericMapCache
supplier using fieldRunnerProperties.getGlobalFunctionsCacheSize()).

}

/**
Expand Down
Original file line number Diff line number Diff line change
@@ -1,15 +1,21 @@
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.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

@Component
@Slf4j
@Component
@RequiredArgsConstructor
public final class FunctionFactory {

private final IFunctionValidator functionValidator;

public Function getFunction(com.netgrif.application.engine.objects.importer.model.Function function) {
functionValidator.checkDeprecatedAttributes(function);
Function function1 = new Function();

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

return function1;
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package com.netgrif.application.engine.importer.service;

import com.netgrif.application.engine.objects.importer.model.Function;
import com.netgrif.application.engine.objects.importer.model.Scope;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

@Component
@Slf4j
public class FunctionValidator implements IFunctionValidator {

private static final String NAMESPACE = "namespace";

/**
* Validates and updates deprecated function attributes.
* <p>
* This method mutates the input function by replacing deprecated scope values.
* Specifically, it replaces the deprecated NAMESPACE scope with GLOBAL scope.
*
* @param function the function to validate and update (mutated in-place)
*/
@Override
public void checkDeprecatedAttributes(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
@@ -0,0 +1,15 @@
package com.netgrif.application.engine.importer.service;

import com.netgrif.application.engine.objects.importer.model.Function;

public interface IFunctionValidator extends IModelValidator {
/**
* Validates and updates deprecated function attributes.
* <p>
* This method mutates the input function by replacing deprecated scope values.
* Specifically, it replaces the deprecated NAMESPACE scope with GLOBAL scope.
*
* @param function the function to validate and update (mutated in-place)
*/
void checkDeprecatedAttributes(Function function);
}
Loading
Loading