Visitar URL original
Add type introspection to DeclarativeConfigProperties by colamong · Pull Request #8883 · open-telemetry/opentelemetry-java · GitHub
Skip to content

Add type introspection to DeclarativeConfigProperties - #8883

Merged
jack-berg merged 3 commits into
open-telemetry:mainfrom
colamong:feat/declarative-config-type-introspection
Oct 7, 2026
Merged

jack-berg merged 3 commits into
open-telemetry:mainfrom
colamong:feat/declarative-config-type-introspection

Conversation

@colamong

@colamong colamong commented Sep 29, 2026 •

Copy link
Copy Markdown
Contributor

Resolves #8101

Adds isString / isBoolean / isInt / isLong / isDouble to DeclarativeConfigProperties, the is<Type> option agreed on in the issue.

Each predicate answers "would the corresponding getter return a non-null value", using exactly the getter's accepted types — isInt / isLong accept both Integer and Long, isDouble accepts both Float and Double. Unlike calling the getter, it never logs a type-mismatch warning, which is what makes a type-coercing decorator possible.

Downstream motivation: the Spring Boot starter currently keeps a full copy of YamlDeclarativeConfigProperties with coercing getters (open-telemetry/opentelemetry-java-instrumentation#15775, open-telemetry/opentelemetry-java-instrumentation#20034), because wrapping the real one triggers those warnings. That copy can be replaced by a decorator once this lands.

Changes:

  • DeclarativeConfigProperties: five new methods
  • EmptyDeclarativeConfigProperties: all return false
  • YamlDeclarativeConfigProperties: implementation mirroring the getters
  • DeclarativeConfigContext: delegating wrapper forwards the new methods
  • Tests: predicates vs. stored types, no warning logs emitted, predicates agree with getters for every key, the Long / Float conversions (built directly, since YAML parsing only yields Integer / Double), and forwarding through the config wrapper handed to a ComponentProvider

The methods are abstract rather than default: a default could only be built on the getters, which would reintroduce the warnings. Since this is the incubator API I assumed that is acceptable — happy to change if you'd prefer otherwise.

Add isString/isBoolean/isInt/isLong/isDouble, mirroring the accepted
types of the corresponding getters, so a caller can ask what a property
holds without the implementation reporting a type mismatch.

Without this a type-coercing decorator is impossible: the only way to
learn the stored type is to call a getter, which logs a warning when it
does not match. The Spring Boot starter works around it today by copying
YamlDeclarativeConfigProperties wholesale.

Resolves open-telemetry#8101
@colamong
colamong requested a review from a team as a code owner September 29, 2026 23:29
@opentelemetry-pr-dashboard

opentelemetry-pr-dashboard Bot commented Sep 29, 2026 •

Copy link
Copy Markdown

Pull request dashboard status

Merged · refreshed 2026-10-07 21:19 UTC

Status above doesn't look right?
  • Anything look wrong? Report it with what you expected; it helps us improve the dashboard.

@codecov

codecov Bot commented Sep 29, 2026 •

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 91.13%. Comparing base (7f423cb) to head (3acc1fc).
⚠️ Report is 10 commits behind head on main.

Additional details and impacted files
@@             Coverage Diff              @@
##               main    #8883      +/-   ##
============================================
+ Coverage     91.11%   91.13%   +0.01%     
- Complexity    10678    10718      +40     
============================================
  Files          1007     1007              
  Lines         28871    28941      +70     
  Branches       3694     3705      +11     
============================================
+ Hits          26305    26374      +69     
- Misses         1735     1736       +1     
  Partials        831      831              

☔ 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.

@colamong
colamong force-pushed the feat/declarative-config-type-introspection branch from 8c73fae to 3d937e8 Compare September 29, 2026 23:52
YAML parsing only produces Integer and Double, so test the Long branch
of isInt/isLong and the Float branch of isDouble with values built
directly. Also check that the config handed to a ComponentProvider
forwards the predicates to its delegate.
@colamong
colamong force-pushed the feat/declarative-config-type-introspection branch from 3d937e8 to 8f4276e Compare September 29, 2026 23:54

@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.

Thanks - just a few nits

*
* <p>This is the introspection counterpart of {@link #getString(String)}: it answers whether that
* getter would return a non-null value, without the implementation reporting a type mismatch for
* a property which holds some other type.

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.

Let's make these comments consistent. I see a few variants of this explanation of pairing with a corresponding get method: this, none, and "Accepts the same values {@link #getInt(String)} accepts, including a {@link Long} which that getter narrows with {@link Long#intValue()}."

I think mentioning the "implementation reporting a type mismatch" is a mistake because it implies the log warning is part of the API contract, but its actually just an implementation detail.

Should also probably mention that all these return false if the value is null.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Done in 3acc1fc. All five now share one form: "holds a value which {@link #getX(String)} accepts", with @return stating false otherwise, including when the property is null. Dropped the type-mismatch wording and the per-type widening notes — linking the getter carries that.


@Override
public boolean isString(String name) {
Objects.requireNonNull(name, "Null configuration property name");

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.

Applies to all these.

Suggested change
Objects.requireNonNull(name, "Null configuration property name");
Objects.requireNonNull(name, "name");

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Done in 3acc1fc for all five is<Type> methods.

@jack-berg

Copy link
Copy Markdown
Member

Nice - thanks!

@jack-berg
jack-berg merged commit c99cb41 into open-telemetry:main Oct 7, 2026
34 checks passed
@otelbot

otelbot Bot commented Oct 7, 2026

Copy link
Copy Markdown
Contributor

Thank you for your contribution @colamong! 🎉 We would like to hear from you about your experience contributing to OpenTelemetry by taking a few minutes to fill out this survey.

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.

DeclarativeConfigProperties: no way to coerce types without triggering warnings

2 participants