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; + [email protected] +@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"))); + } +}
