You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nifi.apache.org by kd...@apache.org on 2018/09/20 17:57:06 UTC

[2/4] nifi-registry git commit: NIFIREG-186: Adding Ranger authorizer

http://git-wip-us.apache.org/repos/asf/nifi-registry/blob/e1bd6e26/nifi-registry-extensions/nifi-registry-ranger/nifi-registry-ranger-plugin/src/test/java/org/apache/nifi/registry/ranger/TestRangerBasePluginWithPolicies.java
----------------------------------------------------------------------
diff --git a/nifi-registry-extensions/nifi-registry-ranger/nifi-registry-ranger-plugin/src/test/java/org/apache/nifi/registry/ranger/TestRangerBasePluginWithPolicies.java b/nifi-registry-extensions/nifi-registry-ranger/nifi-registry-ranger-plugin/src/test/java/org/apache/nifi/registry/ranger/TestRangerBasePluginWithPolicies.java
new file mode 100644
index 0000000..78c346a
--- /dev/null
+++ b/nifi-registry-extensions/nifi-registry-ranger/nifi-registry-ranger-plugin/src/test/java/org/apache/nifi/registry/ranger/TestRangerBasePluginWithPolicies.java
@@ -0,0 +1,544 @@
+/*
+ * 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.registry.ranger;
+
+import org.apache.nifi.registry.security.authorization.AccessPolicy;
+import org.apache.nifi.registry.security.authorization.AuthorizerConfigurationContext;
+import org.apache.nifi.registry.security.authorization.Group;
+import org.apache.nifi.registry.security.authorization.RequestAction;
+import org.apache.nifi.registry.security.authorization.User;
+import org.apache.nifi.registry.security.authorization.UserAndGroups;
+import org.apache.nifi.registry.security.authorization.UserGroupProvider;
+import org.apache.nifi.registry.security.authorization.UserGroupProviderInitializationContext;
+import org.apache.nifi.registry.security.authorization.exception.AuthorizationAccessException;
+import org.apache.nifi.registry.security.exception.SecurityProviderCreationException;
+import org.apache.ranger.plugin.model.RangerPolicy;
+import org.apache.ranger.plugin.model.RangerServiceDef;
+import org.apache.ranger.plugin.util.ServicePolicies;
+import org.junit.Test;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+
+public class TestRangerBasePluginWithPolicies {
+
+    @Test
+    public void testPoliciesWithoutUserGroupProvider() {
+        final String user1 = "user-1";
+        final String group1 = "group-1";
+
+        final String resourceIdentifier1 = "/resource-1";
+        RangerPolicy.RangerPolicyResource resource1 = new RangerPolicy.RangerPolicyResource(resourceIdentifier1);
+
+        final Map<String, RangerPolicy.RangerPolicyResource> policy1Resources = new HashMap<>();
+        policy1Resources.put(resourceIdentifier1, resource1);
+
+        final RangerPolicy.RangerPolicyItem policy1Item = new RangerPolicy.RangerPolicyItem();
+        policy1Item.setAccesses(Stream.of(new RangerPolicy.RangerPolicyItemAccess("READ")).collect(Collectors.toList()));
+        policy1Item.setUsers(Stream.of(user1).collect(Collectors.toList()));
+
+        final RangerPolicy policy1 = new RangerPolicy();
+        policy1.setResources(policy1Resources);
+        policy1.setPolicyItems(Stream.of(policy1Item).collect(Collectors.toList()));
+
+        final String resourceIdentifier2 = "/resource-2";
+        RangerPolicy.RangerPolicyResource resource2 = new RangerPolicy.RangerPolicyResource(resourceIdentifier2);
+
+        final Map<String, RangerPolicy.RangerPolicyResource> policy2Resources = new HashMap<>();
+        policy2Resources.put(resourceIdentifier2, resource2);
+
+        final RangerPolicy.RangerPolicyItem policy2Item = new RangerPolicy.RangerPolicyItem();
+        policy2Item.setAccesses(Stream.of(new RangerPolicy.RangerPolicyItemAccess("READ"), new RangerPolicy.RangerPolicyItemAccess("WRITE")).collect(Collectors.toList()));
+        policy2Item.setGroups(Stream.of(group1).collect(Collectors.toList()));
+
+        final RangerPolicy policy2 = new RangerPolicy();
+        policy2.setResources(policy2Resources);
+        policy2.setPolicyItems(Stream.of(policy2Item).collect(Collectors.toList()));
+
+        final List<RangerPolicy> policies = new ArrayList<>();
+        policies.add(policy1);
+        policies.add(policy2);
+
+        final RangerServiceDef serviceDef = new RangerServiceDef();
+        serviceDef.setName("nifi-registry");
+
+        final ServicePolicies servicePolicies = new ServicePolicies();
+        servicePolicies.setPolicies(policies);
+        servicePolicies.setServiceDef(serviceDef);
+
+        // set all the policies in the plugin
+        final RangerBasePluginWithPolicies pluginWithPolicies = new RangerBasePluginWithPolicies("nifi-registry", "nifi-registry");
+        pluginWithPolicies.setPolicies(servicePolicies);
+
+        // ensure the two ranger policies converted into 3 nifi-registry access policies
+        final Set<AccessPolicy> accessPolicies = pluginWithPolicies.getAccessPolicies();
+        assertEquals(3, accessPolicies.size());
+
+        // resource 1 -> read but no write
+        assertFalse(pluginWithPolicies.doesPolicyExist(resourceIdentifier1, RequestAction.WRITE));
+        assertTrue(pluginWithPolicies.doesPolicyExist(resourceIdentifier1, RequestAction.READ));
+
+        // read
+        final AccessPolicy readResource1 = pluginWithPolicies.getAccessPolicy(resourceIdentifier1, RequestAction.READ);
+        assertNotNull(readResource1);
+        assertTrue(accessPolicies.contains(readResource1));
+        assertTrue(readResource1.equals(pluginWithPolicies.getAccessPolicy(readResource1.getIdentifier())));
+        assertEquals(1, readResource1.getUsers().size());
+        assertTrue(readResource1.getUsers().contains(new User.Builder().identifierGenerateFromSeed(user1).identity(user1).build().getIdentifier()));
+        assertTrue(readResource1.getGroups().isEmpty());
+
+        // but no write
+        assertNull(pluginWithPolicies.getAccessPolicy(resourceIdentifier1, RequestAction.WRITE));
+
+        // resource 2 -> read and write
+        assertTrue(pluginWithPolicies.doesPolicyExist(resourceIdentifier2, RequestAction.WRITE));
+        assertTrue(pluginWithPolicies.doesPolicyExist(resourceIdentifier2, RequestAction.READ));
+
+        // read
+        final AccessPolicy readResource2 = pluginWithPolicies.getAccessPolicy(resourceIdentifier2, RequestAction.READ);
+        assertNotNull(readResource2);
+        assertTrue(accessPolicies.contains(readResource2));
+        assertTrue(readResource2.equals(pluginWithPolicies.getAccessPolicy(readResource2.getIdentifier())));
+        assertTrue(readResource2.getUsers().isEmpty());
+        assertEquals(1, readResource2.getGroups().size());
+        assertTrue(readResource2.getGroups().contains(new Group.Builder().identifierGenerateFromSeed(group1).name(group1).build().getIdentifier()));
+
+        // and write
+        final AccessPolicy writeResource2 = pluginWithPolicies.getAccessPolicy(resourceIdentifier2, RequestAction.READ);
+        assertNotNull(writeResource2);
+        assertTrue(accessPolicies.contains(writeResource2));
+        assertTrue(writeResource2.equals(pluginWithPolicies.getAccessPolicy(writeResource2.getIdentifier())));
+        assertTrue(writeResource2.getUsers().isEmpty());
+        assertEquals(1, writeResource2.getGroups().size());
+        assertTrue(writeResource2.getGroups().contains(new Group.Builder().identifierGenerateFromSeed(group1).name(group1).build().getIdentifier()));
+
+        // resource 3 -> no read or write
+        assertFalse(pluginWithPolicies.doesPolicyExist("resource-3", RequestAction.WRITE));
+        assertFalse(pluginWithPolicies.doesPolicyExist("resource-3", RequestAction.READ));
+
+        // no read or write
+        assertNull(pluginWithPolicies.getAccessPolicy("resource-3", RequestAction.WRITE));
+        assertNull(pluginWithPolicies.getAccessPolicy("resource-3", RequestAction.READ));
+    }
+
+    @Test
+    public void testNoPolicies() {
+        final RangerBasePluginWithPolicies pluginWithPolicies = new RangerBasePluginWithPolicies("nifi-registry", "nifi-registry");
+
+        assertFalse(pluginWithPolicies.doesPolicyExist("non-existent-resource", RequestAction.READ));
+        assertTrue(pluginWithPolicies.getAccessPolicies().isEmpty());
+        assertNull(pluginWithPolicies.getAccessPolicy("non-existent-identifier"));
+        assertNull(pluginWithPolicies.getAccessPolicy("non-existent-resource", RequestAction.READ));
+    }
+
+    @Test
+    public void testDisabledPolicy() {
+        final String resourceIdentifier1 = "/resource-1";
+        RangerPolicy.RangerPolicyResource resource1 = new RangerPolicy.RangerPolicyResource(resourceIdentifier1);
+
+        final Map<String, RangerPolicy.RangerPolicyResource> policy1Resources = new HashMap<>();
+        policy1Resources.put(resourceIdentifier1, resource1);
+
+        final RangerPolicy.RangerPolicyItem policy1Item = new RangerPolicy.RangerPolicyItem();
+        policy1Item.setAccesses(Stream.of(new RangerPolicy.RangerPolicyItemAccess("READ")).collect(Collectors.toList()));
+
+        final RangerPolicy policy1 = new RangerPolicy();
+        policy1.setIsEnabled(false);
+        policy1.setResources(policy1Resources);
+        policy1.setPolicyItems(Stream.of(policy1Item).collect(Collectors.toList()));
+
+        final List<RangerPolicy> policies = new ArrayList<>();
+        policies.add(policy1);
+
+        final RangerServiceDef serviceDef = new RangerServiceDef();
+        serviceDef.setName("nifi-registry");
+
+        final ServicePolicies servicePolicies = new ServicePolicies();
+        servicePolicies.setPolicies(policies);
+        servicePolicies.setServiceDef(serviceDef);
+
+        // set all the policies in the plugin
+        final RangerBasePluginWithPolicies pluginWithPolicies = new RangerBasePluginWithPolicies("nifi-registry", "nifi-registry");
+        pluginWithPolicies.setPolicies(servicePolicies);
+
+        // ensure the policy was skipped
+        assertFalse(pluginWithPolicies.doesPolicyExist(resourceIdentifier1, RequestAction.READ));
+        assertTrue(pluginWithPolicies.getAccessPolicies().isEmpty());
+        assertNull(pluginWithPolicies.getAccessPolicy(resourceIdentifier1, RequestAction.READ));
+    }
+
+    @Test
+    public void testMissingResourceValue() {
+        final String resourceIdentifier1 = "/resource-1";
+        RangerPolicy.RangerPolicyResource resource1 = new RangerPolicy.RangerPolicyResource();
+
+        final Map<String, RangerPolicy.RangerPolicyResource> policy1Resources = new HashMap<>();
+        policy1Resources.put(resourceIdentifier1, resource1);
+
+        final RangerPolicy.RangerPolicyItem policy1Item = new RangerPolicy.RangerPolicyItem();
+        policy1Item.setAccesses(Stream.of(new RangerPolicy.RangerPolicyItemAccess("WRITE")).collect(Collectors.toList()));
+
+        final RangerPolicy policy1 = new RangerPolicy();
+        policy1.setResources(policy1Resources);
+        policy1.setPolicyItems(Stream.of(policy1Item).collect(Collectors.toList()));
+
+        final List<RangerPolicy> policies = new ArrayList<>();
+        policies.add(policy1);
+
+        final RangerServiceDef serviceDef = new RangerServiceDef();
+        serviceDef.setName("nifi-registry");
+
+        final ServicePolicies servicePolicies = new ServicePolicies();
+        servicePolicies.setPolicies(policies);
+        servicePolicies.setServiceDef(serviceDef);
+
+        // set all the policies in the plugin
+        final RangerBasePluginWithPolicies pluginWithPolicies = new RangerBasePluginWithPolicies("nifi-registry", "nifi-registry");
+        pluginWithPolicies.setPolicies(servicePolicies);
+
+        // ensure the policy was skipped
+        assertFalse(pluginWithPolicies.doesPolicyExist(resourceIdentifier1, RequestAction.WRITE));
+        assertTrue(pluginWithPolicies.getAccessPolicies().isEmpty());
+        assertNull(pluginWithPolicies.getAccessPolicy(resourceIdentifier1, RequestAction.WRITE));
+    }
+
+    @Test
+    public void testWildcardResourceValue() {
+        final String resourceIdentifier1 = "*";
+        RangerPolicy.RangerPolicyResource resource1 = new RangerPolicy.RangerPolicyResource(resourceIdentifier1);
+
+        final Map<String, RangerPolicy.RangerPolicyResource> policy1Resources = new HashMap<>();
+        policy1Resources.put(resourceIdentifier1, resource1);
+
+        final RangerPolicy.RangerPolicyItem policy1Item = new RangerPolicy.RangerPolicyItem();
+        policy1Item.setAccesses(Stream.of(new RangerPolicy.RangerPolicyItemAccess("WRITE")).collect(Collectors.toList()));
+
+        final RangerPolicy policy1 = new RangerPolicy();
+        policy1.setResources(policy1Resources);
+        policy1.setPolicyItems(Stream.of(policy1Item).collect(Collectors.toList()));
+
+        final List<RangerPolicy> policies = new ArrayList<>();
+        policies.add(policy1);
+
+        final RangerServiceDef serviceDef = new RangerServiceDef();
+        serviceDef.setName("nifi-registry");
+
+        final ServicePolicies servicePolicies = new ServicePolicies();
+        servicePolicies.setPolicies(policies);
+        servicePolicies.setServiceDef(serviceDef);
+
+        // set all the policies in the plugin
+        final RangerBasePluginWithPolicies pluginWithPolicies = new RangerBasePluginWithPolicies("nifi-registry", "nifi-registry");
+        pluginWithPolicies.setPolicies(servicePolicies);
+
+        // ensure the policy was skipped
+        assertFalse(pluginWithPolicies.doesPolicyExist(resourceIdentifier1, RequestAction.WRITE));
+        assertTrue(pluginWithPolicies.getAccessPolicies().isEmpty());
+        assertNull(pluginWithPolicies.getAccessPolicy(resourceIdentifier1, RequestAction.WRITE));
+    }
+
+    @Test
+    public void testExcludesPolicy() {
+        final String resourceIdentifier1 = "/resource-1";
+        RangerPolicy.RangerPolicyResource resource1 = new RangerPolicy.RangerPolicyResource(resourceIdentifier1);
+        resource1.setIsExcludes(true);
+
+        final Map<String, RangerPolicy.RangerPolicyResource> policy1Resources = new HashMap<>();
+        policy1Resources.put(resourceIdentifier1, resource1);
+
+        final RangerPolicy.RangerPolicyItem policy1Item = new RangerPolicy.RangerPolicyItem();
+        policy1Item.setAccesses(Stream.of(new RangerPolicy.RangerPolicyItemAccess("WRITE")).collect(Collectors.toList()));
+
+        final RangerPolicy policy1 = new RangerPolicy();
+        policy1.setResources(policy1Resources);
+        policy1.setPolicyItems(Stream.of(policy1Item).collect(Collectors.toList()));
+
+        final List<RangerPolicy> policies = new ArrayList<>();
+        policies.add(policy1);
+
+        final RangerServiceDef serviceDef = new RangerServiceDef();
+        serviceDef.setName("nifi-registry");
+
+        final ServicePolicies servicePolicies = new ServicePolicies();
+        servicePolicies.setPolicies(policies);
+        servicePolicies.setServiceDef(serviceDef);
+
+        // set all the policies in the plugin
+        final RangerBasePluginWithPolicies pluginWithPolicies = new RangerBasePluginWithPolicies("nifi-registry", "nifi-registry");
+        pluginWithPolicies.setPolicies(servicePolicies);
+
+        // ensure the policy was skipped
+        assertFalse(pluginWithPolicies.doesPolicyExist(resourceIdentifier1, RequestAction.WRITE));
+        assertTrue(pluginWithPolicies.getAccessPolicies().isEmpty());
+        assertNull(pluginWithPolicies.getAccessPolicy(resourceIdentifier1, RequestAction.WRITE));
+    }
+
+    @Test
+    public void testRecursivePolicy() {
+        final String resourceIdentifier1 = "/resource-1";
+        RangerPolicy.RangerPolicyResource resource1 = new RangerPolicy.RangerPolicyResource(resourceIdentifier1);
+        resource1.setIsRecursive(true);
+
+        final Map<String, RangerPolicy.RangerPolicyResource> policy1Resources = new HashMap<>();
+        policy1Resources.put(resourceIdentifier1, resource1);
+
+        final RangerPolicy.RangerPolicyItem policy1Item = new RangerPolicy.RangerPolicyItem();
+        policy1Item.setAccesses(Stream.of(new RangerPolicy.RangerPolicyItemAccess("WRITE")).collect(Collectors.toList()));
+
+        final RangerPolicy policy1 = new RangerPolicy();
+        policy1.setResources(policy1Resources);
+        policy1.setPolicyItems(Stream.of(policy1Item).collect(Collectors.toList()));
+
+        final List<RangerPolicy> policies = new ArrayList<>();
+        policies.add(policy1);
+
+        final RangerServiceDef serviceDef = new RangerServiceDef();
+        serviceDef.setName("nifi-registry");
+
+        final ServicePolicies servicePolicies = new ServicePolicies();
+        servicePolicies.setPolicies(policies);
+        servicePolicies.setServiceDef(serviceDef);
+
+        // set all the policies in the plugin
+        final RangerBasePluginWithPolicies pluginWithPolicies = new RangerBasePluginWithPolicies("nifi-registry", "nifi-registry");
+        pluginWithPolicies.setPolicies(servicePolicies);
+
+        // ensure the policy was skipped
+        assertFalse(pluginWithPolicies.doesPolicyExist(resourceIdentifier1, RequestAction.WRITE));
+        assertTrue(pluginWithPolicies.getAccessPolicies().isEmpty());
+        assertNull(pluginWithPolicies.getAccessPolicy(resourceIdentifier1, RequestAction.WRITE));
+    }
+
+    @Test
+    public void testDelegateAdmin() {
+        final String user1 = "user-1";
+
+        final String resourceIdentifier1 = "/resource-1";
+        RangerPolicy.RangerPolicyResource resource1 = new RangerPolicy.RangerPolicyResource(resourceIdentifier1);
+
+        final Map<String, RangerPolicy.RangerPolicyResource> policy1Resources = new HashMap<>();
+        policy1Resources.put(resourceIdentifier1, resource1);
+
+        final RangerPolicy.RangerPolicyItem policy1Item = new RangerPolicy.RangerPolicyItem();
+        policy1Item.setAccesses(Stream.of(new RangerPolicy.RangerPolicyItemAccess("READ"), new RangerPolicy.RangerPolicyItemAccess("WRITE")).collect(Collectors.toList()));
+        policy1Item.setUsers(Stream.of(user1).collect(Collectors.toList()));
+        policy1Item.setDelegateAdmin(true);
+
+        final RangerPolicy policy1 = new RangerPolicy();
+        policy1.setResources(policy1Resources);
+        policy1.setPolicyItems(Stream.of(policy1Item).collect(Collectors.toList()));
+
+        final List<RangerPolicy> policies = new ArrayList<>();
+        policies.add(policy1);
+
+        final RangerServiceDef serviceDef = new RangerServiceDef();
+        serviceDef.setName("nifi-registry");
+
+        final ServicePolicies servicePolicies = new ServicePolicies();
+        servicePolicies.setPolicies(policies);
+        servicePolicies.setServiceDef(serviceDef);
+
+        // set all the policies in the plugin
+        final RangerBasePluginWithPolicies pluginWithPolicies = new RangerBasePluginWithPolicies("nifi-registry", "nifi-registry");
+        pluginWithPolicies.setPolicies(servicePolicies);
+
+        assertEquals(4, pluginWithPolicies.getAccessPolicies().size());
+        assertNotNull(pluginWithPolicies.getAccessPolicy(resourceIdentifier1, RequestAction.READ));
+        assertNotNull(pluginWithPolicies.getAccessPolicy(resourceIdentifier1, RequestAction.WRITE));
+        assertNotNull(pluginWithPolicies.getAccessPolicy("/policies" + resourceIdentifier1, RequestAction.READ));
+        assertNotNull(pluginWithPolicies.getAccessPolicy("/policies" + resourceIdentifier1, RequestAction.WRITE));
+    }
+
+    @Test
+    public void testPoliciesWithUserGroupProvider() {
+        final String user1 = "user-1"; // unknown according to user group provider
+        final String user2 = "user-2"; // known according to user group provider
+        final String group1 = "group-1"; // unknown according to user group provider
+        final String group2 = "group-2"; // known according to user group provider
+
+        final UserGroupProvider userGroupProvider = new UserGroupProvider() {
+            @Override
+            public Set<User> getUsers() throws AuthorizationAccessException {
+                return Stream.of(new User.Builder().identifierGenerateFromSeed(user2).identity(user2).build()).collect(Collectors.toSet());
+            }
+
+            @Override
+            public User getUser(String identifier) throws AuthorizationAccessException {
+                final User u2 = new User.Builder().identifierGenerateFromSeed(user2).identity(user2).build();
+                if (u2.getIdentifier().equals(identifier)) {
+                    return u2;
+                } else {
+                    return null;
+                }
+            }
+
+            @Override
+            public User getUserByIdentity(String identity) throws AuthorizationAccessException {
+                if (user2.equals(identity)) {
+                    return new User.Builder().identifierGenerateFromSeed(user2).identity(user2).build();
+                } else {
+                    return null;
+                }
+            }
+
+            @Override
+            public Set<Group> getGroups() throws AuthorizationAccessException {
+                return Stream.of(new Group.Builder().identifierGenerateFromSeed(group2).name(group2).build()).collect(Collectors.toSet());
+            }
+
+            @Override
+            public Group getGroup(String identifier) throws AuthorizationAccessException {
+                final Group g2 = new Group.Builder().identifierGenerateFromSeed(group2).name(group2).build();
+                if (g2.getIdentifier().equals(identifier)) {
+                    return g2;
+                } else {
+                    return null;
+                }
+            }
+
+            @Override
+            public UserAndGroups getUserAndGroups(String identity) throws AuthorizationAccessException {
+                if (user2.equals(identity)) {
+                    return new UserAndGroups() {
+                        @Override
+                        public User getUser() {
+                            return new User.Builder().identifierGenerateFromSeed(user2).identity(user2).build();
+                        }
+
+                        @Override
+                        public Set<Group> getGroups() {
+                            return Collections.EMPTY_SET;
+                        }
+                    };
+                } else {
+                    return null;
+                }
+            }
+
+            @Override
+            public void initialize(UserGroupProviderInitializationContext initializationContext) throws SecurityProviderCreationException {
+            }
+
+            @Override
+            public void onConfigured(AuthorizerConfigurationContext configurationContext) throws SecurityProviderCreationException {
+            }
+
+            @Override
+            public void preDestruction() throws SecurityProviderCreationException {
+            }
+        };
+
+        final String resourceIdentifier1 = "/resource-1";
+        RangerPolicy.RangerPolicyResource resource1 = new RangerPolicy.RangerPolicyResource(resourceIdentifier1);
+
+        final Map<String, RangerPolicy.RangerPolicyResource> policy1Resources = new HashMap<>();
+        policy1Resources.put(resourceIdentifier1, resource1);
+
+        final RangerPolicy.RangerPolicyItem policy1Item = new RangerPolicy.RangerPolicyItem();
+        policy1Item.setAccesses(Stream.of(new RangerPolicy.RangerPolicyItemAccess("READ")).collect(Collectors.toList()));
+        policy1Item.setUsers(Stream.of(user1).collect(Collectors.toList()));
+        policy1Item.setGroups(Stream.of(group2).collect(Collectors.toList()));
+
+        final RangerPolicy policy1 = new RangerPolicy();
+        policy1.setResources(policy1Resources);
+        policy1.setPolicyItems(Stream.of(policy1Item).collect(Collectors.toList()));
+
+        final String resourceIdentifier2 = "/resource-2";
+        RangerPolicy.RangerPolicyResource resource2 = new RangerPolicy.RangerPolicyResource(resourceIdentifier2);
+
+        final Map<String, RangerPolicy.RangerPolicyResource> policy2Resources = new HashMap<>();
+        policy2Resources.put(resourceIdentifier2, resource2);
+
+        final RangerPolicy.RangerPolicyItem policy2Item = new RangerPolicy.RangerPolicyItem();
+        policy2Item.setAccesses(Stream.of(new RangerPolicy.RangerPolicyItemAccess("READ"), new RangerPolicy.RangerPolicyItemAccess("WRITE")).collect(Collectors.toList()));
+        policy2Item.setUsers(Stream.of(user2).collect(Collectors.toList()));
+        policy2Item.setGroups(Stream.of(group1).collect(Collectors.toList()));
+
+        final RangerPolicy policy2 = new RangerPolicy();
+        policy2.setResources(policy2Resources);
+        policy2.setPolicyItems(Stream.of(policy2Item).collect(Collectors.toList()));
+
+        final List<RangerPolicy> policies = new ArrayList<>();
+        policies.add(policy1);
+        policies.add(policy2);
+
+        final RangerServiceDef serviceDef = new RangerServiceDef();
+        serviceDef.setName("nifi-registry");
+
+        final ServicePolicies servicePolicies = new ServicePolicies();
+        servicePolicies.setPolicies(policies);
+        servicePolicies.setServiceDef(serviceDef);
+
+        // set all the policies in the plugin
+        final RangerBasePluginWithPolicies pluginWithPolicies = new RangerBasePluginWithPolicies("nifi-registry", "nifi-registry", userGroupProvider);
+        pluginWithPolicies.setPolicies(servicePolicies);
+
+        // ensure the two ranger policies converted into 3 nifi-registry access policies
+        final Set<AccessPolicy> accessPolicies = pluginWithPolicies.getAccessPolicies();
+        assertEquals(3, accessPolicies.size());
+
+        // resource 1 -> read but no write
+        assertFalse(pluginWithPolicies.doesPolicyExist(resourceIdentifier1, RequestAction.WRITE));
+        assertTrue(pluginWithPolicies.doesPolicyExist(resourceIdentifier1, RequestAction.READ));
+
+        // read
+        final AccessPolicy readResource1 = pluginWithPolicies.getAccessPolicy(resourceIdentifier1, RequestAction.READ);
+        assertNotNull(readResource1);
+        assertTrue(accessPolicies.contains(readResource1));
+        assertTrue(readResource1.equals(pluginWithPolicies.getAccessPolicy(readResource1.getIdentifier())));
+        assertTrue(readResource1.getUsers().isEmpty());
+        assertEquals(1, readResource1.getGroups().size());
+        assertTrue(readResource1.getGroups().contains(new Group.Builder().identifierGenerateFromSeed(group2).name(group2).build().getIdentifier()));
+
+        // but no write
+        assertNull(pluginWithPolicies.getAccessPolicy(resourceIdentifier1, RequestAction.WRITE));
+
+        // resource 2 -> read and write
+        assertTrue(pluginWithPolicies.doesPolicyExist(resourceIdentifier2, RequestAction.WRITE));
+        assertTrue(pluginWithPolicies.doesPolicyExist(resourceIdentifier2, RequestAction.READ));
+
+        // read
+        final AccessPolicy readResource2 = pluginWithPolicies.getAccessPolicy(resourceIdentifier2, RequestAction.READ);
+        assertNotNull(readResource2);
+        assertTrue(accessPolicies.contains(readResource2));
+        assertTrue(readResource2.equals(pluginWithPolicies.getAccessPolicy(readResource2.getIdentifier())));
+        assertEquals(1, readResource2.getUsers().size());
+        assertTrue(readResource2.getUsers().contains(new User.Builder().identifierGenerateFromSeed(user2).identity(user2).build().getIdentifier()));
+        assertTrue(readResource2.getGroups().isEmpty());
+
+        // and write
+        final AccessPolicy writeResource2 = pluginWithPolicies.getAccessPolicy(resourceIdentifier2, RequestAction.READ);
+        assertNotNull(writeResource2);
+        assertTrue(accessPolicies.contains(writeResource2));
+        assertTrue(writeResource2.equals(pluginWithPolicies.getAccessPolicy(writeResource2.getIdentifier())));
+        assertEquals(1, writeResource2.getUsers().size());
+        assertTrue(writeResource2.getUsers().contains(new User.Builder().identifierGenerateFromSeed(user2).identity(user2).build().getIdentifier()));
+        assertTrue(writeResource2.getGroups().isEmpty());
+    }
+}

http://git-wip-us.apache.org/repos/asf/nifi-registry/blob/e1bd6e26/nifi-registry-extensions/nifi-registry-ranger/nifi-registry-ranger-plugin/src/test/resources/krb5.conf
----------------------------------------------------------------------
diff --git a/nifi-registry-extensions/nifi-registry-ranger/nifi-registry-ranger-plugin/src/test/resources/krb5.conf b/nifi-registry-extensions/nifi-registry-ranger/nifi-registry-ranger-plugin/src/test/resources/krb5.conf
new file mode 100644
index 0000000..0e3f142
--- /dev/null
+++ b/nifi-registry-extensions/nifi-registry-ranger/nifi-registry-ranger-plugin/src/test/resources/krb5.conf
@@ -0,0 +1,25 @@
+# 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.
+
+[libdefaults]
+         default_realm = EXAMPLE.COM
+         dns_lookup_kdc = false
+         dns_lookup_realm = false
+
+[realms]
+         EXAMPLE.COM = {
+             kdc = kerberos.example.com
+             admin_server = kerberos.example.com
+         }
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/nifi-registry/blob/e1bd6e26/nifi-registry-extensions/nifi-registry-ranger/nifi-registry-ranger-plugin/src/test/resources/ranger/core-site.xml
----------------------------------------------------------------------
diff --git a/nifi-registry-extensions/nifi-registry-ranger/nifi-registry-ranger-plugin/src/test/resources/ranger/core-site.xml b/nifi-registry-extensions/nifi-registry-ranger/nifi-registry-ranger-plugin/src/test/resources/ranger/core-site.xml
new file mode 100644
index 0000000..d590a50
--- /dev/null
+++ b/nifi-registry-extensions/nifi-registry-ranger/nifi-registry-ranger-plugin/src/test/resources/ranger/core-site.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0"?>
+<?xml-stylesheet type="text/xsl" href="configuration.xsl"?>
+<!--
+  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.
+-->
+<configuration>
+    <property>
+        <name>hadoop.security.authentication</name>
+        <value>simple</value>
+    </property>
+</configuration>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/nifi-registry/blob/e1bd6e26/nifi-registry-extensions/nifi-registry-ranger/nifi-registry-ranger-plugin/src/test/resources/ranger/ranger-nifi-registry-audit.xml
----------------------------------------------------------------------
diff --git a/nifi-registry-extensions/nifi-registry-ranger/nifi-registry-ranger-plugin/src/test/resources/ranger/ranger-nifi-registry-audit.xml b/nifi-registry-extensions/nifi-registry-ranger/nifi-registry-ranger-plugin/src/test/resources/ranger/ranger-nifi-registry-audit.xml
new file mode 100644
index 0000000..3dbd576
--- /dev/null
+++ b/nifi-registry-extensions/nifi-registry-ranger/nifi-registry-ranger-plugin/src/test/resources/ranger/ranger-nifi-registry-audit.xml
@@ -0,0 +1,101 @@
+<?xml version="1.0"?>
+<!--
+  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.
+-->
+<?xml-stylesheet type="text/xsl" href="configuration.xsl"?>
+<configuration xmlns:xi="http://www.w3.org/2001/XInclude">
+	<property>
+		<name>xasecure.audit.is.enabled</name>
+		<value>true</value>
+	</property>
+
+	<!-- DB audit provider configuration -->
+	<property>
+		<name>xasecure.audit.destination.db</name>
+		<value>false</value>
+	</property>	
+	
+	<property>
+		<name>xasecure.audit.destination.db.jdbc.driver</name>
+		<value>com.mysql.jdbc.Driver</value>
+	</property>	
+	
+	<property>
+		<name>xasecure.audit.destination.db.jdbc.url</name>
+		<value>jdbc:mysql://localhost/ranger_audit</value>
+	</property>	
+
+	<property>
+		<name>xasecure.audit.destination.db.password</name>
+		<value>rangerlogger</value>
+	</property>	
+
+	<property>
+		<name>xasecure.audit.destination.db.user</name>
+		<value>rangerlogger</value>
+	</property>	
+
+	<property>
+		<name>xasecure.audit.destination.db.batch.filespool.dir</name>
+		<value>/tmp/audit/db/spool</value>
+	</property>
+
+
+	<!-- HDFS audit provider configuration -->
+	<property>
+		<name>xasecure.audit.destination.hdfs</name>
+		<value>false</value>
+	</property>
+
+	<property>
+		<name>xasecure.audit.destination.hdfs.dir</name>
+		<value>hdfs://localhost:8020/ranger/audit</value>
+	</property>
+
+	<property>
+		<name>xasecure.audit.destination.hdfs.batch.filespool.dir</name>
+		<value>/tmp/audit/hdfs/spool</value>
+	</property>
+
+
+	<!-- Log4j audit provider configuration -->
+	<property>
+		<name>xasecure.audit.destination.log4j</name>
+		<value>false</value>
+	</property>	
+
+	<property>
+		<name>xasecure.audit.destination.log4j.logger</name>
+		<value>ranger_audit_logger</value>
+	</property>
+
+	<!-- Solr audit provider configuration -->
+	<property>
+		<name>xasecure.audit.destination.solr</name>
+		<value>true</value>
+	</property>
+
+	<property>
+		<name>xasecure.audit.destination.solr.batch.filespool.dir</name>
+		<value>/tmp/audit/solr/spool</value>
+	</property>
+
+	<property>
+		<name>xasecure.audit.destination.solr.urls</name>
+		<value>http://localhost:6083/solr/ranger_audits</value>
+	</property>
+
+</configuration>

http://git-wip-us.apache.org/repos/asf/nifi-registry/blob/e1bd6e26/nifi-registry-extensions/nifi-registry-ranger/nifi-registry-ranger-plugin/src/test/resources/ranger/ranger-nifi-registry-security.xml
----------------------------------------------------------------------
diff --git a/nifi-registry-extensions/nifi-registry-ranger/nifi-registry-ranger-plugin/src/test/resources/ranger/ranger-nifi-registry-security.xml b/nifi-registry-extensions/nifi-registry-ranger/nifi-registry-ranger-plugin/src/test/resources/ranger/ranger-nifi-registry-security.xml
new file mode 100644
index 0000000..ab55fba
--- /dev/null
+++ b/nifi-registry-extensions/nifi-registry-ranger/nifi-registry-ranger-plugin/src/test/resources/ranger/ranger-nifi-registry-security.xml
@@ -0,0 +1,83 @@
+<?xml version="1.0"?>
+<?xml-stylesheet type="text/xsl" href="configuration.xsl"?>
+<!--
+  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.
+-->
+<configuration>
+	<property>
+		<name>ranger.plugin.nifi-registry.policy.rest.url</name>
+		<value>http://localhost:6080</value>
+		<description>
+			URL to Ranger Admin
+		</description>
+	</property>
+
+	<property>
+		<name>ranger.plugin.nifi-registry.service.name</name>
+		<value>nifi-registry</value>
+		<description>
+			Name of the Ranger service containing policies for this nifi instance
+		</description>
+	</property>
+
+	<property>
+		<name>ranger.plugin.nifi-registry.policy.source.impl</name>
+		<value>org.apache.ranger.admin.client.RangerAdminRESTClient</value>
+		<description>
+			Class to retrieve policies from the source
+		</description>
+	</property>
+
+	<property>
+		<name>ranger.plugin.nifi-registry.policy.rest.ssl.config.file</name>
+		<value>ranger-policymgr-ssl.xml</value>
+		<description>
+			Path to the file containing SSL details to contact Ranger Admin
+		</description>
+	</property>
+
+	<property>
+		<name>ranger.plugin.nifi-registry.policy.pollIntervalMs</name>
+		<value>30000</value>
+		<description>
+			How often to poll for changes in policies?
+		</description>
+	</property>
+
+	<property>
+		<name>ranger.plugin.nifi-registry.policy.cache.dir</name>
+		<value>/tmp</value>
+		<description>
+			Directory where Ranger policies are cached after successful retrieval from the source
+		</description>
+	</property>
+
+	<property>
+		<name>ranger.plugin.nifi-registry.policy.rest.client.connection.timeoutMs</name>
+		<value>120000</value>
+		<description>
+			RangerRestClient Connection Timeout in Milli Seconds
+		</description>
+	</property>
+
+	<property>
+		<name>ranger.plugin.nifi-registry.policy.rest.client.read.timeoutMs</name>
+		<value>30000</value>
+		<description>
+			RangerRestClient read Timeout in Milli Seconds
+		</description>
+	</property>
+</configuration>

http://git-wip-us.apache.org/repos/asf/nifi-registry/blob/e1bd6e26/nifi-registry-extensions/nifi-registry-ranger/nifi-registry-ranger-plugin/src/test/resources/ranger/ranger-policymgr-ssl.xml
----------------------------------------------------------------------
diff --git a/nifi-registry-extensions/nifi-registry-ranger/nifi-registry-ranger-plugin/src/test/resources/ranger/ranger-policymgr-ssl.xml b/nifi-registry-extensions/nifi-registry-ranger/nifi-registry-ranger-plugin/src/test/resources/ranger/ranger-policymgr-ssl.xml
new file mode 100644
index 0000000..a6e0574
--- /dev/null
+++ b/nifi-registry-extensions/nifi-registry-ranger/nifi-registry-ranger-plugin/src/test/resources/ranger/ranger-policymgr-ssl.xml
@@ -0,0 +1,63 @@
+<?xml version="1.0"?>
+<!--
+  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.
+-->
+<?xml-stylesheet type="text/xsl" href="configuration.xsl"?>
+<configuration xmlns:xi="http://www.w3.org/2001/XInclude">
+	<!--  The following properties are used for 2-way SSL client server validation -->
+	<property>
+		<name>xasecure.policymgr.clientssl.keystore</name>
+		<value></value>
+		<description> 
+			Java Keystore files 
+		</description>
+	</property>
+	<property>
+		<name>xasecure.policymgr.clientssl.keystore.password</name>
+		<value>none</value>
+		<description> 
+			password for keystore 
+		</description>
+	</property>
+	<property>
+		<name>xasecure.policymgr.clientssl.truststore</name>
+		<value></value>
+		<description> 
+			java truststore file
+		</description>
+	</property>
+	<property>
+		<name>xasecure.policymgr.clientssl.truststore.password</name>
+		<value>none</value>
+		<description> 
+			java  truststore password
+		</description>
+	</property>
+    <property>
+		<name>xasecure.policymgr.clientssl.keystore.credential.file</name>
+		<value></value>
+		<description> 
+			java  keystore credential file
+		</description>
+	</property>
+	<property>
+		<name>xasecure.policymgr.clientssl.truststore.credential.file</name>
+		<value></value>
+		<description> 
+			java  truststore credential file
+		</description>
+	</property>
+</configuration>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/nifi-registry/blob/e1bd6e26/nifi-registry-extensions/nifi-registry-ranger/pom.xml
----------------------------------------------------------------------
diff --git a/nifi-registry-extensions/nifi-registry-ranger/pom.xml b/nifi-registry-extensions/nifi-registry-ranger/pom.xml
new file mode 100644
index 0000000..1417637
--- /dev/null
+++ b/nifi-registry-extensions/nifi-registry-ranger/pom.xml
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  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.
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <parent>
+        <artifactId>nifi-registry-extensions</artifactId>
+        <groupId>org.apache.nifi.registry</groupId>
+        <version>0.3.0-SNAPSHOT</version>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+
+    <artifactId>nifi-registry-ranger</artifactId>
+    <packaging>pom</packaging>
+
+    <modules>
+        <module>nifi-registry-ranger-assembly</module>
+        <module>nifi-registry-ranger-jersey-bundle</module>
+        <module>nifi-registry-ranger-plugin</module>
+    </modules>
+
+</project>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/nifi-registry/blob/e1bd6e26/nifi-registry-extensions/pom.xml
----------------------------------------------------------------------
diff --git a/nifi-registry-extensions/pom.xml b/nifi-registry-extensions/pom.xml
new file mode 100644
index 0000000..47f8196
--- /dev/null
+++ b/nifi-registry-extensions/pom.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  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.
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <parent>
+        <artifactId>nifi-registry</artifactId>
+        <groupId>org.apache.nifi.registry</groupId>
+        <version>0.3.0-SNAPSHOT</version>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+
+    <artifactId>nifi-registry-extensions</artifactId>
+    <packaging>pom</packaging>
+
+    <modules>
+        <module>nifi-registry-ranger</module>
+    </modules>
+
+
+</project>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/nifi-registry/blob/e1bd6e26/nifi-registry-framework/src/main/java/org/apache/nifi/registry/extension/ExtensionCloseable.java
----------------------------------------------------------------------
diff --git a/nifi-registry-framework/src/main/java/org/apache/nifi/registry/extension/ExtensionCloseable.java b/nifi-registry-framework/src/main/java/org/apache/nifi/registry/extension/ExtensionCloseable.java
new file mode 100644
index 0000000..b24f950
--- /dev/null
+++ b/nifi-registry-framework/src/main/java/org/apache/nifi/registry/extension/ExtensionCloseable.java
@@ -0,0 +1,49 @@
+/*
+ * 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.registry.extension;
+
+import java.io.Closeable;
+import java.io.IOException;
+
+public class ExtensionCloseable implements Closeable {
+    private final ClassLoader toSet;
+
+    private ExtensionCloseable(ClassLoader toSet) {
+        this.toSet = toSet;
+    }
+
+    public static ExtensionCloseable withComponentClassLoader(final ExtensionManager manager, final Class componentClass) {
+
+        final ClassLoader current = Thread.currentThread().getContextClassLoader();
+        final ExtensionCloseable closeable = new ExtensionCloseable(current);
+
+        ClassLoader componentClassLoader = manager.getExtensionClassLoader(componentClass.getName());
+        if (componentClassLoader == null) {
+            componentClassLoader = componentClass.getClassLoader();
+        }
+
+        Thread.currentThread().setContextClassLoader(componentClassLoader);
+        return closeable;
+    }
+
+    @Override
+    public void close() throws IOException {
+        if (toSet != null) {
+            Thread.currentThread().setContextClassLoader(toSet);
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/nifi-registry/blob/e1bd6e26/nifi-registry-framework/src/main/java/org/apache/nifi/registry/security/authorization/AuthorizerCapabilityDetection.java
----------------------------------------------------------------------
diff --git a/nifi-registry-framework/src/main/java/org/apache/nifi/registry/security/authorization/AuthorizerCapabilityDetection.java b/nifi-registry-framework/src/main/java/org/apache/nifi/registry/security/authorization/AuthorizerCapabilityDetection.java
index 5252c7f..0652583 100644
--- a/nifi-registry-framework/src/main/java/org/apache/nifi/registry/security/authorization/AuthorizerCapabilityDetection.java
+++ b/nifi-registry-framework/src/main/java/org/apache/nifi/registry/security/authorization/AuthorizerCapabilityDetection.java
@@ -16,15 +16,6 @@
  */
 package org.apache.nifi.registry.security.authorization;
 
-import org.apache.nifi.registry.security.authorization.AccessPolicy;
-import org.apache.nifi.registry.security.authorization.AccessPolicyProvider;
-import org.apache.nifi.registry.security.authorization.Authorizer;
-import org.apache.nifi.registry.security.authorization.ConfigurableAccessPolicyProvider;
-import org.apache.nifi.registry.security.authorization.ConfigurableUserGroupProvider;
-import org.apache.nifi.registry.security.authorization.Group;
-import org.apache.nifi.registry.security.authorization.ManagedAuthorizer;
-import org.apache.nifi.registry.security.authorization.User;
-
 public final class AuthorizerCapabilityDetection {
 
     public static boolean isManagedAuthorizer(final Authorizer authorizer) {