Repository navigation
CAMEL-26919: camel-hashicorp-vault - a Vault client without a CamelContext, for the Spring Boot early resolution - #29819
Conversation
…ntext, for the Spring Boot early resolution The early resolution of hashicorp: properties of Camel on Spring Boot runs before there is a CamelContext, so it cannot create a HashicorpVaultClient, whose token renewal runs on the executor service manager of the context. It therefore logs in only with a token. - HashicorpVaultClient.create(HashicorpVaultClientSettings) creates a client that renews its token on a daemon thread of its own, which closing the client stops. - HashicorpVaultClientSettings.fromConfiguration(HashicorpVaultConfiguration) takes the settings of the camel.vault.hashicorp options alone, without the CAMEL_HASHICORP_VAULT_* environment variables. - The Spring Boot section of the component documentation says that the early resolution logs in as the properties function does, and revokes the token of its login once the properties are resolved. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: Andrea Cosentino <ancosen@gmail.com>
|
🌟 Thank you for your contribution to the Apache Camel project! 🌟 🐫 Apache Camel Committers, please review the following items:
|
gnodet-bot
left a comment
There was a problem hiding this comment.
Clean refactoring. The extraction of Supplier<ScheduledExecutorService> + Consumer<ScheduledExecutorService> strategy into the private create is well-designed — it eliminates the CamelContext dependency from instance fields while keeping the two code paths consistent.
One minor nit on the fromConfiguration Javadoc — missing @return. Not blocking.
This review was generated by an AI agent, Hermès on behalf of @gnodet.
| * @param configuration the vault configuration | ||
| * @since 4.24 |
There was a problem hiding this comment.
💡 Nit: Missing @return tag. Add it between @param and @since:
| * @param configuration the vault configuration | |
| * @since 4.24 | |
| * @param configuration the vault configuration | |
| * @return the settings | |
| * @since 4.24 |
|
🧪 CI tested the following changed modules:
🔁 1 test passed only after a retry on JDK 21 (1 retried attempt) Recovered flaky tests on JDK 21 (1)
🔬 Scalpel shadow comparison — Scalpel: 9 of 722 tested, 26 compile-only — current: 9 all testedMaveniverse Scalpel detected 9 affected modules (current approach: 9). Skip-tests mode would test 9 modules (2 direct + 8 downstream), skip tests for 26 (generated code, meta-modules) Modules Scalpel would test (9)
Modules with tests skipped (26)
All tested modules (36 modules, 5m 23s total)Total reactor time: 5m 23s
Top 20 slowest modules:
|
davsclaus
left a comment
There was a problem hiding this comment.
This adds a HashiCorp Vault client that needs no CamelContext, for the early property resolution of Camel on Spring Boot, and pulls the camel.vault.hashicorp mapping out into HashicorpVaultClientSettings.fromConfiguration. The refactoring is small and keeps the context-based path as it was. Looks good to me.
What I checked:
- Both
createmethods now share the privatecreate(settings, renewals, shutdown)(HashicorpVaultClient.java:141), so the context-free client gets the same behaviour: the samevalidate, the TLS context fromHashicorpVaultTls.sslContext(it reads plain files and needs no CamelContext), the cloud namespace only on the login client, the same logins, and the same cleanup when building the session manager fails. - No change for existing users:
create(CamelContext, Object, settings)still asks the context'sExecutorServiceManagerfor theHashicorpVaultTokenRenewalscheduler and callsshutdownNowon it inclose()(:421), as before. The constructor is private, so the new constructor signature does not break any public API. - The context-free renewal thread is a daemon (
Camel HashicorpVaultTokenRenewal), so a caller that forgetsclose()does not keep the JVM running.close()still stops the renewal, then revokes the login token throughsessionManager.destroy(), then closes the login resources. fromConfigurationcopies all 22 client fields ofHashicorpVaultConfiguration(all getters except refresh/secrets, which are not client settings), the same list as before.fromEnvironmentOrConfigurationdelegates to it, and the environment variables still win.- Nothing new is logged, and the validation messages do not include secrets.
- Tests: the new AppRole test against the fake Vault checks the renewal on a daemon thread and the revoke-self on close (
HashicorpVaultClientTest.java:176), and the settings test coversfromConfiguration. Awaitility usesatMost, there is noThread.sleep, and the JUnit assertions match the module style.@since 4.24is on the new public methods. The catalog doc copy is regenerated, and the_logging_in_to_hashicorp_vault/_tlsanchors exist.
Small points, none blocking:
HashicorpVaultClientSettings.java:130: gnodet-bot's@returnnit is still open. It is consistent withfromEnvironmentOrConfiguration, which also has no@return. Adding@return the settingsto both would be fine.- The new doc paragraph says the early resolution revokes "the token of its login". With
authentication=token, nothing is revoked (by design, see theclose()Javadoc). A short "(a token given for the token login is not revoked)" would avoid surprising readers. The paragraph also describes the behaviour of apache/camel-spring-boot#2091, so that PR should land in the same release.
Claude Code on behalf of davsclaus. This review was generated by an AI agent and may contain inaccuracies; please verify all suggestions before applying.
Summary
Fixes CAMEL-26919, a follow-up of CAMEL-25675 (#29235, #29619, #29708).
Camel on Spring Boot can resolve
hashicorp:properties early (camel.component.hashicorp-vault.early-resolve-properties=true), before there is a CamelContext. That early resolution builds its ownVaultTemplatewithcamel.vault.hashicorp.token, so the logins of CAMEL-25675 (AppRole, Kubernetes, JWT, cert, cloud) and the TLS options do not apply to it: an application that logs in with AppRole needs a fixed token again just for the early resolution. It cannot useHashicorpVaultClientas it is, because the token renewal runs on the executor service manager of the CamelContext.This PR adds what camel-spring-boot needs:
HashicorpVaultClient.create(HashicorpVaultClientSettings)creates a client without a CamelContext. It renews its token on a daemon thread of its own (Camel HashicorpVaultTokenRenewal), andclose()stops that thread and revokes the token of the login, as for the clients of the endpoint, the properties function and the secret refresh task. The twocreatemethods share their code: only where the renewal runs differs.HashicorpVaultClientSettings.fromConfiguration(HashicorpVaultConfiguration)takes the settings of thecamel.vault.hashicorpoptions alone. Spring Boot binds these options itself, and theCAMEL_HASHICORP_VAULT_*environment variables belong to the properties function.fromEnvironmentOrConfigurationnow delegates to it.The camel-spring-boot side is apache/camel-spring-boot#2091, a draft until this change is in the SNAPSHOT: the early resolution binds
camel.vault.hashicorpwith Spring Boot's relaxed binding, logs in withHashicorpVaultClient.create(settings), and closes the client once the properties are resolved.Tests
HashicorpVaultClientTest.aClientWithoutCamelContextRenewsItsTokenOnADaemonThreadAndRevokesItOnClose: an AppRole login against the fake Vault. The token is renewed on a daemon thread, and closing the client revokes it.HashicorpVaultClientSettingsTest.takesTheSettingsOfTheConfigurationAlone.mvn clean install -DskipTests -DskipITs): the only regenerated file is the catalog copy of the component documentation, committed.Claude Code on behalf of oscerd
🤖 Generated with Claude Code