You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nifi.apache.org by jo...@apache.org on 2014/12/15 11:14:53 UTC
[08/12] incubator-nifi git commit: NIFI-169 well it finally all
builds. There is a classpath issue still to sort out which impacts startup
http://git-wip-us.apache.org/repos/asf/incubator-nifi/blob/19d4a150/nar-bundles/distributed-cache-services-bundle/distributed-cache-server/src/main/java/org/apache/nifi/distributed/cache/server/set/SimpleSetCache.java
----------------------------------------------------------------------
diff --git a/nar-bundles/distributed-cache-services-bundle/distributed-cache-server/src/main/java/org/apache/nifi/distributed/cache/server/set/SimpleSetCache.java b/nar-bundles/distributed-cache-services-bundle/distributed-cache-server/src/main/java/org/apache/nifi/distributed/cache/server/set/SimpleSetCache.java
deleted file mode 100644
index 77d6481..0000000
--- a/nar-bundles/distributed-cache-services-bundle/distributed-cache-server/src/main/java/org/apache/nifi/distributed/cache/server/set/SimpleSetCache.java
+++ /dev/null
@@ -1,117 +0,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.
- */
-package org.apache.nifi.distributed.cache.server.set;
-
-import java.io.IOException;
-import java.nio.ByteBuffer;
-import java.nio.charset.StandardCharsets;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.SortedMap;
-import java.util.TreeMap;
-
-import org.apache.nifi.distributed.cache.server.EvictionPolicy;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public class SimpleSetCache implements SetCache {
- private static final Logger logger = LoggerFactory.getLogger(SimpleSetCache.class);
-
- private final Map<ByteBuffer, SetCacheRecord> cache = new HashMap<>();
- private final SortedMap<SetCacheRecord, ByteBuffer> inverseCacheMap;
-
- private final String serviceIdentifier;
-
- private final int maxSize;
-
- public SimpleSetCache(final String serviceIdentifier, final int maxSize, final EvictionPolicy evictionPolicy) {
- inverseCacheMap = new TreeMap<>(evictionPolicy.getComparator());
- this.serviceIdentifier = serviceIdentifier;
- this.maxSize = maxSize;
- }
-
- private synchronized SetCacheRecord evict() {
- if ( cache.size() < maxSize ) {
- return null;
- }
-
- final SetCacheRecord recordToEvict = inverseCacheMap.firstKey();
- final ByteBuffer valueToEvict = inverseCacheMap.remove(recordToEvict);
- cache.remove(valueToEvict);
-
- if ( logger.isDebugEnabled() ) {
- logger.debug("Evicting value {} from cache", new String(valueToEvict.array(), StandardCharsets.UTF_8));
- }
-
- return recordToEvict;
- }
-
- @Override
- public synchronized SetCacheResult addIfAbsent(final ByteBuffer value) {
- final SetCacheRecord record = cache.get(value);
- if ( record == null ) {
- final SetCacheRecord evicted = evict();
- final SetCacheRecord newRecord = new SetCacheRecord(value);
- cache.put(value, newRecord);
- inverseCacheMap.put(newRecord, value);
- return new SetCacheResult(true, newRecord, evicted);
- } else {
- // We have to remove the record and add it again in order to cause the Map to stay sorted
- inverseCacheMap.remove(record);
- record.hit();
- inverseCacheMap.put(record, value);
-
- return new SetCacheResult(false, record, null);
- }
- }
-
- @Override
- public synchronized SetCacheResult contains(final ByteBuffer value) {
- final SetCacheRecord record = cache.get(value);
- if ( record == null ) {
- return new SetCacheResult(false, null, null);
- } else {
- // We have to remove the record and add it again in order to cause the Map to stay sorted
- inverseCacheMap.remove(record);
- record.hit();
- inverseCacheMap.put(record, value);
-
- return new SetCacheResult(true, record, null);
- }
- }
-
- @Override
- public synchronized SetCacheResult remove(final ByteBuffer value) {
- final SetCacheRecord record = cache.remove(value);
- if ( record == null ) {
- return new SetCacheResult(false, null, null);
- } else {
- inverseCacheMap.remove(record);
- return new SetCacheResult(true, record, null);
- }
- }
-
- @Override
- public String toString() {
- return "SimpleSetCache[service id=" + serviceIdentifier + "]";
- }
-
- @Override
- public void shutdown() throws IOException {
- }
-}
http://git-wip-us.apache.org/repos/asf/incubator-nifi/blob/19d4a150/nar-bundles/distributed-cache-services-bundle/distributed-cache-server/src/main/resources/META-INF/services/org.apache.nifi.controller.ControllerService
----------------------------------------------------------------------
diff --git a/nar-bundles/distributed-cache-services-bundle/distributed-cache-server/src/main/resources/META-INF/services/org.apache.nifi.controller.ControllerService b/nar-bundles/distributed-cache-services-bundle/distributed-cache-server/src/main/resources/META-INF/services/org.apache.nifi.controller.ControllerService
deleted file mode 100644
index 0509c7c..0000000
--- a/nar-bundles/distributed-cache-services-bundle/distributed-cache-server/src/main/resources/META-INF/services/org.apache.nifi.controller.ControllerService
+++ /dev/null
@@ -1,16 +0,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.
-org.apache.nifi.distributed.cache.server.DistributedSetCacheServer
-org.apache.nifi.distributed.cache.server.map.DistributedMapCacheServer
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-nifi/blob/19d4a150/nar-bundles/distributed-cache-services-bundle/distributed-cache-server/src/main/resources/docs/org.apache.nifi.distributed.cache.server.map.DistributedMapCacheServer/index.html
----------------------------------------------------------------------
diff --git a/nar-bundles/distributed-cache-services-bundle/distributed-cache-server/src/main/resources/docs/org.apache.nifi.distributed.cache.server.map.DistributedMapCacheServer/index.html b/nar-bundles/distributed-cache-services-bundle/distributed-cache-server/src/main/resources/docs/org.apache.nifi.distributed.cache.server.map.DistributedMapCacheServer/index.html
deleted file mode 100644
index dca3aa1..0000000
--- a/nar-bundles/distributed-cache-services-bundle/distributed-cache-server/src/main/resources/docs/org.apache.nifi.distributed.cache.server.map.DistributedMapCacheServer/index.html
+++ /dev/null
@@ -1,82 +0,0 @@
-<!DOCTYPE html>
-<html lang="en">
-<!--
- 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.
--->
-<head>
-<meta charset="utf-8" />
-<title>Distributed Map Cache Client Service</title>
-<link rel="stylesheet" href="../../css/component-usage.css" type="text/css" />
-</head>
-
-<body>
- <h2>Description:</h2>
-
- <p>A Controller Service that starts an embedded server and listens for connections from clients. The
- server provides the ability to query the cache, add data to the cache, and remove data from the cache.</p>
-
-
-
- <p>
- <strong>Properties:</strong>
- </p>
- <p>In the list below, the names of required properties appear
- in bold. Any other properties (not in bold) are considered optional.
- If a property has a default value, it is indicated. If a property
- supports the use of the NiFi Expression Language (or simply,
- "expression language"), that is also indicated.</p>
-
- <ul>
- <li><strong>Port</strong>
- <ul>
- <li>The port to listen on for incoming connections</li>
- <li>Default value: 4557</li>
- <li>Supports expression language: false</li>
- </ul></li>
- <li>SSL Context Service
- <ul>
- <li>If specified, this service will be used to create an SSL Context that will be used to secure communications; if not specified, communications will not be secure</li>
- <li>Default value: no default</li>
- <li>Supports expression language: false</li>
- </ul></li>
- <li><strong>Maximum Cache Entries</strong>
- <ul>
- <li>The maximum number of cache entries that the cache can hold
- <li>Default value: 10,000</li>
- <li>Supports expression language: false</li>
- </ul></li>
- <li><strong>Eviction Strategy</strong>
- <ul>
- <li>Determines which strategy should be used to evict values from the cache to make room for new entries. Valid values:
- <code>Least Frequently Used</code>, <code>Least Recently Used</code>, and <code>First In, First Out</code>
- <li>Default value: Least Frequently Used</li>
- <li>Supports expression language: false</li>
- </ul></li>
- <li>Persistence Directory
- <ul>
- <li>If specified, the cache will be persisted in the given directory; if not specified, the cache will be in-memory only</li>
- <li>Default value: no default (in-memory)</li>
- <li>Supports expression language: true - JVM and System Properties Only</li>
- </ul></li>
- </ul>
-
-
- <i>See Also:</i>
- <ul>
- <li><a href="../org.apache.nifi.distributed.cache.client.DistributedMapCacheClientService/index.html">Distributed Map Cache Client Service</a></li>
- <li><a href="../org.apache.nifi.ssl.StandardSSLContextService/index.html">Standard SSL Context Service</a></li>
- </ul>
-
-</body>
-</html>
http://git-wip-us.apache.org/repos/asf/incubator-nifi/blob/19d4a150/nar-bundles/distributed-cache-services-bundle/distributed-cache-server/src/test/java/org/apache/nifi/distributed/cache/server/TestServerAndClient.java
----------------------------------------------------------------------
diff --git a/nar-bundles/distributed-cache-services-bundle/distributed-cache-server/src/test/java/org/apache/nifi/distributed/cache/server/TestServerAndClient.java b/nar-bundles/distributed-cache-services-bundle/distributed-cache-server/src/test/java/org/apache/nifi/distributed/cache/server/TestServerAndClient.java
deleted file mode 100644
index b5f3fd6..0000000
--- a/nar-bundles/distributed-cache-services-bundle/distributed-cache-server/src/test/java/org/apache/nifi/distributed/cache/server/TestServerAndClient.java
+++ /dev/null
@@ -1,530 +0,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.
- */
-package org.apache.nifi.distributed.cache.server;
-
-import org.apache.nifi.distributed.cache.server.DistributedSetCacheServer;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
-
-import java.io.File;
-import java.io.IOException;
-import java.io.OutputStream;
-import java.net.ConnectException;
-import java.nio.charset.StandardCharsets;
-import java.util.HashMap;
-import java.util.Map;
-
-import org.apache.nifi.components.PropertyDescriptor;
-import org.apache.nifi.distributed.cache.client.Deserializer;
-import org.apache.nifi.distributed.cache.client.DistributedMapCacheClientService;
-import org.apache.nifi.distributed.cache.client.DistributedSetCacheClientService;
-import org.apache.nifi.distributed.cache.client.Serializer;
-import org.apache.nifi.distributed.cache.client.exception.DeserializationException;
-import org.apache.nifi.distributed.cache.server.map.DistributedMapCacheServer;
-import org.apache.nifi.reporting.InitializationException;
-import org.apache.nifi.ssl.SSLContextService.ClientAuth;
-import org.apache.nifi.ssl.StandardSSLContextService;
-import org.apache.nifi.util.MockConfigurationContext;
-import org.apache.nifi.util.MockControllerServiceInitializationContext;
-
-import org.apache.commons.lang3.SerializationException;
-import org.junit.Ignore;
-import org.junit.Test;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public class TestServerAndClient {
-
- private static Logger LOGGER;
-
- static {
- System.setProperty("org.slf4j.simpleLogger.defaultLogLevel", "info");
- System.setProperty("org.slf4j.simpleLogger.showDateTime", "true");
- System.setProperty("org.slf4j.simpleLogger.log.nifi.distributed.cache.server.AbstractCacheServer", "debug");
- System.setProperty("org.slf4j.simpleLogger.log.nifi.distributed.cache.client.DistributedMapCacheClientService", "debug");
- System.setProperty("org.slf4j.simpleLogger.log.nifi.distributed.cache.server.TestServerAndClient", "debug");
- System.setProperty("org.slf4j.simpleLogger.log.nifi.remote.io.socket.ssl.SSLSocketChannel", "trace");
- LOGGER = LoggerFactory.getLogger(TestServerAndClient.class);
- }
-
- @Test
- public void testNonPersistentSetServerAndClient() throws InitializationException, IOException {
- LOGGER.info("Testing " + Thread.currentThread().getStackTrace()[1].getMethodName());
- // Create server
- final DistributedSetCacheServer server = new DistributedSetCacheServer();
- MockControllerServiceInitializationContext serverInitContext = new MockControllerServiceInitializationContext(server, "server");
- server.initialize(serverInitContext);
-
- final Map<PropertyDescriptor, String> serverProperties = new HashMap<>();
- final MockConfigurationContext serverContext = new MockConfigurationContext(serverProperties, serverInitContext.getControllerServiceLookup());
- server.startServer(serverContext);
-
- final DistributedSetCacheClientService client = createClient();
- final Serializer<String> serializer = new StringSerializer();
- final boolean added = client.addIfAbsent("test", serializer);
- assertTrue(added);
-
- final boolean contains = client.contains("test", serializer);
- assertTrue(contains);
-
- final boolean addedAgain = client.addIfAbsent("test", serializer);
- assertFalse(addedAgain);
-
- final boolean removed = client.remove("test", serializer);
- assertTrue(removed);
-
- final boolean containedAfterRemove = client.contains("test", serializer);
- assertFalse(containedAfterRemove);
-
- server.shutdownServer();
- }
-
- @Test
- public void testPersistentSetServerAndClient() throws InitializationException, IOException {
- LOGGER.info("Testing " + Thread.currentThread().getStackTrace()[1].getMethodName());
- // Create server
- final DistributedSetCacheServer server = new DistributedSetCacheServer();
- MockControllerServiceInitializationContext serverInitContext = new MockControllerServiceInitializationContext(server, "server");
- server.initialize(serverInitContext);
-
- final File dataFile = new File("target/cache-data");
- deleteRecursively(dataFile);
-
- final Map<PropertyDescriptor, String> serverProperties = new HashMap<>();
- serverProperties.put(DistributedSetCacheServer.PERSISTENCE_PATH, dataFile.getAbsolutePath());
- final MockConfigurationContext serverContext = new MockConfigurationContext(serverProperties, serverInitContext.getControllerServiceLookup());
- server.startServer(serverContext);
-
- final DistributedSetCacheClientService client = createClient();
- final Serializer<String> serializer = new StringSerializer();
- final boolean added = client.addIfAbsent("test", serializer);
- final boolean added2 = client.addIfAbsent("test2", serializer);
- assertTrue(added);
- assertTrue(added2);
-
- final boolean contains = client.contains("test", serializer);
- final boolean contains2 = client.contains("test2", serializer);
- assertTrue(contains);
- assertTrue(contains2);
-
- final boolean addedAgain = client.addIfAbsent("test", serializer);
- assertFalse(addedAgain);
-
- final boolean removed = client.remove("test", serializer);
- assertTrue(removed);
-
- final boolean containedAfterRemove = client.contains("test", serializer);
- assertFalse(containedAfterRemove);
-
- server.shutdownServer();
-
- final DistributedSetCacheServer newServer = new DistributedSetCacheServer();
- MockControllerServiceInitializationContext newServerInitContext = new MockControllerServiceInitializationContext(newServer, "server2");
- newServer.initialize(newServerInitContext);
-
- final MockConfigurationContext newServerContext = new MockConfigurationContext(serverProperties,
- newServerInitContext.getControllerServiceLookup());
- newServer.startServer(newServerContext);
-
- assertFalse(client.contains("test", serializer));
- assertTrue(client.contains("test2", serializer));
-
- newServer.shutdownServer();
- }
-
- @Test
- public void testPersistentSetServerAndClientWithLFUEvictions() throws InitializationException, IOException {
- LOGGER.info("Testing " + Thread.currentThread().getStackTrace()[1].getMethodName());
- // Create server
- final DistributedSetCacheServer server = new DistributedSetCacheServer();
- MockControllerServiceInitializationContext serverInitContext = new MockControllerServiceInitializationContext(server, "server");
- server.initialize(serverInitContext);
-
- final File dataFile = new File("target/cache-data");
- deleteRecursively(dataFile);
-
- final Map<PropertyDescriptor, String> serverProperties = new HashMap<>();
- serverProperties.put(DistributedSetCacheServer.PERSISTENCE_PATH, dataFile.getAbsolutePath());
- serverProperties.put(DistributedSetCacheServer.MAX_CACHE_ENTRIES, "3");
-
- final MockConfigurationContext serverContext = new MockConfigurationContext(serverProperties, serverInitContext.getControllerServiceLookup());
- server.startServer(serverContext);
-
- final DistributedSetCacheClientService client = createClient();
- final Serializer<String> serializer = new StringSerializer();
- final boolean added = client.addIfAbsent("test", serializer);
- waitABit();
- final boolean added2 = client.addIfAbsent("test2", serializer);
- waitABit();
- final boolean added3 = client.addIfAbsent("test3", serializer);
- waitABit();
- assertTrue(added);
- assertTrue(added2);
- assertTrue(added3);
-
- final boolean contains = client.contains("test", serializer);
- final boolean contains2 = client.contains("test2", serializer);
- assertTrue(contains);
- assertTrue(contains2);
-
- final boolean addedAgain = client.addIfAbsent("test", serializer);
- assertFalse(addedAgain);
-
- final boolean added4 = client.addIfAbsent("test4", serializer);
- assertTrue(added4);
-
- // ensure that added3 was evicted because it was used least frequently
- assertFalse(client.contains("test3", serializer));
-
- server.shutdownServer();
-
- final DistributedSetCacheServer newServer = new DistributedSetCacheServer();
- MockControllerServiceInitializationContext newServerInitContext = new MockControllerServiceInitializationContext(newServer, "server2");
- newServer.initialize(newServerInitContext);
-
- final MockConfigurationContext newServerContext = new MockConfigurationContext(serverProperties,
- newServerInitContext.getControllerServiceLookup());
- newServer.startServer(newServerContext);
-
- assertTrue(client.contains("test", serializer));
- assertTrue(client.contains("test2", serializer));
- assertFalse(client.contains("test3", serializer));
- assertTrue(client.contains("test4", serializer));
-
- newServer.shutdownServer();
- }
-
- @Test
- public void testPersistentSetServerAndClientWithFIFOEvictions() throws InitializationException, IOException {
- LOGGER.info("Testing " + Thread.currentThread().getStackTrace()[1].getMethodName());
- // Create server
- final DistributedSetCacheServer server = new DistributedSetCacheServer();
- MockControllerServiceInitializationContext serverInitContext = new MockControllerServiceInitializationContext(server, "server");
- server.initialize(serverInitContext);
-
- final File dataFile = new File("target/cache-data");
- deleteRecursively(dataFile);
-
- final Map<PropertyDescriptor, String> serverProperties = new HashMap<>();
- serverProperties.put(DistributedSetCacheServer.PERSISTENCE_PATH, dataFile.getAbsolutePath());
- serverProperties.put(DistributedSetCacheServer.MAX_CACHE_ENTRIES, "3");
- serverProperties.put(DistributedSetCacheServer.EVICTION_POLICY, DistributedSetCacheServer.EVICTION_STRATEGY_FIFO);
-
- final MockConfigurationContext serverContext = new MockConfigurationContext(serverProperties, serverInitContext.getControllerServiceLookup());
- server.startServer(serverContext);
-
- final DistributedSetCacheClientService client = createClient();
- final Serializer<String> serializer = new StringSerializer();
-
- // add 3 entries to the cache. But, if we add too fast, we'll have the same millisecond
- // for the entry time so we don't know which entry will be evicted. So we wait a few millis in between
- final boolean added = client.addIfAbsent("test", serializer);
- waitABit();
- final boolean added2 = client.addIfAbsent("test2", serializer);
- waitABit();
- final boolean added3 = client.addIfAbsent("test3", serializer);
- waitABit();
-
- assertTrue(added);
- assertTrue(added2);
- assertTrue(added3);
-
- final boolean contains = client.contains("test", serializer);
- final boolean contains2 = client.contains("test2", serializer);
- assertTrue(contains);
- assertTrue(contains2);
-
- final boolean addedAgain = client.addIfAbsent("test", serializer);
- assertFalse(addedAgain);
-
- final boolean added4 = client.addIfAbsent("test4", serializer);
- assertTrue(added4);
-
- // ensure that added3 was evicted because it was used least frequently
- assertFalse(client.contains("test", serializer));
- assertTrue(client.contains("test3", serializer));
-
- server.shutdownServer();
-
- final DistributedSetCacheServer newServer = new DistributedSetCacheServer();
- MockControllerServiceInitializationContext newServerInitContext = new MockControllerServiceInitializationContext(newServer, "server2");
- newServer.initialize(newServerInitContext);
-
- final MockConfigurationContext newServerContext = new MockConfigurationContext(serverProperties,
- newServerInitContext.getControllerServiceLookup());
- newServer.startServer(newServerContext);
-
- assertFalse(client.contains("test", serializer));
- assertTrue(client.contains("test2", serializer));
- assertTrue(client.contains("test3", serializer));
- assertTrue(client.contains("test4", serializer));
-
- newServer.shutdownServer();
- }
-
- @Test
- public void testNonPersistentMapServerAndClient() throws InitializationException, IOException, InterruptedException {
- LOGGER.info("Testing " + Thread.currentThread().getStackTrace()[1].getMethodName());
- // Create server
- final DistributedMapCacheServer server = new DistributedMapCacheServer();
- MockControllerServiceInitializationContext serverInitContext = new MockControllerServiceInitializationContext(server, "server");
- server.initialize(serverInitContext);
-
- final Map<PropertyDescriptor, String> serverProperties = new HashMap<>();
- final MockConfigurationContext serverContext = new MockConfigurationContext(serverProperties, serverInitContext.getControllerServiceLookup());
- server.startServer(serverContext);
-
- DistributedMapCacheClientService client = new DistributedMapCacheClientService();
- MockControllerServiceInitializationContext clientInitContext = new MockControllerServiceInitializationContext(client, "client");
- client.initialize(clientInitContext);
-
- final Map<PropertyDescriptor, String> clientProperties = new HashMap<>();
- clientProperties.put(DistributedMapCacheClientService.HOSTNAME, "localhost");
- clientProperties.put(DistributedMapCacheClientService.COMMUNICATIONS_TIMEOUT, "360 secs");
- MockConfigurationContext clientContext = new MockConfigurationContext(clientProperties, clientInitContext.getControllerServiceLookup());
- client.cacheConfig(clientContext);
- final Serializer<String> valueSerializer = new StringSerializer();
- final Serializer<String> keySerializer = new StringSerializer();
- final Deserializer<String> deserializer = new StringDeserializer();
-
- final String original = client.getAndPutIfAbsent("testKey", "test", keySerializer, valueSerializer, deserializer);
- assertEquals(null, original);
- LOGGER.debug("end getAndPutIfAbsent");
-
- final boolean contains = client.containsKey("testKey", keySerializer);
- assertTrue(contains);
- LOGGER.debug("end containsKey");
-
- final boolean added = client.putIfAbsent("testKey", "test", keySerializer, valueSerializer);
- assertFalse(added);
- LOGGER.debug("end putIfAbsent");
-
- final String originalAfterPut = client.getAndPutIfAbsent("testKey", "test", keySerializer, valueSerializer, deserializer);
- assertEquals("test", originalAfterPut);
- LOGGER.debug("end getAndPutIfAbsent");
-
- final boolean removed = client.remove("testKey", keySerializer);
- assertTrue(removed);
- LOGGER.debug("end remove");
-
- final boolean containedAfterRemove = client.containsKey("testKey", keySerializer);
- assertFalse(containedAfterRemove);
-
- client.putIfAbsent("testKey", "test", keySerializer, valueSerializer);
- client.close();
- try {
- client.containsKey("testKey", keySerializer);
- fail("Should be closed and not accessible");
- } catch (Exception e) {
-
- }
- client = null;
- clientInitContext = null;
- clientContext = null;
-
- DistributedMapCacheClientService client2 = new DistributedMapCacheClientService();
-
- MockControllerServiceInitializationContext clientInitContext2 = new MockControllerServiceInitializationContext(client2, "client2");
- client2.initialize(clientInitContext2);
-
- MockConfigurationContext clientContext2 = new MockConfigurationContext(clientProperties,
- clientInitContext2.getControllerServiceLookup());
- client2.cacheConfig(clientContext2);
- assertFalse(client2.putIfAbsent("testKey", "test", keySerializer, valueSerializer));
- assertTrue(client2.containsKey("testKey", keySerializer));
- server.shutdownServer();
- Thread.sleep(1000);
- try {
- client2.containsKey("testKey", keySerializer);
- fail("Should have blown exception!");
- } catch (ConnectException e) {
- client2 = null;
- clientContext2 = null;
- clientInitContext2 = null;
- }
- Thread.sleep(2000);
- System.gc();
- LOGGER.debug("end testNonPersistentMapServerAndClient");
- }
-
- @Test
- public void testClientTermination() throws InitializationException, IOException, InterruptedException {
- LOGGER.info("Testing " + Thread.currentThread().getStackTrace()[1].getMethodName());
- // Create server
- final DistributedMapCacheServer server = new DistributedMapCacheServer();
- MockControllerServiceInitializationContext serverInitContext = new MockControllerServiceInitializationContext(server, "server");
- server.initialize(serverInitContext);
-
- final Map<PropertyDescriptor, String> serverProperties = new HashMap<>();
- final MockConfigurationContext serverContext = new MockConfigurationContext(serverProperties, serverInitContext.getControllerServiceLookup());
- server.startServer(serverContext);
-
- DistributedMapCacheClientService client = new DistributedMapCacheClientService();
- MockControllerServiceInitializationContext clientInitContext = new MockControllerServiceInitializationContext(client, "client");
- client.initialize(clientInitContext);
-
- final Map<PropertyDescriptor, String> clientProperties = new HashMap<>();
- clientProperties.put(DistributedMapCacheClientService.HOSTNAME, "localhost");
- clientProperties.put(DistributedMapCacheClientService.COMMUNICATIONS_TIMEOUT, "360 secs");
- MockConfigurationContext clientContext = new MockConfigurationContext(clientProperties, clientInitContext.getControllerServiceLookup());
- client.cacheConfig(clientContext);
- final Serializer<String> valueSerializer = new StringSerializer();
- final Serializer<String> keySerializer = new StringSerializer();
- final Deserializer<String> deserializer = new StringDeserializer();
-
- final String original = client.getAndPutIfAbsent("testKey", "test", keySerializer, valueSerializer, deserializer);
- assertEquals(null, original);
-
- final boolean contains = client.containsKey("testKey", keySerializer);
- assertTrue(contains);
-
- final boolean added = client.putIfAbsent("testKey", "test", keySerializer, valueSerializer);
- assertFalse(added);
-
- final String originalAfterPut = client.getAndPutIfAbsent("testKey", "test", keySerializer, valueSerializer, deserializer);
- assertEquals("test", originalAfterPut);
-
- final boolean removed = client.remove("testKey", keySerializer);
- assertTrue(removed);
-
- final boolean containedAfterRemove = client.containsKey("testKey", keySerializer);
- assertFalse(containedAfterRemove);
-
- client = null;
- clientInitContext = null;
- clientContext = null;
- Thread.sleep(2000);
- System.gc();
- server.shutdownServer();
- }
-
- @Ignore
- @Test
- public void testSSLWith2RequestsWithServerTimeout() throws InitializationException, IOException, InterruptedException {
- LOGGER.info("Testing " + Thread.currentThread().getStackTrace()[1].getMethodName());
- // Create SSLContext Service
- final StandardSSLContextService sslService = new StandardSSLContextService();
- final MockControllerServiceInitializationContext sslServerInitContext = new MockControllerServiceInitializationContext(sslService,
- "ssl-context");
- sslService.initialize(sslServerInitContext);
-
- final Map<PropertyDescriptor, String> sslServerProps = new HashMap<>();
- sslServerProps.put(StandardSSLContextService.KEYSTORE, "src/test/resources/localhost-ks.jks");
- sslServerProps.put(StandardSSLContextService.KEYSTORE_PASSWORD, "localtest");
- sslServerProps.put(StandardSSLContextService.KEYSTORE_TYPE, "JKS");
- sslServerProps.put(StandardSSLContextService.TRUSTSTORE, "src/test/resources/localhost-ts.jks");
- sslServerProps.put(StandardSSLContextService.TRUSTSTORE_PASSWORD, "localtest");
- sslServerProps.put(StandardSSLContextService.TRUSTSTORE_TYPE, "JKS");
- MockConfigurationContext sslServerContext = new MockConfigurationContext(sslServerProps, sslServerInitContext);
- sslService.onConfigured(sslServerContext);
- sslService.createSSLContext(ClientAuth.REQUIRED);
- // Create server
- final DistributedMapCacheServer server = new DistributedMapCacheServer();
- final MockControllerServiceInitializationContext serverInitContext = new MockControllerServiceInitializationContext(server, "server");
- server.initialize(serverInitContext);
-
- final Map<PropertyDescriptor, String> serverProperties = new HashMap<>();
- serverProperties.put(DistributedMapCacheServer.SSL_CONTEXT_SERVICE, "ssl-context");
- final MockConfigurationContext serverContext = new MockConfigurationContext(serverProperties, serverInitContext.getControllerServiceLookup());
- server.startServer(serverContext);
-
- DistributedMapCacheClientService client = new DistributedMapCacheClientService();
- MockControllerServiceInitializationContext clientInitContext = new MockControllerServiceInitializationContext(client, "client");
- client.initialize(clientInitContext);
-
- final Map<PropertyDescriptor, String> clientProperties = new HashMap<>();
- clientProperties.put(DistributedMapCacheClientService.HOSTNAME, "localhost");
- clientProperties.put(DistributedMapCacheClientService.COMMUNICATIONS_TIMEOUT, "360 secs");
- clientProperties.put(DistributedMapCacheClientService.SSL_CONTEXT_SERVICE, "ssl-context");
- MockConfigurationContext clientContext = new MockConfigurationContext(clientProperties, clientInitContext.getControllerServiceLookup());
- client.cacheConfig(clientContext);
- final Serializer<String> valueSerializer = new StringSerializer();
- final Serializer<String> keySerializer = new StringSerializer();
- final Deserializer<String> deserializer = new StringDeserializer();
-
- final String original = client.getAndPutIfAbsent("testKey", "test", keySerializer, valueSerializer, deserializer);
- assertEquals(null, original);
-
- Thread.sleep(30000);
- try {
- final boolean contains = client.containsKey("testKey", keySerializer);
- assertTrue(contains);
- } catch (IOException e) {
- // this is due to the server timing out in the middle of this request
- assertTrue(e.getMessage().contains("Channel is closed"));
- }
-
- server.shutdownServer();
- }
-
- private void waitABit() {
- try {
- Thread.sleep(10L);
- } catch (final InterruptedException e) {
- }
- }
-
- private DistributedSetCacheClientService createClient() throws InitializationException {
- final DistributedSetCacheClientService client = new DistributedSetCacheClientService();
- MockControllerServiceInitializationContext clientInitContext = new MockControllerServiceInitializationContext(client, "client");
- client.initialize(clientInitContext);
-
- final Map<PropertyDescriptor, String> clientProperties = new HashMap<>();
- clientProperties.put(DistributedSetCacheClientService.HOSTNAME, "localhost");
- final MockConfigurationContext clientContext = new MockConfigurationContext(clientProperties, clientInitContext.getControllerServiceLookup());
- client.onConfigured(clientContext);
-
- return client;
- }
-
- private static class StringSerializer implements Serializer<String> {
- @Override
- public void serialize(final String value, final OutputStream output) throws SerializationException, IOException {
- output.write(value.getBytes(StandardCharsets.UTF_8));
- }
- }
-
- private static class StringDeserializer implements Deserializer<String> {
- @Override
- public String deserialize(final byte[] input) throws DeserializationException, IOException {
- return (input.length == 0) ? null : new String(input, StandardCharsets.UTF_8);
- }
- }
-
- private static void deleteRecursively(final File dataFile) throws IOException {
- if (dataFile == null || !dataFile.exists()) {
- return;
- }
-
- final File[] children = dataFile.listFiles();
- for (final File child : children) {
- if (child.isDirectory()) {
- deleteRecursively(child);
- } else {
- for (int i = 0; i < 100 && child.exists(); i++) {
- child.delete();
- }
-
- if (child.exists()) {
- throw new IOException("Could not delete " + dataFile.getAbsolutePath());
- }
- }
- }
- }
-}
http://git-wip-us.apache.org/repos/asf/incubator-nifi/blob/19d4a150/nar-bundles/distributed-cache-services-bundle/distributed-cache-server/src/test/resources/localhost-ks.jks
----------------------------------------------------------------------
diff --git a/nar-bundles/distributed-cache-services-bundle/distributed-cache-server/src/test/resources/localhost-ks.jks b/nar-bundles/distributed-cache-services-bundle/distributed-cache-server/src/test/resources/localhost-ks.jks
deleted file mode 100755
index 81be31d..0000000
Binary files a/nar-bundles/distributed-cache-services-bundle/distributed-cache-server/src/test/resources/localhost-ks.jks and /dev/null differ
http://git-wip-us.apache.org/repos/asf/incubator-nifi/blob/19d4a150/nar-bundles/distributed-cache-services-bundle/distributed-cache-server/src/test/resources/localhost-ts.jks
----------------------------------------------------------------------
diff --git a/nar-bundles/distributed-cache-services-bundle/distributed-cache-server/src/test/resources/localhost-ts.jks b/nar-bundles/distributed-cache-services-bundle/distributed-cache-server/src/test/resources/localhost-ts.jks
deleted file mode 100755
index 820e1e1..0000000
Binary files a/nar-bundles/distributed-cache-services-bundle/distributed-cache-server/src/test/resources/localhost-ts.jks and /dev/null differ
http://git-wip-us.apache.org/repos/asf/incubator-nifi/blob/19d4a150/nar-bundles/distributed-cache-services-bundle/distributed-cache-services-nar/pom.xml
----------------------------------------------------------------------
diff --git a/nar-bundles/distributed-cache-services-bundle/distributed-cache-services-nar/pom.xml b/nar-bundles/distributed-cache-services-bundle/distributed-cache-services-nar/pom.xml
deleted file mode 100644
index 75cab34..0000000
--- a/nar-bundles/distributed-cache-services-bundle/distributed-cache-services-nar/pom.xml
+++ /dev/null
@@ -1,49 +0,0 @@
-<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">
-<!--
- 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.
--->
- <modelVersion>4.0.0</modelVersion>
- <parent>
- <groupId>org.apache.nifi</groupId>
- <artifactId>distributed-cache-services-bundle</artifactId>
- <version>0.0.1-SNAPSHOT</version>
- </parent>
-
- <artifactId>distributed-cache-services-nar</artifactId>
- <name>Distributed Cache Services NAR</name>
- <packaging>nar</packaging>
-
- <dependencies>
- <dependency>
- <groupId>org.apache.nifi</groupId>
- <artifactId>standard-services-api-nar</artifactId>
- <type>nar</type>
- </dependency>
- <dependency>
- <groupId>org.apache.nifi</groupId>
- <artifactId>distributed-cache-client-service</artifactId>
- <version>${project.version}</version>
- </dependency>
- <dependency>
- <groupId>org.apache.nifi</groupId>
- <artifactId>distributed-cache-protocol</artifactId>
- <version>${project.version}</version>
- </dependency>
- <dependency>
- <groupId>org.apache.nifi</groupId>
- <artifactId>distributed-cache-server</artifactId>
- <version>${project.version}</version>
- </dependency>
- </dependencies>
-</project>
http://git-wip-us.apache.org/repos/asf/incubator-nifi/blob/19d4a150/nar-bundles/distributed-cache-services-bundle/pom.xml
----------------------------------------------------------------------
diff --git a/nar-bundles/distributed-cache-services-bundle/pom.xml b/nar-bundles/distributed-cache-services-bundle/pom.xml
deleted file mode 100644
index dcfa541..0000000
--- a/nar-bundles/distributed-cache-services-bundle/pom.xml
+++ /dev/null
@@ -1,83 +0,0 @@
-<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/maven-v4_0_0.xsd">
- <!--
- 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.
- -->
- <modelVersion>4.0.0</modelVersion>
-
- <parent>
- <groupId>org.apache.nifi</groupId>
- <artifactId>standard-services-api-bundle</artifactId>
- <version>0.0.1-SNAPSHOT</version>
- </parent>
-
- <artifactId>distributed-cache-services-bundle</artifactId>
- <version>0.0.1-SNAPSHOT</version>
- <name>Distributed Cache Services Bundle</name>
- <packaging>pom</packaging>
-
- <modules>
- <module>distributed-cache-protocol</module>
- <module>distributed-cache-client-service</module>
- <module>distributed-cache-server</module>
- <module>distributed-cache-services-nar</module>
- </modules>
-
-
- <dependencyManagement>
- <dependencies>
- <dependency>
- <groupId>org.apache.nifi</groupId>
- <artifactId>distributed-cache-client-service-api</artifactId>
- <version>${standard.services.api.version}</version>
- </dependency>
- <dependency>
- <groupId>org.apache.nifi</groupId>
- <artifactId>ssl-context-service-api</artifactId>
- <version>${standard.services.api.version}</version>
- </dependency>
- <dependency>
- <groupId>org.apache.nifi</groupId>
- <artifactId>nifi-processor-utils</artifactId>
- <version>0.0.1-SNAPSHOT</version>
- </dependency>
- <dependency>
- <groupId>org.apache.nifi</groupId>
- <artifactId>nifi-stream-utils</artifactId>
- <version>0.0.1-SNAPSHOT</version>
- </dependency>
- <dependency>
- <groupId>org.apache.nifi</groupId>
- <artifactId>remote-communications-utils</artifactId>
- <version>0.0.1-SNAPSHOT</version>
- </dependency>
- <dependency>
- <groupId>org.apache.nifi</groupId>
- <artifactId>nifi-mock</artifactId>
- <version>0.0.1-SNAPSHOT</version>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>wali</groupId>
- <artifactId>wali</artifactId>
- <version>3.0.0-SNAPSHOT</version>
- </dependency>
- <dependency>
- <groupId>org.apache.nifi</groupId>
- <artifactId>ssl-context-service</artifactId>
- <version>0.0.1-SNAPSHOT</version>
- <scope>test</scope>
- </dependency>
- </dependencies>
- </dependencyManagement>
-</project>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-nifi/blob/19d4a150/nar-bundles/framework-bundle/framework/cluster/pom.xml
----------------------------------------------------------------------
diff --git a/nar-bundles/framework-bundle/framework/cluster/pom.xml b/nar-bundles/framework-bundle/framework/cluster/pom.xml
index ad5dda7..78f4527 100644
--- a/nar-bundles/framework-bundle/framework/cluster/pom.xml
+++ b/nar-bundles/framework-bundle/framework/cluster/pom.xml
@@ -80,7 +80,6 @@
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-compress</artifactId>
- <version>1.9</version>
</dependency>
<!-- third party dependencies -->
http://git-wip-us.apache.org/repos/asf/incubator-nifi/blob/19d4a150/nar-bundles/framework-bundle/framework/core/pom.xml
----------------------------------------------------------------------
diff --git a/nar-bundles/framework-bundle/framework/core/pom.xml b/nar-bundles/framework-bundle/framework/core/pom.xml
index 547c75d..1836d32 100644
--- a/nar-bundles/framework-bundle/framework/core/pom.xml
+++ b/nar-bundles/framework-bundle/framework/core/pom.xml
@@ -117,9 +117,8 @@
<artifactId>data-provenance-utils</artifactId>
</dependency>
<dependency>
- <groupId>wali</groupId>
+ <groupId>org.apache.nifi</groupId>
<artifactId>wali</artifactId>
- <version>3.0.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.apache.nifi</groupId>
http://git-wip-us.apache.org/repos/asf/incubator-nifi/blob/19d4a150/nar-bundles/framework-bundle/framework/file-authorization-provider/pom.xml
----------------------------------------------------------------------
diff --git a/nar-bundles/framework-bundle/framework/file-authorization-provider/pom.xml b/nar-bundles/framework-bundle/framework/file-authorization-provider/pom.xml
new file mode 100644
index 0000000..cb01488
--- /dev/null
+++ b/nar-bundles/framework-bundle/framework/file-authorization-provider/pom.xml
@@ -0,0 +1,81 @@
+<?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">
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <groupId>org.apache.nifi</groupId>
+ <artifactId>nifi-framework-parent</artifactId>
+ <version>0.0.1-SNAPSHOT</version>
+ </parent>
+
+ <artifactId>file-authorization-provider</artifactId>
+ <version>0.0.1-SNAPSHOT</version>
+ <name>Authorization Provider: File</name>
+
+ <build>
+ <resources>
+ <resource>
+ <directory>src/main/resources</directory>
+ </resource>
+ <resource>
+ <directory>src/main/xsd</directory>
+ </resource>
+ </resources>
+ <plugins>
+ <plugin>
+ <groupId>org.codehaus.mojo</groupId>
+ <artifactId>jaxb2-maven-plugin</artifactId>
+ <executions>
+ <execution>
+ <id>xjc</id>
+ <goals>
+ <goal>xjc</goal>
+ </goals>
+ <configuration>
+ <packageName>org.apache.nifi.user.generated</packageName>
+ </configuration>
+ </execution>
+ </executions>
+ <configuration>
+ <generateDirectory>${project.build.directory}/generated-sources/jaxb</generateDirectory>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.nifi</groupId>
+ <artifactId>nifi-api</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.nifi</groupId>
+ <artifactId>nifi-file-utils</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.nifi</groupId>
+ <artifactId>nifi-properties</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.commons</groupId>
+ <artifactId>commons-lang3</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>commons-codec</groupId>
+ <artifactId>commons-codec</artifactId>
+ <scope>test</scope>
+ </dependency>
+ </dependencies>
+</project>
http://git-wip-us.apache.org/repos/asf/incubator-nifi/blob/19d4a150/nar-bundles/framework-bundle/framework/file-authorization-provider/src/main/java/org/apache/nifi/authorization/FileAuthorizationProvider.java
----------------------------------------------------------------------
diff --git a/nar-bundles/framework-bundle/framework/file-authorization-provider/src/main/java/org/apache/nifi/authorization/FileAuthorizationProvider.java b/nar-bundles/framework-bundle/framework/file-authorization-provider/src/main/java/org/apache/nifi/authorization/FileAuthorizationProvider.java
new file mode 100644
index 0000000..0f4a75c
--- /dev/null
+++ b/nar-bundles/framework-bundle/framework/file-authorization-provider/src/main/java/org/apache/nifi/authorization/FileAuthorizationProvider.java
@@ -0,0 +1,568 @@
+/*
+ * 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.authorization;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.Collection;
+import java.util.EnumSet;
+import java.util.HashSet;
+import java.util.Set;
+import javax.xml.XMLConstants;
+import javax.xml.bind.JAXBContext;
+import javax.xml.bind.JAXBElement;
+import javax.xml.bind.JAXBException;
+import javax.xml.bind.Marshaller;
+import javax.xml.bind.Unmarshaller;
+import javax.xml.transform.stream.StreamSource;
+import javax.xml.validation.Schema;
+import javax.xml.validation.SchemaFactory;
+import org.apache.nifi.authorization.annotation.AuthorityProviderContext;
+import org.apache.nifi.authorization.exception.AuthorityAccessException;
+import org.apache.nifi.authorization.exception.IdentityAlreadyExistsException;
+import org.apache.nifi.authorization.exception.ProviderCreationException;
+import org.apache.nifi.authorization.exception.UnknownIdentityException;
+import org.apache.nifi.file.FileUtils;
+import org.apache.nifi.user.generated.ObjectFactory;
+import org.apache.nifi.user.generated.Role;
+import org.apache.nifi.user.generated.User;
+import org.apache.nifi.user.generated.Users;
+import org.apache.nifi.util.NiFiProperties;
+import org.apache.commons.lang3.StringUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.xml.sax.SAXException;
+
+/**
+ * Provides identity checks and grants authorities.
+ */
+public class FileAuthorizationProvider implements AuthorityProvider {
+
+ private static final Logger logger = LoggerFactory.getLogger(FileAuthorizationProvider.class);
+ private static final String USERS_XSD = "/users.xsd";
+ private static final String JAXB_GENERATED_PATH = "org.apache.nifi.user.generated";
+ private static final JAXBContext JAXB_CONTEXT = initializeJaxbContext();
+
+ /**
+ * Load the JAXBContext.
+ */
+ private static JAXBContext initializeJaxbContext() {
+ try {
+ return JAXBContext.newInstance(JAXB_GENERATED_PATH, FileAuthorizationProvider.class.getClassLoader());
+ } catch (JAXBException e) {
+ throw new RuntimeException("Unable to create JAXBContext.");
+ }
+ }
+
+ private NiFiProperties properties;
+ private File usersFile;
+ private File restoreUsersFile;
+ private Users users;
+ private final Set<String> defaultAuthorities = new HashSet<>();
+
+ @Override
+ public void initialize(final AuthorityProviderInitializationContext initializationContext) throws ProviderCreationException {
+ }
+
+ @Override
+ public void onConfigured(final AuthorityProviderConfigurationContext configurationContext) throws ProviderCreationException {
+ try {
+ final String usersFilePath = configurationContext.getProperty("Authorized Users File");
+ if (usersFilePath == null || usersFilePath.trim().isEmpty()) {
+ throw new ProviderCreationException("The authorized users file must be specified.");
+ }
+
+ // the users file instance will never be null because a default is used
+ usersFile = new File(usersFilePath);
+ final File usersFileDirectory = usersFile.getParentFile();
+
+ // the restore directory is optional and may be null
+ final File restoreDirectory = properties.getRestoreDirectory();
+
+ if (restoreDirectory != null) {
+
+ // sanity check that restore directory is a directory, creating it if necessary
+ FileUtils.ensureDirectoryExistAndCanAccess(restoreDirectory);
+
+ // check that restore directory is not the same as the primary directory
+ if (usersFileDirectory.getAbsolutePath().equals(restoreDirectory.getAbsolutePath())) {
+ throw new ProviderCreationException(String.format("Authorized User's directory '%s' is the same as restore directory '%s' ",
+ usersFileDirectory.getAbsolutePath(), restoreDirectory.getAbsolutePath()));
+ }
+
+ // the restore copy will have same file name, but reside in a different directory
+ restoreUsersFile = new File(restoreDirectory, usersFile.getName());
+
+ // sync the primary copy with the restore copy
+ try {
+ FileUtils.syncWithRestore(usersFile, restoreUsersFile, logger);
+ } catch (final IOException | IllegalStateException ioe) {
+ throw new ProviderCreationException(ioe);
+ }
+
+ }
+
+ // load the users from the specified file
+ if (usersFile.exists()) {
+ // find the schema
+ final SchemaFactory schemaFactory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
+ final Schema schema = schemaFactory.newSchema(FileAuthorizationProvider.class.getResource(USERS_XSD));
+
+ // attempt to unmarshal
+ final Unmarshaller unmarshaller = JAXB_CONTEXT.createUnmarshaller();
+ unmarshaller.setSchema(schema);
+ final JAXBElement<Users> element = unmarshaller.unmarshal(new StreamSource(usersFile), Users.class);
+ users = element.getValue();
+ } else {
+ final ObjectFactory objFactory = new ObjectFactory();
+ users = objFactory.createUsers();
+ }
+
+ // attempt to load a default roles
+ final String rawDefaultAuthorities = configurationContext.getProperty("Default User Roles");
+ if (StringUtils.isNotBlank(rawDefaultAuthorities)) {
+ final Set<String> invalidDefaultAuthorities = new HashSet<>();
+
+ // validate the specified authorities
+ final String[] rawDefaultAuthorityList = rawDefaultAuthorities.split(",");
+ for (String rawAuthority : rawDefaultAuthorityList) {
+ rawAuthority = rawAuthority.trim();
+ final Authority authority = Authority.valueOfAuthority(rawAuthority);
+ if (authority == null) {
+ invalidDefaultAuthorities.add(rawAuthority);
+ } else {
+ defaultAuthorities.add(rawAuthority);
+ }
+ }
+
+ // report any unrecognized authorities
+ if (!invalidDefaultAuthorities.isEmpty()) {
+ logger.warn(String.format("The following default role(s) '%s' were not recognized. Possible values: %s.",
+ StringUtils.join(invalidDefaultAuthorities, ", "), StringUtils.join(Authority.getRawAuthorities(), ", ")));
+ }
+ }
+ } catch (IOException | ProviderCreationException | SAXException | JAXBException e) {
+ throw new ProviderCreationException(e);
+ }
+
+ }
+
+ @Override
+ public void preDestruction() {
+ }
+
+ /**
+ * Determines if this provider has a default role.
+ *
+ * @return
+ */
+ private boolean hasDefaultRoles() {
+ return !defaultAuthorities.isEmpty();
+ }
+
+ /**
+ * Determines if the specified dn is known to this authority provider. When
+ * this provider is configured to have default role(s), all dn are
+ * considered to exist.
+ *
+ * @param dn
+ * @return True if he dn is known, false otherwise
+ */
+ @Override
+ public boolean doesDnExist(String dn) throws AuthorityAccessException {
+ if (hasDefaultRoles()) {
+ return true;
+ }
+
+ final User user = getUser(dn);
+ return user != null;
+ }
+
+ /**
+ * Loads the authorities for the specified user. If this provider is
+ * configured for default user role(s) and a non existent dn is specified, a
+ * new user will be automatically created with the default role(s).
+ *
+ * @param dn
+ * @return
+ * @throws UnknownIdentityException
+ * @throws AuthorityAccessException
+ */
+ @Override
+ public synchronized Set<Authority> getAuthorities(String dn) throws UnknownIdentityException, AuthorityAccessException {
+ final Set<Authority> authorities = EnumSet.noneOf(Authority.class);
+
+ // get the user
+ final User user = getUser(dn);
+
+ // ensure the user was located
+ if (user == null) {
+ if (hasDefaultRoles()) {
+ logger.debug(String.format("User DN not found: %s. Creating new user with default roles.", dn));
+
+ // create the user (which will automatically add any default authorities)
+ addUser(dn, null);
+
+ // get the authorities for the newly created user
+ authorities.addAll(getAuthorities(dn));
+ } else {
+ throw new UnknownIdentityException(String.format("User DN not found: %s.", dn));
+ }
+ } else {
+ // create the authorities that this user has
+ for (final Role role : user.getRole()) {
+ authorities.add(Authority.valueOfAuthority(role.getName()));
+ }
+ }
+
+ return authorities;
+ }
+
+ /**
+ * Adds the specified authorities to the specified user. Regardless of
+ * whether this provider is configured for a default user role, when a non
+ * existent dn is specified, an UnknownIdentityException will be thrown.
+ *
+ * @param dn
+ * @param authorities
+ * @throws UnknownIdentityException
+ * @throws AuthorityAccessException
+ */
+ @Override
+ public synchronized void setAuthorities(String dn, Set<Authority> authorities) throws UnknownIdentityException, AuthorityAccessException {
+ // get the user
+ final User user = getUser(dn);
+
+ // ensure the user was located
+ if (user == null) {
+ throw new UnknownIdentityException(String.format("User DN not found: %s.", dn));
+ }
+
+ // add the user authorities
+ setUserAuthorities(user, authorities);
+
+ try {
+ // save the file
+ save();
+ } catch (Exception e) {
+ throw new AuthorityAccessException(e.getMessage(), e);
+ }
+ }
+
+ /**
+ * Adds the specified authorities to the specified user.
+ *
+ * @param user
+ * @param authorities
+ */
+ private void setUserAuthorities(final User user, final Set<Authority> authorities) {
+ // clear the existing rules
+ user.getRole().clear();
+
+ // set the new roles
+ final ObjectFactory objFactory = new ObjectFactory();
+ for (final Authority authority : authorities) {
+ final Role role = objFactory.createRole();
+ role.setName(authority.toString());
+
+ // add the new role
+ user.getRole().add(role);
+ }
+ }
+
+ /**
+ * Adds the specified user. If this provider is configured with default
+ * role(s) they will be added to the new user.
+ *
+ * @param dn
+ * @param group
+ * @throws UnknownIdentityException
+ * @throws AuthorityAccessException
+ */
+ @Override
+ public synchronized void addUser(String dn, String group) throws IdentityAlreadyExistsException, AuthorityAccessException {
+ final User user = getUser(dn);
+
+ // ensure the user doesn't already exist
+ if (user != null) {
+ throw new IdentityAlreadyExistsException(String.format("User DN already exists: %s", dn));
+ }
+
+ // create the new user
+ final ObjectFactory objFactory = new ObjectFactory();
+ final User newUser = objFactory.createUser();
+
+ // set the user properties
+ newUser.setDn(dn);
+ newUser.setGroup(group);
+
+ // add default roles if appropriate
+ if (hasDefaultRoles()) {
+ for (final String authority : defaultAuthorities) {
+ Role role = objFactory.createRole();
+ role.setName(authority);
+
+ // add the role
+ newUser.getRole().add(role);
+ }
+ }
+
+ // add the user
+ users.getUser().add(newUser);
+
+ try {
+ // save the file
+ save();
+ } catch (Exception e) {
+ throw new AuthorityAccessException(e.getMessage(), e);
+ }
+ }
+
+ /**
+ * Gets the users for the specified authority.
+ *
+ * @param authority
+ * @return
+ * @throws AuthorityAccessException
+ */
+ @Override
+ public synchronized Set<String> getUsers(Authority authority) throws AuthorityAccessException {
+ final Set<String> userSet = new HashSet<>();
+ for (final User user : users.getUser()) {
+ for (final Role role : user.getRole()) {
+ if (role.getName().equals(authority.toString())) {
+ userSet.add(user.getDn());
+ }
+ }
+ }
+ return userSet;
+ }
+
+ /**
+ * Removes the specified user. Regardless of whether this provider is
+ * configured for a default user role, when a non existent dn is specified,
+ * an UnknownIdentityException will be thrown.
+ *
+ * @param dn
+ * @throws UnknownIdentityException
+ * @throws AuthorityAccessException
+ */
+ @Override
+ public synchronized void revokeUser(String dn) throws UnknownIdentityException, AuthorityAccessException {
+ // get the user
+ final User user = getUser(dn);
+
+ // ensure the user was located
+ if (user == null) {
+ throw new UnknownIdentityException(String.format("User DN not found: %s.", dn));
+ }
+
+ // remove the specified user
+ users.getUser().remove(user);
+
+ try {
+ // save the file
+ save();
+ } catch (Exception e) {
+ throw new AuthorityAccessException(e.getMessage(), e);
+ }
+ }
+
+ @Override
+ public void setUsersGroup(Set<String> dns, String group) throws UnknownIdentityException, AuthorityAccessException {
+ final Collection<User> groupedUsers = new HashSet<>();
+
+ // get the specified users
+ for (final String dn : dns) {
+ // get the user
+ final User user = getUser(dn);
+
+ // ensure the user was located
+ if (user == null) {
+ throw new UnknownIdentityException(String.format("User DN not found: %s.", dn));
+ }
+
+ groupedUsers.add(user);
+ }
+
+ // update each user group
+ for (final User user : groupedUsers) {
+ user.setGroup(group);
+ }
+
+ try {
+ // save the file
+ save();
+ } catch (Exception e) {
+ throw new AuthorityAccessException(e.getMessage(), e);
+ }
+ }
+
+ @Override
+ public void ungroupUser(String dn) throws UnknownIdentityException, AuthorityAccessException {
+ // get the user
+ final User user = getUser(dn);
+
+ // ensure the user was located
+ if (user == null) {
+ throw new UnknownIdentityException(String.format("User DN not found: %s.", dn));
+ }
+
+ // remove the users group
+ user.setGroup(null);
+
+ try {
+ // save the file
+ save();
+ } catch (Exception e) {
+ throw new AuthorityAccessException(e.getMessage(), e);
+ }
+ }
+
+ @Override
+ public void ungroup(String group) throws AuthorityAccessException {
+ // get the user group
+ final Collection<User> userGroup = getUserGroup(group);
+
+ // ensure the user group was located
+ if (userGroup == null) {
+ return;
+ }
+
+ // update each user group
+ for (final User user : userGroup) {
+ user.setGroup(null);
+ }
+
+ try {
+ // save the file
+ save();
+ } catch (Exception e) {
+ throw new AuthorityAccessException(e.getMessage(), e);
+ }
+ }
+
+ @Override
+ public String getGroupForUser(String dn) throws UnknownIdentityException, AuthorityAccessException {
+ // get the user
+ final User user = getUser(dn);
+
+ // ensure the user was located
+ if (user == null) {
+ throw new UnknownIdentityException(String.format("User DN not found: %s.", dn));
+ }
+
+ return user.getGroup();
+ }
+
+ @Override
+ public void revokeGroup(String group) throws UnknownIdentityException, AuthorityAccessException {
+ // get the user group
+ final Collection<User> userGroup = getUserGroup(group);
+
+ // ensure the user group was located
+ if (userGroup == null) {
+ throw new UnknownIdentityException(String.format("User group not found: %s.", group));
+ }
+
+ // remove each user in the group
+ for (final User user : userGroup) {
+ users.getUser().remove(user);
+ }
+
+ try {
+ // save the file
+ save();
+ } catch (Exception e) {
+ throw new AuthorityAccessException(e.getMessage(), e);
+ }
+ }
+
+ /**
+ * Locates the user with the specified DN.
+ *
+ * @param dn
+ * @return
+ */
+ private User getUser(String dn) throws UnknownIdentityException {
+ // ensure the DN was specified
+ if (dn == null) {
+ throw new UnknownIdentityException("User DN not specified.");
+ }
+
+ // attempt to get the user and ensure it was located
+ User desiredUser = null;
+ for (final User user : users.getUser()) {
+ if (dn.equalsIgnoreCase(user.getDn())) {
+ desiredUser = user;
+ break;
+ }
+ }
+
+ return desiredUser;
+ }
+
+ /**
+ * Locates all users that are part of the specified group.
+ *
+ * @param group
+ * @return
+ * @throws UnknownIdentityException
+ */
+ private Collection<User> getUserGroup(String group) throws UnknownIdentityException {
+ // ensure the DN was specified
+ if (group == null) {
+ throw new UnknownIdentityException("User group not specified.");
+ }
+
+ // get all users with this group
+ Collection<User> userGroup = null;
+ for (final User user : users.getUser()) {
+ if (group.equals(user.getGroup())) {
+ if (userGroup == null) {
+ userGroup = new HashSet<>();
+ }
+ userGroup.add(user);
+ }
+ }
+
+ return userGroup;
+ }
+
+ /**
+ * Saves the users file.
+ *
+ * @throws Exception
+ */
+ private void save() throws Exception {
+ final Marshaller marshaller = JAXB_CONTEXT.createMarshaller();
+ marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
+
+ // save users to restore directory before primary directory
+ if (restoreUsersFile != null) {
+ marshaller.marshal(users, restoreUsersFile);
+ }
+
+ // save users to primary directory
+ marshaller.marshal(users, usersFile);
+ }
+
+ @AuthorityProviderContext
+ public void setNiFiProperties(NiFiProperties properties) {
+ this.properties = properties;
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-nifi/blob/19d4a150/nar-bundles/framework-bundle/framework/file-authorization-provider/src/main/resources/META-INF/services/org.apache.nifi.authorization.AuthorityProvider
----------------------------------------------------------------------
diff --git a/nar-bundles/framework-bundle/framework/file-authorization-provider/src/main/resources/META-INF/services/org.apache.nifi.authorization.AuthorityProvider b/nar-bundles/framework-bundle/framework/file-authorization-provider/src/main/resources/META-INF/services/org.apache.nifi.authorization.AuthorityProvider
new file mode 100755
index 0000000..93d2941
--- /dev/null
+++ b/nar-bundles/framework-bundle/framework/file-authorization-provider/src/main/resources/META-INF/services/org.apache.nifi.authorization.AuthorityProvider
@@ -0,0 +1,15 @@
+# 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.
+org.apache.nifi.authorization.FileAuthorizationProvider
http://git-wip-us.apache.org/repos/asf/incubator-nifi/blob/19d4a150/nar-bundles/framework-bundle/framework/file-authorization-provider/src/main/xsd/users.xsd
----------------------------------------------------------------------
diff --git a/nar-bundles/framework-bundle/framework/file-authorization-provider/src/main/xsd/users.xsd b/nar-bundles/framework-bundle/framework/file-authorization-provider/src/main/xsd/users.xsd
new file mode 100644
index 0000000..4ee1e17
--- /dev/null
+++ b/nar-bundles/framework-bundle/framework/file-authorization-provider/src/main/xsd/users.xsd
@@ -0,0 +1,64 @@
+<?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.
+-->
+<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
+ <!-- role -->
+ <xs:complexType name="Role">
+ <xs:attribute name="name">
+ <xs:simpleType>
+ <xs:restriction base="xs:string">
+ <xs:enumeration value="ROLE_MONITOR"/>
+ <xs:enumeration value="ROLE_PROVENANCE"/>
+ <xs:enumeration value="ROLE_DFM"/>
+ <xs:enumeration value="ROLE_ADMIN"/>
+ <xs:enumeration value="ROLE_PROXY"/>
+ <xs:enumeration value="ROLE_NIFI"/>
+ </xs:restriction>
+ </xs:simpleType>
+ </xs:attribute>
+ </xs:complexType>
+
+ <!-- user -->
+ <xs:complexType name="User">
+ <xs:sequence>
+ <xs:element name="role" type="Role" minOccurs="0" maxOccurs="unbounded"/>
+ </xs:sequence>
+ <xs:attribute name="dn">
+ <xs:simpleType>
+ <xs:restriction base="xs:string">
+ <xs:minLength value="1"/>
+ <xs:pattern value=".*[^\s].*"/>
+ </xs:restriction>
+ </xs:simpleType>
+ </xs:attribute>
+ <xs:attribute name="group">
+ <xs:simpleType>
+ <xs:restriction base="xs:string">
+ <xs:minLength value="1"/>
+ <xs:pattern value=".*[^\s].*"/>
+ </xs:restriction>
+ </xs:simpleType>
+ </xs:attribute>
+ </xs:complexType>
+
+ <!-- users -->
+ <xs:element name="users">
+ <xs:complexType>
+ <xs:sequence>
+ <xs:element name="user" type="User" minOccurs="0" maxOccurs="unbounded"/>
+ </xs:sequence>
+ </xs:complexType>
+ </xs:element>
+</xs:schema>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-nifi/blob/19d4a150/nar-bundles/framework-bundle/framework/file-authorization-provider/src/test/java/org/apache/nifi/authorization/FileAuthorizationProviderTest.java
----------------------------------------------------------------------
diff --git a/nar-bundles/framework-bundle/framework/file-authorization-provider/src/test/java/org/apache/nifi/authorization/FileAuthorizationProviderTest.java b/nar-bundles/framework-bundle/framework/file-authorization-provider/src/test/java/org/apache/nifi/authorization/FileAuthorizationProviderTest.java
new file mode 100644
index 0000000..3d0196d
--- /dev/null
+++ b/nar-bundles/framework-bundle/framework/file-authorization-provider/src/test/java/org/apache/nifi/authorization/FileAuthorizationProviderTest.java
@@ -0,0 +1,127 @@
+/*
+ * 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.authorization;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import org.apache.nifi.authorization.exception.ProviderCreationException;
+import org.apache.nifi.file.FileUtils;
+import org.apache.nifi.util.NiFiProperties;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import static org.mockito.Mockito.*;
+import static org.junit.Assert.*;
+import org.junit.Ignore;
+import org.mockito.Mockito;
+
+@Ignore
+public class FileAuthorizationProviderTest {
+
+ private FileAuthorizationProvider provider;
+
+ private File primary;
+
+ private File restore;
+
+ private NiFiProperties mockProperties;
+
+ private AuthorityProviderConfigurationContext mockConfigurationContext;
+
+ @Before
+ public void setup() throws IOException {
+
+ primary = new File("target/primary/users.txt");
+ restore = new File("target/restore/users.txt");
+
+ System.out.println("absolute path: " + primary.getAbsolutePath());
+
+ mockProperties = mock(NiFiProperties.class);
+ when(mockProperties.getRestoreDirectory()).thenReturn(restore.getParentFile());
+
+ mockConfigurationContext = mock(AuthorityProviderConfigurationContext.class);
+ when(mockConfigurationContext.getProperty(Mockito.eq("Authorized Users File"))).thenReturn(primary.getPath());
+
+ provider = new FileAuthorizationProvider();
+ provider.setNiFiProperties(mockProperties);
+ provider.initialize(null);
+ }
+
+ @After
+ public void cleanup() throws Exception {
+ deleteFile(primary);
+ deleteFile(restore);
+ }
+
+ private boolean deleteFile(final File file) {
+ if(file.isDirectory()) {
+ FileUtils.deleteFilesInDir(file, null, null, true, true);
+ }
+ return FileUtils.deleteFile(file, null, 10);
+ }
+
+ @Test
+ public void testPostContructionWhenRestoreDoesNotExist() throws Exception {
+
+ byte[] primaryBytes = "<users/>".getBytes();
+ FileOutputStream fos = new FileOutputStream(primary);
+ fos.write(primaryBytes);
+ fos.close();
+
+ provider.onConfigured(mockConfigurationContext);
+ assertEquals(primary.length(), restore.length());
+ }
+
+ @Test
+ public void testPostContructionWhenPrimaryDoesNotExist() throws Exception {
+
+ byte[] restoreBytes = "<users/>".getBytes();
+ FileOutputStream fos = new FileOutputStream(restore);
+ fos.write(restoreBytes);
+ fos.close();
+
+ provider.onConfigured(mockConfigurationContext);
+ assertEquals(restore.length(), primary.length());
+
+ }
+
+ @Test(expected = ProviderCreationException.class)
+ public void testPostContructionWhenPrimaryDifferentThanRestore() throws Exception {
+
+ byte[] primaryBytes = "<users></users>".getBytes();
+ FileOutputStream fos = new FileOutputStream(primary);
+ fos.write(primaryBytes);
+ fos.close();
+
+ byte[] restoreBytes = "<users/>".getBytes();
+ fos = new FileOutputStream(restore);
+ fos.write(restoreBytes);
+ fos.close();
+
+ provider.onConfigured(mockConfigurationContext);
+ }
+
+ @Test
+ public void testPostContructionWhenPrimaryAndBackupDoNotExist() throws Exception {
+
+ provider.onConfigured(mockConfigurationContext);
+ assertEquals(0, restore.length());
+ assertEquals(restore.length(), primary.length());
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-nifi/blob/19d4a150/nar-bundles/framework-bundle/framework/pom.xml
----------------------------------------------------------------------
diff --git a/nar-bundles/framework-bundle/framework/pom.xml b/nar-bundles/framework-bundle/framework/pom.xml
index 65fdaf1..f8ccdd0 100644
--- a/nar-bundles/framework-bundle/framework/pom.xml
+++ b/nar-bundles/framework-bundle/framework/pom.xml
@@ -35,6 +35,7 @@
<module>cluster-protocol</module>
<module>cluster-web</module>
<module>cluster</module>
+ <module>file-authorization-provider</module>
<module>cluster-authorization-provider</module>
<module>user-actions</module>
<module>administration</module>
http://git-wip-us.apache.org/repos/asf/incubator-nifi/blob/19d4a150/nar-bundles/framework-bundle/framework/resources/pom.xml
----------------------------------------------------------------------
diff --git a/nar-bundles/framework-bundle/framework/resources/pom.xml b/nar-bundles/framework-bundle/framework/resources/pom.xml
index 9c984e7..ea25529 100644
--- a/nar-bundles/framework-bundle/framework/resources/pom.xml
+++ b/nar-bundles/framework-bundle/framework/resources/pom.xml
@@ -29,6 +29,9 @@
<plugins>
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
+ <configuration>
+ <attach>true</attach>
+ </configuration>
<executions>
<execution>
<id>make shared resource</id>
http://git-wip-us.apache.org/repos/asf/incubator-nifi/blob/19d4a150/nar-bundles/framework-bundle/framework/runtime/pom.xml
----------------------------------------------------------------------
diff --git a/nar-bundles/framework-bundle/framework/runtime/pom.xml b/nar-bundles/framework-bundle/framework/runtime/pom.xml
index af4b404..e193729 100644
--- a/nar-bundles/framework-bundle/framework/runtime/pom.xml
+++ b/nar-bundles/framework-bundle/framework/runtime/pom.xml
@@ -29,6 +29,10 @@
<artifactId>nifi-nar</artifactId>
</dependency>
<dependency>
+ <groupId>org.apache.nifi</groupId>
+ <artifactId>nifi-properties</artifactId>
+ </dependency>
+ <dependency>
<groupId>org.slf4j</groupId>
<artifactId>jul-to-slf4j</artifactId>
</dependency>
http://git-wip-us.apache.org/repos/asf/incubator-nifi/blob/19d4a150/nar-bundles/framework-bundle/framework/site-to-site/pom.xml
----------------------------------------------------------------------
diff --git a/nar-bundles/framework-bundle/framework/site-to-site/pom.xml b/nar-bundles/framework-bundle/framework/site-to-site/pom.xml
index ce18ec7..30cd325 100644
--- a/nar-bundles/framework-bundle/framework/site-to-site/pom.xml
+++ b/nar-bundles/framework-bundle/framework/site-to-site/pom.xml
@@ -43,6 +43,10 @@
</dependency>
<dependency>
<groupId>org.apache.nifi</groupId>
+ <artifactId>nifi-properties</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.nifi</groupId>
<artifactId>core-api</artifactId>
</dependency>
<dependency>
@@ -68,7 +72,6 @@
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
- <version>4.3.6</version>
</dependency>
<dependency>
<groupId>org.apache.nifi</groupId>
@@ -77,7 +80,6 @@
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
- <version>1.10.8</version>
<scope>test</scope>
</dependency>
</dependencies>