You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nifi.apache.org by ns...@apache.org on 2023/05/25 14:14:09 UTC

[nifi] branch support/nifi-1.x updated: NIFI-11585: Added ADLSCredentialsControllerServiceLookup

This is an automated email from the ASF dual-hosted git repository.

nsabonyi pushed a commit to branch support/nifi-1.x
in repository https://gitbox.apache.org/repos/asf/nifi.git


The following commit(s) were added to refs/heads/support/nifi-1.x by this push:
     new 5fba0410d8 NIFI-11585: Added ADLSCredentialsControllerServiceLookup
5fba0410d8 is described below

commit 5fba0410d8a29a3cb14cc7a2ca9dccfb41c028a5
Author: Peter Turcsanyi <tu...@apache.org>
AuthorDate: Tue May 23 17:47:40 2023 +0200

    NIFI-11585: Added ADLSCredentialsControllerServiceLookup
    
    Backported
    This closes #7287
    
    Signed-off-by: Nandor Soma Abonyi <ns...@apache.org>
    (cherry picked from commit e2dd9359e4004c2a45d1a9740295ddc8bab102ce)
---
 .../ADLSCredentialsControllerServiceLookup.java    |  55 ++++++++
 .../org.apache.nifi.controller.ControllerService   |   1 +
 ...TestADLSCredentialsControllerServiceLookup.java | 155 +++++++++++++++++++++
 3 files changed, 211 insertions(+)

diff --git a/nifi-nar-bundles/nifi-azure-bundle/nifi-azure-processors/src/main/java/org/apache/nifi/services/azure/storage/ADLSCredentialsControllerServiceLookup.java b/nifi-nar-bundles/nifi-azure-bundle/nifi-azure-processors/src/main/java/org/apache/nifi/services/azure/storage/ADLSCredentialsControllerServiceLookup.java
new file mode 100644
index 0000000000..c1984fb890
--- /dev/null
+++ b/nifi-nar-bundles/nifi-azure-bundle/nifi-azure-processors/src/main/java/org/apache/nifi/services/azure/storage/ADLSCredentialsControllerServiceLookup.java
@@ -0,0 +1,55 @@
+/*
+ * 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.services.azure.storage;
+
+import org.apache.nifi.annotation.behavior.DynamicProperty;
+import org.apache.nifi.annotation.documentation.CapabilityDescription;
+import org.apache.nifi.annotation.documentation.Tags;
+import org.apache.nifi.expression.ExpressionLanguageScope;
+import org.apache.nifi.service.lookup.AbstractSingleAttributeBasedControllerServiceLookup;
+
+import java.util.Map;
+
+@Tags({ "azure", "microsoft", "cloud", "storage", "adls", "credentials" })
+@CapabilityDescription("Provides an ADLSCredentialsService that can be used to dynamically select another ADLSCredentialsService. " +
+        "This service requires an attribute named 'adls.credentials.name' to be passed in, and will throw an exception if the attribute is missing. " +
+        "The value of 'adls.credentials.name' will be used to select the ADLSCredentialsService that has been registered with that name. " +
+        "This will allow multiple ADLSCredentialsServices to be defined and registered, and then selected dynamically at runtime by tagging flow files " +
+        "with the appropriate 'adls.credentials.name' attribute.")
+@DynamicProperty(name = "The name to register ADLSCredentialsService", value = "The ADLSCredentialsService",
+        description = "If '" + ADLSCredentialsControllerServiceLookup.ADLS_CREDENTIALS_NAME_ATTRIBUTE + "' attribute contains " +
+                "the name of the dynamic property, then the ADLSCredentialsService (registered in the value) will be selected.",
+        expressionLanguageScope = ExpressionLanguageScope.NONE)
+public class ADLSCredentialsControllerServiceLookup extends AbstractSingleAttributeBasedControllerServiceLookup<ADLSCredentialsService> implements ADLSCredentialsService {
+
+    public static final String ADLS_CREDENTIALS_NAME_ATTRIBUTE = "adls.credentials.name";
+
+    @Override
+    protected String getLookupAttribute() {
+        return ADLS_CREDENTIALS_NAME_ATTRIBUTE;
+    }
+
+    @Override
+    public Class<ADLSCredentialsService> getServiceType() {
+        return ADLSCredentialsService.class;
+    }
+
+    @Override
+    public ADLSCredentialsDetails getCredentialsDetails(final Map<String, String> attributes) {
+        return lookupService(attributes).getCredentialsDetails(attributes);
+    }
+}
diff --git a/nifi-nar-bundles/nifi-azure-bundle/nifi-azure-processors/src/main/resources/META-INF/services/org.apache.nifi.controller.ControllerService b/nifi-nar-bundles/nifi-azure-bundle/nifi-azure-processors/src/main/resources/META-INF/services/org.apache.nifi.controller.ControllerService
index e494c28476..0e5796ac58 100644
--- a/nifi-nar-bundles/nifi-azure-bundle/nifi-azure-processors/src/main/resources/META-INF/services/org.apache.nifi.controller.ControllerService
+++ b/nifi-nar-bundles/nifi-azure-bundle/nifi-azure-processors/src/main/resources/META-INF/services/org.apache.nifi.controller.ControllerService
@@ -16,6 +16,7 @@ org.apache.nifi.services.azure.eventhub.AzureEventHubRecordSink
 org.apache.nifi.services.azure.storage.AzureStorageCredentialsControllerService
 org.apache.nifi.services.azure.storage.AzureStorageCredentialsControllerServiceLookup
 org.apache.nifi.services.azure.storage.ADLSCredentialsControllerService
+org.apache.nifi.services.azure.storage.ADLSCredentialsControllerServiceLookup
 org.apache.nifi.services.azure.cosmos.document.AzureCosmosDBClientService
 org.apache.nifi.services.azure.storage.AzureStorageEmulatorCredentialsControllerService
 org.apache.nifi.services.azure.storage.AzureStorageCredentialsControllerService_v12
diff --git a/nifi-nar-bundles/nifi-azure-bundle/nifi-azure-processors/src/test/java/org/apache/nifi/services/azure/storage/TestADLSCredentialsControllerServiceLookup.java b/nifi-nar-bundles/nifi-azure-bundle/nifi-azure-processors/src/test/java/org/apache/nifi/services/azure/storage/TestADLSCredentialsControllerServiceLookup.java
new file mode 100644
index 0000000000..b3ba9e99e5
--- /dev/null
+++ b/nifi-nar-bundles/nifi-azure-bundle/nifi-azure-processors/src/test/java/org/apache/nifi/services/azure/storage/TestADLSCredentialsControllerServiceLookup.java
@@ -0,0 +1,155 @@
+/*
+ * 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.services.azure.storage;
+
+import org.apache.nifi.controller.AbstractControllerService;
+import org.apache.nifi.processor.exception.ProcessException;
+import org.apache.nifi.reporting.InitializationException;
+import org.apache.nifi.util.NoOpProcessor;
+import org.apache.nifi.util.TestRunner;
+import org.apache.nifi.util.TestRunners;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertNull;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+
+public class TestADLSCredentialsControllerServiceLookup {
+
+    private MockADLSCredentialsService serviceA;
+    private MockADLSCredentialsService serviceB;
+
+    private ADLSCredentialsControllerServiceLookup lookupService;
+    private TestRunner runner;
+
+    @BeforeEach
+    public void setup() throws InitializationException {
+        serviceA = new MockADLSCredentialsService(ADLSCredentialsDetails.Builder.newBuilder()
+                .setAccountName("Account_Name_A")
+                .setAccountKey("Account_Key")
+                .build());
+        serviceB = new MockADLSCredentialsService(ADLSCredentialsDetails.Builder.newBuilder()
+                .setAccountName("Account_Name_B")
+                .setSasToken("SAS_Token")
+                .build());
+
+        lookupService = new ADLSCredentialsControllerServiceLookup();
+
+        runner = TestRunners.newTestRunner(NoOpProcessor.class);
+
+        final String serviceAIdentifier = "service-a";
+        runner.addControllerService(serviceAIdentifier, serviceA);
+
+        final String serviceBIdentifier = "service-b";
+        runner.addControllerService(serviceBIdentifier, serviceB);
+
+        runner.addControllerService("lookup-service", lookupService);
+        runner.setProperty(lookupService, "a", serviceAIdentifier);
+        runner.setProperty(lookupService, "b", serviceBIdentifier);
+
+        runner.enableControllerService(serviceA);
+        runner.enableControllerService(serviceB);
+        runner.enableControllerService(lookupService);
+    }
+
+    @Test
+    public void testLookupServiceA() {
+        final Map<String,String> attributes = new HashMap<>();
+        attributes.put(ADLSCredentialsControllerServiceLookup.ADLS_CREDENTIALS_NAME_ATTRIBUTE, "a");
+
+        final ADLSCredentialsDetails adlsCredentialsDetails = lookupService.getCredentialsDetails(attributes);
+
+        assertNotNull(adlsCredentialsDetails);
+        assertEquals("Account_Name_A", adlsCredentialsDetails.getAccountName());
+        assertEquals("Account_Key", adlsCredentialsDetails.getAccountKey());
+        assertNull(adlsCredentialsDetails.getSasToken());
+    }
+
+    @Test
+    public void testLookupServiceB() {
+        final Map<String, String> attributes = new HashMap<>();
+        attributes.put(ADLSCredentialsControllerServiceLookup.ADLS_CREDENTIALS_NAME_ATTRIBUTE, "b");
+
+        final ADLSCredentialsDetails adlsCredentialsDetails = lookupService.getCredentialsDetails(attributes);
+
+        assertNotNull(adlsCredentialsDetails);
+        assertEquals("Account_Name_B", adlsCredentialsDetails.getAccountName());
+        assertEquals("SAS_Token", adlsCredentialsDetails.getSasToken());
+        assertNull(adlsCredentialsDetails.getAccountKey());
+    }
+
+    @Test
+    public void testLookupMissingCredentialsNameAttribute() {
+        final Map<String, String> attributes = new HashMap<>();
+
+        assertThrows(ProcessException.class, () -> lookupService.getCredentialsDetails(attributes));
+    }
+
+    @Test
+    public void testLookupWithCredentialsNameThatDoesNotExist() {
+        final Map<String, String> attributes = new HashMap<>();
+        attributes.put(ADLSCredentialsControllerServiceLookup.ADLS_CREDENTIALS_NAME_ATTRIBUTE, "DOES-NOT-EXIST");
+
+        assertThrows(ProcessException.class, () -> lookupService.getCredentialsDetails(attributes));
+    }
+
+    @Test
+    public void testCustomValidateAtLeaseOneServiceDefined() throws InitializationException {
+        // enable lookup service with no services registered, verify not valid
+        runner = TestRunners.newTestRunner(NoOpProcessor.class);
+        runner.addControllerService("lookup-service", lookupService);
+        runner.assertNotValid(lookupService);
+
+        final String serviceAIdentifier = "service-a";
+        runner.addControllerService(serviceAIdentifier, serviceA);
+
+        // register a service and now verify valid
+        runner.setProperty(lookupService, "a", serviceAIdentifier);
+        runner.enableControllerService(lookupService);
+        runner.assertValid(lookupService);
+    }
+
+    @Test
+    public void testCustomValidateSelfReferenceNotAllowed() throws InitializationException {
+        runner = TestRunners.newTestRunner(NoOpProcessor.class);
+        runner.addControllerService("lookup-service", lookupService);
+        runner.setProperty(lookupService, "lookup-service", "lookup-service");
+        runner.assertNotValid(lookupService);
+    }
+
+    /**
+     * A mock ADLSCredentialsService that will always return the passed in ADLSStorageCredentialsDetails.
+     */
+    private static class MockADLSCredentialsService extends AbstractControllerService implements ADLSCredentialsService {
+
+        private final ADLSCredentialsDetails adlsCredentialsDetails;
+
+        MockADLSCredentialsService(ADLSCredentialsDetails adlsCredentialsDetails) {
+            this.adlsCredentialsDetails = adlsCredentialsDetails;
+        }
+
+        @Override
+        public ADLSCredentialsDetails getCredentialsDetails(final Map<String, String> attributes) {
+            return adlsCredentialsDetails;
+        }
+    }
+}