You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nifi.apache.org by al...@apache.org on 2017/03/31 16:22:55 UTC
[2/5] nifi-minifi git commit: MINIFI-238 - MiNiFi Initial Command and
Control Server Implementation
http://git-wip-us.apache.org/repos/asf/nifi-minifi/blob/f89f4150/minifi-c2/minifi-c2-integration-tests/src/test/resources/mocknifi/www/nifi-api/templates/dd737a3e-333e-40df-a0bc-d7e28c8e6843/download
----------------------------------------------------------------------
diff --git a/minifi-c2/minifi-c2-integration-tests/src/test/resources/mocknifi/www/nifi-api/templates/dd737a3e-333e-40df-a0bc-d7e28c8e6843/download b/minifi-c2/minifi-c2-integration-tests/src/test/resources/mocknifi/www/nifi-api/templates/dd737a3e-333e-40df-a0bc-d7e28c8e6843/download
new file mode 100644
index 0000000..6b364d0
--- /dev/null
+++ b/minifi-c2/minifi-c2-integration-tests/src/test/resources/mocknifi/www/nifi-api/templates/dd737a3e-333e-40df-a0bc-d7e28c8e6843/download
@@ -0,0 +1,203 @@
+<?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.
+-->
+<template encoding-version="1.0">
+ <description></description>
+ <groupId>8f8eda5e-015a-1000-a9c1-b7e4fe10ae83</groupId>
+ <name>raspi3.v2</name>
+ <snippet>
+ <connections>
+ <id>8f96f2a9-015a-1000-0000-000000000000</id>
+ <parentGroupId>8f8eda5e-015a-1000-0000-000000000000</parentGroupId>
+ <backPressureDataSizeThreshold>1 GB</backPressureDataSizeThreshold>
+ <backPressureObjectThreshold>10000</backPressureObjectThreshold>
+ <destination>
+ <groupId>8f8eda5e-015a-1000-0000-000000000000</groupId>
+ <id>8f96bf68-015a-1000-0000-000000000000</id>
+ <type>PROCESSOR</type>
+ </destination>
+ <flowFileExpiration>0 sec</flowFileExpiration>
+ <labelIndex>1</labelIndex>
+ <name></name>
+ <selectedRelationships>success</selectedRelationships>
+ <source>
+ <groupId>8f8eda5e-015a-1000-0000-000000000000</groupId>
+ <id>8f96e313-015a-1000-0000-000000000000</id>
+ <type>PROCESSOR</type>
+ </source>
+ <zIndex>0</zIndex>
+ </connections>
+ <processors>
+ <id>8f96bf68-015a-1000-0000-000000000000</id>
+ <parentGroupId>8f8eda5e-015a-1000-0000-000000000000</parentGroupId>
+ <position>
+ <x>14.0</x>
+ <y>253.0</y>
+ </position>
+ <config>
+ <bulletinLevel>WARN</bulletinLevel>
+ <comments></comments>
+ <concurrentlySchedulableTaskCount>1</concurrentlySchedulableTaskCount>
+ <descriptors>
+ <entry>
+ <key>Log Level</key>
+ <value>
+ <name>Log Level</name>
+ </value>
+ </entry>
+ <entry>
+ <key>Log Payload</key>
+ <value>
+ <name>Log Payload</name>
+ </value>
+ </entry>
+ <entry>
+ <key>Attributes to Log</key>
+ <value>
+ <name>Attributes to Log</name>
+ </value>
+ </entry>
+ <entry>
+ <key>Attributes to Ignore</key>
+ <value>
+ <name>Attributes to Ignore</name>
+ </value>
+ </entry>
+ <entry>
+ <key>Log prefix</key>
+ <value>
+ <name>Log prefix</name>
+ </value>
+ </entry>
+ </descriptors>
+ <executionNode>ALL</executionNode>
+ <lossTolerant>false</lossTolerant>
+ <penaltyDuration>30 sec</penaltyDuration>
+ <properties>
+ <entry>
+ <key>Log Level</key>
+ <value>info</value>
+ </entry>
+ <entry>
+ <key>Log Payload</key>
+ <value>true</value>
+ </entry>
+ <entry>
+ <key>Attributes to Log</key>
+ </entry>
+ <entry>
+ <key>Attributes to Ignore</key>
+ </entry>
+ <entry>
+ <key>Log prefix</key>
+ </entry>
+ </properties>
+ <runDurationMillis>0</runDurationMillis>
+ <schedulingPeriod>0 sec</schedulingPeriod>
+ <schedulingStrategy>TIMER_DRIVEN</schedulingStrategy>
+ <yieldDuration>1 sec</yieldDuration>
+ </config>
+ <name>LogAttribute</name>
+ <relationships>
+ <autoTerminate>true</autoTerminate>
+ <name>success</name>
+ </relationships>
+ <style></style>
+ <type>org.apache.nifi.processors.standard.LogAttribute</type>
+ </processors>
+ <processors>
+ <id>8f96e313-015a-1000-0000-000000000000</id>
+ <parentGroupId>8f8eda5e-015a-1000-0000-000000000000</parentGroupId>
+ <position>
+ <x>0.0</x>
+ <y>0.0</y>
+ </position>
+ <config>
+ <bulletinLevel>WARN</bulletinLevel>
+ <comments></comments>
+ <concurrentlySchedulableTaskCount>1</concurrentlySchedulableTaskCount>
+ <descriptors>
+ <entry>
+ <key>File Size</key>
+ <value>
+ <name>File Size</name>
+ </value>
+ </entry>
+ <entry>
+ <key>Batch Size</key>
+ <value>
+ <name>Batch Size</name>
+ </value>
+ </entry>
+ <entry>
+ <key>Data Format</key>
+ <value>
+ <name>Data Format</name>
+ </value>
+ </entry>
+ <entry>
+ <key>Unique FlowFiles</key>
+ <value>
+ <name>Unique FlowFiles</name>
+ </value>
+ </entry>
+ <entry>
+ <key>generate-ff-custom-text</key>
+ <value>
+ <name>generate-ff-custom-text</name>
+ </value>
+ </entry>
+ </descriptors>
+ <executionNode>ALL</executionNode>
+ <lossTolerant>false</lossTolerant>
+ <penaltyDuration>30 sec</penaltyDuration>
+ <properties>
+ <entry>
+ <key>File Size</key>
+ <value>0B</value>
+ </entry>
+ <entry>
+ <key>Batch Size</key>
+ <value>1</value>
+ </entry>
+ <entry>
+ <key>Data Format</key>
+ <value>Text</value>
+ </entry>
+ <entry>
+ <key>Unique FlowFiles</key>
+ <value>false</value>
+ </entry>
+ <entry>
+ <key>generate-ff-custom-text</key>
+ <value>abcdefg</value>
+ </entry>
+ </properties>
+ <runDurationMillis>0</runDurationMillis>
+ <schedulingPeriod>0 sec</schedulingPeriod>
+ <schedulingStrategy>TIMER_DRIVEN</schedulingStrategy>
+ <yieldDuration>1 sec</yieldDuration>
+ </config>
+ <name>GenerateFlowFile</name>
+ <relationships>
+ <autoTerminate>false</autoTerminate>
+ <name>success</name>
+ </relationships>
+ <style></style>
+ <type>org.apache.nifi.processors.standard.GenerateFlowFile</type>
+ </processors>
+ </snippet>
+ <timestamp>03/17/2017 13:22:58 EDT</timestamp>
+</template>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/nifi-minifi/blob/f89f4150/minifi-c2/minifi-c2-integration-tests/src/test/resources/mocknifi/www/nifi-api/templates/f080ec50-ca32-4b36-8453-5a7145bec4c5/download
----------------------------------------------------------------------
diff --git a/minifi-c2/minifi-c2-integration-tests/src/test/resources/mocknifi/www/nifi-api/templates/f080ec50-ca32-4b36-8453-5a7145bec4c5/download b/minifi-c2/minifi-c2-integration-tests/src/test/resources/mocknifi/www/nifi-api/templates/f080ec50-ca32-4b36-8453-5a7145bec4c5/download
new file mode 100644
index 0000000..ad65498
--- /dev/null
+++ b/minifi-c2/minifi-c2-integration-tests/src/test/resources/mocknifi/www/nifi-api/templates/f080ec50-ca32-4b36-8453-5a7145bec4c5/download
@@ -0,0 +1,202 @@
+<?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.
+-->
+<template encoding-version="1.0">
+ <description></description>
+ <groupId>8f8eda5e-015a-1000-a9c1-b7e4fe10ae83</groupId>
+ <name>raspi3.v1</name>
+ <snippet>
+ <connections>
+ <id>8f96f2a9-015a-1000-0000-000000000000</id>
+ <parentGroupId>8f8eda5e-015a-1000-0000-000000000000</parentGroupId>
+ <backPressureDataSizeThreshold>1 GB</backPressureDataSizeThreshold>
+ <backPressureObjectThreshold>10000</backPressureObjectThreshold>
+ <destination>
+ <groupId>8f8eda5e-015a-1000-0000-000000000000</groupId>
+ <id>8f96bf68-015a-1000-0000-000000000000</id>
+ <type>PROCESSOR</type>
+ </destination>
+ <flowFileExpiration>0 sec</flowFileExpiration>
+ <labelIndex>1</labelIndex>
+ <name></name>
+ <selectedRelationships>success</selectedRelationships>
+ <source>
+ <groupId>8f8eda5e-015a-1000-0000-000000000000</groupId>
+ <id>8f96e313-015a-1000-0000-000000000000</id>
+ <type>PROCESSOR</type>
+ </source>
+ <zIndex>0</zIndex>
+ </connections>
+ <processors>
+ <id>8f96bf68-015a-1000-0000-000000000000</id>
+ <parentGroupId>8f8eda5e-015a-1000-0000-000000000000</parentGroupId>
+ <position>
+ <x>14.0</x>
+ <y>253.0</y>
+ </position>
+ <config>
+ <bulletinLevel>WARN</bulletinLevel>
+ <comments></comments>
+ <concurrentlySchedulableTaskCount>1</concurrentlySchedulableTaskCount>
+ <descriptors>
+ <entry>
+ <key>Log prefix</key>
+ <value>
+ <name>Log prefix</name>
+ </value>
+ </entry>
+ <entry>
+ <key>Log Level</key>
+ <value>
+ <name>Log Level</name>
+ </value>
+ </entry>
+ <entry>
+ <key>Attributes to Ignore</key>
+ <value>
+ <name>Attributes to Ignore</name>
+ </value>
+ </entry>
+ <entry>
+ <key>Attributes to Log</key>
+ <value>
+ <name>Attributes to Log</name>
+ </value>
+ </entry>
+ <entry>
+ <key>Log Payload</key>
+ <value>
+ <name>Log Payload</name>
+ </value>
+ </entry>
+ </descriptors>
+ <executionNode>ALL</executionNode>
+ <lossTolerant>false</lossTolerant>
+ <penaltyDuration>30 sec</penaltyDuration>
+ <properties>
+ <entry>
+ <key>Log prefix</key>
+ </entry>
+ <entry>
+ <key>Log Level</key>
+ <value>info</value>
+ </entry>
+ <entry>
+ <key>Attributes to Ignore</key>
+ </entry>
+ <entry>
+ <key>Attributes to Log</key>
+ </entry>
+ <entry>
+ <key>Log Payload</key>
+ <value>true</value>
+ </entry>
+ </properties>
+ <runDurationMillis>0</runDurationMillis>
+ <schedulingPeriod>0 sec</schedulingPeriod>
+ <schedulingStrategy>TIMER_DRIVEN</schedulingStrategy>
+ <yieldDuration>1 sec</yieldDuration>
+ </config>
+ <name>LogAttribute</name>
+ <relationships>
+ <autoTerminate>true</autoTerminate>
+ <name>success</name>
+ </relationships>
+ <style></style>
+ <type>org.apache.nifi.processors.standard.LogAttribute</type>
+ </processors>
+ <processors>
+ <id>8f96e313-015a-1000-0000-000000000000</id>
+ <parentGroupId>8f8eda5e-015a-1000-0000-000000000000</parentGroupId>
+ <position>
+ <x>0.0</x>
+ <y>0.0</y>
+ </position>
+ <config>
+ <bulletinLevel>WARN</bulletinLevel>
+ <comments></comments>
+ <concurrentlySchedulableTaskCount>1</concurrentlySchedulableTaskCount>
+ <descriptors>
+ <entry>
+ <key>File Size</key>
+ <value>
+ <name>File Size</name>
+ </value>
+ </entry>
+ <entry>
+ <key>generate-ff-custom-text</key>
+ <value>
+ <name>generate-ff-custom-text</name>
+ </value>
+ </entry>
+ <entry>
+ <key>Batch Size</key>
+ <value>
+ <name>Batch Size</name>
+ </value>
+ </entry>
+ <entry>
+ <key>Unique FlowFiles</key>
+ <value>
+ <name>Unique FlowFiles</name>
+ </value>
+ </entry>
+ <entry>
+ <key>Data Format</key>
+ <value>
+ <name>Data Format</name>
+ </value>
+ </entry>
+ </descriptors>
+ <executionNode>ALL</executionNode>
+ <lossTolerant>false</lossTolerant>
+ <penaltyDuration>30 sec</penaltyDuration>
+ <properties>
+ <entry>
+ <key>File Size</key>
+ <value>0B</value>
+ </entry>
+ <entry>
+ <key>generate-ff-custom-text</key>
+ </entry>
+ <entry>
+ <key>Batch Size</key>
+ <value>1</value>
+ </entry>
+ <entry>
+ <key>Unique FlowFiles</key>
+ <value>false</value>
+ </entry>
+ <entry>
+ <key>Data Format</key>
+ <value>Text</value>
+ </entry>
+ </properties>
+ <runDurationMillis>0</runDurationMillis>
+ <schedulingPeriod>0 sec</schedulingPeriod>
+ <schedulingStrategy>TIMER_DRIVEN</schedulingStrategy>
+ <yieldDuration>1 sec</yieldDuration>
+ </config>
+ <name>GenerateFlowFile</name>
+ <relationships>
+ <autoTerminate>false</autoTerminate>
+ <name>success</name>
+ </relationships>
+ <style></style>
+ <type>org.apache.nifi.processors.standard.GenerateFlowFile</type>
+ </processors>
+ </snippet>
+ <timestamp>03/07/2017 11:13:03 EST</timestamp>
+</template>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/nifi-minifi/blob/f89f4150/minifi-c2/minifi-c2-integration-tests/src/test/resources/overlay.properties
----------------------------------------------------------------------
diff --git a/minifi-c2/minifi-c2-integration-tests/src/test/resources/overlay.properties b/minifi-c2/minifi-c2-integration-tests/src/test/resources/overlay.properties
new file mode 100644
index 0000000..b1312a0
--- /dev/null
+++ b/minifi-c2/minifi-c2-integration-tests/src/test/resources/overlay.properties
@@ -0,0 +1,16 @@
+#
+# 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.
+#
http://git-wip-us.apache.org/repos/asf/nifi-minifi/blob/f89f4150/minifi-c2/minifi-c2-integration-tests/src/test/resources/squid/squid.conf
----------------------------------------------------------------------
diff --git a/minifi-c2/minifi-c2-integration-tests/src/test/resources/squid/squid.conf b/minifi-c2/minifi-c2-integration-tests/src/test/resources/squid/squid.conf
new file mode 100644
index 0000000..90a5248
--- /dev/null
+++ b/minifi-c2/minifi-c2-integration-tests/src/test/resources/squid/squid.conf
@@ -0,0 +1,19 @@
+# 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.
+
+http_access allow all
+
+# Choose the port you want. Below we set it to default 3128.
+http_port 3128
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/nifi-minifi/blob/f89f4150/minifi-c2/minifi-c2-jetty/pom.xml
----------------------------------------------------------------------
diff --git a/minifi-c2/minifi-c2-jetty/pom.xml b/minifi-c2/minifi-c2-jetty/pom.xml
new file mode 100644
index 0000000..df24c62
--- /dev/null
+++ b/minifi-c2/minifi-c2-jetty/pom.xml
@@ -0,0 +1,43 @@
+<?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>
+ <artifactId>minifi-c2</artifactId>
+ <groupId>org.apache.nifi.minifi</groupId>
+ <version>0.2.0-SNAPSHOT</version>
+ </parent>
+ <artifactId>minifi-c2-jetty</artifactId>
+ <packaging>jar</packaging>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.nifi.minifi</groupId>
+ <artifactId>minifi-c2-api</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.eclipse.jetty</groupId>
+ <artifactId>jetty-server</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.eclipse.jetty</groupId>
+ <artifactId>jetty-webapp</artifactId>
+ </dependency>
+ </dependencies>
+</project>
http://git-wip-us.apache.org/repos/asf/nifi-minifi/blob/f89f4150/minifi-c2/minifi-c2-jetty/src/main/java/org/apache/nifi/minifi/c2/jetty/JettyServer.java
----------------------------------------------------------------------
diff --git a/minifi-c2/minifi-c2-jetty/src/main/java/org/apache/nifi/minifi/c2/jetty/JettyServer.java b/minifi-c2/minifi-c2-jetty/src/main/java/org/apache/nifi/minifi/c2/jetty/JettyServer.java
new file mode 100644
index 0000000..5c8b1f8
--- /dev/null
+++ b/minifi-c2/minifi-c2-jetty/src/main/java/org/apache/nifi/minifi/c2/jetty/JettyServer.java
@@ -0,0 +1,142 @@
+/*
+ * 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.minifi.c2.jetty;
+
+import org.apache.nifi.minifi.c2.api.properties.C2Properties;
+import org.eclipse.jetty.server.Handler;
+import org.eclipse.jetty.server.HttpConfiguration;
+import org.eclipse.jetty.server.HttpConnectionFactory;
+import org.eclipse.jetty.server.SecureRequestCustomizer;
+import org.eclipse.jetty.server.Server;
+import org.eclipse.jetty.server.ServerConnector;
+import org.eclipse.jetty.server.SslConnectionFactory;
+import org.eclipse.jetty.server.handler.HandlerCollection;
+import org.eclipse.jetty.util.ssl.SslContextFactory;
+import org.eclipse.jetty.webapp.WebAppClassLoader;
+import org.eclipse.jetty.webapp.WebAppContext;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.File;
+import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.stream.Collectors;
+
+public class JettyServer {
+ private static final Logger logger = LoggerFactory.getLogger(JettyServer.class);
+ private static String C2_SERVER_HOME = System.getenv("C2_SERVER_HOME");
+ private static final String WEB_DEFAULTS_XML = "webdefault.xml";
+
+ public static void main(String[] args) throws Exception {
+ C2Properties properties = C2Properties.getInstance();
+
+ final HandlerCollection handlers = new HandlerCollection();
+ for (Path path : Files.list(Paths.get(C2_SERVER_HOME, "webapps")).collect(Collectors.toList())) {
+ handlers.addHandler(loadWar(path.toFile(), "/c2", JettyServer.class.getClassLoader()));
+ }
+
+ Server server;
+ int port = Integer.parseInt(properties.getProperty("minifi.c2.server.port", "10080"));
+ SslContextFactory sslContextFactory = properties.getSslContextFactory();
+ if (sslContextFactory == null) {
+ server = new Server(port);
+ } else {
+ HttpConfiguration config = new HttpConfiguration();
+ config.setSecureScheme("https");
+ config.setSecurePort(port);
+ config.addCustomizer(new SecureRequestCustomizer());
+
+ server = new Server();
+
+ ServerConnector serverConnector = new ServerConnector(server, new SslConnectionFactory(sslContextFactory, "http/1.1"), new HttpConnectionFactory(config));
+ serverConnector.setPort(port);
+
+ server.addConnector(serverConnector);
+ }
+
+ server.setHandler(handlers);
+ server.start();
+
+ // ensure everything started successfully
+ for (Handler handler : server.getChildHandlers()) {
+ // see if the handler is a web app
+ if (handler instanceof WebAppContext) {
+ WebAppContext context = (WebAppContext) handler;
+
+ // see if this webapp had any exceptions that would
+ // cause it to be unavailable
+ if (context.getUnavailableException() != null) {
+
+ System.err.println("Failed to start web server: " + context.getUnavailableException().getMessage());
+ System.err.println("Shutting down...");
+ logger.warn("Failed to start web server... shutting down.", context.getUnavailableException());
+ server.stop();
+ System.exit(1);
+ }
+ }
+ }
+
+ server.dumpStdErr();
+ server.join();
+ }
+
+ private static WebAppContext loadWar(final File warFile, final String contextPath, final ClassLoader parentClassLoader) throws IOException {
+ final WebAppContext webappContext = new WebAppContext(warFile.getPath(), contextPath);
+ webappContext.setContextPath(contextPath);
+ webappContext.setDisplayName(contextPath);
+
+ // instruction jetty to examine these jars for tlds, web-fragments, etc
+ webappContext.setAttribute("org.eclipse.jetty.server.webapp.ContainerIncludeJarPattern", ".*/[^/]*servlet-api-[^/]*\\.jar$|.*/javax.servlet.jsp.jstl-.*\\\\.jar$|.*/[^/]*taglibs.*\\.jar$" );
+
+ // remove slf4j server class to allow WAR files to have slf4j dependencies in WEB-INF/lib
+ List<String> serverClasses = new ArrayList<>(Arrays.asList(webappContext.getServerClasses()));
+ serverClasses.remove("org.slf4j.");
+ webappContext.setServerClasses(serverClasses.toArray(new String[0]));
+ webappContext.setDefaultsDescriptor(WEB_DEFAULTS_XML);
+
+ // get the temp directory for this webapp
+ File tempDir = Paths.get(C2_SERVER_HOME, "tmp", warFile.getName()).toFile();
+ if (tempDir.exists() && !tempDir.isDirectory()) {
+ throw new RuntimeException(tempDir.getAbsolutePath() + " is not a directory");
+ } else if (!tempDir.exists()) {
+ final boolean made = tempDir.mkdirs();
+ if (!made) {
+ throw new RuntimeException(tempDir.getAbsolutePath() + " could not be created");
+ }
+ }
+ if (!(tempDir.canRead() && tempDir.canWrite())) {
+ throw new RuntimeException(tempDir.getAbsolutePath() + " directory does not have read/write privilege");
+ }
+
+ // configure the temp dir
+ webappContext.setTempDirectory(tempDir);
+
+ // configure the max form size (3x the default)
+ webappContext.setMaxFormContentSize(600000);
+
+ webappContext.setClassLoader(new WebAppClassLoader(parentClassLoader, webappContext));
+
+ logger.info("Loading WAR: " + warFile.getAbsolutePath() + " with context path set to " + contextPath);
+ return webappContext;
+ }
+}
http://git-wip-us.apache.org/repos/asf/nifi-minifi/blob/f89f4150/minifi-c2/minifi-c2-provider/minifi-c2-provider-cache/pom.xml
----------------------------------------------------------------------
diff --git a/minifi-c2/minifi-c2-provider/minifi-c2-provider-cache/pom.xml b/minifi-c2/minifi-c2-provider/minifi-c2-provider-cache/pom.xml
new file mode 100644
index 0000000..76e082e
--- /dev/null
+++ b/minifi-c2/minifi-c2-provider/minifi-c2-provider-cache/pom.xml
@@ -0,0 +1,40 @@
+<?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>
+ <artifactId>minifi-c2-provider</artifactId>
+ <groupId>org.apache.nifi.minifi</groupId>
+ <version>0.2.0-SNAPSHOT</version>
+ </parent>
+ <artifactId>minifi-c2-provider-cache</artifactId>
+ <packaging>jar</packaging>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.nifi.minifi</groupId>
+ <artifactId>minifi-c2-api</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.mockito</groupId>
+ <artifactId>mockito-all</artifactId>
+ <scope>test</scope>
+ </dependency>
+ </dependencies>
+</project>
http://git-wip-us.apache.org/repos/asf/nifi-minifi/blob/f89f4150/minifi-c2/minifi-c2-provider/minifi-c2-provider-cache/src/main/java/org/apache/nifi/minifi/c2/provider/cache/CacheConfigurationProvider.java
----------------------------------------------------------------------
diff --git a/minifi-c2/minifi-c2-provider/minifi-c2-provider-cache/src/main/java/org/apache/nifi/minifi/c2/provider/cache/CacheConfigurationProvider.java b/minifi-c2/minifi-c2-provider/minifi-c2-provider-cache/src/main/java/org/apache/nifi/minifi/c2/provider/cache/CacheConfigurationProvider.java
new file mode 100644
index 0000000..b0864ac
--- /dev/null
+++ b/minifi-c2/minifi-c2-provider/minifi-c2-provider-cache/src/main/java/org/apache/nifi/minifi/c2/provider/cache/CacheConfigurationProvider.java
@@ -0,0 +1,46 @@
+/*
+ * 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.minifi.c2.provider.cache;
+
+import org.apache.nifi.minifi.c2.api.Configuration;
+import org.apache.nifi.minifi.c2.api.ConfigurationProvider;
+import org.apache.nifi.minifi.c2.api.ConfigurationProviderException;
+import org.apache.nifi.minifi.c2.api.cache.ConfigurationCache;
+
+import java.util.List;
+import java.util.Map;
+
+public class CacheConfigurationProvider implements ConfigurationProvider {
+ private final String contentType;
+ private final ConfigurationCache configurationCache;
+
+ public CacheConfigurationProvider(String contentType, ConfigurationCache configurationCache) {
+ this.contentType = contentType;
+ this.configurationCache = configurationCache;
+ }
+
+ @Override
+ public String getContentType() {
+ return contentType;
+ }
+
+ @Override
+ public Configuration getConfiguration(Integer version, Map<String, List<String>> parameters) throws ConfigurationProviderException {
+ return configurationCache.getCacheFileInfo(parameters).getConfiguration(version);
+ }
+}
http://git-wip-us.apache.org/repos/asf/nifi-minifi/blob/f89f4150/minifi-c2/minifi-c2-provider/minifi-c2-provider-cache/src/test/java/org/apache/nifi/minifi/c2/provider/cache/CacheConfigurationProviderTest.java
----------------------------------------------------------------------
diff --git a/minifi-c2/minifi-c2-provider/minifi-c2-provider-cache/src/test/java/org/apache/nifi/minifi/c2/provider/cache/CacheConfigurationProviderTest.java b/minifi-c2/minifi-c2-provider/minifi-c2-provider-cache/src/test/java/org/apache/nifi/minifi/c2/provider/cache/CacheConfigurationProviderTest.java
new file mode 100644
index 0000000..d038194
--- /dev/null
+++ b/minifi-c2/minifi-c2-provider/minifi-c2-provider-cache/src/test/java/org/apache/nifi/minifi/c2/provider/cache/CacheConfigurationProviderTest.java
@@ -0,0 +1,65 @@
+/*
+ * 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.minifi.c2.provider.cache;
+
+import org.apache.nifi.minifi.c2.api.ConfigurationProviderException;
+import org.apache.nifi.minifi.c2.api.cache.ConfigurationCache;
+import org.apache.nifi.minifi.c2.api.cache.ConfigurationCacheFileInfo;
+import org.apache.nifi.minifi.c2.api.cache.WriteableConfiguration;
+import org.apache.nifi.minifi.c2.provider.cache.CacheConfigurationProvider;
+import org.junit.Before;
+import org.junit.Test;
+
+import java.util.List;
+import java.util.Map;
+
+import static org.junit.Assert.assertEquals;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+public class CacheConfigurationProviderTest {
+ public static final String TEST_CONTENT_TYPE = "test/contenttype";
+
+ private CacheConfigurationProvider cacheConfigurationProvider;
+ private ConfigurationCache configConfigurationCache;
+
+ @Before
+ public void setup() {
+ configConfigurationCache = mock(ConfigurationCache.class);
+ cacheConfigurationProvider = new CacheConfigurationProvider(TEST_CONTENT_TYPE, configConfigurationCache);
+ }
+
+ @Test
+ public void testContentType() {
+ assertEquals(TEST_CONTENT_TYPE, cacheConfigurationProvider.getContentType());
+ }
+
+ @Test
+ public void testGetConfiguration() throws ConfigurationProviderException {
+ int version = 99;
+
+ Map<String, List<String>> parameters = mock(Map.class);
+ ConfigurationCacheFileInfo configurationCacheFileInfo = mock(ConfigurationCacheFileInfo.class);
+ WriteableConfiguration configuration = mock(WriteableConfiguration.class);
+
+ when(configConfigurationCache.getCacheFileInfo(parameters)).thenReturn(configurationCacheFileInfo);
+ when(configurationCacheFileInfo.getConfiguration(version)).thenReturn(configuration);
+
+ assertEquals(configuration, cacheConfigurationProvider.getConfiguration(version, parameters));
+ }
+}
http://git-wip-us.apache.org/repos/asf/nifi-minifi/blob/f89f4150/minifi-c2/minifi-c2-provider/minifi-c2-provider-nifi-rest/pom.xml
----------------------------------------------------------------------
diff --git a/minifi-c2/minifi-c2-provider/minifi-c2-provider-nifi-rest/pom.xml b/minifi-c2/minifi-c2-provider/minifi-c2-provider-nifi-rest/pom.xml
new file mode 100644
index 0000000..8595246
--- /dev/null
+++ b/minifi-c2/minifi-c2-provider/minifi-c2-provider-nifi-rest/pom.xml
@@ -0,0 +1,77 @@
+<?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>
+ <artifactId>minifi-c2-provider</artifactId>
+ <groupId>org.apache.nifi.minifi</groupId>
+ <version>0.2.0-SNAPSHOT</version>
+ </parent>
+ <artifactId>minifi-c2-provider-nifi-rest</artifactId>
+ <packaging>jar</packaging>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.nifi.minifi</groupId>
+ <artifactId>minifi-c2-api</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>com.fasterxml.jackson.core</groupId>
+ <artifactId>jackson-core</artifactId>
+ <version>2.8.7</version>
+ </dependency>
+ <dependency>
+ <groupId>org.eclipse.jetty</groupId>
+ <artifactId>jetty-util</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.nifi.minifi</groupId>
+ <artifactId>minifi-toolkit-configuration</artifactId>
+ <version>${project.version}</version>
+ <exclusions>
+ <exclusion>
+ <groupId>org.slf4j</groupId>
+ <artifactId>slf4j-log4j12</artifactId>
+ </exclusion>
+ </exclusions>
+ </dependency>
+
+ <dependency>
+ <groupId>org.mockito</groupId>
+ <artifactId>mockito-all</artifactId>
+ <scope>test</scope>
+ </dependency>
+ </dependencies>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.rat</groupId>
+ <artifactId>apache-rat-plugin</artifactId>
+ <configuration>
+ <excludes combine.children="append">
+ <exclude>src/test/resources/noTemplates.json</exclude>
+ <exclude>src/test/resources/oneTemplate.json</exclude>
+ <exclude>src/test/resources/twoTemplates.json</exclude>
+ </excludes>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+</project>
http://git-wip-us.apache.org/repos/asf/nifi-minifi/blob/f89f4150/minifi-c2/minifi-c2-provider/minifi-c2-provider-nifi-rest/src/main/java/org/apache/nifi/minifi/c2/provider/nifi/rest/NiFiRestConfigurationProvider.java
----------------------------------------------------------------------
diff --git a/minifi-c2/minifi-c2-provider/minifi-c2-provider-nifi-rest/src/main/java/org/apache/nifi/minifi/c2/provider/nifi/rest/NiFiRestConfigurationProvider.java b/minifi-c2/minifi-c2-provider/minifi-c2-provider-nifi-rest/src/main/java/org/apache/nifi/minifi/c2/provider/nifi/rest/NiFiRestConfigurationProvider.java
new file mode 100644
index 0000000..77175d7
--- /dev/null
+++ b/minifi-c2/minifi-c2-provider/minifi-c2-provider-nifi-rest/src/main/java/org/apache/nifi/minifi/c2/provider/nifi/rest/NiFiRestConfigurationProvider.java
@@ -0,0 +1,149 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.nifi.minifi.c2.provider.nifi.rest;
+
+import com.fasterxml.jackson.core.JsonFactory;
+import org.apache.nifi.minifi.c2.api.Configuration;
+import org.apache.nifi.minifi.c2.api.ConfigurationProvider;
+import org.apache.nifi.minifi.c2.api.ConfigurationProviderException;
+import org.apache.nifi.minifi.c2.api.InvalidParameterException;
+import org.apache.nifi.minifi.c2.api.cache.ConfigurationCache;
+import org.apache.nifi.minifi.c2.api.cache.ConfigurationCacheFileInfo;
+import org.apache.nifi.minifi.c2.api.cache.WriteableConfiguration;
+import org.apache.nifi.minifi.c2.api.util.Pair;
+import org.apache.nifi.minifi.commons.schema.ConfigSchema;
+import org.apache.nifi.minifi.commons.schema.serialization.SchemaSaver;
+import org.apache.nifi.minifi.toolkit.configuration.ConfigMain;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import javax.xml.bind.JAXBException;
+import java.io.Closeable;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.HttpURLConnection;
+import java.security.GeneralSecurityException;
+import java.util.Comparator;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+import java.util.Spliterator;
+import java.util.Spliterators;
+import java.util.stream.Stream;
+import java.util.stream.StreamSupport;
+
+public class NiFiRestConfigurationProvider implements ConfigurationProvider {
+ public static final String CONTENT_TYPE = "text/yml";
+ private static final Logger logger = LoggerFactory.getLogger(NiFiRestConfigurationProvider.class);
+ private final JsonFactory jsonFactory = new JsonFactory();
+ private final ConfigurationCache configurationCache;
+ private final NiFiRestConnector niFiRestConnector;
+
+ public NiFiRestConfigurationProvider(ConfigurationCache configurationCache, String nifiUrl) throws InvalidParameterException, GeneralSecurityException, IOException {
+ this(configurationCache, new NiFiRestConnector(nifiUrl));
+ }
+
+ public NiFiRestConfigurationProvider(ConfigurationCache configurationCache, NiFiRestConnector niFiRestConnector) {
+ this.configurationCache = configurationCache;
+ this.niFiRestConnector = niFiRestConnector;
+ }
+
+ @Override
+ public String getContentType() {
+ return CONTENT_TYPE;
+ }
+
+ @Override
+ public Configuration getConfiguration(Integer version, Map<String, List<String>> parameters) throws ConfigurationProviderException {
+ ConfigurationCacheFileInfo configurationCacheFileInfo = configurationCache.getCacheFileInfo(parameters);
+ String id = null;
+ if (version == null) {
+ Pair<String, Integer> maxIdAndVersion = getMaxIdAndVersion(configurationCacheFileInfo);
+ id = maxIdAndVersion.getFirst();
+ version = maxIdAndVersion.getSecond();
+ }
+ WriteableConfiguration configuration = configurationCacheFileInfo.getConfiguration(version);
+ if (configuration.exists()) {
+ if (logger.isDebugEnabled()) {
+ logger.debug("Configuration " + configuration + " exists and can be served from configurationCache.");
+ }
+ } else {
+ if (logger.isDebugEnabled()) {
+ logger.debug("Configuration " + configuration + " doesn't exist, will need to download and convert template.");
+ }
+ if (id == null) {
+ try {
+ String filename = configuration.getName();
+ Pair<Stream<Pair<String, String>>, Closeable> streamCloseablePair = getIdAndFilenameStream();
+ try {
+ id = streamCloseablePair.getFirst().filter(p -> filename.equals(p.getSecond())).map(Pair::getFirst).findFirst()
+ .orElseThrow(() -> new InvalidParameterException("Unable to find template named " + filename));
+ } finally {
+ streamCloseablePair.getSecond().close();
+ }
+ } catch (IOException|TemplatesIteratorException e) {
+ throw new ConfigurationProviderException("Unable to retrieve template list", e);
+ }
+ }
+
+ HttpURLConnection urlConnection = niFiRestConnector.get("/templates/" + id + "/download");
+
+ try (InputStream inputStream = urlConnection.getInputStream()){
+ ConfigSchema configSchema = ConfigMain.transformTemplateToSchema(inputStream);
+ SchemaSaver.saveConfigSchema(configSchema, configuration.getOutputStream());
+ } catch (IOException e) {
+ throw new ConfigurationProviderException("Unable to download template from url " + urlConnection.getURL(), e);
+ } catch (JAXBException e) {
+ throw new ConfigurationProviderException("Unable to convert template to yaml", e);
+ } finally {
+ urlConnection.disconnect();
+ }
+ }
+ return configuration;
+ }
+
+ private Pair<Stream<Pair<String, String>>, Closeable> getIdAndFilenameStream() throws ConfigurationProviderException, IOException {
+ TemplatesIterator templatesIterator = new TemplatesIterator(niFiRestConnector, jsonFactory);
+ return new Pair<>(StreamSupport.stream(Spliterators.spliteratorUnknownSize(templatesIterator, Spliterator.ORDERED), false), templatesIterator);
+ }
+
+ private Pair<Stream<Pair<String, Integer>>, Closeable> getIdAndVersionStream(ConfigurationCacheFileInfo configurationCacheFileInfo) throws ConfigurationProviderException, IOException {
+ Pair<Stream<Pair<String, String>>, Closeable> streamCloseablePair = getIdAndFilenameStream();
+ return new Pair<>(streamCloseablePair.getFirst().map(p -> {
+ Integer version = configurationCacheFileInfo.getVersionIfMatch(p.getSecond());
+ if (version == null) {
+ return null;
+ }
+ return new Pair<>(p.getFirst(), version);
+ }).filter(Objects::nonNull), streamCloseablePair.getSecond());
+ }
+
+ private Pair<String, Integer> getMaxIdAndVersion(ConfigurationCacheFileInfo configurationCacheFileInfo) throws ConfigurationProviderException {
+ try {
+ Pair<Stream<Pair<String, Integer>>, Closeable> streamCloseablePair = getIdAndVersionStream(configurationCacheFileInfo);
+ try {
+ return streamCloseablePair.getFirst().sorted(Comparator.comparing(p -> ((Pair<String, Integer>) p).getSecond()).reversed()).findFirst()
+ .orElseThrow(() -> new ConfigurationProviderException("Didn't find any templates that matched " + configurationCacheFileInfo + ".v[0-9]+"));
+ } finally {
+ streamCloseablePair.getSecond().close();
+ }
+ } catch (IOException|TemplatesIteratorException e) {
+ throw new ConfigurationProviderException("Unable to retrieve template list", e);
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/nifi-minifi/blob/f89f4150/minifi-c2/minifi-c2-provider/minifi-c2-provider-nifi-rest/src/main/java/org/apache/nifi/minifi/c2/provider/nifi/rest/NiFiRestConnector.java
----------------------------------------------------------------------
diff --git a/minifi-c2/minifi-c2-provider/minifi-c2-provider-nifi-rest/src/main/java/org/apache/nifi/minifi/c2/provider/nifi/rest/NiFiRestConnector.java b/minifi-c2/minifi-c2-provider/minifi-c2-provider-nifi-rest/src/main/java/org/apache/nifi/minifi/c2/provider/nifi/rest/NiFiRestConnector.java
new file mode 100644
index 0000000..9a0befc
--- /dev/null
+++ b/minifi-c2/minifi-c2-provider/minifi-c2-provider-nifi-rest/src/main/java/org/apache/nifi/minifi/c2/provider/nifi/rest/NiFiRestConnector.java
@@ -0,0 +1,80 @@
+/*
+ * 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.minifi.c2.provider.nifi.rest;
+
+import org.apache.nifi.minifi.c2.api.ConfigurationProviderException;
+import org.apache.nifi.minifi.c2.api.InvalidParameterException;
+import org.apache.nifi.minifi.c2.api.properties.C2Properties;
+import org.eclipse.jetty.util.ssl.SslContextFactory;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import javax.net.ssl.HttpsURLConnection;
+import javax.net.ssl.SSLContext;
+import javax.net.ssl.SSLSocketFactory;
+import java.io.IOException;
+import java.net.HttpURLConnection;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.security.GeneralSecurityException;
+
+public class NiFiRestConnector {
+ private static final Logger logger = LoggerFactory.getLogger(NiFiRestConnector.class);
+
+ private final String nifiApiUrl;
+ private final SslContextFactory sslContextFactory;
+
+ public NiFiRestConnector(String nifiApiUrl) throws InvalidParameterException, GeneralSecurityException, IOException {
+ if (nifiApiUrl.startsWith("https:")) {
+ sslContextFactory = C2Properties.getInstance().getSslContextFactory();
+ if (sslContextFactory == null) {
+ throw new InvalidParameterException("Need sslContextFactory to connect to https NiFi endpoint (" + nifiApiUrl + ")");
+ }
+ } else {
+ sslContextFactory = null;
+ }
+ this.nifiApiUrl = nifiApiUrl;
+ }
+
+ protected HttpURLConnection get(String endpointPath) throws ConfigurationProviderException {
+ String endpointUrl = nifiApiUrl + endpointPath;
+ if (logger.isDebugEnabled()) {
+ logger.debug("Connecting to NiFi endpoint: " + endpointUrl);
+ }
+ URL url;
+ try {
+ url = new URL(endpointUrl);
+ } catch (MalformedURLException e) {
+ throw new ConfigurationProviderException("Malformed url " + endpointUrl, e);
+ }
+
+ try {
+ if (sslContextFactory == null) {
+ return (HttpURLConnection) url.openConnection();
+ } else {
+ HttpsURLConnection httpsURLConnection = (HttpsURLConnection) url.openConnection();
+ SSLContext sslContext = sslContextFactory.getSslContext();
+ SSLSocketFactory socketFactory = sslContext.getSocketFactory();
+ httpsURLConnection.setSSLSocketFactory(socketFactory);
+ return httpsURLConnection;
+ }
+ } catch (IOException e) {
+ throw new ConfigurationProviderException("Unable to connect to " + url, e);
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/nifi-minifi/blob/f89f4150/minifi-c2/minifi-c2-provider/minifi-c2-provider-nifi-rest/src/main/java/org/apache/nifi/minifi/c2/provider/nifi/rest/TemplatesIterator.java
----------------------------------------------------------------------
diff --git a/minifi-c2/minifi-c2-provider/minifi-c2-provider-nifi-rest/src/main/java/org/apache/nifi/minifi/c2/provider/nifi/rest/TemplatesIterator.java b/minifi-c2/minifi-c2-provider/minifi-c2-provider-nifi-rest/src/main/java/org/apache/nifi/minifi/c2/provider/nifi/rest/TemplatesIterator.java
new file mode 100644
index 0000000..afe6c6e
--- /dev/null
+++ b/minifi-c2/minifi-c2-provider/minifi-c2-provider-nifi-rest/src/main/java/org/apache/nifi/minifi/c2/provider/nifi/rest/TemplatesIterator.java
@@ -0,0 +1,115 @@
+/*
+ * 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.minifi.c2.provider.nifi.rest;
+
+import com.fasterxml.jackson.core.JsonFactory;
+import com.fasterxml.jackson.core.JsonParser;
+import com.fasterxml.jackson.core.JsonToken;
+import org.apache.nifi.minifi.c2.api.ConfigurationProviderException;
+import org.apache.nifi.minifi.c2.api.util.Pair;
+
+import java.io.Closeable;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.HttpURLConnection;
+import java.util.Iterator;
+import java.util.NoSuchElementException;
+
+public class TemplatesIterator implements Iterator<Pair<String, String>>, Closeable {
+ public static final String FLOW_TEMPLATES = "/flow/templates";
+
+ private final HttpURLConnection urlConnection;
+ private final InputStream inputStream;
+ private final JsonParser parser;
+ private Pair<String, String> next;
+
+ public TemplatesIterator(NiFiRestConnector niFiRestConnector, JsonFactory jsonFactory) throws ConfigurationProviderException, IOException {
+ urlConnection = niFiRestConnector.get(FLOW_TEMPLATES);
+ inputStream = urlConnection.getInputStream();
+ parser = jsonFactory.createParser(inputStream);
+ while (parser.nextToken() != JsonToken.END_OBJECT) {
+ if ("templates".equals(parser.getCurrentName())) {
+ break;
+ }
+ }
+ next = getNext();
+ }
+
+ private Pair<String, String> getNext() throws IOException {
+ while (parser.nextToken() != JsonToken.END_ARRAY) {
+ if ("template".equals(parser.getCurrentName())) {
+ String id = null;
+ String name = null;
+ while (parser.nextToken() != JsonToken.END_OBJECT) {
+ String currentName = parser.getCurrentName();
+ if ("id".equals(currentName)) {
+ parser.nextToken();
+ id = parser.getText();
+ } else if ("name".equals(currentName)) {
+ parser.nextToken();
+ name = parser.getText();
+ }
+ }
+ return new Pair<>(id, name);
+ }
+ }
+ return null;
+ }
+
+ @Override
+ public boolean hasNext() {
+ return next != null;
+ }
+
+ @Override
+ public Pair<String, String> next() {
+ if (next == null) {
+ throw new NoSuchElementException();
+ }
+ try {
+ return next;
+ } finally {
+ try {
+ next = getNext();
+ } catch (IOException e) {
+ throw new TemplatesIteratorException(e);
+ }
+ }
+ }
+
+ @Override
+ public void close() throws IOException {
+ if (parser != null) {
+ try {
+ parser.close();
+ } catch (IOException e) {
+ //Ignore
+ }
+ }
+ if (inputStream != null) {
+ try {
+ inputStream.close();
+ } catch (IOException e) {
+ //Ignore
+ }
+ }
+ if (urlConnection != null) {
+ urlConnection.disconnect();
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/nifi-minifi/blob/f89f4150/minifi-c2/minifi-c2-provider/minifi-c2-provider-nifi-rest/src/main/java/org/apache/nifi/minifi/c2/provider/nifi/rest/TemplatesIteratorException.java
----------------------------------------------------------------------
diff --git a/minifi-c2/minifi-c2-provider/minifi-c2-provider-nifi-rest/src/main/java/org/apache/nifi/minifi/c2/provider/nifi/rest/TemplatesIteratorException.java b/minifi-c2/minifi-c2-provider/minifi-c2-provider-nifi-rest/src/main/java/org/apache/nifi/minifi/c2/provider/nifi/rest/TemplatesIteratorException.java
new file mode 100644
index 0000000..af22474
--- /dev/null
+++ b/minifi-c2/minifi-c2-provider/minifi-c2-provider-nifi-rest/src/main/java/org/apache/nifi/minifi/c2/provider/nifi/rest/TemplatesIteratorException.java
@@ -0,0 +1,31 @@
+/*
+ * 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.minifi.c2.provider.nifi.rest;
+
+import java.io.IOException;
+
+public class TemplatesIteratorException extends RuntimeException {
+ public TemplatesIteratorException(IOException cause) {
+ super(cause);
+ }
+
+ @Override
+ public synchronized IOException getCause() {
+ return (IOException) super.getCause();
+ }
+}
http://git-wip-us.apache.org/repos/asf/nifi-minifi/blob/f89f4150/minifi-c2/minifi-c2-provider/minifi-c2-provider-nifi-rest/src/test/java/org/apache/nifi/minifi/c2/provider/nifi/rest/NiFiRestConfigurationProviderTest.java
----------------------------------------------------------------------
diff --git a/minifi-c2/minifi-c2-provider/minifi-c2-provider-nifi-rest/src/test/java/org/apache/nifi/minifi/c2/provider/nifi/rest/NiFiRestConfigurationProviderTest.java b/minifi-c2/minifi-c2-provider/minifi-c2-provider-nifi-rest/src/test/java/org/apache/nifi/minifi/c2/provider/nifi/rest/NiFiRestConfigurationProviderTest.java
new file mode 100644
index 0000000..2cb3a8d
--- /dev/null
+++ b/minifi-c2/minifi-c2-provider/minifi-c2-provider-nifi-rest/src/test/java/org/apache/nifi/minifi/c2/provider/nifi/rest/NiFiRestConfigurationProviderTest.java
@@ -0,0 +1,66 @@
+/*
+ * 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.minifi.c2.provider.nifi.rest;
+
+import org.apache.nifi.minifi.c2.api.cache.ConfigurationCache;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.util.Comparator;
+
+import static org.junit.Assert.assertEquals;
+import static org.mockito.Mockito.mock;
+
+public class NiFiRestConfigurationProviderTest {
+ private ConfigurationCache configConfigurationCache;
+ private NiFiRestConnector niFiRestConnector;
+ private NiFiRestConfigurationProvider niFiRestConfigurationProvider;
+ private Path cachePath;
+
+ @Before
+ public void setup() throws IOException {
+ configConfigurationCache = mock(ConfigurationCache.class);
+ niFiRestConnector = mock(NiFiRestConnector.class);
+ niFiRestConfigurationProvider = new NiFiRestConfigurationProvider(configConfigurationCache, niFiRestConnector);
+ cachePath = Files.createTempDirectory(NiFiRestConfigurationProviderTest.class.getCanonicalName());
+ }
+
+ @After
+ public void teardown() throws IOException {
+ Files.walk(cachePath)
+ .sorted(Comparator.reverseOrder())
+ .forEach(p -> {
+ try {
+ Files.deleteIfExists(p);
+ } catch (IOException e) {
+ p.toFile().deleteOnExit();
+ }
+ });
+ }
+
+ @Test
+ public void testContentType() {
+ assertEquals(NiFiRestConfigurationProvider.CONTENT_TYPE, niFiRestConfigurationProvider.getContentType());
+ }
+
+
+}
http://git-wip-us.apache.org/repos/asf/nifi-minifi/blob/f89f4150/minifi-c2/minifi-c2-provider/minifi-c2-provider-nifi-rest/src/test/java/org/apache/nifi/minifi/c2/provider/nifi/rest/TemplatesIteratorExceptionTest.java
----------------------------------------------------------------------
diff --git a/minifi-c2/minifi-c2-provider/minifi-c2-provider-nifi-rest/src/test/java/org/apache/nifi/minifi/c2/provider/nifi/rest/TemplatesIteratorExceptionTest.java b/minifi-c2/minifi-c2-provider/minifi-c2-provider-nifi-rest/src/test/java/org/apache/nifi/minifi/c2/provider/nifi/rest/TemplatesIteratorExceptionTest.java
new file mode 100644
index 0000000..3be3445
--- /dev/null
+++ b/minifi-c2/minifi-c2-provider/minifi-c2-provider-nifi-rest/src/test/java/org/apache/nifi/minifi/c2/provider/nifi/rest/TemplatesIteratorExceptionTest.java
@@ -0,0 +1,34 @@
+/*
+ * 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.minifi.c2.provider.nifi.rest;
+
+import org.apache.nifi.minifi.c2.provider.nifi.rest.TemplatesIteratorException;
+import org.junit.Test;
+
+import java.io.IOException;
+
+import static org.junit.Assert.assertEquals;
+import static org.mockito.Mockito.mock;
+
+public class TemplatesIteratorExceptionTest {
+ @Test
+ public void testCauseConstructor() {
+ IOException ioException = mock(IOException.class);
+ assertEquals(ioException, new TemplatesIteratorException(ioException).getCause());
+ }
+}
http://git-wip-us.apache.org/repos/asf/nifi-minifi/blob/f89f4150/minifi-c2/minifi-c2-provider/minifi-c2-provider-nifi-rest/src/test/java/org/apache/nifi/minifi/c2/provider/nifi/rest/TemplatesIteratorTest.java
----------------------------------------------------------------------
diff --git a/minifi-c2/minifi-c2-provider/minifi-c2-provider-nifi-rest/src/test/java/org/apache/nifi/minifi/c2/provider/nifi/rest/TemplatesIteratorTest.java b/minifi-c2/minifi-c2-provider/minifi-c2-provider-nifi-rest/src/test/java/org/apache/nifi/minifi/c2/provider/nifi/rest/TemplatesIteratorTest.java
new file mode 100644
index 0000000..ca20e4a
--- /dev/null
+++ b/minifi-c2/minifi-c2-provider/minifi-c2-provider-nifi-rest/src/test/java/org/apache/nifi/minifi/c2/provider/nifi/rest/TemplatesIteratorTest.java
@@ -0,0 +1,108 @@
+/*
+ * 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.minifi.c2.provider.nifi.rest;
+
+import com.fasterxml.jackson.core.JsonFactory;
+import com.google.common.collect.Lists;
+import org.apache.nifi.minifi.c2.api.ConfigurationProviderException;
+import org.apache.nifi.minifi.c2.api.util.Pair;
+import org.junit.Before;
+import org.junit.Test;
+
+import java.io.IOException;
+import java.net.HttpURLConnection;
+import java.util.List;
+import java.util.NoSuchElementException;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+public class TemplatesIteratorTest {
+ private JsonFactory jsonFactory;
+ private HttpURLConnection httpURLConnection;
+ private NiFiRestConnector niFiRestConnector;
+
+ @Before
+ public void setup() throws ConfigurationProviderException {
+ jsonFactory = new JsonFactory();
+ httpURLConnection = mock(HttpURLConnection.class);
+ niFiRestConnector = mock(NiFiRestConnector.class);
+ when(niFiRestConnector.get(TemplatesIterator.FLOW_TEMPLATES)).thenReturn(httpURLConnection);
+ }
+
+ @Test(expected = NoSuchElementException.class)
+ public void testIteratorNoSuchElementException() throws ConfigurationProviderException, IOException {
+ when(httpURLConnection.getInputStream()).thenReturn(TemplatesIteratorTest.class.getClassLoader().getResourceAsStream("noTemplates.json"));
+
+ try (TemplatesIterator templatesIterator = new TemplatesIterator(niFiRestConnector, jsonFactory)) {
+ assertFalse(templatesIterator.hasNext());
+ templatesIterator.next();
+ } finally {
+ verify(httpURLConnection).disconnect();
+ }
+ }
+
+ @Test
+ public void testIteratorNoTemplates() throws ConfigurationProviderException, IOException {
+ when(httpURLConnection.getInputStream()).thenReturn(TemplatesIteratorTest.class.getClassLoader().getResourceAsStream("noTemplates.json"));
+ List<Pair<String, String>> idToNameList;
+ try (TemplatesIterator templatesIterator = new TemplatesIterator(niFiRestConnector, jsonFactory)) {
+ idToNameList = Lists.newArrayList(templatesIterator);
+ }
+ assertEquals(0, idToNameList.size());
+
+ verify(httpURLConnection).disconnect();
+ }
+
+ @Test
+ public void testIteratorSingleTemplate() throws ConfigurationProviderException, IOException {
+ when(httpURLConnection.getInputStream()).thenReturn(TemplatesIteratorTest.class.getClassLoader().getResourceAsStream("oneTemplate.json"));
+ List<Pair<String, String>> idToNameList;
+ try (TemplatesIterator templatesIterator = new TemplatesIterator(niFiRestConnector, jsonFactory)) {
+ idToNameList = Lists.newArrayList(templatesIterator);
+ }
+ assertEquals(1, idToNameList.size());
+ Pair<String, String> idNamePair = idToNameList.get(0);
+ assertEquals("d05845ae-ceda-4c50-b7c2-037e42ddf1d3", idNamePair.getFirst());
+ assertEquals("raspi3.v1", idNamePair.getSecond());
+
+ verify(httpURLConnection).disconnect();
+ }
+
+ @Test
+ public void testIteratorTwoTemplates() throws ConfigurationProviderException, IOException {
+ when(httpURLConnection.getInputStream()).thenReturn(TemplatesIteratorTest.class.getClassLoader().getResourceAsStream("twoTemplates.json"));
+ List<Pair<String, String>> idToNameList;
+ try (TemplatesIterator templatesIterator = new TemplatesIterator(niFiRestConnector, jsonFactory)) {
+ idToNameList = Lists.newArrayList(templatesIterator);
+ }
+ assertEquals(2, idToNameList.size());
+ Pair<String, String> idNamePair = idToNameList.get(0);
+ assertEquals("d05845ae-ceda-4c50-b7c2-037e42ddf1d3", idNamePair.getFirst());
+ assertEquals("raspi3.v1", idNamePair.getSecond());
+
+ idNamePair = idToNameList.get(1);
+ assertEquals("9384b48d-85b4-478a-bf3e-64d113f8fbc5", idNamePair.getFirst());
+ assertEquals("raspi3.v2", idNamePair.getSecond());
+
+ verify(httpURLConnection).disconnect();
+ }
+}
http://git-wip-us.apache.org/repos/asf/nifi-minifi/blob/f89f4150/minifi-c2/minifi-c2-provider/minifi-c2-provider-nifi-rest/src/test/resources/noTemplates.json
----------------------------------------------------------------------
diff --git a/minifi-c2/minifi-c2-provider/minifi-c2-provider-nifi-rest/src/test/resources/noTemplates.json b/minifi-c2/minifi-c2-provider/minifi-c2-provider-nifi-rest/src/test/resources/noTemplates.json
new file mode 100644
index 0000000..ff41507
--- /dev/null
+++ b/minifi-c2/minifi-c2-provider/minifi-c2-provider-nifi-rest/src/test/resources/noTemplates.json
@@ -0,0 +1 @@
+{"templates":[],"generated":"14:55:13 EST"}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/nifi-minifi/blob/f89f4150/minifi-c2/minifi-c2-provider/minifi-c2-provider-nifi-rest/src/test/resources/oneTemplate.json
----------------------------------------------------------------------
diff --git a/minifi-c2/minifi-c2-provider/minifi-c2-provider-nifi-rest/src/test/resources/oneTemplate.json b/minifi-c2/minifi-c2-provider/minifi-c2-provider-nifi-rest/src/test/resources/oneTemplate.json
new file mode 100644
index 0000000..0d981f1
--- /dev/null
+++ b/minifi-c2/minifi-c2-provider/minifi-c2-provider-nifi-rest/src/test/resources/oneTemplate.json
@@ -0,0 +1,21 @@
+{
+ "generated": "10:26:04 EST",
+ "templates": [
+ {
+ "id": "d05845ae-ceda-4c50-b7c2-037e42ddf1d3",
+ "permissions": {
+ "canRead": true,
+ "canWrite": true
+ },
+ "template": {
+ "description": "",
+ "encoding-version": "1.0",
+ "groupId": "8f8eda5e-015a-1000-a9c1-b7e4fe10ae83",
+ "id": "d05845ae-ceda-4c50-b7c2-037e42ddf1d3",
+ "name": "raspi3.v1",
+ "timestamp": "03/02/2017 10:26:01 EST",
+ "uri": "http://localhost:8081/nifi-api/templates/d05845ae-ceda-4c50-b7c2-037e42ddf1d3"
+ }
+ }
+ ]
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/nifi-minifi/blob/f89f4150/minifi-c2/minifi-c2-provider/minifi-c2-provider-nifi-rest/src/test/resources/twoTemplates.json
----------------------------------------------------------------------
diff --git a/minifi-c2/minifi-c2-provider/minifi-c2-provider-nifi-rest/src/test/resources/twoTemplates.json b/minifi-c2/minifi-c2-provider/minifi-c2-provider-nifi-rest/src/test/resources/twoTemplates.json
new file mode 100644
index 0000000..9b4245a
--- /dev/null
+++ b/minifi-c2/minifi-c2-provider/minifi-c2-provider-nifi-rest/src/test/resources/twoTemplates.json
@@ -0,0 +1,37 @@
+{
+ "generated": "14:53:15 EST",
+ "templates": [
+ {
+ "id": "d05845ae-ceda-4c50-b7c2-037e42ddf1d3",
+ "permissions": {
+ "canRead": true,
+ "canWrite": true
+ },
+ "template": {
+ "description": "",
+ "encoding-version": "1.0",
+ "groupId": "8f8eda5e-015a-1000-a9c1-b7e4fe10ae83",
+ "id": "d05845ae-ceda-4c50-b7c2-037e42ddf1d3",
+ "name": "raspi3.v1",
+ "timestamp": "03/02/2017 10:26:01 EST",
+ "uri": "http://localhost:8081/nifi-api/templates/d05845ae-ceda-4c50-b7c2-037e42ddf1d3"
+ }
+ },
+ {
+ "id": "9384b48d-85b4-478a-bf3e-64d113f8fbc5",
+ "permissions": {
+ "canRead": true,
+ "canWrite": true
+ },
+ "template": {
+ "description": "",
+ "encoding-version": "1.0",
+ "groupId": "8f8eda5e-015a-1000-a9c1-b7e4fe10ae83",
+ "id": "9384b48d-85b4-478a-bf3e-64d113f8fbc5",
+ "name": "raspi3.v2",
+ "timestamp": "03/02/2017 13:08:14 EST",
+ "uri": "http://localhost:8081/nifi-api/templates/9384b48d-85b4-478a-bf3e-64d113f8fbc5"
+ }
+ }
+ ]
+}
http://git-wip-us.apache.org/repos/asf/nifi-minifi/blob/f89f4150/minifi-c2/minifi-c2-provider/pom.xml
----------------------------------------------------------------------
diff --git a/minifi-c2/minifi-c2-provider/pom.xml b/minifi-c2/minifi-c2-provider/pom.xml
new file mode 100644
index 0000000..fc0fbae
--- /dev/null
+++ b/minifi-c2/minifi-c2-provider/pom.xml
@@ -0,0 +1,32 @@
+<?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>
+ <artifactId>minifi-c2</artifactId>
+ <groupId>org.apache.nifi.minifi</groupId>
+ <version>0.2.0-SNAPSHOT</version>
+ </parent>
+ <artifactId>minifi-c2-provider</artifactId>
+ <packaging>pom</packaging>
+
+ <modules>
+ <module>minifi-c2-provider-cache</module>
+ <module>minifi-c2-provider-nifi-rest</module>
+ </modules>
+</project>
http://git-wip-us.apache.org/repos/asf/nifi-minifi/blob/f89f4150/minifi-c2/minifi-c2-service/pom.xml
----------------------------------------------------------------------
diff --git a/minifi-c2/minifi-c2-service/pom.xml b/minifi-c2/minifi-c2-service/pom.xml
new file mode 100644
index 0000000..eb52d7d
--- /dev/null
+++ b/minifi-c2/minifi-c2-service/pom.xml
@@ -0,0 +1,83 @@
+<?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>
+ <artifactId>minifi-c2</artifactId>
+ <groupId>org.apache.nifi.minifi</groupId>
+ <version>0.2.0-SNAPSHOT</version>
+ </parent>
+ <artifactId>minifi-c2-service</artifactId>
+ <packaging>war</packaging>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.nifi.minifi</groupId>
+ <artifactId>minifi-c2-api</artifactId>
+ <version>${project.version}</version>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.springframework</groupId>
+ <artifactId>spring-context</artifactId>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.springframework</groupId>
+ <artifactId>spring-web</artifactId>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.springframework</groupId>
+ <artifactId>spring-beans</artifactId>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.springframework.security</groupId>
+ <artifactId>spring-security-web</artifactId>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.springframework.security</groupId>
+ <artifactId>spring-security-config</artifactId>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.yaml</groupId>
+ <artifactId>snakeyaml</artifactId>
+ <version>1.17</version>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>javax.servlet</groupId>
+ <artifactId>javax.servlet-api</artifactId>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>javax.ws.rs</groupId>
+ <artifactId>jsr311-api</artifactId>
+ <version>1.1.1</version>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>com.wordnik</groupId>
+ <artifactId>swagger-annotations</artifactId>
+ <scope>provided</scope>
+ </dependency>
+ </dependencies>
+</project>
http://git-wip-us.apache.org/repos/asf/nifi-minifi/blob/f89f4150/minifi-c2/minifi-c2-service/src/main/java/org/apache/nifi/minifi/c2/configuration/Configuration.java
----------------------------------------------------------------------
diff --git a/minifi-c2/minifi-c2-service/src/main/java/org/apache/nifi/minifi/c2/configuration/Configuration.java b/minifi-c2/minifi-c2-service/src/main/java/org/apache/nifi/minifi/c2/configuration/Configuration.java
new file mode 100644
index 0000000..19b647f
--- /dev/null
+++ b/minifi-c2/minifi-c2-service/src/main/java/org/apache/nifi/minifi/c2/configuration/Configuration.java
@@ -0,0 +1,28 @@
+/*
+ * 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.minifi.c2.configuration;
+
+import org.apache.nifi.minifi.c2.security.SecurityConfiguration;
+import org.springframework.context.annotation.Import;
+import org.springframework.context.annotation.ImportResource;
+
+@org.springframework.context.annotation.Configuration
+@Import({SecurityConfiguration.class})
+@ImportResource({"classpath:minifi-c2-context.xml"})
+public class Configuration {
+}
http://git-wip-us.apache.org/repos/asf/nifi-minifi/blob/f89f4150/minifi-c2/minifi-c2-service/src/main/java/org/apache/nifi/minifi/c2/security/SecurityConfiguration.java
----------------------------------------------------------------------
diff --git a/minifi-c2/minifi-c2-service/src/main/java/org/apache/nifi/minifi/c2/security/SecurityConfiguration.java b/minifi-c2/minifi-c2-service/src/main/java/org/apache/nifi/minifi/c2/security/SecurityConfiguration.java
new file mode 100644
index 0000000..2c4630c
--- /dev/null
+++ b/minifi-c2/minifi-c2-service/src/main/java/org/apache/nifi/minifi/c2/security/SecurityConfiguration.java
@@ -0,0 +1,91 @@
+/*
+ * 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.minifi.c2.security;
+
+import org.apache.nifi.minifi.c2.security.authentication.C2AnonymousAuthenticationFilter;
+import org.apache.nifi.minifi.c2.security.authentication.X509AuthenticationFilter;
+import org.apache.nifi.minifi.c2.security.authentication.X509AuthenticationProvider;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.context.annotation.ImportResource;
+import org.springframework.security.authentication.AuthenticationManager;
+import org.springframework.security.authentication.AuthenticationProvider;
+import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
+import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
+import org.springframework.security.config.annotation.web.builders.HttpSecurity;
+import org.springframework.security.config.annotation.web.builders.WebSecurity;
+import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
+import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
+import org.springframework.security.config.http.SessionCreationPolicy;
+import org.springframework.security.web.authentication.AnonymousAuthenticationFilter;
+
+@Configuration
+@EnableWebSecurity
+@EnableGlobalMethodSecurity(prePostEnabled = true)
+@ImportResource({"classpath:minifi-c2-web-security-context.xml"})
+public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
+ private AuthenticationProvider authenticationProvider;
+ private X509AuthenticationFilter x509AuthenticationFilter;
+ private C2AnonymousAuthenticationFilter c2AnonymousAuthenticationFilter;
+
+ public SecurityConfiguration() {
+ super(true);
+ }
+
+ @Bean
+ @Override
+ public AuthenticationManager authenticationManagerBean() throws Exception {
+ // override xxxBean method so the authentication manager is available in app context (necessary for the method level security)
+ return super.authenticationManagerBean();
+ }
+
+ @Override
+ public void configure(WebSecurity web) throws Exception {
+ web.ignoring().antMatchers("/access", "/access/config", "/access/token", "/access/kerberos");
+ }
+
+ @Override
+ protected void configure(HttpSecurity http) throws Exception {
+ http
+ .rememberMe().disable().authorizeRequests().anyRequest().fullyAuthenticated().and()
+ .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
+ http.addFilterBefore(x509AuthenticationFilter, AnonymousAuthenticationFilter.class);
+ http.anonymous().authenticationFilter(c2AnonymousAuthenticationFilter);
+ }
+
+ @Override
+ protected void configure(AuthenticationManagerBuilder auth) throws Exception {
+ auth.authenticationProvider(authenticationProvider);
+ }
+
+ @Autowired
+ public void setX509AuthenticationProvider(X509AuthenticationProvider x509AuthenticationProvider) {
+ this.authenticationProvider = x509AuthenticationProvider;
+ }
+
+ @Autowired
+ public void setX509AuthenticationFilter(X509AuthenticationFilter x509AuthenticationFilter) {
+ this.x509AuthenticationFilter = x509AuthenticationFilter;
+ }
+
+ @Autowired
+ public void setC2AnonymousAuthenticationFilter(C2AnonymousAuthenticationFilter c2AnonymousAuthenticationFilter) {
+ this.c2AnonymousAuthenticationFilter = c2AnonymousAuthenticationFilter;
+ }
+}
http://git-wip-us.apache.org/repos/asf/nifi-minifi/blob/f89f4150/minifi-c2/minifi-c2-service/src/main/java/org/apache/nifi/minifi/c2/security/authentication/C2AnonymousAuthenticationFilter.java
----------------------------------------------------------------------
diff --git a/minifi-c2/minifi-c2-service/src/main/java/org/apache/nifi/minifi/c2/security/authentication/C2AnonymousAuthenticationFilter.java b/minifi-c2/minifi-c2-service/src/main/java/org/apache/nifi/minifi/c2/security/authentication/C2AnonymousAuthenticationFilter.java
new file mode 100644
index 0000000..e73d2ee
--- /dev/null
+++ b/minifi-c2/minifi-c2-service/src/main/java/org/apache/nifi/minifi/c2/security/authentication/C2AnonymousAuthenticationFilter.java
@@ -0,0 +1,38 @@
+/*
+ * 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.minifi.c2.security.authentication;
+
+import org.springframework.security.core.Authentication;
+import org.springframework.security.core.authority.SimpleGrantedAuthority;
+import org.springframework.security.web.authentication.AnonymousAuthenticationFilter;
+
+import javax.servlet.http.HttpServletRequest;
+import java.util.Arrays;
+
+public class C2AnonymousAuthenticationFilter extends AnonymousAuthenticationFilter {
+ public static final String ANONYMOUS = "anonymous";
+
+ public C2AnonymousAuthenticationFilter() {
+ super(ANONYMOUS);
+ }
+
+ @Override
+ protected Authentication createAuthentication(HttpServletRequest request) {
+ return new C2AuthenticationToken(ANONYMOUS, null, Arrays.asList(new SimpleGrantedAuthority("ROLE_ANONYMOUS")));
+ }
+}