Skip to content

feat(core): add base64 decode JSLT custom function - #126

Merged
brandPittCode merged 33 commits into
mainfrom
feat/add-custom-base64-jstl-function
Aug 18, 2026
Merged

feat(core): add base64 decode JSLT custom function#126
brandPittCode merged 33 commits into
mainfrom
feat/add-custom-base64-jstl-function

Conversation

@brandPittCode

@brandPittCode brandPittCode commented Aug 14, 2026

Copy link
Copy Markdown
Collaborator

PR Description

What this PR Provides

This pull request introduces support for custom JSLT functions in the JsltEngine, and adds a new DecodeBase64 function for decoding Base64-encoded strings within JSLT expressions. The implementation includes robust error handling, integration with Spring, and comprehensive unit and integration tests to ensure correctness.

Key changes include:

JSLT Engine Extensibility

  • Refactored JsltEngine to accept a collection of custom JSLT Function instances via its constructor, enabling injection and registration of custom functions. Updated the compile method to use these functions when compiling expressions. Error handling in validateExpression and evaluate now catches all exceptions for consistent error reporting. [1] [2]

New Custom Function: DecodeBase64

  • Added DecodeBase64, a Spring component implementing the JSLT Function interface. This function decodes Base64-encoded strings, gracefully returns null for absent/blank inputs, parses decoded content as JSON if possible, and throws clear exceptions for invalid input types or malformed Base64.

Testing and Validation

  • Added DecodeBase64Test to thoroughly test the new function, covering direct invocation, error cases, and integration with JsltEngine.
  • Updated existing tests (JsltEntityMappingValidatorTest, JsltMappingEngineAdapterTest) to instantiate JsltEngine with an empty list of functions, ensuring compatibility with the new constructor. [1] [2] [3] [4]

Tooling

  • Added a new agent configuration .github/agents/comment-audit.agent.json for auditing code comments and docstrings for consistency with implementation.

Fixes

Review

The reviewer must double-check these points:

  • The reviewer has tested the feature
  • The reviewer has reviewed the implementation of the feature
  • The documentation has been updated
  • The feature implementation respects the Technical Doc / ADR previously produced
  • The Pull Request title has a ! after the type/scope to identify the breaking
    change in the release note and ensure we will release a major version.

How to test

Please refer (copy/paste) the test section from the User Story. This should include

  • The initial state: Have and existing Entity Template configuration.
  • What and how to test: Create a new valid Entity Dinamyc Mapping that uses the function base64-decode() for a payload with a base64 encoded section.
  • Expected results: The function must be recognized and the dry run must succeed.

Breaking changes (if any)

  • Data loss / modification
  • API JSON schema modification (existing resource / behavior)
  • Behavior modification of a component
  • Others
  • N/A

Context of the Breaking Change

For example: we redefined the component types list in the DPAC referential

Result of the Breaking Change

For example: your component of type xxx will migrate to the type yyy

foukou19 and others added 27 commits July 21, 2026 13:24
…object and array payloads

Signed-off-by: foukou19 <ferial.oukoukas@decathlon.com>
Signed-off-by: foukou19 <ferial.oukoukas@decathlon.com>
Signed-off-by: foukou19 <ferial.oukoukas@decathlon.com>
Signed-off-by: foukou19 <ferial.oukoukas@decathlon.com>
Signed-off-by: foukou19 <ferial.oukoukas@decathlon.com>
Signed-off-by: foukou19 <ferial.oukoukas@decathlon.com>
Signed-off-by: foukou19 <ferial.oukoukas@decathlon.com>
Signed-off-by: foukou19 <ferial.oukoukas@decathlon.com>
Signed-off-by: foukou19 <ferial.oukoukas@decathlon.com>
Signed-off-by: foukou19 <ferial.oukoukas@decathlon.com>
Signed-off-by: foukou19 <ferial.oukoukas@decathlon.com>
Signed-off-by: ferial OUKOUKAS <75682459+foukou19@users.noreply.github.com>
@brandPittCode brandPittCode changed the title Feat(core): add base64 decode JSLT custom function feat(core): add base64 decode JSLT custom function Aug 14, 2026
@github-code-quality

github-code-quality Bot commented Aug 14, 2026

Copy link
Copy Markdown

Code Coverage Overview

Languages: Java

Java / code-coverage/jacoco

The overall coverage in commit 6683b40 in the feat/add-custom-base... branch remains at 90%, unchanged from commit ef5cf4b in the main branch.

Show a code coverage summary of the most impacted files.
File main ef5cf4b feat/add-custom-base... 6683b40 +/-
com/decathlon/i...JsltEngine.java 100% 100% 0%
com/decathlon/i...codeBase64.java 0% 88% +88%

Updated August 18, 2026 09:19 UTC

@brandPittCode
brandPittCode requested a balanced review from Copilot August 14, 2026 09:05

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Adds a custom Base64 decoder to the JSLT entity-mapping engine.

Changes:

  • Registers injectable custom JSLT functions.
  • Implements and tests base64-decode.
  • Adds a comment-audit agent configuration.

Reviewed changes

Copilot reviewed 6 out of 6 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
JsltEngine.java Registers custom JSLT functions.
DecodeBase64.java Implements Base64 decoding.
DecodeBase64Test.java Tests decoding and integration.
JsltMappingEngineAdapterTest.java Updates engine construction.
JsltEntityMappingValidatorTest.java Updates engine construction.
comment-audit.agent.json Adds an agent configuration.
Suppressed comments (3)

src/main/java/com/decathlon/idp_core/infrastructure/adapters/entity_mapping/jslt/functions/DecodeBase64.java:93

  • Do not include the supplied Base64 value in this exception. JsltEngine preserves the message, and ApiExceptionHandler logs and returns it (ApiExceptionHandler.java:347-351), so malformed values—which may contain encoded credentials or tokens—are copied into application logs and API errors.
      throw new IllegalArgumentException("Invalid Base64 string payload: '" + textValue + "'", e);

src/main/java/com/decathlon/idp_core/infrastructure/adapters/entity_mapping/jslt/functions/DecodeBase64.java:24

  • This adds a platform-specific JSLT function, but the user-facing JSLT mapping reference still only points to upstream JSLT documentation (docs/src/features/data-integration.md:185-187), where base64-decode does not exist. Document its name, accepted input, return behavior, and failure behavior in docs/src/ so mapping authors can discover and use the feature.
  public static final String FUNCTION_NAME = "base64-decode";

src/main/java/com/decathlon/idp_core/infrastructure/adapters/entity_mapping/jslt/functions/DecodeBase64.java:102

  • The new behavior that parses decoded content as JSON is not exercised by DecodeBase64Test; its success cases only take the plain-text fallback. Add coverage for Base64-encoded JSON (including an object or scalar) so the function's type-changing return contract is protected.
      JsonNode parsed = OBJECT_MAPPER.readTree(decodedString);
      // Jackson returns Java null if decodedString is empty ("")
      return (parsed != null) ? parsed : TextNode.valueOf(decodedString);

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread .github/agents/comment-audit.agent.md Outdated
@brandPittCode
brandPittCode marked this pull request as ready for review August 17, 2026 09:21

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 7 out of 7 changed files in this pull request and generated no new comments.

Suppressed comments (6)

src/main/java/com/decathlon/idp_core/infrastructure/adapters/entity_mapping/jslt/JsltEngine.java:19

  • The constructor description is still a plain // comment, so the JavaDoc consists only of an @param tag. Make the description part of the contiguous /// JavaDoc block.
  // Creates a JSLT engine with the custom functions discovered by Spring.

src/main/java/com/decathlon/idp_core/infrastructure/adapters/entity_mapping/jslt/functions/DecodeBase64.java:93

  • The malformed value is propagated through JsltEngine and is both logged and returned by ApiExceptionHandler (ApiExceptionHandler.java:350-351). Because mapped fields may contain credentials or other sensitive payload data, do not embed the input value in the exception message; retain it only as the cause-free context if needed.
      throw new IllegalArgumentException("Invalid Base64 string payload: '" + textValue + "'", e);

src/main/java/com/decathlon/idp_core/infrastructure/adapters/entity_mapping/jslt/functions/DecodeBase64.java:20

  • This adds a user-facing JSLT function, but the JSLT mapping reference in docs/src/features/data-integration.md:185-187 still only points to the upstream language documentation, which cannot describe this project-specific function. Add the function name, usage, accepted input, null behavior, and JSON/text return behavior under that reference, as required for behavior changes.
/// **Usage in JSLT:** `base64-decode(<base64-encoded-string>)`
///
/// Returns `null` if the input is absent, null, or blank.

src/main/java/com/decathlon/idp_core/infrastructure/adapters/entity_mapping/jslt/functions/DecodeBase64.java:100

  • ObjectMapper.readTree does not reject trailing root-level tokens by default. A decoded non-JSON string such as true story can therefore become the Boolean node true instead of falling back to the original text, silently discarding content. Enable trailing-token validation so only a complete JSON document is treated as JSON.
      JsonNode parsed = OBJECT_MAPPER.readTree(decodedString);

.github/agents/comment-audit.agent.md:24

  • The declared output-format example ends inside an unclosed Java fence and never tells the agent to report the observed behavior, discrepancy, or correction. As a result, the agent has no complete structured output contract. Complete and close the template.
- **Existing Docstring:**
  ```java
  <existing_docstring>

src/test/java/com/decathlon/idp_core/infrastructure/adapters/entity_mapping/jslt/functions/DecodeBase64Test.java:110

  • All successful cases currently decode plain text, which takes the JsonProcessingException fallback path. The newly advertised behavior that returns structured decoded JSON is therefore untested; add a case that decodes a JSON object and asserts its structure.
    JsonNode result = jsltEngine.evaluate(jsltExpression, payload);

@sonarqubecloud

Copy link
Copy Markdown

@brandPittCode
brandPittCode merged commit 8de7fd7 into main Aug 18, 2026
18 checks passed
@brandPittCode
brandPittCode deleted the feat/add-custom-base64-jstl-function branch August 18, 2026 15:45
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants