exceptionfactory commented on code in PR #6304:
URL: https://github.com/apache/nifi/pull/6304#discussion_r967364520


##########
nifi-nar-bundles/nifi-hashicorp-vault-bundle/nifi-hashicorp-vault-client-service-api/src/main/java/org/apache/nifi/vault/hashicorp/HashiCorpVaultClientService.java:
##########
@@ -0,0 +1,149 @@
+/*
+ * 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.nifi.vault.hashicorp;
+
+import org.apache.nifi.components.AllowableValue;
+import org.apache.nifi.components.PropertyDescriptor;
+import org.apache.nifi.components.ValidationContext;
+import org.apache.nifi.components.ValidationResult;
+import org.apache.nifi.components.Validator;
+import org.apache.nifi.controller.ControllerService;
+import org.apache.nifi.controller.VerifiableControllerService;
+import org.apache.nifi.expression.ExpressionLanguageScope;
+import org.apache.nifi.processor.util.StandardValidators;
+import org.apache.nifi.ssl.SSLContextService;
+
+import java.io.File;
+import java.util.Arrays;
+import java.util.Set;
+import java.util.stream.Collectors;
+
+/**
+ * Provides a HashiCorpVaultCommunicationService.
+ */
+public interface HashiCorpVaultClientService extends ControllerService, 
VerifiableControllerService {
+
+    AllowableValue DIRECT_PROPERTIES = new AllowableValue("direct-properties", 
"Direct Properties",
+            "Use properties, including dynamic properties, configured directly 
in the Controller Service to configure the client");
+    AllowableValue PROPERTIES_FILES = new AllowableValue("properties-files", 
"Properties Files",
+            "Use one or more '.properties' files to configure the client");
+
+    PropertyDescriptor CONFIGURATION_STRATEGY = new 
PropertyDescriptor.Builder()
+            .displayName("Configuration Strategy")
+            .name("configuration-strategy")
+            .required(true)
+            .allowableValues(DIRECT_PROPERTIES, PROPERTIES_FILES)
+            .defaultValue(DIRECT_PROPERTIES.getValue())
+            .description("Specifies the source of the configuration 
properties.")
+            .build();
+
+    PropertyDescriptor VAULT_URI = new PropertyDescriptor.Builder()
+            .name("vault.uri")
+            .displayName("Vault URI")
+            .description("The URI of the HashiCorp Vault server (e.g., 
http://localhost:8200).  Required if not specified in the " +
+                    "Bootstrap HashiCorp Vault Configuration File.")
+            .required(true)
+            
.expressionLanguageSupported(ExpressionLanguageScope.VARIABLE_REGISTRY)
+            .addValidator(StandardValidators.URI_VALIDATOR)
+            .dependsOn(CONFIGURATION_STRATEGY, DIRECT_PROPERTIES)
+            .build();
+
+    PropertyDescriptor VAULT_AUTHENTICATION = new PropertyDescriptor.Builder()
+            .name("vault.authentication")
+            .displayName("Vault Authentication")
+            .description("Vault authentication method, as described in the 
Spring Vault Environment Configuration documentation " +
+                    
"(https://docs.spring.io/spring-vault/docs/2.3.x/reference/html/#vault.core.environment-vault-configuration).")
+            .required(true)
+            .allowableValues(VaultAuthenticationMethod.values())
+            .defaultValue(VaultAuthenticationMethod.TOKEN.name())
+            .dependsOn(CONFIGURATION_STRATEGY, DIRECT_PROPERTIES)
+            .build();
+
+    PropertyDescriptor SSL_CONTEXT_SERVICE = new PropertyDescriptor.Builder()
+            .name("vault.ssl.context.service")
+            .displayName("SSL Context Service")
+            .description("The SSL Context Service used to provide client 
certificate information for TLS/SSL connections to the " +
+                    "HashiCorp Vault server.")
+            .required(false)
+            .identifiesControllerService(SSLContextService.class)
+            .dependsOn(CONFIGURATION_STRATEGY, DIRECT_PROPERTIES)
+            .build();
+
+    PropertyDescriptor VAULT_PROPERTIES_FILES = new 
PropertyDescriptor.Builder()
+            .name("vault.properties.files")
+            .displayName("Vault Properties Files")
+            .description("A comma-separated list of files containing HashiCorp 
Vault configuration properties, as described in the Spring Vault " +
+                    "Environment Configuration documentation 
(https://docs.spring.io/spring-vault/docs/2.3.x/reference/html/#vault.core.environment-vault-configuration).
 " +
+                    "All of the Spring property keys and 
authentication-specific property keys are supported.")
+            .required(true)
+            .addValidator(MultiFileExistsValidator.INSTANCE)

Review Comment:
   This should be changed to use the 
`identifiesExternalResource(ResourceCardinality.MULTIPLE, ResourceType.FILE)` 
description to support framework-based resource handling.



##########
nifi-nar-bundles/nifi-hashicorp-vault-bundle/nifi-hashicorp-vault-client-service/src/main/java/org/apache/nifi/vault/hashicorp/StandardHashiCorpVaultClientService.java:
##########
@@ -0,0 +1,209 @@
+/*
+ * 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.nifi.vault.hashicorp;
+
+import org.apache.nifi.annotation.behavior.DynamicProperties;
+import org.apache.nifi.annotation.behavior.DynamicProperty;
+import org.apache.nifi.annotation.behavior.SupportsSensitiveDynamicProperties;
+import org.apache.nifi.annotation.documentation.CapabilityDescription;
+import org.apache.nifi.annotation.documentation.Tags;
+import org.apache.nifi.annotation.lifecycle.OnDisabled;
+import org.apache.nifi.annotation.lifecycle.OnEnabled;
+import org.apache.nifi.components.ConfigVerificationResult;
+import org.apache.nifi.components.PropertyDescriptor;
+import org.apache.nifi.controller.AbstractControllerService;
+import org.apache.nifi.controller.ConfigurationContext;
+import org.apache.nifi.expression.ExpressionLanguageScope;
+import org.apache.nifi.logging.ComponentLog;
+import org.apache.nifi.processor.util.StandardValidators;
+import org.apache.nifi.reporting.InitializationException;
+import org.apache.nifi.ssl.SSLContextService;
+import org.apache.nifi.vault.hashicorp.config.HashiCorpVaultConfiguration;
+import org.springframework.core.env.PropertySource;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+
+
+@Tags({"hashicorp", "vault", "client"})
+@CapabilityDescription("A controller service for interacting with HashiCorp 
Vault.")
+@SupportsSensitiveDynamicProperties
+@DynamicProperties(
+        @DynamicProperty(name = "A Spring Vault configuration property name",
+                value = "The property value",
+                description = "Allows any Spring Vault property keys to be 
specified, as described in " +
+                        
"(https://docs.spring.io/spring-vault/docs/2.3.x/reference/html/#vault.core.environment-vault-configuration).
 " +
+                        "See Additional Details for more information.",
+                expressionLanguageScope = 
ExpressionLanguageScope.VARIABLE_REGISTRY
+        )
+)
+public class StandardHashiCorpVaultClientService extends 
AbstractControllerService implements HashiCorpVaultClientService {
+
+    private static final String COMMA_SEPARATOR = ",";
+    private static List<PropertyDescriptor> PROPERTIES = 
Collections.unmodifiableList(Arrays.asList(
+            CONFIGURATION_STRATEGY,
+            VAULT_URI,
+            VAULT_AUTHENTICATION,
+            SSL_CONTEXT_SERVICE,
+            VAULT_PROPERTIES_FILES,
+            CONNECTION_TIMEOUT,
+            READ_TIMEOUT
+    ));
+
+    private HashiCorpVaultCommunicationService communicationService;
+
+    @Override
+    protected PropertyDescriptor getSupportedDynamicPropertyDescriptor(final 
String propertyDescriptorName) {
+        return new PropertyDescriptor.Builder()
+                .name(propertyDescriptorName)
+                .displayName(propertyDescriptorName)
+                .dynamic(true)
+                
.expressionLanguageSupported(ExpressionLanguageScope.VARIABLE_REGISTRY)
+                .addValidator(StandardValidators.NON_EMPTY_VALIDATOR)
+                .build();
+    }
+
+    @Override
+    protected List<PropertyDescriptor> getSupportedPropertyDescriptors() {
+        return PROPERTIES;
+    }
+
+    @Override
+    public List<ConfigVerificationResult> verify(final ConfigurationContext 
context, final ComponentLog verificationLogger,
+                                                 final Map<String, String> 
variables) {
+        final List<ConfigVerificationResult> results = new ArrayList<>();
+        HashiCorpVaultCommunicationService service = null;
+        try {
+            service = createCommunicationService(context);
+            results.add(new ConfigVerificationResult.Builder()
+                    .outcome(ConfigVerificationResult.Outcome.SUCCESSFUL)
+                    .verificationStepName("Configure HashiCorp Vault Client")
+                    .explanation("Successfully configured HashiCorp Vault 
Client")
+                    .build());
+        } catch (final Exception e) {
+            verificationLogger.error("Failed to configure HashiCorp Vault 
Client", e);
+
+            results.add(new ConfigVerificationResult.Builder()
+                    .outcome(ConfigVerificationResult.Outcome.FAILED)
+                    .verificationStepName("Configure HashiCorp Vault Client")
+                    .explanation("Failed to configure HashiCorp Vault Client: 
" + e.getMessage())
+                    .build());
+        }
+        if (service != null) {
+            try {
+                service.testConnection();
+                results.add(new ConfigVerificationResult.Builder()
+                        .outcome(ConfigVerificationResult.Outcome.SUCCESSFUL)
+                        .verificationStepName("Connect to HashiCorp Vault 
Server")
+                        .explanation("Successfully connected to HashiCorp 
Vault Server")
+                        .build());
+            } catch (final Exception e) {
+                verificationLogger.error("Failed to connect to HashiCorp Vault 
Server", e);
+
+                results.add(new ConfigVerificationResult.Builder()
+                        .outcome(ConfigVerificationResult.Outcome.FAILED)
+                        .verificationStepName("Connect to HashiCorp Vault 
Server")
+                        .explanation("Failed to connect to HashiCorp Vault 
Server: " + e.getMessage())
+                        .build());
+            }
+        }
+
+        return results;
+    }
+
+    @OnEnabled
+    public void onEnabled(final ConfigurationContext context) throws 
InitializationException {
+        try {
+            communicationService = createCommunicationService(context);
+        } catch (final Exception e) {
+            throw new InitializationException("Failed to initialize HashiCorp 
Vault client", e);
+        }
+    }
+
+    @OnDisabled
+    public void onDisabled() {
+        communicationService = null;
+    }
+
+    @Override
+    public HashiCorpVaultCommunicationService 
getHashiCorpVaultCommunicationService() {
+        return communicationService;
+    }
+
+    private HashiCorpVaultCommunicationService 
createCommunicationService(final ConfigurationContext context) throws 
IOException {
+        final List<PropertySource<?>> propertySources = new ArrayList<>();
+
+        final String configurationStrategy = 
context.getProperty(CONFIGURATION_STRATEGY).getValue();
+        if (DIRECT_PROPERTIES.getValue().equals(configurationStrategy)) {
+            final PropertySource<?> configurationPropertySource = new 
DirectPropertySource("Direct Properties", context);
+            propertySources.add(configurationPropertySource);
+        } else {
+            final String propertiesFiles = 
context.getProperty(VAULT_PROPERTIES_FILES).getValue();
+            for (final String propertiesFile : 
propertiesFiles.split(COMMA_SEPARATOR)) {

Review Comment:
   This approach can be changed to use the `asResources()` and Resource 
References feature of Property Descriptors.



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