Skip to content

Conversation

@SamuelPalaj
Copy link
Contributor

@SamuelPalaj SamuelPalaj commented Nov 18, 2025

Description

  • added pageable to method calls in ActionDelegate
  • unused imports removed

Fixes JIRA-ISSUE

Test Configuration

<Please describe configuration for tests to run if applicable, like program parameters, host OS, VM configuration etc.>

Test Configuration

Name Tested on
OS windows 10
Runtime java 21
Dependency Manager Maven 3.9.9
Framework version Spring Boot 3.4.4
Run parameters
Other configuration

Checklist:

  • My code follows the style guidelines of this project
  • I have performed a self-review of my own code
  • My changes have been checked, personally or remotely, with @...
  • I have commented my code, particularly in hard-to-understand areas
  • I have resolved all conflicts with the target branch of the PR
  • I have updated and synced my code with the target branch
  • I have added tests that prove my fix is effective or that my feature works
  • New and existing tests pass locally with my changes:
    • Lint test
    • Unit tests
    • Integration tests
  • I have checked my contribution with code analysis tools:
  • I have made corresponding changes to the documentation:
    • Developer documentation
    • User Guides
    • Migration Guides

Summary by CodeRabbit

  • New Features

    • Added pagination support for action migration and for bulk role assignment/removal operations.
  • Bug Fixes

    • Safer handling when updating users by email to avoid failures if a user is missing.
  • Chores

    • Removed unused imports and cleaned up minor code artifacts across modules.

- added pageable to method calls in ActionDelegate
- unused imports removed
@SamuelPalaj SamuelPalaj self-assigned this Nov 18, 2025
@SamuelPalaj SamuelPalaj added the bugfix A change that fixes a bug label Nov 18, 2025
@coderabbitai
Copy link

coderabbitai bot commented Nov 18, 2025

Walkthrough

Adds pageable support to action migration and per-net role operations, changes tests and service call return types to use PetriNet, adjusts ImportHelper's net creation and role lookup calls, and removes several unused imports.

Changes

Cohort / File(s) Summary
Unused import removals
application-engine/src/main/groovy/com/netgrif/application/engine/integration/modules/ModuleServiceInjector.groovy, application-engine/src/main/java/com/netgrif/application/engine/workflow/service/WorkflowAuthorizationService.java, application-engine/src/main/java/com/netgrif/application/engine/workflow/web/RestResponseExceptionHandler.java, application-engine/src/main/java/com/netgrif/application/engine/workflow/web/WorkflowController.java
Removed unused imports (AnnotatedElementUtils, LoggedUserImpl, HttpStatus, ArrayList). No behavioral changes.
Pagination and role operations
application-engine/src/main/groovy/com/netgrif/application/engine/migration/ActionMigration.groovy, application-engine/src/main/groovy/com/netgrif/application/engine/petrinet/domain/dataset/logic/action/ActionDelegate.groovy
Added Pageable pageable = Pageable.unpaged() parameter to migrateActions, assignRole, and removeRole; updated calls to petriNetService.getByIdentifier(..., pageable) and paged result handling. changeUserByEmail now checks Optional presence before proceeding.
ImportHelper flow changes
application-engine/src/main/groovy/com/netgrif/application/engine/startup/ImportHelper.groovy
Calls createNet(...) overload without uriNodeId; changed process role lookup to processRoleService.findAllByNetStringId(net.stringId).
Service/test API return type change
application-engine/src/test/groovy/com/netgrif/application/engine/petrinet/domain/PetriNetTest.groovy, application-engine/src/main/groovy/.../ActionDelegate.groovy
IPetriNetService.getByIdentifier(String, Pageable) return type changed from Page<PetriNetReference> to Page<PetriNet>; tests and usages updated accordingly.

Sequence Diagram(s)

mermaid
sequenceDiagram
participant Migrator as ActionMigration
participant PNService as PetriNetService
participant DB as Repository
Migrator->>PNService: getByIdentifier(importId, pageable)
PNService->>DB: query by importId with pageable
DB-->>PNService: Page
PNService-->>Migrator: Page
Migrator->>Migrator: filter by version, migrate actions

mermaid
sequenceDiagram
participant Controller as Caller
participant Delegate as ActionDelegate
participant PNService as PetriNetService
participant UserSvc as UserService
Controller->>Delegate: assignRole(roleId, netId, user, pageable)
Delegate->>PNService: getByIdentifier(netId, pageable)
PNService-->>Delegate: Page.content
Delegate->>UserSvc: findByEmail(email)
alt user found
UserSvc-->>Delegate: Optional[user]
Delegate->>Delegate: assign role on each net
else user not found
UserSvc-->>Delegate: Optional.empty
Delegate-->>Controller: log error / return

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

  • Verify all callers and tests accommodate the added Pageable parameters and default Pageable.unpaged() usage.
  • Confirm Optional handling in changeUserByEmail is safe and doesn't reintroduce unchecked .get() usage.
  • Review the getByIdentifier return-type change for all call sites (tests and production) to ensure field access still valid.
  • Check ImportHelper overload resolution and role lookup correctness.

Possibly related PRs

Pre-merge checks

✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately describes the main change: updating method calls to include the Pageable parameter that was previously added. It directly corresponds to the core modifications across multiple files (ActionMigration, ActionDelegate, ImportHelper) where Pageable parameters are being integrated into method signatures and call sites.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

📜 Recent review details

Configuration used: CodeRabbit UI

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 9133315 and c8c3785.

📒 Files selected for processing (1)
  • application-engine/src/main/groovy/com/netgrif/application/engine/petrinet/domain/dataset/logic/action/ActionDelegate.groovy (3 hunks)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: Build
🔇 Additional comments (3)
application-engine/src/main/groovy/com/netgrif/application/engine/petrinet/domain/dataset/logic/action/ActionDelegate.groovy (3)

1048-1052: Verify intended behavior when multiple net versions exist.

Similar to assignRole above, when netId matches multiple versions of a Petri net, this will remove the role for all returned versions (or a paginated subset).

Consider the same questions:

  • Should this target only the newest version?
  • Should it handle empty results explicitly?
  • Is pagination semantically correct for this operation?

1324-1330: Excellent fix for the unsafe Optional handling!

This correctly addresses the past review concern about the unsafe .get() call. The implementation now:

  • Checks isPresent() before calling .get()
  • Logs a clear error message when the user is not found
  • Returns early to prevent further processing with a null user

1027-1031: Verify intended behavior when multiple net versions exist.

When netId matches multiple versions of a Petri net, this implementation will assign the role to all returned versions (or a paginated subset if using custom pagination). A dedicated getNewestVersionByIdentifier() method exists in PetriNetService, suggesting this design choice warrants explicit verification.

Confirm whether:

  • Assigning roles to all versions is the intended behavior, or
  • Only the newest version should receive the role change

If only the newest version is required, use petriNetService.getNewestVersionByIdentifier(netId) instead. The same consideration applies to the removeRole method at lines 1048–1052.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai coderabbitai bot added the Medium label Nov 18, 2025
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
application-engine/src/main/groovy/com/netgrif/application/engine/startup/ImportHelper.groovy (1)

169-175: Handle missing persisted roles (and avoid repeated linear searches) in getProcessRoles

Using processRoleService.findAllByNetStringId(net.stringId) is consistent with looking roles up by net string ID, but the current implementation will:

  • Perform an O(n²) search (roles.find) over the same list for each netRole.
  • Silently store null values in the map if a matching ProcessRole is not found in the DB.

Consider indexing the loaded roles by stringId once and logging or skipping missing matches to surface inconsistencies:

-    Map<String, ProcessRole> getProcessRoles(PetriNet net) {
-        List<ProcessRole> roles = processRoleService.findAllByNetStringId(net.stringId)
-        Map<String, ProcessRole> map = [:]
-        net.roles.values().each { netRole ->
-            map[netRole.name.getDefaultValue()] = roles.find { it.stringId == netRole.stringId }
-        }
-        return map
-    }
+    Map<String, ProcessRole> getProcessRoles(PetriNet net) {
+        List<ProcessRole> roles = processRoleService.findAllByNetStringId(net.stringId)
+        Map<String, ProcessRole> rolesByStringId = roles.collectEntries { [it.stringId, it] }
+        Map<String, ProcessRole> map = [:]
+        net.roles.values().each { netRole ->
+            ProcessRole persisted = rolesByStringId[netRole.stringId]
+            if (persisted != null) {
+                map[netRole.name.getDefaultValue()] = persisted
+            } else {
+                log.warn("No persisted ProcessRole found for net [${net.stringId}] role [${netRole.stringId}]")
+            }
+        }
+        return map
+    }

This keeps the method behaviorally similar while making it more robust and slightly more efficient.

application-engine/src/main/groovy/com/netgrif/application/engine/migration/ActionMigration.groovy (1)

32-40: Critical logic errors: inverted null check and missing .getContent() call.

Two critical issues:

  1. Line 33: The condition is inverted. It checks if(newPetriNet.getNet() != null) but then throws an error saying the net "was not imported". This should be == null.

  2. Line 37: getByIdentifier now returns Page<PetriNet>, so calling .stream() directly on it will fail. You need to call .getContent().stream() or just use .getContent() and then apply the stream operations.

Apply this diff:

-        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)
         } else {
-            oldPetriNets = petriNetService.getByIdentifier(newPetriNet.getNet().importId, pageable)
-                    .stream().filter({ net -> (net.version != newPetriNet.getNet().version)})
+            oldPetriNets = petriNetService.getByIdentifier(newPetriNet.getNet().importId, pageable)
+                    .getContent().stream().filter({ net -> (net.version != newPetriNet.getNet().version)})
                     .collect(Collectors.toList())
         }
📜 Review details

Configuration used: CodeRabbit UI

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 2f11efc and 9133315.

📒 Files selected for processing (8)
  • application-engine/src/main/groovy/com/netgrif/application/engine/integration/modules/ModuleServiceInjector.groovy (0 hunks)
  • application-engine/src/main/groovy/com/netgrif/application/engine/migration/ActionMigration.groovy (3 hunks)
  • application-engine/src/main/groovy/com/netgrif/application/engine/petrinet/domain/dataset/logic/action/ActionDelegate.groovy (3 hunks)
  • application-engine/src/main/groovy/com/netgrif/application/engine/startup/ImportHelper.groovy (2 hunks)
  • application-engine/src/main/java/com/netgrif/application/engine/workflow/service/WorkflowAuthorizationService.java (0 hunks)
  • application-engine/src/main/java/com/netgrif/application/engine/workflow/web/RestResponseExceptionHandler.java (0 hunks)
  • application-engine/src/main/java/com/netgrif/application/engine/workflow/web/WorkflowController.java (0 hunks)
  • application-engine/src/test/groovy/com/netgrif/application/engine/petrinet/domain/PetriNetTest.groovy (1 hunks)
💤 Files with no reviewable changes (4)
  • application-engine/src/main/groovy/com/netgrif/application/engine/integration/modules/ModuleServiceInjector.groovy
  • application-engine/src/main/java/com/netgrif/application/engine/workflow/service/WorkflowAuthorizationService.java
  • application-engine/src/main/java/com/netgrif/application/engine/workflow/web/RestResponseExceptionHandler.java
  • application-engine/src/main/java/com/netgrif/application/engine/workflow/web/WorkflowController.java
🧰 Additional context used
🧠 Learnings (2)
📚 Learning: 2025-07-31T23:40:46.499Z
Learnt from: tuplle
Repo: netgrif/application-engine PR: 334
File: application-engine/src/main/java/com/netgrif/application/engine/petrinet/service/PetriNetService.java:204-214
Timestamp: 2025-07-31T23:40:46.499Z
Learning: In the PetriNetService.importPetriNet method, existingNet.getVersion() cannot be null because all existing nets in the system were deployed through processes that ensure every net always has a version assigned.

Applied to files:

  • application-engine/src/main/groovy/com/netgrif/application/engine/migration/ActionMigration.groovy
  • application-engine/src/test/groovy/com/netgrif/application/engine/petrinet/domain/PetriNetTest.groovy
  • application-engine/src/main/groovy/com/netgrif/application/engine/startup/ImportHelper.groovy
📚 Learning: 2025-09-29T10:31:57.325Z
Learnt from: renczesstefan
Repo: netgrif/application-engine PR: 362
File: application-engine/src/main/java/com/netgrif/application/engine/petrinet/service/ProcessRoleService.java:513-529
Timestamp: 2025-09-29T10:31:57.325Z
Learning: PetriNet.getStringId() returns a simple ObjectId string representation (_id.toString()), not a composite Netgrif ID format, so new ObjectId(petriNetId) works correctly when petriNetId comes from PetriNet.getStringId().

Applied to files:

  • application-engine/src/main/groovy/com/netgrif/application/engine/migration/ActionMigration.groovy
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: Build
🔇 Additional comments (6)
application-engine/src/main/groovy/com/netgrif/application/engine/startup/ImportHelper.groovy (1)

114-116: String-based createNet overload now delegates cleanly to the VersionType overload

The delegation to createNet(fileName, VersionType, author) keeps all import logic in one place, and normalizing release via trim().toUpperCase() before VersionType.valueOf is reasonable given the existing API. No functional concerns from this change alone.

application-engine/src/test/groovy/com/netgrif/application/engine/petrinet/domain/PetriNetTest.groovy (1)

125-127: LGTM! Test correctly updated to reflect API change.

The test has been properly updated to use Page<PetriNet> instead of Page<PetriNetReference>, aligning with the changed return type of IPetriNetService.getByIdentifier.

application-engine/src/main/groovy/com/netgrif/application/engine/migration/ActionMigration.groovy (2)

12-12: LGTM! Import added for pagination support.


27-27: LGTM! Method signature extended with pagination support.

The default value of Pageable.unpaged() ensures backward compatibility for existing callers.

application-engine/src/main/groovy/com/netgrif/application/engine/petrinet/domain/dataset/logic/action/ActionDelegate.groovy (2)

1027-1031: LGTM! Pagination support added correctly.

The method signature has been extended with a Pageable parameter (defaulting to Pageable.unpaged()), and .content correctly extracts the list from the Page<PetriNet> result.


1048-1052: LGTM! Pagination support added correctly.

The method signature has been extended with a Pageable parameter (defaulting to Pageable.unpaged()), and .content correctly extracts the list from the Page<PetriNet> result.

Retoocs
Retoocs previously approved these changes Nov 18, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bugfix A change that fixes a bug Medium

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants