Skip to content

Make declarative config parsing and mapping pluggable - #8983

Open
ash-thakur-rh wants to merge 9 commits into
open-telemetry:mainfrom
ash-thakur-rh:features/fe-config-spi
Open

ash-thakur-rh wants to merge 9 commits into
open-telemetry:mainfrom
ash-thakur-rh:features/fe-config-spi

Conversation

@ash-thakur-rh

@ash-thakur-rh ash-thakur-rh commented Oct 28, 2026 •

Copy link
Copy Markdown

Description:

  • Added a dedicated declarative-config-spi module for the mapper and YAML parser interfaces.
  • Added the Jackson 2 mapper as a runtime dependency so it is available by default.
  • Documented how to exclude the Jackson 2 mapper and register a custom mapper, such as one using Jackson 3.
  • Updated OSGi metadata and integration coverage for declarative configuration.
  • Updated the declarative configuration README and changelog.
  • Verified the affected declarative config, autoconfigure, API incubator, Graal, and OSGi test suites. Will fix other if there are other test failures.
  • Did a manual end-to-end check in a local consumer project, excluded the Jackson 2 adapter, registered a Jackson 3 mapper through ServiceLoader, and verified configuration parsing and mapping.

Closes #8820

Add parser and mapper SPIs, and move the Jackson 2 mapper into an
optional adapter module.

Signed-off-by: Ashish Thakur <ashishth@redhat.com>
Signed-off-by: Ashish Thakur <ashishth@redhat.com>
@linux-foundation-easycla

linux-foundation-easycla Bot commented Oct 28, 2026 •

Copy link
Copy Markdown

CLA Signed
The committers listed above are authorized under a signed CLA.

@opentelemetry-pr-dashboard

opentelemetry-pr-dashboard Bot commented Oct 28, 2026 •

Copy link
Copy Markdown

Pull request dashboard status

Waiting on the author · refreshed 2026-11-11 13:14 UTC

Two things need attention:

  • Required checks are failing — investigate the failures.
  • 6 review items — respond to each (e.g. link a commit, explain why not, ask a follow-up):
    • Inline threads: 1, 2, 3, 4, 5, 6
Status above doesn't look right?
  • Just replied or pushed? Anything around or after the refresh time above may not be picked up yet — give it a few minutes.
  • Should this be with reviewers? Comment /dashboard route:reviewers to route it to them.
  • Anything wrong — including the routing? Report it with what you expected; it helps us improve the dashboard.

@codecov

codecov Bot commented Oct 28, 2026 •

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 92.91339% with 9 lines in your changes missing coverage. Please review.
✅ Project coverage is 90.36%. Comparing base (53d860b) to head (82dfaa7).

Files with missing lines Patch % Lines
...nfig/internal/DeclarativeConfigProviderLoader.java 82.60% 2 Missing and 2 partials ⚠️
...g/internal/DeclarativeConfigurationMapperUtil.java 55.55% 4 Missing ⚠️
...veconfig/model/internal/ExtensionPropertyUtil.java 75.00% 0 Missing and 1 partial ⚠️
Additional details and impacted files
@@             Coverage Diff              @@
##               main    #8983      +/-   ##
============================================
+ Coverage     90.33%   90.36%   +0.02%     
- Complexity    11017    11034      +17     
============================================
  Files          1021     1025       +4     
  Lines         30124    30168      +44     
  Branches       3933     3939       +6     
============================================
+ Hits          27214    27261      +47     
+ Misses         1953     1947       -6     
- Partials        957      960       +3     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Signed-off-by: Ashish Thakur <ashishth@redhat.com>
@ash-thakur-rh

ash-thakur-rh commented Oct 28, 2026 •

Copy link
Copy Markdown
Author

CLA Signed
The committers listed above are authorized under a signed CLA.

@ash-thakur-rh
ash-thakur-rh marked this pull request as ready for review October 29, 2026 05:26
@ash-thakur-rh
ash-thakur-rh requested a review from a team as a code owner October 29, 2026 05:26

@jack-berg jack-berg left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

This is pretty close to the shape I imagined. Couple of things to think through tho.

* This class is internal and is hence not for public use. Its APIs are unstable and can change at
* any time.
*/
public final class SnakeYamlDeclarativeConfigurationParser

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Interesting.. so we have a dedicated jackson module, but build the snakeyaml implementation into declarative-config directly despite it being pluggable via SPI.

I think we need to think this through and be consistent.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

yes, I agree. we can move the snakeyaml impl to its own. For now, I will have sankeyaml impl in declarative-config until we think this through.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Ok upon further thought, I think we need to either rip out the DeclarativeConfigurationYamlParser SPI or split the snakeyaml out into its own module now.

The argument to rip out the yaml SPI is that nobody has reported issues with snakeyaml yet so its possible its stable enough / ubiquitous enough that nobody wants it pluggable. The argument to keep it and split snakeymal into its own module is that there are other YAML parsers out there and it may be inevitable that someone eventually takes issue with snakeyaml and wants to bring their own.

I still lean towards keeping the yaml SPI since it buys a mitigation step in case snakeyaml library falls into disrepair or has some other issue that makes it a toxic dependency. So let's break out a snakeyaml module.

Comment thread CHANGELOG.md Resolved
@ash-thakur-rh

ash-thakur-rh commented Nov 5, 2026 •

Copy link
Copy Markdown
Author

This is pretty close to the shape I imagined. Couple of things to think through tho.

Thanks @jack-berg , will take care of the things suggested.

Signed-off-by: Ashish Thakur <ashishth@redhat.com>
Signed-off-by: Ashish Thakur <ashishth@redhat.com>
@otelbot otelbot Bot added the api-change Changes to public API surface area label Nov 5, 2026
Signed-off-by: Ashish Thakur <ashishth@redhat.com>
Signed-off-by: Ashish Thakur <ashishth@redhat.com>
@otelbot otelbot Bot removed the api-change Changes to public API surface area label Nov 5, 2026
Signed-off-by: Ashish Thakur <ashishth@redhat.com>
@opentelemetry-pr-dashboard

This comment has been minimized.

@ash-thakur-rh

Copy link
Copy Markdown
Author

/dashboard route:reviewers

@opentelemetry-pr-dashboard

Copy link
Copy Markdown

@ash-thakur-rh, this pull request was routed to reviewers. The handoff remains active across pushes until newer actionable human feedback arrives. Top-level feedback through this request will not return; unresolved review threads remain open.

* @param <T> the target type
* @return the converted value
*/
<T> T convert(Object value, Class<T> targetType);

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

The new SPI methods convert / toMap / DeclarativeConfigurationYamlParser.parse throw under certain conditions. We should standardize the throws contract so callers can catch in a consistent way regardless of implementation.

Logger.getLogger(DeclarativeConfigProviderLoader.class.getName());

private static final ComponentLoader COMPONENT_LOADER =
ComponentLoader.forClassLoader(DeclarativeConfigProperties.class.getClassLoader());

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

We need to find a way for ComponentLoader to be a part of the contract and passed through from the caller. Every time we've loaded SPIs previously using a convenient class loader available to us, we eventually get an issue opened where someone needs that class loader to be configurable. That's why you see setComponentLoader style methods everywhere.

This is going to be disruptive for ExtensionPropertyUtil, which calls DeclarativeConfigurationMapper, and maybe the contracts in DeclarativeConfiguration itself since the parse operation currently doesn't have any overload which includes a ComponentLoader. If it proves too disruptive, let's skip and open an issue to followup.

Comment on lines +69 to +72
MessageFormat.format(
"Multiple {0} providers found. Please include only one, or specify preference "
+ "setting {1} to the FQCN of the preferred provider.",
spiClass.getSimpleName(), configProperty));

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

We don't use this MessageFormat style anywhere in this repo so let's not start

Suggested change
MessageFormat.format(
"Multiple {0} providers found. Please include only one, or specify preference "
+ "setting {1} to the FQCN of the preferred provider.",
spiClass.getSimpleName(), configProperty));
"Multiple {0} providers found. Please include only one, or specify preference "
+ "setting {1} to the FQCN of the preferred provider.",
new Object[]{spiClass.getSimpleName(), configProperty});

* This class is internal and is hence not for public use. Its APIs are unstable and can change at
* any time.
*/
public final class SnakeYamlDeclarativeConfigurationParser

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Ok upon further thought, I think we need to either rip out the DeclarativeConfigurationYamlParser SPI or split the snakeyaml out into its own module now.

The argument to rip out the yaml SPI is that nobody has reported issues with snakeyaml yet so its possible its stable enough / ubiquitous enough that nobody wants it pluggable. The argument to keep it and split snakeymal into its own module is that there are other YAML parsers out there and it may be inevitable that someone eventually takes issue with snakeyaml and wants to bring their own.

I still lean towards keeping the yaml SPI since it buys a mitigation step in case snakeyaml library falls into disrepair or has some other issue that makes it a toxic dependency. So let's break out a snakeyaml module.

api(project(":sdk:all"))
api(project(":api:incubator"))
compileOnly(project(":sdk-extensions:autoconfigure-spi"))
api(project(":sdk-extensions:autoconfigure-spi"))

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

This should be an implementation dependency on spi unless any spi classes are part of declarative config public facing API contracts

* The built-in SnakeYAML parser and Jackson 2 mapper work by default. The mapper is supplied by
the `declarative-config-jackson2` module (`opentelemetry-sdk-extension-declarative-config-jackson2`
artifact). If you exclude that module, register a mapper provider of your own; otherwise,
operations that need mapping fail with a `DeclarativeConfigException`.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Tighten this up - too wordy.

This branch has not been deployed

No deployments
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.

Make declarative config YAML parsing and object mapping requirements pluggable via SPI

2 participants