Skip to content

Conversation

@Kovy95
Copy link
Contributor

@Kovy95 Kovy95 commented Nov 18, 2025

Description

  • add AuthPrincipalDto to object library
  • remove immediate data from elasticCase and add NodeInfo
  • rework of elastic Datafields to remove dependency to TextField
  • remove code from 2251 - when the search node fetches cases from mongo, its not nessessery anymore to store translations of value into elastic

Implements NAE-2261

Dependencies

none

Third party dependencies

  • No new dependencies were introduced

Blocking Pull requests

Depends on #(373) and merging rev8 into rev9

How Has Been This Tested?

manually

Test Configuration

Name Tested on
OS linux mint 21
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 node information tracking for Elasticsearch deployments.
    • New authentication principal data structure for improved identity management.
  • Bug Fixes

    • Enhanced handling of translated values in enumeration and multichoice map fields.
  • Refactor

    • Restructured internal field type inheritance for improved maintainability.
    • Optimized Elasticsearch field transformations and data mapping logic.

✏️ Tip: You can customize this high-level summary in your review settings.

- add AuthPrincipalDto to object library
- remove immediate data from elasticCase and add NodeInfo
- rework of elastic Datafields to remove dependency to TextField
- remove code from 2251 - when the search node fetches cases from mongo, its not nessessery anymore to store translations of value into elastic
@Kovy95 Kovy95 self-assigned this Nov 18, 2025
@Kovy95 Kovy95 changed the title Nae 2261 [NAE-2261] SEARCH Node - fetch cases from mongo Nov 18, 2025
@coderabbitai
Copy link

coderabbitai bot commented Dec 9, 2025

Walkthrough

The PR restructures Elasticsearch mapping for collection and map fields by transitioning map field values from single I18nString translations to Collection. Multiple field classes (MapField, I18nField, StringCollectionField) now inherit from DataField instead of TextField. New value objects (NodeInfo, AuthPrincipalDto) are introduced for data model enhancements.

Changes

Cohort / File(s) Summary
Map Field Refactoring
nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/MapField.java, nae-spring-core-adapter/src/main/java/com/netgrif/application/engine/adapter/spring/elastic/domain/MapField.java
Constructor signatures updated to accept Map.Entry values with Collection instead of I18nString. Inheritance changed from TextField to DataField. Removed keyValueTranslations map and translation-specific handling. Added getValue() method. ES mapping annotations updated in adapter version.
Field Inheritance Changes
nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/I18nField.java, nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/StringCollectionField.java
Both classes updated to extend DataField instead of TextField. I18nField now uses fulltextValue instead of textValue for getValue() behavior.
Elastic Mapping Service
application-engine/src/main/java/com/netgrif/application/engine/elastic/service/ElasticCaseMappingService.java
transformMultichoiceMapField() and transformEnumerationMapField() now return Map.Entry values with Collection instead of I18nString via I18nStringUtils.collectTranslations().
Data Model Objects
nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/NodeInfo.java, nae-object-library/src/main/java/com/netgrif/application/engine/objects/auth/dto/AuthPrincipalDto.java
New value objects added: NodeInfo with nodeHost and nodePort fields; AuthPrincipalDto with username, realmId, and sessionId fields. Both implement Serializable.
ElasticCase Model Update
nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/ElasticCase.java
Removed immediateData field and replaced with nodeInfo field.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~30 minutes

  • MapField refactoring: Verify inheritance change from TextField to DataField doesn't break downstream usage; confirm constructor signature updates and value collection logic work correctly across both module versions
  • Type system changes: Ensure Collection transition from I18nString is handled consistently in all calling code
  • Field class inheritance: Review I18nField and StringCollectionField parent class changes for potential impact on superclass method expectations
  • Cross-module consistency: Confirm changes in nae-object-library align with adapter implementation in nae-spring-core-adapter

Possibly related PRs

Suggested labels

improvement, Medium

Pre-merge checks

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'NAE-2261 SEARCH Node - fetch cases from mongo' accurately reflects the main objective of this PR, which implements changes to enable the SEARCH node to fetch cases from Mongo while removing translation storage from Elastic.

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 improvement A change that improves on an existing feature Medium labels Dec 9, 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: 3

Caution

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

⚠️ Outside diff range comments (1)
nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/StringCollectionField.java (1)

10-17: Consider using private access modifier for collectionValue field.

The field collectionValue on line 12 is declared as public, which breaks encapsulation. Since the class uses Lombok @Data, getters and setters are already generated. Consider making it private for consistency with typical Java bean conventions.

Also note: the constructor stores values both in the parent class via super(values) (which sets fulltextValue) and in collectionValue. If this dual storage is intentional for different Elasticsearch query patterns (similar to the caseValue/fulltextValue pattern in CaseField), this is fine. Otherwise, consider whether both are necessary.

-    public String[] collectionValue;
+    private String[] collectionValue;
♻️ Duplicate comments (1)
application-engine/src/main/java/com/netgrif/application/engine/elastic/service/ElasticCaseMappingService.java (1)

136-136: Same null handling concern applies here.

Similar to the multichoice map field transformation, if selectedKey is not present in the options map, the result will be an entry with an empty collection of translations.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 46e49ec and b7d12ff.

📒 Files selected for processing (8)
  • application-engine/src/main/java/com/netgrif/application/engine/elastic/service/ElasticCaseMappingService.java (2 hunks)
  • nae-object-library/src/main/java/com/netgrif/application/engine/objects/auth/dto/AuthPrincipalDto.java (1 hunks)
  • nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/ElasticCase.java (1 hunks)
  • nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/I18nField.java (1 hunks)
  • nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/MapField.java (1 hunks)
  • nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/NodeInfo.java (1 hunks)
  • nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/StringCollectionField.java (1 hunks)
  • nae-spring-core-adapter/src/main/java/com/netgrif/application/engine/adapter/spring/elastic/domain/MapField.java (1 hunks)
🧰 Additional context used
🧠 Learnings (6)
📓 Common learnings
Learnt from: renczesstefan
Repo: netgrif/application-engine PR: 339
File: application-engine/src/test/groovy/com/netgrif/application/engine/filters/FilterImportExportTest.groovy:341-341
Timestamp: 2025-08-19T20:07:15.621Z
Learning: In the Elasticsearch migration, the stringId property was removed from ElasticCase and ElasticTask, with the id property now containing the MongoDB case/task object ID directly. This consolidation eliminates redundancy and simplifies the data model.
📚 Learning: 2025-08-19T20:07:15.621Z
Learnt from: renczesstefan
Repo: netgrif/application-engine PR: 339
File: application-engine/src/test/groovy/com/netgrif/application/engine/filters/FilterImportExportTest.groovy:341-341
Timestamp: 2025-08-19T20:07:15.621Z
Learning: In the Elasticsearch migration, the stringId property was removed from ElasticCase and ElasticTask, with the id property now containing the MongoDB case/task object ID directly. This consolidation eliminates redundancy and simplifies the data model.

Applied to files:

  • application-engine/src/main/java/com/netgrif/application/engine/elastic/service/ElasticCaseMappingService.java
  • nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/ElasticCase.java
📚 Learning: 2025-08-19T20:13:40.087Z
Learnt from: renczesstefan
Repo: netgrif/application-engine PR: 339
File: nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/CaseField.java:16-16
Timestamp: 2025-08-19T20:13:40.087Z
Learning: In CaseField.java, fulltextValue is mapped as a keyword field type in Elasticsearch (for exact matches, filtering, aggregations), while the separate caseValue field serves different Elasticsearch query requirements, allowing the system to support multiple query patterns on the same data through different field mappings.

Applied to files:

  • application-engine/src/main/java/com/netgrif/application/engine/elastic/service/ElasticCaseMappingService.java
  • nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/MapField.java
  • nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/StringCollectionField.java
  • nae-spring-core-adapter/src/main/java/com/netgrif/application/engine/adapter/spring/elastic/domain/MapField.java
  • nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/I18nField.java
📚 Learning: 2025-08-19T20:07:43.748Z
Learnt from: renczesstefan
Repo: netgrif/application-engine PR: 339
File: nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/CaseField.java:16-16
Timestamp: 2025-08-19T20:07:43.748Z
Learning: In CaseField.java, the separate caseValue field (List<String>) is intentionally maintained alongside fulltextValue for specific Elasticsearch query requirements, rather than being derived on-the-fly from fulltextValue.

Applied to files:

  • application-engine/src/main/java/com/netgrif/application/engine/elastic/service/ElasticCaseMappingService.java
  • nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/ElasticCase.java
  • nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/MapField.java
  • nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/StringCollectionField.java
  • nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/I18nField.java
📚 Learning: 2025-06-23T13:30:13.096Z
Learnt from: renczesstefan
Repo: netgrif/application-engine PR: 318
File: nae-object-library/src/main/java/com/netgrif/application/engine/objects/workflow/domain/menu/MenuItemConstants.java:60-62
Timestamp: 2025-06-23T13:30:13.096Z
Learning: In MenuItemConstants enum in nae-object-library/src/main/java/com/netgrif/application/engine/objects/workflow/domain/menu/MenuItemConstants.java, the field `attributeId` will be renamed to `value` to make it more generic and appropriate for both dataset attribute identifiers and technical constants like PATH_SEPARATOR.

Applied to files:

  • nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/I18nField.java
📚 Learning: 2025-12-02T14:35:05.305Z
Learnt from: renczesstefan
Repo: netgrif/application-engine PR: 373
File: nae-spring-core-adapter/src/main/java/com/netgrif/application/engine/adapter/spring/actions/ActionApi.java:98-98
Timestamp: 2025-12-02T14:35:05.305Z
Learning: In ActionApi, the deleteCase method intentionally does not include an AuthPrincipalDto parameter because it does not require author information, unlike createCase which needs the author via authPrincipalDto.

Applied to files:

  • nae-object-library/src/main/java/com/netgrif/application/engine/objects/auth/dto/AuthPrincipalDto.java
🧬 Code graph analysis (2)
application-engine/src/main/java/com/netgrif/application/engine/elastic/service/ElasticCaseMappingService.java (1)
nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/I18nStringUtils.java (1)
  • I18nStringUtils (8-18)
nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/NodeInfo.java (1)
nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/ElasticCase.java (1)
  • Data (18-126)
⏰ 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). (3)
  • GitHub Check: task-list-completed
  • GitHub Check: task-list-completed
  • GitHub Check: Build
🔇 Additional comments (10)
nae-object-library/src/main/java/com/netgrif/application/engine/objects/auth/dto/AuthPrincipalDto.java (1)

11-24: LGTM!

The DTO structure is well-designed. Excluding sessionId from toString and equals/hashCode is a good practice—it prevents accidental logging of sensitive session data and ensures object equality is based on identity attributes rather than transient session state.

nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/I18nField.java (2)

14-24: LGTM on the DataField migration.

The inheritance change to DataField and constructor update align with the broader refactoring in this PR.


26-32: Verify single-value behavior is intentional.

The getValue() method only uses fulltextValue[0] when constructing the I18nString. If fulltextValue can contain multiple elements (since values is a Set passed to the constructor), confirm this single-value extraction is the intended behavior.

nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/ElasticCase.java (3)

82-107: LGTM on constructor logic.

The constructor properly initializes all case-related fields from the source Case object, with appropriate null-safety checks for tasks and proper use of defensive copies for collections.


109-125: LGTM on update method.

The update method correctly synchronizes relevant mutable fields while incrementing the version counter.


80-81: Remove the unused nodeInfo field or integrate it properly.

The nodeInfo field is declared at line 80 but is not initialized in the constructor, not updated in the update() method, and is never accessed anywhere in the codebase. Either remove this unused field or integrate it fully by initializing it during construction and updating it in the update() method.

Likely an incorrect or invalid review comment.

nae-spring-core-adapter/src/main/java/com/netgrif/application/engine/adapter/spring/elastic/domain/MapField.java (1)

14-31: LGTM!

The constructor signatures correctly align with the base class refactoring from I18nString to Collection. The Elasticsearch field annotations are properly applied: Text type for full-text search and Keyword type for exact matching and aggregations.

nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/MapField.java (3)

12-12: Architectural change aligns with PR objectives.

The change from extending TextField to DataField removes the dependency on TextField as stated in the PR objectives. This is part of the broader refactoring to decouple Elasticsearch datafields from TextField.


16-29: Constructor implementation is correct.

The refactored constructors properly handle the transition from I18nString to Collection:

  • Single-entry constructor delegates to the list constructor
  • List constructor correctly extracts keys into keyValue array and flattens all translation collections into fulltextValue

31-38: getValue() method provides convenient API.

The new getValue() method returns:

  • A single key as String for enumeration fields
  • A LinkedHashSet of keys for multichoice fields
  • null for empty/null keyValue

The LinkedHashSet preserves insertion order while ensuring uniqueness, which is appropriate for multichoice selections.

Comment on lines +96 to 99
List<Map.Entry<String, Collection<String>>> values = new ArrayList<>();
for (String key : (Set<String>) mapValues) {
I18nString selectedValue = options.get(key);
values.add(new AbstractMap.SimpleEntry<>(key, selectedValue != null ? selectedValue : new I18nString("")));
values.add(new AbstractMap.SimpleEntry<>(key, I18nStringUtils.collectTranslations(options.get(key))));
}
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:

# First, let's look at the file and the complete method context
cat -n application-engine/src/main/java/com/netgrif/application/engine/elastic/service/ElasticCaseMappingService.java | sed -n '80,110p'

Repository: netgrif/application-engine

Length of output: 2089


🏁 Script executed:

# Search for I18nStringUtils.collectTranslations implementation
find . -type f -name "*.java" | xargs grep -l "I18nStringUtils" | head -5

Repository: netgrif/application-engine

Length of output: 292


🏁 Script executed:

# Look for the I18nStringUtils class definition
fd -type f -name "I18nStringUtils.java"

Repository: netgrif/application-engine

Length of output: 240


🏁 Script executed:

# Read the I18nStringUtils file to see the collectTranslations implementation
cat -n nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/I18nStringUtils.java

Repository: netgrif/application-engine

Length of output: 786


🏁 Script executed:

# Search for getFieldOptions implementation
rg -nA10 "getFieldOptions" application-engine/src/main/java/com/netgrif/application/engine/elastic/service/ElasticCaseMappingService.java

Repository: netgrif/application-engine

Length of output: 1830


🏁 Script executed:

# Search for tests related to transformMultichoiceMapField
fd -type f -name "*.java" | xargs grep -l "transformMultichoiceMapField\|ElasticCaseMappingService" | grep -i test

Repository: netgrif/application-engine

Length of output: 240


🏁 Script executed:

# Search for tests of ElasticCaseMappingService
find . -type f -name "*.java" -path "*/test/*" | xargs grep -l "ElasticCaseMappingService" 2>/dev/null | head -3

Repository: netgrif/application-engine

Length of output: 52


🏁 Script executed:

# Search for any validation or warnings about missing keys
rg -n "mapValues|options\.get" application-engine/src/main/java/com/netgrif/application/engine/elastic/service/ElasticCaseMappingService.java -B2 -A2

Repository: netgrif/application-engine

Length of output: 1025


🏁 Script executed:

# Check if there's any logging or warning in the surrounding code
rg -n "logger|log\.|warn|error" application-engine/src/main/java/com/netgrif/application/engine/elastic/service/ElasticCaseMappingService.java | head -20

Repository: netgrif/application-engine

Length of output: 1771


🏁 Script executed:

# Check the git history of this specific method to understand its evolution
git log --oneline -n 20 -- application-engine/src/main/java/com/netgrif/application/engine/elastic/service/ElasticCaseMappingService.java

Repository: netgrif/application-engine

Length of output: 150


Inconsistent error handling: missing options keys are silently converted to empty translations.

The code at line 98 does not validate that all keys from mapValues exist in the options map. While I18nStringUtils.collectTranslations(null) handles null gracefully by returning an empty list, this pattern is inconsistent with the error handling established elsewhere in this class. Other methods (e.g., lines 163, 180, 194) log errors when encountering data inconsistencies. Consider either adding validation to ensure all keys are present in the options map, or logging a warning when options.get(key) returns null to make data issues visible during debugging.

🤖 Prompt for AI Agents
In
application-engine/src/main/java/com/netgrif/application/engine/elastic/service/ElasticCaseMappingService.java
around lines 96-99, the code blindly calls options.get(key) and passes the
result to I18nStringUtils.collectTranslations, silently producing empty
translations for missing keys; change this to first check
options.containsKey(key) and if the key is missing log a warning (including the
missing key and identifying context such as the parent map or document id), then
either continue with an explicit empty translation list or handle it
consistently with the class’s error strategy (throw or collect an error),
ensuring missing keys are visible in logs rather than silently ignored.

Comment on lines +3 to +6
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NonNull;
import lombok.ToString;
Copy link

Choose a reason for hiding this comment

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

🧹 Nitpick | 🔵 Trivial

Remove unused import.

lombok.NonNull is imported but not used in this class.

 import lombok.Data;
 import lombok.EqualsAndHashCode;
-import lombok.NonNull;
 import lombok.ToString;
📝 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
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NonNull;
import lombok.ToString;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.ToString;
🤖 Prompt for AI Agents
In
nae-object-library/src/main/java/com/netgrif/application/engine/objects/auth/dto/AuthPrincipalDto.java
around lines 3 to 6, the import lombok.NonNull is unused; remove that import
line and keep only the required lombok imports (Data, EqualsAndHashCode,
ToString) so there are no unused imports.

Comment on lines +9 to +18
@Data
@AllArgsConstructor
public class NodeInfo implements Serializable {

@Serial
private static final long serialVersionUID = 7454569786379865L;

private String nodeHost;
private int nodePort;
}
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

Add @NoArgsConstructor for deserialization compatibility.

This class is used as a field in ElasticCase, which is serialized to Elasticsearch. Most serialization frameworks (including Jackson, commonly used with Elasticsearch) require a no-argument constructor for deserialization. Without it, you may encounter runtime errors when reading ElasticCase documents from Elasticsearch.

 @Data
 @AllArgsConstructor
+@NoArgsConstructor
 public class NodeInfo implements Serializable {

Also add the import:

import lombok.NoArgsConstructor;
🤖 Prompt for AI Agents
In
nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/NodeInfo.java
around lines 9 to 18, the class lacks a no-argument constructor required by
deserializers (e.g., Jackson) — add Lombok's @NoArgsConstructor annotation to
the class and import lombok.NoArgsConstructor so the class has an implicit
no-arg constructor for deserialization while keeping the existing @Data and
@AllArgsConstructor.

@machacjozef machacjozef changed the base branch from release/7.0.0-rev9 to release/7.0.0-rev10 December 15, 2025 14:26
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

improvement A change that improves on an existing feature Medium

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants