oscerd commented on code in PR #29235:
URL: https://github.com/apache/camel/pull/29235#discussion_r4480628945


##########
components/camel-hashicorp-vault/src/main/java/org/apache/camel/component/hashicorp/vault/HashicorpVaultPropertiesFunction.java:
##########
@@ -78,19 +89,11 @@ public class HashicorpVaultPropertiesFunction extends 
ServiceSupport implements
 
     private static final Logger LOG = 
LoggerFactory.getLogger(HashicorpVaultPropertiesFunction.class);
 
-    private static final String CAMEL_HASHICORP_VAULT_TOKEN_ENV = 
"CAMEL_HASHICORP_VAULT_TOKEN";
-    private static final String CAMEL_HASHICORP_VAULT_HOST_ENV = 
"CAMEL_HASHICORP_VAULT_HOST";
-    private static final String CAMEL_HASHICORP_VAULT_PORT_ENV
-            = "CAMEL_HASHICORP_VAULT_PORT";
-    private static final String CAMEL_HASHICORP_VAULT_SCHEME_ENV
-            = "CAMEL_HASHICORP_VAULT_SCHEME";
-    private static final String CAMEL_HASHICORP_VAULT_CLOUD_ENV
-            = "CAMEL_HASHICORP_VAULT_CLOUD";
-    private static final String CAMEL_HASHICORP_VAULT_NAMESPACE_ENV
-            = "CAMEL_HASHICORP_VAULT_NAMESPACE";
     private static final String DEFAULT_ENGINE = "secret";
     private CamelContext camelContext;
     private VaultTemplate client;
+    // the client the function created, which it closes on stop (a client 
given to the function is not closed)

Review Comment:
   Applied in 471ee1affb07: `client` is now `volatile`, as in the refresh task, 
so a thread resolving a property sees the null that `doStop()` sets.
   
   _Claude Code on behalf of oscerd_



##########
components/camel-hashicorp-vault/src/main/java/org/apache/camel/component/hashicorp/vault/HashicorpVaultClient.java:
##########
@@ -0,0 +1,245 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.component.hashicorp.vault;
+
+import java.io.Closeable;
+import java.util.concurrent.ScheduledExecutorService;
+import java.util.function.Supplier;
+
+import org.apache.camel.CamelContext;
+import org.apache.camel.spi.ExecutorServiceManager;
+import org.apache.camel.util.ObjectHelper;
+import org.springframework.http.client.SimpleClientHttpRequestFactory;
+import org.springframework.scheduling.concurrent.ConcurrentTaskScheduler;
+import org.springframework.vault.authentication.AppRoleAuthentication;
+import org.springframework.vault.authentication.AppRoleAuthenticationOptions;
+import 
org.springframework.vault.authentication.AppRoleAuthenticationOptions.RoleId;
+import 
org.springframework.vault.authentication.AppRoleAuthenticationOptions.SecretId;
+import org.springframework.vault.authentication.ClientAuthentication;
+import org.springframework.vault.authentication.JwtAuthentication;
+import org.springframework.vault.authentication.JwtAuthenticationOptions;
+import org.springframework.vault.authentication.KubernetesAuthentication;
+import 
org.springframework.vault.authentication.KubernetesAuthenticationOptions;
+import 
org.springframework.vault.authentication.KubernetesServiceAccountTokenFile;
+import org.springframework.vault.authentication.LifecycleAwareSessionManager;
+import org.springframework.vault.authentication.ResourceCredentialSupplier;
+import org.springframework.vault.authentication.TokenAuthentication;
+import org.springframework.vault.client.VaultClient;
+import org.springframework.vault.client.VaultEndpoint;
+import org.springframework.vault.core.VaultTemplate;
+import org.springframework.vault.support.ClientOptions;
+
+/**
+ * A client of HashiCorp Vault that logs in as its {@link 
HashicorpVaultClientSettings} say, and keeps its token valid:
+ * it renews the token before the token expires, and logs in again when the 
token can no longer be renewed. Closing the
+ * client stops the renewal and revokes the token it logged in with. A token 
given for the token login is renewed too,
+ * but never revoked.
+ * <p/>
+ * The endpoint, the properties function and the secret refresh task each 
create their client with
+ * {@link #create(CamelContext, Object, HashicorpVaultClientSettings)}, and 
close it when they stop.
+ */
+public final class HashicorpVaultClient implements Closeable {
+
+    private final VaultTemplate vaultTemplate;
+    private final LifecycleAwareSessionManager sessionManager;
+    private final ExecutorServiceManager executorServiceManager;
+    private final ScheduledExecutorService renewal;
+
+    private HashicorpVaultClient(VaultTemplate vaultTemplate, 
LifecycleAwareSessionManager sessionManager,
+                                 ExecutorServiceManager 
executorServiceManager, ScheduledExecutorService renewal) {
+        this.vaultTemplate = vaultTemplate;
+        this.sessionManager = sessionManager;
+        this.executorServiceManager = executorServiceManager;
+        this.renewal = renewal;
+    }
+
+    /**
+     * Creates a client. It logs in at its first request to Vault.
+     *
+     * @param  camelContext             the context, whose executor service 
manager runs the renewal of the token
+     * @param  source                   the owner of the client, which names 
the thread that renews the token
+     * @param  settings                 where Vault is and how to log in to it
+     * @return                          the client, to close when it is no 
longer used
+     * @throws IllegalArgumentException when the settings are incomplete or 
not valid
+     */
+    public static HashicorpVaultClient create(CamelContext camelContext, 
Object source, HashicorpVaultClientSettings settings) {
+        validate(settings);
+        VaultEndpoint endpoint = new VaultEndpoint();
+        endpoint.setHost(settings.getHost());
+        endpoint.setPort(Integer.parseInt(settings.getPort()));
+        endpoint.setScheme(settings.getScheme());
+
+        VaultClient client = vaultClient(endpoint, null);
+        // on HashiCorp Cloud the login methods are in the namespace, while 
Camel reads the secrets with the namespace in
+        // their path: so only the login, and the renewal and revocation of 
its token, are sent to the namespace
+        String namespace = settings.getCloudNamespace();
+        VaultClient loginClient = namespace != null ? vaultClient(endpoint, 
namespace) : client;
+        ClientAuthentication authentication = createAuthentication(settings, 
loginClient);
+
+        ExecutorServiceManager executorServiceManager = 
camelContext.getExecutorServiceManager();
+        ScheduledExecutorService renewal
+                = 
executorServiceManager.newSingleThreadScheduledExecutor(source, 
"HashicorpVaultTokenRenewal");

Review Comment:
   Applied in 471ee1affb07: the session manager, the template and the client 
are now built in a `try`, and the renewal executor is shut down (`shutdownNow`, 
as nothing is scheduled on it yet) if one of them throws.
   
   This guards against a later change rather than a failure that can happen 
today: the settings are validated, and the login is created, before the 
executor; the two Spring constructors only check that their arguments are not 
null, and the login itself happens at the first request. Camel's executor also 
starts no thread until a task is scheduled, and the `ExecutorServiceManager` 
shuts it down with the context.
   
   _Claude Code on behalf of oscerd_



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to