You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nifi.apache.org by tk...@apache.org on 2015/12/02 04:51:19 UTC

[13/24] nifi git commit: NIFI-1054: Fixed DOS line endings in xml, java and js source files

http://git-wip-us.apache.org/repos/asf/nifi/blob/3a7ddc6a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/test/java/org/apache/nifi/controller/service/StandardControllerServiceProviderTest.java
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/test/java/org/apache/nifi/controller/service/StandardControllerServiceProviderTest.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/test/java/org/apache/nifi/controller/service/StandardControllerServiceProviderTest.java
index acd9993..ed9af31 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/test/java/org/apache/nifi/controller/service/StandardControllerServiceProviderTest.java
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/test/java/org/apache/nifi/controller/service/StandardControllerServiceProviderTest.java
@@ -1,71 +1,71 @@
-/*
- * 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.controller.service;
-
-import org.apache.nifi.controller.ControllerService;
-import org.apache.nifi.controller.StandardFlowServiceTest;
-import org.apache.nifi.nar.ExtensionManager;
-import org.apache.nifi.nar.NarClassLoaders;
-import org.apache.nifi.reporting.InitializationException;
-import org.apache.nifi.util.NiFiProperties;
-import org.junit.Before;
-import org.junit.BeforeClass;
-import org.junit.Test;
-
-public class StandardControllerServiceProviderTest {
-
-    private ControllerService proxied;
-    private ControllerService implementation;
-
-    @BeforeClass
-    public static void setupSuite() throws Exception {
-        System.setProperty(NiFiProperties.PROPERTIES_FILE_PATH, StandardFlowServiceTest.class.getResource("/conf/nifi.properties").getFile());
-        NiFiProperties properties = NiFiProperties.getInstance();
-        NarClassLoaders.load(properties);
-        ExtensionManager.discoverExtensions();
-    }
-
-    @Before
-    public void setup() throws Exception {
-        String id = "id";
-        String clazz = "org.apache.nifi.controller.service.util.TestControllerService";
-        ControllerServiceProvider provider = new StandardControllerServiceProvider(null, null);
-        ControllerServiceNode node = provider.createControllerService(clazz, id, true);
-        proxied = node.getProxiedControllerService();
-        implementation = node.getControllerServiceImplementation();
-    }
-
-    @Test(expected = UnsupportedOperationException.class)
-    public void testCallProxiedOnPropertyModified() {
-        proxied.onPropertyModified(null, "oldValue", "newValue");
-    }
-
-    @Test
-    public void testCallImplementationOnPropertyModified() {
-        implementation.onPropertyModified(null, "oldValue", "newValue");
-    }
-
-    @Test(expected = UnsupportedOperationException.class)
-    public void testCallProxiedInitialized() throws InitializationException {
-        proxied.initialize(null);
-    }
-
-    @Test
-    public void testCallImplementationInitialized() throws InitializationException {
-        implementation.initialize(null);
-    }
-}
+/*
+ * 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.controller.service;
+
+import org.apache.nifi.controller.ControllerService;
+import org.apache.nifi.controller.StandardFlowServiceTest;
+import org.apache.nifi.nar.ExtensionManager;
+import org.apache.nifi.nar.NarClassLoaders;
+import org.apache.nifi.reporting.InitializationException;
+import org.apache.nifi.util.NiFiProperties;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+public class StandardControllerServiceProviderTest {
+
+    private ControllerService proxied;
+    private ControllerService implementation;
+
+    @BeforeClass
+    public static void setupSuite() throws Exception {
+        System.setProperty(NiFiProperties.PROPERTIES_FILE_PATH, StandardFlowServiceTest.class.getResource("/conf/nifi.properties").getFile());
+        NiFiProperties properties = NiFiProperties.getInstance();
+        NarClassLoaders.load(properties);
+        ExtensionManager.discoverExtensions();
+    }
+
+    @Before
+    public void setup() throws Exception {
+        String id = "id";
+        String clazz = "org.apache.nifi.controller.service.util.TestControllerService";
+        ControllerServiceProvider provider = new StandardControllerServiceProvider(null, null);
+        ControllerServiceNode node = provider.createControllerService(clazz, id, true);
+        proxied = node.getProxiedControllerService();
+        implementation = node.getControllerServiceImplementation();
+    }
+
+    @Test(expected = UnsupportedOperationException.class)
+    public void testCallProxiedOnPropertyModified() {
+        proxied.onPropertyModified(null, "oldValue", "newValue");
+    }
+
+    @Test
+    public void testCallImplementationOnPropertyModified() {
+        implementation.onPropertyModified(null, "oldValue", "newValue");
+    }
+
+    @Test(expected = UnsupportedOperationException.class)
+    public void testCallProxiedInitialized() throws InitializationException {
+        proxied.initialize(null);
+    }
+
+    @Test
+    public void testCallImplementationInitialized() throws InitializationException {
+        implementation.initialize(null);
+    }
+}

http://git-wip-us.apache.org/repos/asf/nifi/blob/3a7ddc6a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/test/java/org/apache/nifi/controller/service/TestStandardControllerServiceProvider.java
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/test/java/org/apache/nifi/controller/service/TestStandardControllerServiceProvider.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/test/java/org/apache/nifi/controller/service/TestStandardControllerServiceProvider.java
index bca13eb..5cd3648 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/test/java/org/apache/nifi/controller/service/TestStandardControllerServiceProvider.java
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/test/java/org/apache/nifi/controller/service/TestStandardControllerServiceProvider.java
@@ -1,457 +1,457 @@
-/*
- * 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.controller.service;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
-
-import java.beans.PropertyDescriptor;
-import java.util.HashSet;
-import java.util.LinkedHashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.UUID;
-
-import org.apache.nifi.controller.Heartbeater;
-import org.apache.nifi.controller.ProcessScheduler;
-import org.apache.nifi.controller.ProcessorNode;
-import org.apache.nifi.controller.ScheduledState;
-import org.apache.nifi.controller.StandardProcessorNode;
-import org.apache.nifi.controller.scheduling.StandardProcessScheduler;
-import org.apache.nifi.controller.service.mock.DummyProcessor;
-import org.apache.nifi.controller.service.mock.ServiceA;
-import org.apache.nifi.controller.service.mock.ServiceB;
-import org.apache.nifi.groups.ProcessGroup;
-import org.apache.nifi.groups.StandardProcessGroup;
-import org.apache.nifi.processor.StandardProcessorInitializationContext;
-import org.apache.nifi.processor.StandardValidationContextFactory;
-import org.junit.Assert;
-import org.junit.BeforeClass;
-import org.junit.Test;
-import org.mockito.Mockito;
-import org.mockito.invocation.InvocationOnMock;
-import org.mockito.stubbing.Answer;
-
-public class TestStandardControllerServiceProvider {
-
-    @BeforeClass
-    public static void setNiFiProps() {
-        System.setProperty("nifi.properties.file.path", "src/test/resources/nifi.properties");
-    }
-
-    private ProcessScheduler createScheduler() {
-        final Heartbeater heartbeater = Mockito.mock(Heartbeater.class);
-        return new StandardProcessScheduler(heartbeater, null, null);
-    }
-
-    @Test
-    public void testDisableControllerService() {
-        final ProcessScheduler scheduler = createScheduler();
-        final StandardControllerServiceProvider provider = new StandardControllerServiceProvider(scheduler, null);
-
-        final ControllerServiceNode serviceNode = provider.createControllerService(ServiceB.class.getName(), "B", false);
-        provider.enableControllerService(serviceNode);
-        provider.disableControllerService(serviceNode);
-    }
-
-    @Test(timeout=10000)
-    public void testEnableDisableWithReference() {
-        final ProcessScheduler scheduler = createScheduler();
-        final StandardControllerServiceProvider provider = new StandardControllerServiceProvider(scheduler, null);
-
-        final ControllerServiceNode serviceNodeB = provider.createControllerService(ServiceB.class.getName(), "B", false);
-        final ControllerServiceNode serviceNodeA = provider.createControllerService(ServiceA.class.getName(), "A", false);
-
-        serviceNodeA.setProperty(ServiceA.OTHER_SERVICE.getName(), "B");
-
-        try {
-            provider.enableControllerService(serviceNodeA);
-            Assert.fail("Was able to enable Service A but Service B is disabled.");
-        } catch (final IllegalStateException expected) {
-        }
-
-        provider.enableControllerService(serviceNodeB);
-        provider.enableControllerService(serviceNodeA);
-
-        try {
-            provider.disableControllerService(serviceNodeB);
-            Assert.fail("Was able to disable Service B but Service A is enabled and references B");
-        } catch (final IllegalStateException expected) {
-        }
-
-        provider.disableControllerService(serviceNodeA);
-        waitForServiceState(serviceNodeA, ControllerServiceState.DISABLED);
-
-        provider.disableControllerService(serviceNodeB);
-        waitForServiceState(serviceNodeB, ControllerServiceState.DISABLED);
-    }
-
-    private void waitForServiceState(final ControllerServiceNode service, final ControllerServiceState desiredState) {
-        while (service.getState() != desiredState) {
-            try {
-                Thread.sleep(50L);
-            } catch (final InterruptedException e) {
-            }
-        }
-    }
-
-    /**
-     * We run the same test 1000 times and prior to bug fix (see NIFI-1143) it
-     * would fail on some iteration. For more details please see
-     * {@link PropertyDescriptor}.isDependentServiceEnableable() as well as
-     * https://issues.apache.org/jira/browse/NIFI-1143
-     */
-    @Test(timeout = 10000)
-    public void testConcurrencyWithEnablingReferencingServicesGraph() {
-        final ProcessScheduler scheduler = createScheduler();
-        for (int i = 0; i < 1000; i++) {
-            testEnableReferencingServicesGraph(scheduler);
-        }
-    }
-
-    public void testEnableReferencingServicesGraph(ProcessScheduler scheduler) {
-        final StandardControllerServiceProvider provider = new StandardControllerServiceProvider(scheduler, null);
-
-        // build a graph of controller services with dependencies as such:
-        //
-        // A -> B -> D
-        // C ---^----^
-        //
-        // In other words, A references B, which references D.
-        // AND
-        // C references B and D.
-        //
-        // So we have to verify that if D is enabled, when we enable its referencing services,
-        // we enable C and B, even if we attempt to enable C before B... i.e., if we try to enable C, we cannot do so
-        // until B is first enabled so ensure that we enable B first.
-        final ControllerServiceNode serviceNode1 = provider.createControllerService(ServiceA.class.getName(), "1", false);
-        final ControllerServiceNode serviceNode2 = provider.createControllerService(ServiceA.class.getName(), "2", false);
-        final ControllerServiceNode serviceNode3 = provider.createControllerService(ServiceA.class.getName(), "3", false);
-        final ControllerServiceNode serviceNode4 = provider.createControllerService(ServiceB.class.getName(), "4", false);
-
-        serviceNode1.setProperty(ServiceA.OTHER_SERVICE.getName(), "2");
-        serviceNode2.setProperty(ServiceA.OTHER_SERVICE.getName(), "4");
-        serviceNode3.setProperty(ServiceA.OTHER_SERVICE.getName(), "2");
-        serviceNode3.setProperty(ServiceA.OTHER_SERVICE_2.getName(), "4");
-
-        provider.enableControllerService(serviceNode4);
-        provider.enableReferencingServices(serviceNode4);
-
-        // Verify that the services are either ENABLING or ENABLED, and wait for all of them to become ENABLED.
-        // Note that we set a timeout of 10 seconds, in case a bug occurs and the services never become ENABLED.
-        final Set<ControllerServiceState> validStates = new HashSet<>();
-        validStates.add(ControllerServiceState.ENABLED);
-        validStates.add(ControllerServiceState.ENABLING);
-
-        while (serviceNode3.getState() != ControllerServiceState.ENABLED || serviceNode2.getState() != ControllerServiceState.ENABLED || serviceNode1.getState() != ControllerServiceState.ENABLED) {
-            assertTrue(validStates.contains(serviceNode3.getState()));
-            assertTrue(validStates.contains(serviceNode2.getState()));
-            assertTrue(validStates.contains(serviceNode1.getState()));
-        }
-    }
-
-    @Test(timeout=10000)
-    public void testStartStopReferencingComponents() {
-        final ProcessScheduler scheduler = createScheduler();
-        final StandardControllerServiceProvider provider = new StandardControllerServiceProvider(scheduler, null);
-
-        // build a graph of reporting tasks and controller services with dependencies as such:
-        //
-        // Processor P1 -> A -> B -> D
-        // Processor P2 -> C ---^----^
-        //
-        // In other words, Processor P1 references Controller Service A, which references B, which references D.
-        // AND
-        // Processor P2 references Controller Service C, which references B and D.
-        //
-        // So we have to verify that if D is enabled, when we enable its referencing services,
-        // we enable C and B, even if we attempt to enable C before B... i.e., if we try to enable C, we cannot do so
-        // until B is first enabled so ensure that we enable B first.
-        final ControllerServiceNode serviceNode1 = provider.createControllerService(ServiceA.class.getName(), "1", false);
-        final ControllerServiceNode serviceNode2 = provider.createControllerService(ServiceA.class.getName(), "2", false);
-        final ControllerServiceNode serviceNode3 = provider.createControllerService(ServiceA.class.getName(), "3", false);
-        final ControllerServiceNode serviceNode4 = provider.createControllerService(ServiceB.class.getName(), "4", false);
-
-        final ProcessGroup mockProcessGroup = Mockito.mock(ProcessGroup.class);
-        Mockito.doAnswer(new Answer<Object>() {
-            @Override
-            public Object answer(InvocationOnMock invocation) throws Throwable {
-                final ProcessorNode procNode = (ProcessorNode) invocation.getArguments()[0];
-                procNode.verifyCanStart();
-                procNode.setScheduledState(ScheduledState.RUNNING);
-                return null;
-            }
-        }).when(mockProcessGroup).startProcessor(Mockito.any(ProcessorNode.class));
-
-        Mockito.doAnswer(new Answer<Object>() {
-            @Override
-            public Object answer(final InvocationOnMock invocation) throws Throwable {
-                final ProcessorNode procNode = (ProcessorNode) invocation.getArguments()[0];
-                procNode.verifyCanStop();
-                procNode.setScheduledState(ScheduledState.STOPPED);
-                return null;
-            }
-        }).when(mockProcessGroup).stopProcessor(Mockito.any(ProcessorNode.class));
-
-        final String id1 = UUID.randomUUID().toString();
-        final ProcessorNode procNodeA = new StandardProcessorNode(new DummyProcessor(), id1,
-                new StandardValidationContextFactory(provider), scheduler, provider);
-        procNodeA.getProcessor().initialize(new StandardProcessorInitializationContext(id1, null, provider));
-        procNodeA.setProperty(DummyProcessor.SERVICE.getName(), "1");
-        procNodeA.setProcessGroup(mockProcessGroup);
-
-        final String id2 = UUID.randomUUID().toString();
-        final ProcessorNode procNodeB = new StandardProcessorNode(new DummyProcessor(), id2,
-                new StandardValidationContextFactory(provider), scheduler, provider);
-        procNodeB.getProcessor().initialize(new StandardProcessorInitializationContext(id2, null, provider));
-        procNodeB.setProperty(DummyProcessor.SERVICE.getName(), "3");
-        procNodeB.setProcessGroup(mockProcessGroup);
-
-        serviceNode1.setProperty(ServiceA.OTHER_SERVICE.getName(), "2");
-        serviceNode2.setProperty(ServiceA.OTHER_SERVICE.getName(), "4");
-        serviceNode3.setProperty(ServiceA.OTHER_SERVICE.getName(), "2");
-        serviceNode3.setProperty(ServiceA.OTHER_SERVICE_2.getName(), "4");
-
-        provider.enableControllerService(serviceNode4);
-        provider.enableReferencingServices(serviceNode4);
-        provider.scheduleReferencingComponents(serviceNode4);
-
-        final Set<ControllerServiceState> enableStates = new HashSet<>();
-        enableStates.add(ControllerServiceState.ENABLED);
-        enableStates.add(ControllerServiceState.ENABLING);
-
-        while (serviceNode3.getState() != ControllerServiceState.ENABLED
-            || serviceNode2.getState() != ControllerServiceState.ENABLED
-            || serviceNode1.getState() != ControllerServiceState.ENABLED) {
-            assertTrue(enableStates.contains(serviceNode3.getState()));
-            assertTrue(enableStates.contains(serviceNode2.getState()));
-            assertTrue(enableStates.contains(serviceNode1.getState()));
-        }
-        assertTrue(procNodeA.isRunning());
-        assertTrue(procNodeB.isRunning());
-
-        // stop processors and verify results.
-        provider.unscheduleReferencingComponents(serviceNode4);
-        assertFalse(procNodeA.isRunning());
-        assertFalse(procNodeB.isRunning());
-        while (serviceNode3.getState() != ControllerServiceState.ENABLED
-            || serviceNode2.getState() != ControllerServiceState.ENABLED
-            || serviceNode1.getState() != ControllerServiceState.ENABLED) {
-            assertTrue(enableStates.contains(serviceNode3.getState()));
-            assertTrue(enableStates.contains(serviceNode2.getState()));
-            assertTrue(enableStates.contains(serviceNode1.getState()));
-        }
-
-        provider.disableReferencingServices(serviceNode4);
-        final Set<ControllerServiceState> disableStates = new HashSet<>();
-        disableStates.add(ControllerServiceState.DISABLED);
-        disableStates.add(ControllerServiceState.DISABLING);
-
-        // Wait for the services to be disabled.
-        while (serviceNode3.getState() != ControllerServiceState.DISABLED
-            || serviceNode2.getState() != ControllerServiceState.DISABLED
-            || serviceNode1.getState() != ControllerServiceState.DISABLED) {
-            assertTrue(disableStates.contains(serviceNode3.getState()));
-            assertTrue(disableStates.contains(serviceNode2.getState()));
-            assertTrue(disableStates.contains(serviceNode1.getState()));
-        }
-
-        assertEquals(ControllerServiceState.ENABLED, serviceNode4.getState());
-
-        provider.disableControllerService(serviceNode4);
-        assertTrue(disableStates.contains(serviceNode4.getState()));
-    }
-
-    @Test
-    public void testOrderingOfServices() {
-        final StandardControllerServiceProvider provider = new StandardControllerServiceProvider(null, null);
-        final ControllerServiceNode serviceNode1 = provider.createControllerService(ServiceA.class.getName(), "1", false);
-        final ControllerServiceNode serviceNode2 = provider.createControllerService(ServiceB.class.getName(), "2", false);
-
-        serviceNode1.setProperty(ServiceA.OTHER_SERVICE.getName(), "2");
-
-        final Map<String, ControllerServiceNode> nodeMap = new LinkedHashMap<>();
-        nodeMap.put("1", serviceNode1);
-        nodeMap.put("2", serviceNode2);
-
-        List<List<ControllerServiceNode>> branches = StandardControllerServiceProvider.determineEnablingOrder(nodeMap);
-        assertEquals(2, branches.size());
-        List<ControllerServiceNode> ordered = branches.get(0);
-        assertEquals(2, ordered.size());
-        assertTrue(ordered.get(0) == serviceNode2);
-        assertTrue(ordered.get(1) == serviceNode1);
-        assertEquals(1, branches.get(1).size());
-        assertTrue(branches.get(1).get(0) == serviceNode2);
-
-        nodeMap.clear();
-        nodeMap.put("2", serviceNode2);
-        nodeMap.put("1", serviceNode1);
-
-        branches = StandardControllerServiceProvider.determineEnablingOrder(nodeMap);
-        assertEquals(2, branches.size());
-        ordered = branches.get(1);
-        assertEquals(2, ordered.size());
-        assertTrue(ordered.get(0) == serviceNode2);
-        assertTrue(ordered.get(1) == serviceNode1);
-        assertEquals(1, branches.get(0).size());
-        assertTrue(branches.get(0).get(0) == serviceNode2);
-
-        // add circular dependency on self.
-        nodeMap.clear();
-        serviceNode1.setProperty(ServiceA.OTHER_SERVICE_2.getName(), "1");
-        nodeMap.put("1", serviceNode1);
-        nodeMap.put("2", serviceNode2);
-
-        branches = StandardControllerServiceProvider.determineEnablingOrder(nodeMap);
-        assertEquals(2, branches.size());
-        ordered = branches.get(0);
-        assertEquals(2, ordered.size());
-        assertTrue(ordered.get(0) == serviceNode2);
-        assertTrue(ordered.get(1) == serviceNode1);
-
-        nodeMap.clear();
-        nodeMap.put("2", serviceNode2);
-        nodeMap.put("1", serviceNode1);
-        branches = StandardControllerServiceProvider.determineEnablingOrder(nodeMap);
-        assertEquals(2, branches.size());
-        ordered = branches.get(1);
-        assertEquals(2, ordered.size());
-        assertTrue(ordered.get(0) == serviceNode2);
-        assertTrue(ordered.get(1) == serviceNode1);
-
-        // add circular dependency once removed. In this case, we won't actually be able to enable these because of the
-        // circular dependency because they will never be valid because they will always depend on a disabled service.
-        // But we want to ensure that the method returns successfully without throwing a StackOverflowException or anything
-        // like that.
-        nodeMap.clear();
-        final ControllerServiceNode serviceNode3 = provider.createControllerService(ServiceA.class.getName(), "3", false);
-        serviceNode1.setProperty(ServiceA.OTHER_SERVICE.getName(), "3");
-        serviceNode3.setProperty(ServiceA.OTHER_SERVICE.getName(), "1");
-        nodeMap.put("1", serviceNode1);
-        nodeMap.put("3", serviceNode3);
-        branches = StandardControllerServiceProvider.determineEnablingOrder(nodeMap);
-        assertEquals(2, branches.size());
-        ordered = branches.get(0);
-        assertEquals(2, ordered.size());
-        assertTrue(ordered.get(0) == serviceNode3);
-        assertTrue(ordered.get(1) == serviceNode1);
-
-        nodeMap.clear();
-        nodeMap.put("3", serviceNode3);
-        nodeMap.put("1", serviceNode1);
-        branches = StandardControllerServiceProvider.determineEnablingOrder(nodeMap);
-        assertEquals(2, branches.size());
-        ordered = branches.get(1);
-        assertEquals(2, ordered.size());
-        assertTrue(ordered.get(0) == serviceNode3);
-        assertTrue(ordered.get(1) == serviceNode1);
-
-        // Add multiple completely disparate branches.
-        nodeMap.clear();
-        serviceNode1.setProperty(ServiceA.OTHER_SERVICE.getName(), "2");
-        final ControllerServiceNode serviceNode4 = provider.createControllerService(ServiceB.class.getName(), "4", false);
-        final ControllerServiceNode serviceNode5 = provider.createControllerService(ServiceB.class.getName(), "5", false);
-        serviceNode3.setProperty(ServiceA.OTHER_SERVICE.getName(), "4");
-        nodeMap.put("1", serviceNode1);
-        nodeMap.put("2", serviceNode2);
-        nodeMap.put("3", serviceNode3);
-        nodeMap.put("4", serviceNode4);
-        nodeMap.put("5", serviceNode5);
-
-        branches = StandardControllerServiceProvider.determineEnablingOrder(nodeMap);
-        assertEquals(5, branches.size());
-
-        ordered = branches.get(0);
-        assertEquals(2, ordered.size());
-        assertTrue(ordered.get(0) == serviceNode2);
-        assertTrue(ordered.get(1) == serviceNode1);
-
-        assertEquals(1, branches.get(1).size());
-        assertTrue(branches.get(1).get(0) == serviceNode2);
-
-        ordered = branches.get(2);
-        assertEquals(2, ordered.size());
-        assertTrue(ordered.get(0) == serviceNode4);
-        assertTrue(ordered.get(1) == serviceNode3);
-
-        assertEquals(1, branches.get(3).size());
-        assertTrue(branches.get(3).get(0) == serviceNode4);
-
-        assertEquals(1, branches.get(4).size());
-        assertTrue(branches.get(4).get(0) == serviceNode5);
-
-        // create 2 branches both dependent on the same service
-        nodeMap.clear();
-        serviceNode1.setProperty(ServiceA.OTHER_SERVICE.getName(), "2");
-        serviceNode3.setProperty(ServiceA.OTHER_SERVICE.getName(), "2");
-        nodeMap.put("1", serviceNode1);
-        nodeMap.put("2", serviceNode2);
-        nodeMap.put("3", serviceNode3);
-
-        branches = StandardControllerServiceProvider.determineEnablingOrder(nodeMap);
-        assertEquals(3, branches.size());
-
-        ordered = branches.get(0);
-        assertEquals(2, ordered.size());
-        assertTrue(ordered.get(0) == serviceNode2);
-        assertTrue(ordered.get(1) == serviceNode1);
-
-        ordered = branches.get(1);
-        assertEquals(1, ordered.size());
-        assertTrue(ordered.get(0) == serviceNode2);
-
-        ordered = branches.get(2);
-        assertEquals(2, ordered.size());
-        assertTrue(ordered.get(0) == serviceNode2);
-        assertTrue(ordered.get(1) == serviceNode3);
-    }
-
-    private ProcessorNode createProcessor(final ProcessScheduler scheduler, final ControllerServiceProvider serviceProvider) {
-        final ProcessorNode procNode = new StandardProcessorNode(new DummyProcessor(), UUID.randomUUID().toString(),
-                new StandardValidationContextFactory(serviceProvider), scheduler, serviceProvider);
-
-        final ProcessGroup group = new StandardProcessGroup(UUID.randomUUID().toString(), serviceProvider, scheduler, null, null);
-        group.addProcessor(procNode);
-        procNode.setProcessGroup(group);
-
-        return procNode;
-    }
-
-    @Test
-    public void testEnableReferencingComponents() {
-        final ProcessScheduler scheduler = createScheduler();
-        final StandardControllerServiceProvider provider = new StandardControllerServiceProvider(null, null);
-        final ControllerServiceNode serviceNode = provider.createControllerService(ServiceA.class.getName(), "1", false);
-
-        final ProcessorNode procNode = createProcessor(scheduler, provider);
-        serviceNode.addReference(procNode);
-
-        procNode.setScheduledState(ScheduledState.STOPPED);
-        provider.unscheduleReferencingComponents(serviceNode);
-        assertEquals(ScheduledState.STOPPED, procNode.getScheduledState());
-
-        procNode.setScheduledState(ScheduledState.RUNNING);
-        provider.unscheduleReferencingComponents(serviceNode);
-        assertEquals(ScheduledState.STOPPED, procNode.getScheduledState());
-
-        procNode.setScheduledState(ScheduledState.DISABLED);
-        provider.unscheduleReferencingComponents(serviceNode);
-        assertEquals(ScheduledState.DISABLED, procNode.getScheduledState());
-    }
-}
+/*
+ * 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.controller.service;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+import java.beans.PropertyDescriptor;
+import java.util.HashSet;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.UUID;
+
+import org.apache.nifi.controller.Heartbeater;
+import org.apache.nifi.controller.ProcessScheduler;
+import org.apache.nifi.controller.ProcessorNode;
+import org.apache.nifi.controller.ScheduledState;
+import org.apache.nifi.controller.StandardProcessorNode;
+import org.apache.nifi.controller.scheduling.StandardProcessScheduler;
+import org.apache.nifi.controller.service.mock.DummyProcessor;
+import org.apache.nifi.controller.service.mock.ServiceA;
+import org.apache.nifi.controller.service.mock.ServiceB;
+import org.apache.nifi.groups.ProcessGroup;
+import org.apache.nifi.groups.StandardProcessGroup;
+import org.apache.nifi.processor.StandardProcessorInitializationContext;
+import org.apache.nifi.processor.StandardValidationContextFactory;
+import org.junit.Assert;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.mockito.Mockito;
+import org.mockito.invocation.InvocationOnMock;
+import org.mockito.stubbing.Answer;
+
+public class TestStandardControllerServiceProvider {
+
+    @BeforeClass
+    public static void setNiFiProps() {
+        System.setProperty("nifi.properties.file.path", "src/test/resources/nifi.properties");
+    }
+
+    private ProcessScheduler createScheduler() {
+        final Heartbeater heartbeater = Mockito.mock(Heartbeater.class);
+        return new StandardProcessScheduler(heartbeater, null, null);
+    }
+
+    @Test
+    public void testDisableControllerService() {
+        final ProcessScheduler scheduler = createScheduler();
+        final StandardControllerServiceProvider provider = new StandardControllerServiceProvider(scheduler, null);
+
+        final ControllerServiceNode serviceNode = provider.createControllerService(ServiceB.class.getName(), "B", false);
+        provider.enableControllerService(serviceNode);
+        provider.disableControllerService(serviceNode);
+    }
+
+    @Test(timeout=10000)
+    public void testEnableDisableWithReference() {
+        final ProcessScheduler scheduler = createScheduler();
+        final StandardControllerServiceProvider provider = new StandardControllerServiceProvider(scheduler, null);
+
+        final ControllerServiceNode serviceNodeB = provider.createControllerService(ServiceB.class.getName(), "B", false);
+        final ControllerServiceNode serviceNodeA = provider.createControllerService(ServiceA.class.getName(), "A", false);
+
+        serviceNodeA.setProperty(ServiceA.OTHER_SERVICE.getName(), "B");
+
+        try {
+            provider.enableControllerService(serviceNodeA);
+            Assert.fail("Was able to enable Service A but Service B is disabled.");
+        } catch (final IllegalStateException expected) {
+        }
+
+        provider.enableControllerService(serviceNodeB);
+        provider.enableControllerService(serviceNodeA);
+
+        try {
+            provider.disableControllerService(serviceNodeB);
+            Assert.fail("Was able to disable Service B but Service A is enabled and references B");
+        } catch (final IllegalStateException expected) {
+        }
+
+        provider.disableControllerService(serviceNodeA);
+        waitForServiceState(serviceNodeA, ControllerServiceState.DISABLED);
+
+        provider.disableControllerService(serviceNodeB);
+        waitForServiceState(serviceNodeB, ControllerServiceState.DISABLED);
+    }
+
+    private void waitForServiceState(final ControllerServiceNode service, final ControllerServiceState desiredState) {
+        while (service.getState() != desiredState) {
+            try {
+                Thread.sleep(50L);
+            } catch (final InterruptedException e) {
+            }
+        }
+    }
+
+    /**
+     * We run the same test 1000 times and prior to bug fix (see NIFI-1143) it
+     * would fail on some iteration. For more details please see
+     * {@link PropertyDescriptor}.isDependentServiceEnableable() as well as
+     * https://issues.apache.org/jira/browse/NIFI-1143
+     */
+    @Test(timeout = 10000)
+    public void testConcurrencyWithEnablingReferencingServicesGraph() {
+        final ProcessScheduler scheduler = createScheduler();
+        for (int i = 0; i < 1000; i++) {
+            testEnableReferencingServicesGraph(scheduler);
+        }
+    }
+
+    public void testEnableReferencingServicesGraph(ProcessScheduler scheduler) {
+        final StandardControllerServiceProvider provider = new StandardControllerServiceProvider(scheduler, null);
+
+        // build a graph of controller services with dependencies as such:
+        //
+        // A -> B -> D
+        // C ---^----^
+        //
+        // In other words, A references B, which references D.
+        // AND
+        // C references B and D.
+        //
+        // So we have to verify that if D is enabled, when we enable its referencing services,
+        // we enable C and B, even if we attempt to enable C before B... i.e., if we try to enable C, we cannot do so
+        // until B is first enabled so ensure that we enable B first.
+        final ControllerServiceNode serviceNode1 = provider.createControllerService(ServiceA.class.getName(), "1", false);
+        final ControllerServiceNode serviceNode2 = provider.createControllerService(ServiceA.class.getName(), "2", false);
+        final ControllerServiceNode serviceNode3 = provider.createControllerService(ServiceA.class.getName(), "3", false);
+        final ControllerServiceNode serviceNode4 = provider.createControllerService(ServiceB.class.getName(), "4", false);
+
+        serviceNode1.setProperty(ServiceA.OTHER_SERVICE.getName(), "2");
+        serviceNode2.setProperty(ServiceA.OTHER_SERVICE.getName(), "4");
+        serviceNode3.setProperty(ServiceA.OTHER_SERVICE.getName(), "2");
+        serviceNode3.setProperty(ServiceA.OTHER_SERVICE_2.getName(), "4");
+
+        provider.enableControllerService(serviceNode4);
+        provider.enableReferencingServices(serviceNode4);
+
+        // Verify that the services are either ENABLING or ENABLED, and wait for all of them to become ENABLED.
+        // Note that we set a timeout of 10 seconds, in case a bug occurs and the services never become ENABLED.
+        final Set<ControllerServiceState> validStates = new HashSet<>();
+        validStates.add(ControllerServiceState.ENABLED);
+        validStates.add(ControllerServiceState.ENABLING);
+
+        while (serviceNode3.getState() != ControllerServiceState.ENABLED || serviceNode2.getState() != ControllerServiceState.ENABLED || serviceNode1.getState() != ControllerServiceState.ENABLED) {
+            assertTrue(validStates.contains(serviceNode3.getState()));
+            assertTrue(validStates.contains(serviceNode2.getState()));
+            assertTrue(validStates.contains(serviceNode1.getState()));
+        }
+    }
+
+    @Test(timeout=10000)
+    public void testStartStopReferencingComponents() {
+        final ProcessScheduler scheduler = createScheduler();
+        final StandardControllerServiceProvider provider = new StandardControllerServiceProvider(scheduler, null);
+
+        // build a graph of reporting tasks and controller services with dependencies as such:
+        //
+        // Processor P1 -> A -> B -> D
+        // Processor P2 -> C ---^----^
+        //
+        // In other words, Processor P1 references Controller Service A, which references B, which references D.
+        // AND
+        // Processor P2 references Controller Service C, which references B and D.
+        //
+        // So we have to verify that if D is enabled, when we enable its referencing services,
+        // we enable C and B, even if we attempt to enable C before B... i.e., if we try to enable C, we cannot do so
+        // until B is first enabled so ensure that we enable B first.
+        final ControllerServiceNode serviceNode1 = provider.createControllerService(ServiceA.class.getName(), "1", false);
+        final ControllerServiceNode serviceNode2 = provider.createControllerService(ServiceA.class.getName(), "2", false);
+        final ControllerServiceNode serviceNode3 = provider.createControllerService(ServiceA.class.getName(), "3", false);
+        final ControllerServiceNode serviceNode4 = provider.createControllerService(ServiceB.class.getName(), "4", false);
+
+        final ProcessGroup mockProcessGroup = Mockito.mock(ProcessGroup.class);
+        Mockito.doAnswer(new Answer<Object>() {
+            @Override
+            public Object answer(InvocationOnMock invocation) throws Throwable {
+                final ProcessorNode procNode = (ProcessorNode) invocation.getArguments()[0];
+                procNode.verifyCanStart();
+                procNode.setScheduledState(ScheduledState.RUNNING);
+                return null;
+            }
+        }).when(mockProcessGroup).startProcessor(Mockito.any(ProcessorNode.class));
+
+        Mockito.doAnswer(new Answer<Object>() {
+            @Override
+            public Object answer(final InvocationOnMock invocation) throws Throwable {
+                final ProcessorNode procNode = (ProcessorNode) invocation.getArguments()[0];
+                procNode.verifyCanStop();
+                procNode.setScheduledState(ScheduledState.STOPPED);
+                return null;
+            }
+        }).when(mockProcessGroup).stopProcessor(Mockito.any(ProcessorNode.class));
+
+        final String id1 = UUID.randomUUID().toString();
+        final ProcessorNode procNodeA = new StandardProcessorNode(new DummyProcessor(), id1,
+                new StandardValidationContextFactory(provider), scheduler, provider);
+        procNodeA.getProcessor().initialize(new StandardProcessorInitializationContext(id1, null, provider));
+        procNodeA.setProperty(DummyProcessor.SERVICE.getName(), "1");
+        procNodeA.setProcessGroup(mockProcessGroup);
+
+        final String id2 = UUID.randomUUID().toString();
+        final ProcessorNode procNodeB = new StandardProcessorNode(new DummyProcessor(), id2,
+                new StandardValidationContextFactory(provider), scheduler, provider);
+        procNodeB.getProcessor().initialize(new StandardProcessorInitializationContext(id2, null, provider));
+        procNodeB.setProperty(DummyProcessor.SERVICE.getName(), "3");
+        procNodeB.setProcessGroup(mockProcessGroup);
+
+        serviceNode1.setProperty(ServiceA.OTHER_SERVICE.getName(), "2");
+        serviceNode2.setProperty(ServiceA.OTHER_SERVICE.getName(), "4");
+        serviceNode3.setProperty(ServiceA.OTHER_SERVICE.getName(), "2");
+        serviceNode3.setProperty(ServiceA.OTHER_SERVICE_2.getName(), "4");
+
+        provider.enableControllerService(serviceNode4);
+        provider.enableReferencingServices(serviceNode4);
+        provider.scheduleReferencingComponents(serviceNode4);
+
+        final Set<ControllerServiceState> enableStates = new HashSet<>();
+        enableStates.add(ControllerServiceState.ENABLED);
+        enableStates.add(ControllerServiceState.ENABLING);
+
+        while (serviceNode3.getState() != ControllerServiceState.ENABLED
+            || serviceNode2.getState() != ControllerServiceState.ENABLED
+            || serviceNode1.getState() != ControllerServiceState.ENABLED) {
+            assertTrue(enableStates.contains(serviceNode3.getState()));
+            assertTrue(enableStates.contains(serviceNode2.getState()));
+            assertTrue(enableStates.contains(serviceNode1.getState()));
+        }
+        assertTrue(procNodeA.isRunning());
+        assertTrue(procNodeB.isRunning());
+
+        // stop processors and verify results.
+        provider.unscheduleReferencingComponents(serviceNode4);
+        assertFalse(procNodeA.isRunning());
+        assertFalse(procNodeB.isRunning());
+        while (serviceNode3.getState() != ControllerServiceState.ENABLED
+            || serviceNode2.getState() != ControllerServiceState.ENABLED
+            || serviceNode1.getState() != ControllerServiceState.ENABLED) {
+            assertTrue(enableStates.contains(serviceNode3.getState()));
+            assertTrue(enableStates.contains(serviceNode2.getState()));
+            assertTrue(enableStates.contains(serviceNode1.getState()));
+        }
+
+        provider.disableReferencingServices(serviceNode4);
+        final Set<ControllerServiceState> disableStates = new HashSet<>();
+        disableStates.add(ControllerServiceState.DISABLED);
+        disableStates.add(ControllerServiceState.DISABLING);
+
+        // Wait for the services to be disabled.
+        while (serviceNode3.getState() != ControllerServiceState.DISABLED
+            || serviceNode2.getState() != ControllerServiceState.DISABLED
+            || serviceNode1.getState() != ControllerServiceState.DISABLED) {
+            assertTrue(disableStates.contains(serviceNode3.getState()));
+            assertTrue(disableStates.contains(serviceNode2.getState()));
+            assertTrue(disableStates.contains(serviceNode1.getState()));
+        }
+
+        assertEquals(ControllerServiceState.ENABLED, serviceNode4.getState());
+
+        provider.disableControllerService(serviceNode4);
+        assertTrue(disableStates.contains(serviceNode4.getState()));
+    }
+
+    @Test
+    public void testOrderingOfServices() {
+        final StandardControllerServiceProvider provider = new StandardControllerServiceProvider(null, null);
+        final ControllerServiceNode serviceNode1 = provider.createControllerService(ServiceA.class.getName(), "1", false);
+        final ControllerServiceNode serviceNode2 = provider.createControllerService(ServiceB.class.getName(), "2", false);
+
+        serviceNode1.setProperty(ServiceA.OTHER_SERVICE.getName(), "2");
+
+        final Map<String, ControllerServiceNode> nodeMap = new LinkedHashMap<>();
+        nodeMap.put("1", serviceNode1);
+        nodeMap.put("2", serviceNode2);
+
+        List<List<ControllerServiceNode>> branches = StandardControllerServiceProvider.determineEnablingOrder(nodeMap);
+        assertEquals(2, branches.size());
+        List<ControllerServiceNode> ordered = branches.get(0);
+        assertEquals(2, ordered.size());
+        assertTrue(ordered.get(0) == serviceNode2);
+        assertTrue(ordered.get(1) == serviceNode1);
+        assertEquals(1, branches.get(1).size());
+        assertTrue(branches.get(1).get(0) == serviceNode2);
+
+        nodeMap.clear();
+        nodeMap.put("2", serviceNode2);
+        nodeMap.put("1", serviceNode1);
+
+        branches = StandardControllerServiceProvider.determineEnablingOrder(nodeMap);
+        assertEquals(2, branches.size());
+        ordered = branches.get(1);
+        assertEquals(2, ordered.size());
+        assertTrue(ordered.get(0) == serviceNode2);
+        assertTrue(ordered.get(1) == serviceNode1);
+        assertEquals(1, branches.get(0).size());
+        assertTrue(branches.get(0).get(0) == serviceNode2);
+
+        // add circular dependency on self.
+        nodeMap.clear();
+        serviceNode1.setProperty(ServiceA.OTHER_SERVICE_2.getName(), "1");
+        nodeMap.put("1", serviceNode1);
+        nodeMap.put("2", serviceNode2);
+
+        branches = StandardControllerServiceProvider.determineEnablingOrder(nodeMap);
+        assertEquals(2, branches.size());
+        ordered = branches.get(0);
+        assertEquals(2, ordered.size());
+        assertTrue(ordered.get(0) == serviceNode2);
+        assertTrue(ordered.get(1) == serviceNode1);
+
+        nodeMap.clear();
+        nodeMap.put("2", serviceNode2);
+        nodeMap.put("1", serviceNode1);
+        branches = StandardControllerServiceProvider.determineEnablingOrder(nodeMap);
+        assertEquals(2, branches.size());
+        ordered = branches.get(1);
+        assertEquals(2, ordered.size());
+        assertTrue(ordered.get(0) == serviceNode2);
+        assertTrue(ordered.get(1) == serviceNode1);
+
+        // add circular dependency once removed. In this case, we won't actually be able to enable these because of the
+        // circular dependency because they will never be valid because they will always depend on a disabled service.
+        // But we want to ensure that the method returns successfully without throwing a StackOverflowException or anything
+        // like that.
+        nodeMap.clear();
+        final ControllerServiceNode serviceNode3 = provider.createControllerService(ServiceA.class.getName(), "3", false);
+        serviceNode1.setProperty(ServiceA.OTHER_SERVICE.getName(), "3");
+        serviceNode3.setProperty(ServiceA.OTHER_SERVICE.getName(), "1");
+        nodeMap.put("1", serviceNode1);
+        nodeMap.put("3", serviceNode3);
+        branches = StandardControllerServiceProvider.determineEnablingOrder(nodeMap);
+        assertEquals(2, branches.size());
+        ordered = branches.get(0);
+        assertEquals(2, ordered.size());
+        assertTrue(ordered.get(0) == serviceNode3);
+        assertTrue(ordered.get(1) == serviceNode1);
+
+        nodeMap.clear();
+        nodeMap.put("3", serviceNode3);
+        nodeMap.put("1", serviceNode1);
+        branches = StandardControllerServiceProvider.determineEnablingOrder(nodeMap);
+        assertEquals(2, branches.size());
+        ordered = branches.get(1);
+        assertEquals(2, ordered.size());
+        assertTrue(ordered.get(0) == serviceNode3);
+        assertTrue(ordered.get(1) == serviceNode1);
+
+        // Add multiple completely disparate branches.
+        nodeMap.clear();
+        serviceNode1.setProperty(ServiceA.OTHER_SERVICE.getName(), "2");
+        final ControllerServiceNode serviceNode4 = provider.createControllerService(ServiceB.class.getName(), "4", false);
+        final ControllerServiceNode serviceNode5 = provider.createControllerService(ServiceB.class.getName(), "5", false);
+        serviceNode3.setProperty(ServiceA.OTHER_SERVICE.getName(), "4");
+        nodeMap.put("1", serviceNode1);
+        nodeMap.put("2", serviceNode2);
+        nodeMap.put("3", serviceNode3);
+        nodeMap.put("4", serviceNode4);
+        nodeMap.put("5", serviceNode5);
+
+        branches = StandardControllerServiceProvider.determineEnablingOrder(nodeMap);
+        assertEquals(5, branches.size());
+
+        ordered = branches.get(0);
+        assertEquals(2, ordered.size());
+        assertTrue(ordered.get(0) == serviceNode2);
+        assertTrue(ordered.get(1) == serviceNode1);
+
+        assertEquals(1, branches.get(1).size());
+        assertTrue(branches.get(1).get(0) == serviceNode2);
+
+        ordered = branches.get(2);
+        assertEquals(2, ordered.size());
+        assertTrue(ordered.get(0) == serviceNode4);
+        assertTrue(ordered.get(1) == serviceNode3);
+
+        assertEquals(1, branches.get(3).size());
+        assertTrue(branches.get(3).get(0) == serviceNode4);
+
+        assertEquals(1, branches.get(4).size());
+        assertTrue(branches.get(4).get(0) == serviceNode5);
+
+        // create 2 branches both dependent on the same service
+        nodeMap.clear();
+        serviceNode1.setProperty(ServiceA.OTHER_SERVICE.getName(), "2");
+        serviceNode3.setProperty(ServiceA.OTHER_SERVICE.getName(), "2");
+        nodeMap.put("1", serviceNode1);
+        nodeMap.put("2", serviceNode2);
+        nodeMap.put("3", serviceNode3);
+
+        branches = StandardControllerServiceProvider.determineEnablingOrder(nodeMap);
+        assertEquals(3, branches.size());
+
+        ordered = branches.get(0);
+        assertEquals(2, ordered.size());
+        assertTrue(ordered.get(0) == serviceNode2);
+        assertTrue(ordered.get(1) == serviceNode1);
+
+        ordered = branches.get(1);
+        assertEquals(1, ordered.size());
+        assertTrue(ordered.get(0) == serviceNode2);
+
+        ordered = branches.get(2);
+        assertEquals(2, ordered.size());
+        assertTrue(ordered.get(0) == serviceNode2);
+        assertTrue(ordered.get(1) == serviceNode3);
+    }
+
+    private ProcessorNode createProcessor(final ProcessScheduler scheduler, final ControllerServiceProvider serviceProvider) {
+        final ProcessorNode procNode = new StandardProcessorNode(new DummyProcessor(), UUID.randomUUID().toString(),
+                new StandardValidationContextFactory(serviceProvider), scheduler, serviceProvider);
+
+        final ProcessGroup group = new StandardProcessGroup(UUID.randomUUID().toString(), serviceProvider, scheduler, null, null);
+        group.addProcessor(procNode);
+        procNode.setProcessGroup(group);
+
+        return procNode;
+    }
+
+    @Test
+    public void testEnableReferencingComponents() {
+        final ProcessScheduler scheduler = createScheduler();
+        final StandardControllerServiceProvider provider = new StandardControllerServiceProvider(null, null);
+        final ControllerServiceNode serviceNode = provider.createControllerService(ServiceA.class.getName(), "1", false);
+
+        final ProcessorNode procNode = createProcessor(scheduler, provider);
+        serviceNode.addReference(procNode);
+
+        procNode.setScheduledState(ScheduledState.STOPPED);
+        provider.unscheduleReferencingComponents(serviceNode);
+        assertEquals(ScheduledState.STOPPED, procNode.getScheduledState());
+
+        procNode.setScheduledState(ScheduledState.RUNNING);
+        provider.unscheduleReferencingComponents(serviceNode);
+        assertEquals(ScheduledState.STOPPED, procNode.getScheduledState());
+
+        procNode.setScheduledState(ScheduledState.DISABLED);
+        provider.unscheduleReferencingComponents(serviceNode);
+        assertEquals(ScheduledState.DISABLED, procNode.getScheduledState());
+    }
+}

http://git-wip-us.apache.org/repos/asf/nifi/blob/3a7ddc6a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/test/java/org/apache/nifi/controller/service/mock/DummyProcessor.java
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/test/java/org/apache/nifi/controller/service/mock/DummyProcessor.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/test/java/org/apache/nifi/controller/service/mock/DummyProcessor.java
index 13898a5..b0f0f9f 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/test/java/org/apache/nifi/controller/service/mock/DummyProcessor.java
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/test/java/org/apache/nifi/controller/service/mock/DummyProcessor.java
@@ -1,48 +1,48 @@
-/*
- * 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.controller.service.mock;
-
-import java.util.ArrayList;
-import java.util.List;
-
-import org.apache.nifi.components.PropertyDescriptor;
-import org.apache.nifi.controller.ControllerService;
-import org.apache.nifi.processor.AbstractProcessor;
-import org.apache.nifi.processor.ProcessContext;
-import org.apache.nifi.processor.ProcessSession;
-import org.apache.nifi.processor.exception.ProcessException;
-
-public class DummyProcessor extends AbstractProcessor {
-
-    public static final PropertyDescriptor SERVICE = new PropertyDescriptor.Builder()
-            .name("Controller Service")
-            .identifiesControllerService(ControllerService.class)
-            .required(true)
-            .build();
-
-    @Override
-    protected List<PropertyDescriptor> getSupportedPropertyDescriptors() {
-        final List<PropertyDescriptor> descriptors = new ArrayList<>();
-        descriptors.add(SERVICE);
-        return descriptors;
-    }
-
-    @Override
-    public void onTrigger(ProcessContext context, ProcessSession session) throws ProcessException {
-    }
-
-}
+/*
+ * 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.controller.service.mock;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.nifi.components.PropertyDescriptor;
+import org.apache.nifi.controller.ControllerService;
+import org.apache.nifi.processor.AbstractProcessor;
+import org.apache.nifi.processor.ProcessContext;
+import org.apache.nifi.processor.ProcessSession;
+import org.apache.nifi.processor.exception.ProcessException;
+
+public class DummyProcessor extends AbstractProcessor {
+
+    public static final PropertyDescriptor SERVICE = new PropertyDescriptor.Builder()
+            .name("Controller Service")
+            .identifiesControllerService(ControllerService.class)
+            .required(true)
+            .build();
+
+    @Override
+    protected List<PropertyDescriptor> getSupportedPropertyDescriptors() {
+        final List<PropertyDescriptor> descriptors = new ArrayList<>();
+        descriptors.add(SERVICE);
+        return descriptors;
+    }
+
+    @Override
+    public void onTrigger(ProcessContext context, ProcessSession session) throws ProcessException {
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/nifi/blob/3a7ddc6a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/test/java/org/apache/nifi/controller/service/mock/ServiceA.java
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/test/java/org/apache/nifi/controller/service/mock/ServiceA.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/test/java/org/apache/nifi/controller/service/mock/ServiceA.java
index f93184b..184c32d 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/test/java/org/apache/nifi/controller/service/mock/ServiceA.java
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/test/java/org/apache/nifi/controller/service/mock/ServiceA.java
@@ -1,48 +1,48 @@
-/*
- * 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.controller.service.mock;
-
-import java.util.ArrayList;
-import java.util.List;
-
-import org.apache.nifi.components.PropertyDescriptor;
-import org.apache.nifi.controller.AbstractControllerService;
-import org.apache.nifi.controller.ControllerService;
-
-public class ServiceA extends AbstractControllerService {
-
-    public static final PropertyDescriptor OTHER_SERVICE = new PropertyDescriptor.Builder()
-            .name("Other Service")
-            .identifiesControllerService(ControllerService.class)
-            .required(true)
-            .build();
-
-    public static final PropertyDescriptor OTHER_SERVICE_2 = new PropertyDescriptor.Builder()
-            .name("Other Service 2")
-            .identifiesControllerService(ControllerService.class)
-            .required(false)
-            .build();
-
-    @Override
-    protected List<PropertyDescriptor> getSupportedPropertyDescriptors() {
-        final List<PropertyDescriptor> descriptors = new ArrayList<>();
-        descriptors.add(OTHER_SERVICE);
-        descriptors.add(OTHER_SERVICE_2);
-        return descriptors;
-    }
-
-}
+/*
+ * 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.controller.service.mock;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.nifi.components.PropertyDescriptor;
+import org.apache.nifi.controller.AbstractControllerService;
+import org.apache.nifi.controller.ControllerService;
+
+public class ServiceA extends AbstractControllerService {
+
+    public static final PropertyDescriptor OTHER_SERVICE = new PropertyDescriptor.Builder()
+            .name("Other Service")
+            .identifiesControllerService(ControllerService.class)
+            .required(true)
+            .build();
+
+    public static final PropertyDescriptor OTHER_SERVICE_2 = new PropertyDescriptor.Builder()
+            .name("Other Service 2")
+            .identifiesControllerService(ControllerService.class)
+            .required(false)
+            .build();
+
+    @Override
+    protected List<PropertyDescriptor> getSupportedPropertyDescriptors() {
+        final List<PropertyDescriptor> descriptors = new ArrayList<>();
+        descriptors.add(OTHER_SERVICE);
+        descriptors.add(OTHER_SERVICE_2);
+        return descriptors;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/nifi/blob/3a7ddc6a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/test/java/org/apache/nifi/controller/service/mock/ServiceB.java
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/test/java/org/apache/nifi/controller/service/mock/ServiceB.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/test/java/org/apache/nifi/controller/service/mock/ServiceB.java
index 070b156..a0867d0 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/test/java/org/apache/nifi/controller/service/mock/ServiceB.java
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/test/java/org/apache/nifi/controller/service/mock/ServiceB.java
@@ -1,23 +1,23 @@
-/*
- * 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.controller.service.mock;
-
-import org.apache.nifi.controller.AbstractControllerService;
-
-public class ServiceB extends AbstractControllerService {
-
-}
+/*
+ * 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.controller.service.mock;
+
+import org.apache.nifi.controller.AbstractControllerService;
+
+public class ServiceB extends AbstractControllerService {
+
+}

http://git-wip-us.apache.org/repos/asf/nifi/blob/3a7ddc6a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/test/java/org/apache/nifi/controller/service/util/TestControllerService.java
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/test/java/org/apache/nifi/controller/service/util/TestControllerService.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/test/java/org/apache/nifi/controller/service/util/TestControllerService.java
index 65ef13f..d972dde 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/test/java/org/apache/nifi/controller/service/util/TestControllerService.java
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/test/java/org/apache/nifi/controller/service/util/TestControllerService.java
@@ -1,61 +1,61 @@
-/*
- * 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.controller.service.util;
-
-import java.util.Collection;
-import java.util.List;
-
-import org.apache.nifi.components.PropertyDescriptor;
-import org.apache.nifi.components.ValidationContext;
-import org.apache.nifi.components.ValidationResult;
-import org.apache.nifi.controller.ControllerService;
-import org.apache.nifi.controller.ControllerServiceInitializationContext;
-import org.apache.nifi.reporting.InitializationException;
-
-public class TestControllerService implements ControllerService {
-
-    @Override
-    public Collection<ValidationResult> validate(ValidationContext context) {
-        return null;
-    }
-
-    @Override
-    public PropertyDescriptor getPropertyDescriptor(String name) {
-        return null;
-    }
-
-    @Override
-    public void onPropertyModified(PropertyDescriptor descriptor,
-            String oldValue, String newValue) {
-    }
-
-    @Override
-    public List<PropertyDescriptor> getPropertyDescriptors() {
-        return null;
-    }
-
-    @Override
-    public String getIdentifier() {
-        return null;
-    }
-
-    @Override
-    public void initialize(ControllerServiceInitializationContext context)
-            throws InitializationException {
-    }
-
-}
+/*
+ * 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.controller.service.util;
+
+import java.util.Collection;
+import java.util.List;
+
+import org.apache.nifi.components.PropertyDescriptor;
+import org.apache.nifi.components.ValidationContext;
+import org.apache.nifi.components.ValidationResult;
+import org.apache.nifi.controller.ControllerService;
+import org.apache.nifi.controller.ControllerServiceInitializationContext;
+import org.apache.nifi.reporting.InitializationException;
+
+public class TestControllerService implements ControllerService {
+
+    @Override
+    public Collection<ValidationResult> validate(ValidationContext context) {
+        return null;
+    }
+
+    @Override
+    public PropertyDescriptor getPropertyDescriptor(String name) {
+        return null;
+    }
+
+    @Override
+    public void onPropertyModified(PropertyDescriptor descriptor,
+            String oldValue, String newValue) {
+    }
+
+    @Override
+    public List<PropertyDescriptor> getPropertyDescriptors() {
+        return null;
+    }
+
+    @Override
+    public String getIdentifier() {
+        return null;
+    }
+
+    @Override
+    public void initialize(ControllerServiceInitializationContext context)
+            throws InitializationException {
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/nifi/blob/3a7ddc6a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-nar-utils/src/test/java/org/apache/nifi/nar/NarUnpackerTest.java
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-nar-utils/src/test/java/org/apache/nifi/nar/NarUnpackerTest.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-nar-utils/src/test/java/org/apache/nifi/nar/NarUnpackerTest.java
index 3d3d6af..882c8c6 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-nar-utils/src/test/java/org/apache/nifi/nar/NarUnpackerTest.java
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-nar-utils/src/test/java/org/apache/nifi/nar/NarUnpackerTest.java
@@ -1,214 +1,214 @@
-/*
- * 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.nar;
-
-import org.apache.nifi.util.NiFiProperties;
-import org.junit.Assert;
-import org.junit.BeforeClass;
-import org.junit.Test;
-
-import java.io.BufferedInputStream;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.net.URISyntaxException;
-import java.nio.file.FileVisitResult;
-import java.nio.file.Files;
-import java.nio.file.Path;
-import java.nio.file.Paths;
-import java.nio.file.SimpleFileVisitor;
-import java.nio.file.attribute.BasicFileAttributes;
-import java.util.HashSet;
-import java.util.Set;
-
-import static java.nio.file.StandardCopyOption.REPLACE_EXISTING;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNull;
-import static org.junit.Assert.assertTrue;
-
-public class NarUnpackerTest {
-
-    @BeforeClass
-    public static void copyResources() throws IOException {
-
-        final Path sourcePath = Paths.get("./src/test/resources");
-        final Path targetPath = Paths.get("./target");
-
-        Files.walkFileTree(sourcePath, new SimpleFileVisitor<Path>() {
-
-            @Override
-            public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs)
-                    throws IOException {
-
-                Path relativeSource = sourcePath.relativize(dir);
-                Path target = targetPath.resolve(relativeSource);
-
-                Files.createDirectories(target);
-
-                return FileVisitResult.CONTINUE;
-
-            }
-
-            @Override
-            public FileVisitResult visitFile(Path file, BasicFileAttributes attrs)
-                    throws IOException {
-
-                Path relativeSource = sourcePath.relativize(file);
-                Path target = targetPath.resolve(relativeSource);
-
-                Files.copy(file, target, REPLACE_EXISTING);
-
-                return FileVisitResult.CONTINUE;
-            }
-        });
-    }
-
-    @Test
-    public void testUnpackNars() {
-
-        NiFiProperties properties = loadSpecifiedProperties("/NarUnpacker/conf/nifi.properties");
-
-        assertEquals("./target/NarUnpacker/lib/",
-                properties.getProperty("nifi.nar.library.directory"));
-        assertEquals("./target/NarUnpacker/lib2/",
-                properties.getProperty("nifi.nar.library.directory.alt"));
-
-        final ExtensionMapping extensionMapping = NarUnpacker.unpackNars(properties);
-
-        assertEquals(2, extensionMapping.getAllExtensionNames().size());
-
-        assertTrue(extensionMapping.getAllExtensionNames().contains(
-                "org.apache.nifi.processors.dummy.one"));
-        assertTrue(extensionMapping.getAllExtensionNames().contains(
-                "org.apache.nifi.processors.dummy.two"));
-        final File extensionsWorkingDir = properties.getExtensionsWorkingDirectory();
-        File[] extensionFiles = extensionsWorkingDir.listFiles();
-
-        Set<String> expectedNars = new HashSet<>();
-        expectedNars.add("dummy-one.nar-unpacked");
-        expectedNars.add("dummy-two.nar-unpacked");
-        assertEquals(expectedNars.size(), extensionFiles.length);
-
-        for (File extensionFile : extensionFiles) {
-            Assert.assertTrue(expectedNars.contains(extensionFile.getName()));
-        }
-    }
-
-    @Test
-    public void testUnpackNarsFromEmptyDir() throws IOException {
-
-        NiFiProperties properties = loadSpecifiedProperties("/NarUnpacker/conf/nifi.properties");
-
-        final File emptyDir = new File("./target/empty/dir");
-        emptyDir.delete();
-        emptyDir.deleteOnExit();
-        assertTrue(emptyDir.mkdirs());
-
-        properties.setProperty("nifi.nar.library.directory.alt", emptyDir.toString());
-
-        final ExtensionMapping extensionMapping = NarUnpacker.unpackNars(properties);
-
-        assertEquals(1, extensionMapping.getAllExtensionNames().size());
-        assertTrue(extensionMapping.getAllExtensionNames().contains(
-                "org.apache.nifi.processors.dummy.one"));
-
-        final File extensionsWorkingDir = properties.getExtensionsWorkingDirectory();
-        File[] extensionFiles = extensionsWorkingDir.listFiles();
-
-        assertEquals(1, extensionFiles.length);
-        assertEquals("dummy-one.nar-unpacked", extensionFiles[0].getName());
-    }
-
-    @Test
-    public void testUnpackNarsFromNonExistantDir() {
-
-        final File nonExistantDir = new File("./target/this/dir/should/not/exist/");
-        nonExistantDir.delete();
-        nonExistantDir.deleteOnExit();
-
-        NiFiProperties properties = loadSpecifiedProperties("/NarUnpacker/conf/nifi.properties");
-        properties.setProperty("nifi.nar.library.directory.alt", nonExistantDir.toString());
-
-        final ExtensionMapping extensionMapping = NarUnpacker.unpackNars(properties);
-
-        assertTrue(extensionMapping.getAllExtensionNames().contains(
-                "org.apache.nifi.processors.dummy.one"));
-
-        assertEquals(1, extensionMapping.getAllExtensionNames().size());
-
-        final File extensionsWorkingDir = properties.getExtensionsWorkingDirectory();
-        File[] extensionFiles = extensionsWorkingDir.listFiles();
-
-        assertEquals(1, extensionFiles.length);
-        assertEquals("dummy-one.nar-unpacked", extensionFiles[0].getName());
-    }
-
-    @Test
-    public void testUnpackNarsFromNonDir() throws IOException {
-
-        final File nonDir = new File("./target/file.txt");
-        nonDir.createNewFile();
-        nonDir.deleteOnExit();
-
-        NiFiProperties properties = loadSpecifiedProperties("/NarUnpacker/conf/nifi.properties");
-        properties.setProperty("nifi.nar.library.directory.alt", nonDir.toString());
-
-        final ExtensionMapping extensionMapping = NarUnpacker.unpackNars(properties);
-
-        assertNull(extensionMapping);
-    }
-
-    private NiFiProperties loadSpecifiedProperties(String propertiesFile) {
-        String filePath;
-        try {
-            filePath = NarUnpackerTest.class.getResource(propertiesFile).toURI().getPath();
-        } catch (URISyntaxException ex) {
-            throw new RuntimeException("Cannot load properties file due to "
-                    + ex.getLocalizedMessage(), ex);
-        }
-        System.setProperty(NiFiProperties.PROPERTIES_FILE_PATH, filePath);
-
-        NiFiProperties properties = NiFiProperties.getInstance();
-
-        // clear out existing properties
-        for (String prop : properties.stringPropertyNames()) {
-            properties.remove(prop);
-        }
-
-        InputStream inStream = null;
-        try {
-            inStream = new BufferedInputStream(new FileInputStream(filePath));
-            properties.load(inStream);
-        } catch (final Exception ex) {
-            throw new RuntimeException("Cannot load properties file due to "
-                    + ex.getLocalizedMessage(), ex);
-        } finally {
-            if (null != inStream) {
-                try {
-                    inStream.close();
-                } catch (final Exception ex) {
-                    /**
-                     * do nothing *
-                     */
-                }
-            }
-        }
-
-        return properties;
-    }
+/*
+ * 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.nar;
+
+import org.apache.nifi.util.NiFiProperties;
+import org.junit.Assert;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+import java.io.BufferedInputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URISyntaxException;
+import java.nio.file.FileVisitResult;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.nio.file.SimpleFileVisitor;
+import java.nio.file.attribute.BasicFileAttributes;
+import java.util.HashSet;
+import java.util.Set;
+
+import static java.nio.file.StandardCopyOption.REPLACE_EXISTING;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+
+public class NarUnpackerTest {
+
+    @BeforeClass
+    public static void copyResources() throws IOException {
+
+        final Path sourcePath = Paths.get("./src/test/resources");
+        final Path targetPath = Paths.get("./target");
+
+        Files.walkFileTree(sourcePath, new SimpleFileVisitor<Path>() {
+
+            @Override
+            public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs)
+                    throws IOException {
+
+                Path relativeSource = sourcePath.relativize(dir);
+                Path target = targetPath.resolve(relativeSource);
+
+                Files.createDirectories(target);
+
+                return FileVisitResult.CONTINUE;
+
+            }
+
+            @Override
+            public FileVisitResult visitFile(Path file, BasicFileAttributes attrs)
+                    throws IOException {
+
+                Path relativeSource = sourcePath.relativize(file);
+                Path target = targetPath.resolve(relativeSource);
+
+                Files.copy(file, target, REPLACE_EXISTING);
+
+                return FileVisitResult.CONTINUE;
+            }
+        });
+    }
+
+    @Test
+    public void testUnpackNars() {
+
+        NiFiProperties properties = loadSpecifiedProperties("/NarUnpacker/conf/nifi.properties");
+
+        assertEquals("./target/NarUnpacker/lib/",
+                properties.getProperty("nifi.nar.library.directory"));
+        assertEquals("./target/NarUnpacker/lib2/",
+                properties.getProperty("nifi.nar.library.directory.alt"));
+
+        final ExtensionMapping extensionMapping = NarUnpacker.unpackNars(properties);
+
+        assertEquals(2, extensionMapping.getAllExtensionNames().size());
+
+        assertTrue(extensionMapping.getAllExtensionNames().contains(
+                "org.apache.nifi.processors.dummy.one"));
+        assertTrue(extensionMapping.getAllExtensionNames().contains(
+                "org.apache.nifi.processors.dummy.two"));
+        final File extensionsWorkingDir = properties.getExtensionsWorkingDirectory();
+        File[] extensionFiles = extensionsWorkingDir.listFiles();
+
+        Set<String> expectedNars = new HashSet<>();
+        expectedNars.add("dummy-one.nar-unpacked");
+        expectedNars.add("dummy-two.nar-unpacked");
+        assertEquals(expectedNars.size(), extensionFiles.length);
+
+        for (File extensionFile : extensionFiles) {
+            Assert.assertTrue(expectedNars.contains(extensionFile.getName()));
+        }
+    }
+
+    @Test
+    public void testUnpackNarsFromEmptyDir() throws IOException {
+
+        NiFiProperties properties = loadSpecifiedProperties("/NarUnpacker/conf/nifi.properties");
+
+        final File emptyDir = new File("./target/empty/dir");
+        emptyDir.delete();
+        emptyDir.deleteOnExit();
+        assertTrue(emptyDir.mkdirs());
+
+        properties.setProperty("nifi.nar.library.directory.alt", emptyDir.toString());
+
+        final ExtensionMapping extensionMapping = NarUnpacker.unpackNars(properties);
+
+        assertEquals(1, extensionMapping.getAllExtensionNames().size());
+        assertTrue(extensionMapping.getAllExtensionNames().contains(
+                "org.apache.nifi.processors.dummy.one"));
+
+        final File extensionsWorkingDir = properties.getExtensionsWorkingDirectory();
+        File[] extensionFiles = extensionsWorkingDir.listFiles();
+
+        assertEquals(1, extensionFiles.length);
+        assertEquals("dummy-one.nar-unpacked", extensionFiles[0].getName());
+    }
+
+    @Test
+    public void testUnpackNarsFromNonExistantDir() {
+
+        final File nonExistantDir = new File("./target/this/dir/should/not/exist/");
+        nonExistantDir.delete();
+        nonExistantDir.deleteOnExit();
+
+        NiFiProperties properties = loadSpecifiedProperties("/NarUnpacker/conf/nifi.properties");
+        properties.setProperty("nifi.nar.library.directory.alt", nonExistantDir.toString());
+
+        final ExtensionMapping extensionMapping = NarUnpacker.unpackNars(properties);
+
+        assertTrue(extensionMapping.getAllExtensionNames().contains(
+                "org.apache.nifi.processors.dummy.one"));
+
+        assertEquals(1, extensionMapping.getAllExtensionNames().size());
+
+        final File extensionsWorkingDir = properties.getExtensionsWorkingDirectory();
+        File[] extensionFiles = extensionsWorkingDir.listFiles();
+
+        assertEquals(1, extensionFiles.length);
+        assertEquals("dummy-one.nar-unpacked", extensionFiles[0].getName());
+    }
+
+    @Test
+    public void testUnpackNarsFromNonDir() throws IOException {
+
+        final File nonDir = new File("./target/file.txt");
+        nonDir.createNewFile();
+        nonDir.deleteOnExit();
+
+        NiFiProperties properties = loadSpecifiedProperties("/NarUnpacker/conf/nifi.properties");
+        properties.setProperty("nifi.nar.library.directory.alt", nonDir.toString());
+
+        final ExtensionMapping extensionMapping = NarUnpacker.unpackNars(properties);
+
+        assertNull(extensionMapping);
+    }
+
+    private NiFiProperties loadSpecifiedProperties(String propertiesFile) {
+        String filePath;
+        try {
+            filePath = NarUnpackerTest.class.getResource(propertiesFile).toURI().getPath();
+        } catch (URISyntaxException ex) {
+            throw new RuntimeException("Cannot load properties file due to "
+                    + ex.getLocalizedMessage(), ex);
+        }
+        System.setProperty(NiFiProperties.PROPERTIES_FILE_PATH, filePath);
+
+        NiFiProperties properties = NiFiProperties.getInstance();
+
+        // clear out existing properties
+        for (String prop : properties.stringPropertyNames()) {
+            properties.remove(prop);
+        }
+
+        InputStream inStream = null;
+        try {
+            inStream = new BufferedInputStream(new FileInputStream(filePath));
+            properties.load(inStream);
+        } catch (final Exception ex) {
+            throw new RuntimeException("Cannot load properties file due to "
+                    + ex.getLocalizedMessage(), ex);
+        } finally {
+            if (null != inStream) {
+                try {
+                    inStream.close();
+                } catch (final Exception ex) {
+                    /**
+                     * do nothing *
+                     */
+                }
+            }
+        }
+
+        return properties;
+    }
 }
\ No newline at end of file