Skip to content

feat: extract core flagd evaluation and API modules#1696

Open
toddbaert wants to merge 1 commit intomainfrom
feat/extract-core
Open

feat: extract core flagd evaluation and API modules#1696
toddbaert wants to merge 1 commit intomainfrom
feat/extract-core

Conversation

@toddbaert
Copy link
Member

@toddbaert toddbaert commented Feb 10, 2026

Extraction of the core evaluator of flagd into 2 modules:

  • flagd-api (interfaces only, so that others can implement alternatives)
  • flagd-core (our current implementation)
    • the API is similar to the flagdCore object in JS, but has a smaller surface area for now (only what was currently needed in Java)

I've also included some basic automation to make sure the local version of flagd-core is always resolved in development, and at provider release the dep is pinned to exactly what is present locally.

I've intentionally made as few changes as possible, and made no functional changes; note that a large volume of the changes are git mv operations.

Fixes: #1695

@gemini-code-assist
Copy link
Contributor

Summary of Changes

Hello @toddbaert, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request significantly refactors the flagd provider by extracting its in-process flag evaluation capabilities into dedicated, reusable modules: flagd-api for interfaces and flagd-core for the concrete implementation. This change promotes a cleaner architecture, reduces coupling within the flagd provider, and lays the groundwork for easier maintenance and potential alternative evaluation engine implementations. The existing InProcessResolver now acts as a thin wrapper around the new core evaluator, streamlining its responsibilities.

Highlights

  • Core Logic Extraction: The core flag evaluation logic for flagd has been extracted from the providers/flagd module into a new, independent module named tools/flagd-core. This enhances modularity and reusability.
  • API Definition Module: A new module, tools/flagd-api, has been introduced to define the interfaces for flag evaluation, such as Evaluator and FlagStoreException. This separates the contract from its implementation.
  • In-Process Resolver Refactoring: The InProcessResolver in providers/flagd has been refactored to depend on and utilize the new flagd-core module for all flag storage and evaluation operations, removing its internal, duplicated logic.
  • Dependency Updates: The providers/flagd module's gRPC dependency has been updated to version 1.79.0, and the grpc-netty artifact has been replaced with grpc-netty-shaded to bundle Netty dependencies, simplifying deployment.
  • Schema and Targeting Logic Relocation: JSON schemas for flag configurations and targeting rules, along with their associated parsing and evaluation logic (e.g., Fractional, SemVer, StringComp operators), have been moved to the new flagd-core module.
Changelog
  • pom.xml
    • Added new modules 'tools/flagd-api' and 'tools/flagd-core' to the project build.
  • providers/flagd/pom.xml
    • Updated io.grpc.version property to 1.79.0.
    • Added a new dependency on dev.openfeature.contrib.tools:flagd-core.
    • Replaced grpc-netty dependency with grpc-netty-shaded.
    • Removed explicit netty-transport-native-epoll dependency, as it is now bundled by grpc-netty-shaded.
  • providers/flagd/src/main/java/dev/openfeature/contrib/providers/flagd/resolver/common/ChannelBuilder.java
    • Updated Netty and gRPC related imports to use shaded versions.
    • Removed explicit eventLoopGroup configuration for NettyChannelBuilder.
  • providers/flagd/src/main/java/dev/openfeature/contrib/providers/flagd/resolver/process/InProcessResolver.java
    • Removed direct flag evaluation logic and related imports.
    • Introduced an Evaluator dependency and delegated all flag resolution methods to it.
    • Updated constructor to initialize FlagStore with the new FlagdCore evaluator.
    • Removed operator and scope fields, as their functionality is now handled by the core evaluator.
  • providers/flagd/src/main/java/dev/openfeature/contrib/providers/flagd/resolver/process/model/FeatureFlag.java
    • Renamed and moved to tools/flagd-core/src/main/java/dev/openfeature/contrib/tools/flagd/core/model/FeatureFlag.java.
    • Updated package declaration and added Javadoc comments.
  • providers/flagd/src/main/java/dev/openfeature/contrib/providers/flagd/resolver/process/model/FlagParser.java
    • Renamed and moved to tools/flagd-core/src/main/java/dev/openfeature/contrib/tools/flagd/core/model/FlagParser.java.
    • Updated package declaration, added Javadoc, and adjusted schema loading logic.
  • providers/flagd/src/main/java/dev/openfeature/contrib/providers/flagd/resolver/process/model/ParsingResult.java
    • Renamed and moved to tools/flagd-core/src/main/java/dev/openfeature/contrib/tools/flagd/core/model/FlagParsingResult.java.
    • Updated package declaration and added Javadoc.
  • providers/flagd/src/main/java/dev/openfeature/contrib/providers/flagd/resolver/process/model/StringSerializer.java
    • Renamed and moved to tools/flagd-core/src/main/java/dev/openfeature/contrib/tools/flagd/core/model/StringSerializer.java.
    • Updated package declaration and added Javadoc.
  • providers/flagd/src/main/java/dev/openfeature/contrib/providers/flagd/resolver/process/storage/FlagStore.java
    • Removed internal ReentrantReadWriteLock, flags map, and flagSetMetadata map.
    • Removed throwIfInvalid field.
    • Updated constructor to accept an Evaluator instance.
    • Removed getFlag method.
    • Refactored streamerListener to delegate flag parsing and storage to the injected Evaluator.
  • providers/flagd/src/main/java/dev/openfeature/contrib/providers/flagd/resolver/process/storage/Storage.java
    • Removed getFlag method from the interface.
  • providers/flagd/src/main/java/dev/openfeature/contrib/providers/flagd/resolver/process/storage/StorageQueryResult.java
    • Removed file.
  • providers/flagd/src/main/java/dev/openfeature/contrib/providers/flagd/resolver/process/targeting/Fractional.java
    • Renamed and moved to tools/flagd-core/src/main/java/dev/openfeature/contrib/tools/flagd/core/targeting/Fractional.java.
    • Updated package declaration and added Javadoc.
  • providers/flagd/src/main/java/dev/openfeature/contrib/providers/flagd/resolver/process/targeting/Operator.java
    • Renamed and moved to tools/flagd-core/src/main/java/dev/openfeature/contrib/tools/flagd/core/targeting/Operator.java.
    • Updated package declaration and added Javadoc.
  • providers/flagd/src/main/java/dev/openfeature/contrib/providers/flagd/resolver/process/targeting/SemVer.java
    • Renamed and moved to tools/flagd-core/src/main/java/dev/openfeature/contrib/tools/flagd/core/targeting/SemVer.java.
    • Updated package declaration and added Javadoc.
  • providers/flagd/src/main/java/dev/openfeature/contrib/providers/flagd/resolver/process/targeting/StringComp.java
    • Renamed and moved to tools/flagd-core/src/main/java/dev/openfeature/contrib/tools/flagd/core/targeting/StringComp.java.
    • Updated package declaration and added Javadoc.
  • providers/flagd/src/main/java/dev/openfeature/contrib/providers/flagd/resolver/process/targeting/TargetingRuleException.java
    • Removed file.
  • providers/flagd/src/main/java/dev/openfeature/contrib/providers/flagd/resolver/process/targeting/flag.json
    • Removed file.
  • providers/flagd/src/test/java/dev/openfeature/contrib/providers/flagd/FlagdProviderTest.java
    • Updated import for FeatureFlag to use the new flagd-core model.
  • providers/flagd/src/test/java/dev/openfeature/contrib/providers/flagd/resolver/common/ChannelBuilderTest.java
    • Updated imports to use shaded gRPC Netty classes.
    • Removed mocks and verifications related to EpollIoHandler and MultiThreadIoEventLoopGroup.
  • providers/flagd/src/test/java/dev/openfeature/contrib/providers/flagd/resolver/process/InProcessResolverTest.java
    • Updated import for FeatureFlag to use the new flagd-core model.
    • Removed several metadata validation tests that are now handled by the core evaluator.
    • Refactored helper methods to inject both FlagStore and a new MockEvaluator.
  • providers/flagd/src/test/java/dev/openfeature/contrib/providers/flagd/resolver/process/MockEvaluator.java
    • Added new file implementing the Evaluator interface for testing purposes, wrapping MockStorage.
  • providers/flagd/src/test/java/dev/openfeature/contrib/providers/flagd/resolver/process/MockFlags.java
    • Updated import for FeatureFlag to use the new flagd-core model.
  • providers/flagd/src/test/java/dev/openfeature/contrib/providers/flagd/resolver/process/MockStorage.java
    • Updated import for FeatureFlag to use the new flagd-core model.
    • Modified getFlag and added getFlagSetMetadata to be used by MockEvaluator.
  • providers/flagd/src/test/java/dev/openfeature/contrib/providers/flagd/resolver/process/TestUtils.java
    • Removed import for FlagParser.
    • Updated getResourcePathInternal to use TestUtils.class.getClassLoader().
  • providers/flagd/src/test/java/dev/openfeature/contrib/providers/flagd/resolver/process/model/FlagParserTest.java
    • Renamed and moved to tools/flagd-core/src/test/java/dev/openfeature/contrib/tools/flagd/core/model/FlagParserTest.java.
    • Updated package and imports.
  • providers/flagd/src/test/java/dev/openfeature/contrib/providers/flagd/resolver/process/storage/FlagStoreTest.java
    • Updated imports for FeatureFlag, FlagParser, and FlagdCore to reflect their new locations.
    • Modified FlagStore instantiation to pass a FlagdCore instance.
  • providers/flagd/src/test/java/dev/openfeature/contrib/providers/flagd/resolver/process/targeting/FractionalTest.java
    • Renamed and moved to tools/flagd-core/src/test/java/dev/openfeature/contrib/tools/flagd/core/targeting/FractionalTest.java.
    • Updated package and imports.
  • providers/flagd/src/test/java/dev/openfeature/contrib/providers/flagd/resolver/process/targeting/OperatorTest.java
    • Renamed and moved to tools/flagd-core/src/test/java/dev/openfeature/contrib/tools/flagd/core/targeting/OperatorTest.java.
    • Updated package and imports.
  • providers/flagd/src/test/java/dev/openfeature/contrib/providers/flagd/resolver/process/targeting/SemVerTest.java
    • Renamed and moved to tools/flagd-core/src/test/java/dev/openfeature/contrib/tools/flagd/core/targeting/SemVerTest.java.
    • Updated package and imports.
  • providers/flagd/src/test/java/dev/openfeature/contrib/providers/flagd/resolver/process/targeting/StringCompTest.java
    • Renamed and moved to tools/flagd-core/src/test/java/dev/openfeature/contrib/tools/flagd/core/targeting/StringCompTest.java.
    • Updated package and imports.
  • release-please-config.json
    • Added new configuration entries for tools/flagd-api and tools/flagd-core modules for release management.
  • tools/flagd-api/CHANGELOG.md
    • Added new file.
  • tools/flagd-api/README.md
    • Added new file providing documentation for the flagd-api module, detailing its purpose, installation, and interfaces.
  • tools/flagd-api/pom.xml
    • Added new Maven configuration file for the flagd-api module, defining its artifact ID, version, and parent.
  • tools/flagd-api/src/main/java/dev/openfeature/contrib/tools/flagd/api/Evaluator.java
    • Added new interface Evaluator defining methods for setting flags, retrieving flag set metadata, and resolving various flag types.
  • tools/flagd-api/src/main/java/dev/openfeature/contrib/tools/flagd/api/FlagStoreException.java
    • Added new custom exception FlagStoreException for errors during flag store operations.
  • tools/flagd-api/version.txt
    • Added new file to track the module version.
  • tools/flagd-core/CHANGELOG.md
    • Added new file.
  • tools/flagd-core/README.md
    • Added new file providing documentation for the flagd-core module, detailing its purpose, usage, installation, and implemented interface.
  • tools/flagd-core/lombok.config
    • Added new Lombok configuration file.
  • tools/flagd-core/pom.xml
    • Added new Maven configuration file for the flagd-core module, including dependencies for flagd-api, Jackson, JsonLogic, JSON Schema Validator, Apache Commons Lang3, Semver4j, and Commons Codec.
  • tools/flagd-core/src/main/java/dev/openfeature/contrib/tools/flagd/core/FlagdCore.java
    • Added new file containing the FlagdCore class, which implements the Evaluator interface and encapsulates the core flag storage, locking, and evaluation logic.
  • tools/flagd-core/src/main/java/dev/openfeature/contrib/tools/flagd/core/targeting/TargetingRuleException.java
    • Added new file for custom targeting rule exceptions.
  • tools/flagd-core/src/main/resources/flagd/schemas/flags.json
    • Added new JSON schema file for flag configurations.
  • tools/flagd-core/src/main/resources/flagd/schemas/targeting.json
    • Added new JSON schema file for targeting rules.
  • tools/flagd-core/src/test/java/dev/openfeature/contrib/tools/flagd/core/FlagdCoreTest.java
    • Added new test file for FlagdCore functionality.
  • tools/flagd-core/src/test/java/dev/openfeature/contrib/tools/flagd/core/TestUtils.java
    • Added new test utility file.
  • tools/flagd-core/src/test/resources/flagConfigurations/invalid-configuration.json
    • Added new test resource file.
  • tools/flagd-core/src/test/resources/flagConfigurations/invalid-flag-multiple-errors.json
    • Added new test resource file.
  • tools/flagd-core/src/test/resources/flagConfigurations/invalid-flag-set-metadata.json
    • Added new test resource file.
  • tools/flagd-core/src/test/resources/flagConfigurations/invalid-flag.json
    • Added new test resource file.
  • tools/flagd-core/src/test/resources/flagConfigurations/invalid-metadata.json
    • Added new test resource file.
  • tools/flagd-core/src/test/resources/flagConfigurations/updatableFlags.json
    • Added new test resource file.
  • tools/flagd-core/src/test/resources/flagConfigurations/valid-flag-set-metadata.json
    • Added new test resource file.
  • tools/flagd-core/src/test/resources/flagConfigurations/valid-long.json
    • Added new test resource file.
  • tools/flagd-core/src/test/resources/flagConfigurations/valid-simple-with-extra-fields.json
    • Added new test resource file.
  • tools/flagd-core/src/test/resources/flagConfigurations/valid-simple.json
    • Added new test resource file.
  • tools/flagd-core/src/test/resources/flags/test-flags.json
    • Added new test resource file.
  • tools/flagd-core/version.txt
    • Added new file to track the module version.
Activity
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

Copy link
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

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

Code Review

This pull request introduces a significant and well-executed refactoring by extracting the core flag evaluation logic into new flagd-api and flagd-core modules. This improves modularity and aligns with the architecture of other flagd SDKs. The changes also include updating to grpc-netty-shaded to prevent dependency conflicts, which is a great improvement for a library. The tests have been diligently updated to reflect these architectural changes.

I have found one critical issue in the new flagd-core module where change detection for removed flags is missing. This will prevent consumers from being notified of flag deletions. A detailed comment with a suggested fix is provided.

@toddbaert toddbaert changed the title Feat/extract core feat: extract core flagd evaluation module Feb 10, 2026
@toddbaert toddbaert marked this pull request as draft February 10, 2026 21:42
@toddbaert toddbaert changed the title feat: extract core flagd evaluation module feat: extract core flagd evaluation and API modules Feb 10, 2026
@toddbaert toddbaert force-pushed the feat/extract-core branch 2 times, most recently from 2f7202f to c0421e1 Compare February 10, 2026 22:23
@toddbaert toddbaert closed this Feb 11, 2026
@toddbaert toddbaert reopened this Feb 11, 2026
@toddbaert toddbaert closed this Feb 11, 2026
@toddbaert toddbaert reopened this Feb 11, 2026
@toddbaert toddbaert force-pushed the feat/extract-core branch 2 times, most recently from 3daa738 to c8ec1d4 Compare February 11, 2026 14:52
@toddbaert toddbaert marked this pull request as ready for review February 11, 2026 16:55
: new SyncStreamQueueSource(options);
}

private <T> ProviderEvaluation<T> resolve(Class<T> type, String key, EvaluationContext ctx) {
Copy link
Member Author

Choose a reason for hiding this comment

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

This is one of the few things that weren't moved 1:1

This class was eliminated because FlagdCore now handles flag storage internally and includes the metadata in evaluation results directly. The StorageQueryResult intermediary is no longer needed.

* Interface for in-process flag evaluation in flagd.
* Combines flag storage and evaluation into a single abstraction.
*/
public interface Evaluator {
Copy link
Member Author

Choose a reason for hiding this comment

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

This new interface is equivalent to that in JS' flagd core, and the Go equivalent - though only the minimal features have been implemented (we don't need bulk evaluation here).

for module in "${modules[@]}"
do
mvn --batch-mode --projects $module --settings release/m2-settings.xml -DskipTests -Dcheckstyle.skip clean deploy
mvn --batch-mode --projects $module --settings release/m2-settings.xml -DskipTests -Dcheckstyle.skip -Dflagd-core.version=$FLAGD_CORE_VERSION clean deploy
Copy link
Member Author

Choose a reason for hiding this comment

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

This pins the flagd-core dep in the flagd-provider to the current version in source, ensuring we never have incompatibility.

@toddbaert toddbaert force-pushed the feat/extract-core branch 3 times, most recently from 837eb0a to f7a5c66 Compare February 11, 2026 19:09
Signed-off-by: Todd Baert <todd.baert@dynatrace.com>
Copy link
Contributor

@chrfwow chrfwow left a comment

Choose a reason for hiding this comment

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

looks good

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.

[flagd] Extract common Evaluator interface into shared modules

6 participants