http://git-wip-us.apache.org/repos/asf/nifi-minifi/blob/f89f4150/minifi-c2/minifi-c2-integration-tests/pom.xml ---------------------------------------------------------------------- diff --git a/minifi-c2/minifi-c2-integration-tests/pom.xml b/minifi-c2/minifi-c2-integration-tests/pom.xml new file mode 100644 index 0000000..60af910 --- /dev/null +++ b/minifi-c2/minifi-c2-integration-tests/pom.xml @@ -0,0 +1,128 @@ +<?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-integration-tests</artifactId> + <packaging>jar</packaging> + + <properties> + <minifi.c2.version>${project.version}</minifi.c2.version> + </properties> + + <dependencies> + <dependency> + <groupId>org.apache.nifi.minifi</groupId> + <artifactId>minifi-commons-schema</artifactId> + <version>${project.version}</version> + <scope>test</scope> + </dependency> + <dependency> + <groupId>org.apache.nifi.minifi</groupId> + <artifactId>minifi-c2-api</artifactId> + <version>${project.version}</version> + <scope>test</scope> + </dependency> + <dependency> + <groupId>org.apache.nifi</groupId> + <artifactId>nifi-toolkit-tls</artifactId> + <scope>test</scope> + <exclusions> + <exclusion> + <groupId>org.slf4j</groupId> + <artifactId>slf4j-log4j12</artifactId> + </exclusion> + </exclusions> + </dependency> + <dependency> + <groupId>com.palantir.docker.compose</groupId> + <artifactId>docker-compose-rule-junit4</artifactId> + <version>0.31.1</version> + <scope>test</scope> + </dependency> + </dependencies> + + <build> + <testResources> + <testResource> + <directory>src/test/resources</directory> + <filtering>true</filtering> + <excludes> + <exclude>**/minifi-c2-context.xml</exclude> + </excludes> + </testResource> + <testResource> + <directory>src/test/resources</directory> + <filtering>false</filtering> + <includes> + <include>**/minifi-c2-context.xml</include> + </includes> + </testResource> + </testResources> + + <plugins> + <plugin> + <artifactId>maven-surefire-plugin</artifactId> + <configuration> + <skip>true</skip> + </configuration> + </plugin> + <plugin> + <groupId>org.apache.rat</groupId> + <artifactId>apache-rat-plugin</artifactId> + <configuration> + <excludes combine.children="append"> + <exclude>src/test/resources/mocknifi/www/nifi-api/flow/templates</exclude> + </excludes> + </configuration> + </plugin> + </plugins> + </build> + + <profiles> + <profile> + <id>docker</id> + <properties> + <name>docker</name> + </properties> + <build> + <plugins> + <plugin> + <artifactId>maven-surefire-plugin</artifactId> + <configuration> + <skip>false</skip> + </configuration> + </plugin> + </plugins> + </build> + </profile> + </profiles> + + <repositories> + <repository> + <id>palantir.bintray</id> + <name>Palantir Bintray</name> + <url>https://dl.bintray.com/palantir/releases</url> + </repository> + </repositories> +</project>
http://git-wip-us.apache.org/repos/asf/nifi-minifi/blob/f89f4150/minifi-c2/minifi-c2-integration-tests/src/test/java/org/apache/nifi/minifi/c2/integration/test/AbstractTestSecure.java ---------------------------------------------------------------------- diff --git a/minifi-c2/minifi-c2-integration-tests/src/test/java/org/apache/nifi/minifi/c2/integration/test/AbstractTestSecure.java b/minifi-c2/minifi-c2-integration-tests/src/test/java/org/apache/nifi/minifi/c2/integration/test/AbstractTestSecure.java new file mode 100644 index 0000000..222512f --- /dev/null +++ b/minifi-c2/minifi-c2-integration-tests/src/test/java/org/apache/nifi/minifi/c2/integration/test/AbstractTestSecure.java @@ -0,0 +1,199 @@ +/* + * 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.integration.test; + +import com.palantir.docker.compose.DockerComposeRule; +import com.palantir.docker.compose.connection.DockerPort; +import org.apache.commons.io.IOUtils; +import org.apache.nifi.minifi.commons.schema.ConfigSchema; +import org.apache.nifi.minifi.commons.schema.serialization.SchemaLoader; +import org.apache.nifi.security.util.KeyStoreUtils; +import org.apache.nifi.security.util.SslContextFactory; +import org.apache.nifi.toolkit.tls.standalone.TlsToolkitStandalone; +import org.apache.nifi.toolkit.tls.standalone.TlsToolkitStandaloneCommandLine; +import org.junit.Test; + +import javax.net.ssl.HttpsURLConnection; +import javax.net.ssl.SSLContext; +import javax.net.ssl.TrustManagerFactory; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.net.HttpURLConnection; +import java.net.InetSocketAddress; +import java.net.Proxy; +import java.net.URL; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.nio.file.Path; +import java.security.GeneralSecurityException; +import java.security.KeyStore; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +import static org.junit.Assert.assertEquals; + +public abstract class AbstractTestSecure extends AbstractTestUnsecure { + public static final String C2_URL = "https://c2:10443/c2/config"; + + private final DockerComposeRule docker; + private final Path certificatesDirectory; + private final SSLContext trustSslContext; + + protected AbstractTestSecure(DockerComposeRule docker, Path certificatesDirectory, SSLContext trustSslContext) { + this.docker = docker; + this.certificatesDirectory = certificatesDirectory; + this.trustSslContext = trustSslContext; + } + + @Override + protected String getConfigUrl(DockerComposeRule docker) { + return C2_URL; + } + + public static SSLContext initCertificates(Path certificatesDirectory, List<String> serverHostnames) throws Exception { + List<String> toolkitCommandLine = new ArrayList<>(Arrays.asList("-O", "-o", certificatesDirectory.toFile().getAbsolutePath(), + "-C", "CN=user1", "-C", "CN=user2", "-C", "CN=user3", "-C", "CN=user4", "-S", "badKeystorePass", "-K", "badKeyPass", "-P", "badTrustPass")); + for (String serverHostname : serverHostnames) { + toolkitCommandLine.add("-n"); + toolkitCommandLine.add(serverHostname); + } + Files.createDirectories(certificatesDirectory); + TlsToolkitStandaloneCommandLine tlsToolkitStandaloneCommandLine = new TlsToolkitStandaloneCommandLine(); + tlsToolkitStandaloneCommandLine.parse(toolkitCommandLine.toArray(new String[toolkitCommandLine.size()])); + new TlsToolkitStandalone().createNifiKeystoresAndTrustStores(tlsToolkitStandaloneCommandLine.createConfig()); + + tlsToolkitStandaloneCommandLine = new TlsToolkitStandaloneCommandLine(); + tlsToolkitStandaloneCommandLine.parse(new String[]{"-O", "-o", certificatesDirectory.getParent().resolve("badCert").toFile().getAbsolutePath(), "-C", "CN=user3"}); + new TlsToolkitStandalone().createNifiKeystoresAndTrustStores(tlsToolkitStandaloneCommandLine.createConfig()); + + final KeyStore trustStore = KeyStoreUtils.getTrustStore("jks"); + try (final InputStream trustStoreStream = new FileInputStream(certificatesDirectory.resolve("c2").resolve("truststore.jks").toFile().getAbsolutePath())) { + trustStore.load(trustStoreStream, "badTrustPass".toCharArray()); + } + final TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm()); + trustManagerFactory.init(trustStore); + + return SslContextFactory.createTrustSslContext(certificatesDirectory.resolve("c2").resolve("truststore.jks").toFile().getAbsolutePath(), "badTrustPass".toCharArray(), "jks", "TLS"); + } + + @Test + public void testNoClientCert() throws Exception { + assertReturnCode("", trustSslContext, 403); + assertReturnCode("?class=raspi2", trustSslContext, 403); + assertReturnCode("?class=raspi3", trustSslContext, 403); + } + + @Test + public void testUser1() throws Exception { + SSLContext sslContext = loadSslContext("user1"); + + assertReturnCode("", sslContext, 403); + + ConfigSchema configSchema = assertReturnCode("?class=raspi2", sslContext, 200); + assertEquals("raspi2.v1", configSchema.getFlowControllerProperties().getName()); + + assertReturnCode("?class=raspi3", sslContext, 403); + } + + @Test + public void testUser2() throws Exception { + SSLContext sslContext = loadSslContext("user2"); + + assertReturnCode("", sslContext, 403); + assertReturnCode("?class=raspi2", sslContext, 403); + + ConfigSchema configSchema = assertReturnCode("?class=raspi3", sslContext, 200); + assertEquals("raspi3.v2", configSchema.getFlowControllerProperties().getName()); + } + + @Test + public void testUser3() throws Exception { + SSLContext sslContext = loadSslContext("user3"); + + assertReturnCode("", sslContext, 400); + + ConfigSchema configSchema = assertReturnCode("?class=raspi2", sslContext, 200); + assertEquals("raspi2.v1", configSchema.getFlowControllerProperties().getName()); + + configSchema = assertReturnCode("?class=raspi3", sslContext, 200); + assertEquals("raspi3.v2", configSchema.getFlowControllerProperties().getName()); + } + + @Test(expected = IOException.class) + public void testUser3WrongCA() throws Exception { + assertReturnCode("?class=raspi3", loadSslContext("user3", certificatesDirectory.getParent().resolve("badCert")), 403); + } + + @Test + public void testUser4() throws Exception { + SSLContext sslContext = loadSslContext("user4"); + + assertReturnCode("", sslContext, 403); + assertReturnCode("?class=raspi2", sslContext, 403); + assertReturnCode("?class=raspi3", sslContext, 403); + } + + protected SSLContext loadSslContext(String username) throws GeneralSecurityException, IOException { + return loadSslContext(username, certificatesDirectory); + } + + protected SSLContext loadSslContext(String username, Path directory) throws GeneralSecurityException, IOException { + char[] keystorePasswd; + try (InputStream inputStream = Files.newInputStream(directory.resolve("CN=" + username + ".password"))) { + keystorePasswd = IOUtils.toString(inputStream, StandardCharsets.UTF_8).toCharArray(); + } + return SslContextFactory.createSslContext( + directory.resolve("CN=" + username + ".p12").toFile().getAbsolutePath(), + keystorePasswd, + "PKCS12", + certificatesDirectory.resolve("c2").resolve("truststore.jks").toFile().getAbsolutePath(), + "badTrustPass".toCharArray(), "jks", SslContextFactory.ClientAuth.NONE, "TLS"); + } + + protected ConfigSchema assertReturnCode(String query, SSLContext sslContext, int expectedReturnCode) throws Exception { + HttpsURLConnection httpsURLConnection = openUrlConnection(C2_URL + query, sslContext); + try { + assertEquals(expectedReturnCode, httpsURLConnection.getResponseCode()); + if (expectedReturnCode == 200) { + return SchemaLoader.loadConfigSchemaFromYaml(httpsURLConnection.getInputStream()); + } + } finally { + httpsURLConnection.disconnect(); + } + return null; + } + + protected HttpsURLConnection openUrlConnection(String url, SSLContext sslContext) throws IOException { + DockerPort dockerPort = docker.containers().container("squid").port(3128); + HttpsURLConnection httpURLConnection = (HttpsURLConnection) new URL(url).openConnection( + new Proxy(Proxy.Type.HTTP, new InetSocketAddress(dockerPort.getIp(), dockerPort.getExternalPort()))); + httpURLConnection.setSSLSocketFactory(sslContext.getSocketFactory()); + return httpURLConnection; + } + + @Override + protected HttpURLConnection openSuperUserUrlConnection(String url) throws IOException { + try { + return openUrlConnection(url, loadSslContext("user3")); + } catch (GeneralSecurityException e) { + throw new IOException(e); + } + } +} http://git-wip-us.apache.org/repos/asf/nifi-minifi/blob/f89f4150/minifi-c2/minifi-c2-integration-tests/src/test/java/org/apache/nifi/minifi/c2/integration/test/AbstractTestUnsecure.java ---------------------------------------------------------------------- diff --git a/minifi-c2/minifi-c2-integration-tests/src/test/java/org/apache/nifi/minifi/c2/integration/test/AbstractTestUnsecure.java b/minifi-c2/minifi-c2-integration-tests/src/test/java/org/apache/nifi/minifi/c2/integration/test/AbstractTestUnsecure.java new file mode 100644 index 0000000..27a9683 --- /dev/null +++ b/minifi-c2/minifi-c2-integration-tests/src/test/java/org/apache/nifi/minifi/c2/integration/test/AbstractTestUnsecure.java @@ -0,0 +1,107 @@ +/* + * 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.integration.test; + +import com.palantir.docker.compose.DockerComposeRule; +import com.palantir.docker.compose.connection.Container; +import com.palantir.docker.compose.connection.DockerPort; +import org.apache.nifi.minifi.commons.schema.ConfigSchema; +import org.apache.nifi.minifi.commons.schema.exception.SchemaLoaderException; +import org.apache.nifi.minifi.commons.schema.serialization.SchemaLoader; +import org.junit.Test; + +import java.io.IOException; +import java.io.InputStream; +import java.net.HttpURLConnection; +import java.net.URL; + +import static org.junit.Assert.assertEquals; + +public abstract class AbstractTestUnsecure { + protected String c2Url; + + public static String getUnsecureConfigUrl(Container container) { + DockerPort dockerPort = container.port(10080); + return "http://" + dockerPort.getIp() + ":" + dockerPort.getExternalPort() + "/c2/config"; + } + + protected void setup(DockerComposeRule docker) { + c2Url = getConfigUrl(docker); + } + + protected String getConfigUrl(DockerComposeRule docker) { + return getUnsecureConfigUrl(docker.containers().container("c2")); + } + + @Test + public void testCurrentVersion() throws IOException, SchemaLoaderException { + ConfigSchema configSchema = getConfigSchema(c2Url + "?class=raspi3"); + assertEquals(3, configSchema.getVersion()); + assertEquals("raspi3.v2", configSchema.getFlowControllerProperties().getName()); + } + + @Test + public void testVersion1() throws IOException, SchemaLoaderException { + ConfigSchema configSchema = getConfigSchema(c2Url + "?class=raspi3&version=1"); + assertEquals(3, configSchema.getVersion()); + assertEquals("raspi3.v1", configSchema.getFlowControllerProperties().getName()); + } + + @Test + public void testVersion2() throws IOException, SchemaLoaderException { + ConfigSchema configSchema = getConfigSchema(c2Url + "?class=raspi3&version=2"); + assertEquals(3, configSchema.getVersion()); + assertEquals("raspi3.v2", configSchema.getFlowControllerProperties().getName()); + } + + @Test + public void testUnacceptable() throws IOException { + HttpURLConnection urlConnection = openSuperUserUrlConnection(c2Url + "?class=raspi3"); + try { + urlConnection.setRequestProperty("Accept", "text/xml"); + assertEquals(406, urlConnection.getResponseCode()); + } finally { + urlConnection.disconnect(); + } + } + + @Test + public void testInvalid() throws IOException { + HttpURLConnection urlConnection = openSuperUserUrlConnection(c2Url); + try { + assertEquals(400, urlConnection.getResponseCode()); + } finally { + urlConnection.disconnect(); + } + } + + public ConfigSchema getConfigSchema(String urlString) throws IOException, SchemaLoaderException { + HttpURLConnection urlConnection = openSuperUserUrlConnection(urlString); + ConfigSchema configSchema; + try (InputStream inputStream = urlConnection.getInputStream()) { + configSchema = SchemaLoader.loadConfigSchemaFromYaml(inputStream); + } finally { + urlConnection.disconnect(); + } + return configSchema; + } + + protected HttpURLConnection openSuperUserUrlConnection(String url) throws IOException { + return (HttpURLConnection) new URL(url).openConnection(); + } +} http://git-wip-us.apache.org/repos/asf/nifi-minifi/blob/f89f4150/minifi-c2/minifi-c2-integration-tests/src/test/java/org/apache/nifi/minifi/c2/integration/test/FileSystemCacheProviderSecureTest.java ---------------------------------------------------------------------- diff --git a/minifi-c2/minifi-c2-integration-tests/src/test/java/org/apache/nifi/minifi/c2/integration/test/FileSystemCacheProviderSecureTest.java b/minifi-c2/minifi-c2-integration-tests/src/test/java/org/apache/nifi/minifi/c2/integration/test/FileSystemCacheProviderSecureTest.java new file mode 100644 index 0000000..14ad4ae --- /dev/null +++ b/minifi-c2/minifi-c2-integration-tests/src/test/java/org/apache/nifi/minifi/c2/integration/test/FileSystemCacheProviderSecureTest.java @@ -0,0 +1,69 @@ +/* + * 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.integration.test; + +import com.palantir.docker.compose.DockerComposeRule; +import org.apache.nifi.minifi.c2.integration.test.health.HttpsStatusCodeHealthCheck; +import org.junit.AfterClass; +import org.junit.Before; +import org.junit.BeforeClass; + +import javax.net.ssl.SSLContext; +import javax.net.ssl.SSLSocketFactory; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.Arrays; + +public class FileSystemCacheProviderSecureTest extends AbstractTestSecure { + private static SSLSocketFactory healthCheckSocketFactory; + + // Not annotated as rule because we need to generate certificatesDirectory first + public static DockerComposeRule docker = DockerComposeRule.builder() + .file("target/test-classes/docker-compose-FileSystemCacheProviderSecureTest.yml") + .waitingForServices(Arrays.asList("squid", "c2"), + new HttpsStatusCodeHealthCheck(container -> C2_URL, containers -> containers.get(0), containers -> containers.get(1), () -> healthCheckSocketFactory, 403)) + .build(); + private static Path certificatesDirectory; + private static SSLContext trustSslContext; + + public FileSystemCacheProviderSecureTest() { + super(docker, certificatesDirectory, trustSslContext); + } + + /** + * Generates certificates with the tls-toolkit and then starts up the docker compose file + */ + @BeforeClass + public static void initCertificates() throws Exception { + certificatesDirectory = Paths.get(FileSystemCacheProviderSecureTest.class.getClassLoader() + .getResource("docker-compose-FileSystemCacheProviderSecureTest.yml").getFile()).getParent().toAbsolutePath().resolve("certificates-FileSystemCacheProviderSecureTest"); + trustSslContext = initCertificates(certificatesDirectory, Arrays.asList("c2")); + healthCheckSocketFactory = trustSslContext.getSocketFactory(); + docker.before(); + } + + @AfterClass + public static void cleanup() { + docker.after(); + } + + @Before + public void setup() { + super.setup(docker); + } +} http://git-wip-us.apache.org/repos/asf/nifi-minifi/blob/f89f4150/minifi-c2/minifi-c2-integration-tests/src/test/java/org/apache/nifi/minifi/c2/integration/test/FileSystemCacheProviderUnsecureTest.java ---------------------------------------------------------------------- diff --git a/minifi-c2/minifi-c2-integration-tests/src/test/java/org/apache/nifi/minifi/c2/integration/test/FileSystemCacheProviderUnsecureTest.java b/minifi-c2/minifi-c2-integration-tests/src/test/java/org/apache/nifi/minifi/c2/integration/test/FileSystemCacheProviderUnsecureTest.java new file mode 100644 index 0000000..9834d80 --- /dev/null +++ b/minifi-c2/minifi-c2-integration-tests/src/test/java/org/apache/nifi/minifi/c2/integration/test/FileSystemCacheProviderUnsecureTest.java @@ -0,0 +1,36 @@ +/* + * 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.integration.test; + +import com.palantir.docker.compose.DockerComposeRule; +import org.apache.nifi.minifi.c2.integration.test.health.HttpStatusCodeHealthCheck; +import org.junit.Before; +import org.junit.ClassRule; + +public class FileSystemCacheProviderUnsecureTest extends AbstractTestUnsecure { + @ClassRule + public static DockerComposeRule docker = DockerComposeRule.builder() + .file("target/test-classes/docker-compose-FileSystemProviderUnsecureTest.yml") + .waitingForService("c2", new HttpStatusCodeHealthCheck(FileSystemCacheProviderUnsecureTest::getUnsecureConfigUrl, 400)) + .build(); + + @Before + public void setup() { + super.setup(docker); + } +} http://git-wip-us.apache.org/repos/asf/nifi-minifi/blob/f89f4150/minifi-c2/minifi-c2-integration-tests/src/test/java/org/apache/nifi/minifi/c2/integration/test/NiFiRestConfigurationProviderSecureTest.java ---------------------------------------------------------------------- diff --git a/minifi-c2/minifi-c2-integration-tests/src/test/java/org/apache/nifi/minifi/c2/integration/test/NiFiRestConfigurationProviderSecureTest.java b/minifi-c2/minifi-c2-integration-tests/src/test/java/org/apache/nifi/minifi/c2/integration/test/NiFiRestConfigurationProviderSecureTest.java new file mode 100644 index 0000000..9ce4a9f --- /dev/null +++ b/minifi-c2/minifi-c2-integration-tests/src/test/java/org/apache/nifi/minifi/c2/integration/test/NiFiRestConfigurationProviderSecureTest.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.integration.test; + +import com.palantir.docker.compose.DockerComposeRule; +import org.apache.nifi.minifi.c2.integration.test.health.HttpsStatusCodeHealthCheck; +import org.apache.nifi.security.util.SslContextFactory; +import org.apache.nifi.toolkit.tls.standalone.TlsToolkitStandalone; +import org.bouncycastle.openssl.jcajce.JcaMiscPEMGenerator; +import org.bouncycastle.util.io.pem.PemWriter; +import org.junit.AfterClass; +import org.junit.Before; +import org.junit.BeforeClass; + +import javax.net.ssl.SSLContext; +import javax.net.ssl.SSLSocketFactory; +import java.io.InputStream; +import java.io.OutputStreamWriter; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.security.KeyStore; +import java.security.cert.Certificate; +import java.util.Arrays; + +public class NiFiRestConfigurationProviderSecureTest extends AbstractTestSecure { + private static SSLSocketFactory healthCheckSocketFactory; + private static Path certificatesDirectory; + private static SSLContext trustSslContext; + + // Not annotated as rule because we need to generate certificatesDirectory first + public static DockerComposeRule docker = DockerComposeRule.builder() + .file("target/test-classes/docker-compose-NiFiRestConfigurationProviderSecureTest.yml") + .waitingForServices(Arrays.asList("squid", "mocknifi"), + new HttpsStatusCodeHealthCheck(container -> "https://mocknifi:8443/", containers -> containers.get(0), containers -> containers.get(1), () -> { + Path c2 = certificatesDirectory.resolve("c2"); + try { + return SslContextFactory.createSslContext(c2.resolve("keystore.jks").toFile().getAbsolutePath(), "badKeystorePass".toCharArray(), "badKeyPass".toCharArray(), "JKS", + c2.resolve("truststore.jks").toFile().getAbsolutePath(), "badTrustPass".toCharArray(), "JKS", SslContextFactory.ClientAuth.NONE, "TLS").getSocketFactory(); + } catch (Exception e) { + throw new RuntimeException(e); + } + }, 200)) + .waitingForServices(Arrays.asList("squid", "c2"), + new HttpsStatusCodeHealthCheck(container -> C2_URL, containers -> containers.get(0), containers -> containers.get(1), () -> healthCheckSocketFactory, 403)) + .build(); + + public NiFiRestConfigurationProviderSecureTest() { + super(docker, certificatesDirectory, trustSslContext); + } + + /** + * Generates certificates with the tls-toolkit and then starts up the docker compose file + */ + @BeforeClass + public static void initCertificates() throws Exception { + certificatesDirectory = Paths.get(NiFiRestConfigurationProviderSecureTest.class.getClassLoader() + .getResource("docker-compose-NiFiRestConfigurationProviderSecureTest.yml").getFile()).getParent().toAbsolutePath().resolve("certificates-NiFiRestConfigurationProviderSecureTest"); + trustSslContext = initCertificates(certificatesDirectory, Arrays.asList("c2", "mocknifi")); + healthCheckSocketFactory = trustSslContext.getSocketFactory(); + + KeyStore mockNiFiKeyStore = KeyStore.getInstance("JKS"); + try (InputStream inputStream = Files.newInputStream(certificatesDirectory.resolve("mocknifi").resolve("keystore.jks"))) { + mockNiFiKeyStore.load(inputStream, "badKeystorePass".toCharArray()); + } + try (PemWriter pemWriter = new PemWriter(new OutputStreamWriter(Files.newOutputStream(certificatesDirectory.resolve("mocknifi").resolve("cert.pem"))))) { + pemWriter.writeObject(new JcaMiscPEMGenerator(mockNiFiKeyStore.getKey(TlsToolkitStandalone.NIFI_KEY, "badKeyPass".toCharArray()))); + for (Certificate certificate : mockNiFiKeyStore.getCertificateChain(TlsToolkitStandalone.NIFI_KEY)) { + pemWriter.writeObject(new JcaMiscPEMGenerator(certificate)); + } + } + + KeyStore mockNiFiTrustStore = KeyStore.getInstance("JKS"); + try (InputStream inputStream = Files.newInputStream(certificatesDirectory.resolve("mocknifi").resolve("truststore.jks"))) { + mockNiFiTrustStore.load(inputStream, "badTrustPass".toCharArray()); + } + try (PemWriter pemWriter = new PemWriter(new OutputStreamWriter(Files.newOutputStream(certificatesDirectory.resolve("mocknifi").resolve("ca.pem"))))) { + pemWriter.writeObject(new JcaMiscPEMGenerator(mockNiFiTrustStore.getCertificate(TlsToolkitStandalone.NIFI_CERT))); + } + + docker.before(); + } + + @AfterClass + public static void cleanup() { + docker.after(); + } + + @Before + public void setup() { + super.setup(docker); + } +} http://git-wip-us.apache.org/repos/asf/nifi-minifi/blob/f89f4150/minifi-c2/minifi-c2-integration-tests/src/test/java/org/apache/nifi/minifi/c2/integration/test/NiFiRestConfigurationProviderUnsecureTest.java ---------------------------------------------------------------------- diff --git a/minifi-c2/minifi-c2-integration-tests/src/test/java/org/apache/nifi/minifi/c2/integration/test/NiFiRestConfigurationProviderUnsecureTest.java b/minifi-c2/minifi-c2-integration-tests/src/test/java/org/apache/nifi/minifi/c2/integration/test/NiFiRestConfigurationProviderUnsecureTest.java new file mode 100644 index 0000000..b444cc1 --- /dev/null +++ b/minifi-c2/minifi-c2-integration-tests/src/test/java/org/apache/nifi/minifi/c2/integration/test/NiFiRestConfigurationProviderUnsecureTest.java @@ -0,0 +1,39 @@ +/* + * 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.integration.test; + +import com.palantir.docker.compose.DockerComposeRule; +import com.palantir.docker.compose.connection.waiting.HealthChecks; +import org.apache.nifi.minifi.c2.integration.test.health.HttpStatusCodeHealthCheck; +import org.junit.Before; +import org.junit.ClassRule; + +public class NiFiRestConfigurationProviderUnsecureTest extends AbstractTestUnsecure { + @ClassRule + public static DockerComposeRule docker = DockerComposeRule.builder() + .file("target/test-classes/docker-compose-NiFiRestConfigurationProviderUnsecureTest.yml") + .waitingForService("mocknifi", HealthChecks.toRespond2xxOverHttp(8080, + dockerPort -> "http://" + dockerPort.getIp() + ":" + dockerPort.getExternalPort() + "/")) + .waitingForService("c2", new HttpStatusCodeHealthCheck(FileSystemCacheProviderUnsecureTest::getUnsecureConfigUrl, 400)) + .build(); + + @Before + public void setup() { + super.setup(docker); + } +} http://git-wip-us.apache.org/repos/asf/nifi-minifi/blob/f89f4150/minifi-c2/minifi-c2-integration-tests/src/test/java/org/apache/nifi/minifi/c2/integration/test/health/HttpStatusCodeHealthCheck.java ---------------------------------------------------------------------- diff --git a/minifi-c2/minifi-c2-integration-tests/src/test/java/org/apache/nifi/minifi/c2/integration/test/health/HttpStatusCodeHealthCheck.java b/minifi-c2/minifi-c2-integration-tests/src/test/java/org/apache/nifi/minifi/c2/integration/test/health/HttpStatusCodeHealthCheck.java new file mode 100644 index 0000000..f639d96 --- /dev/null +++ b/minifi-c2/minifi-c2-integration-tests/src/test/java/org/apache/nifi/minifi/c2/integration/test/health/HttpStatusCodeHealthCheck.java @@ -0,0 +1,55 @@ +/* + * 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.integration.test.health; + +import com.palantir.docker.compose.connection.Container; +import com.palantir.docker.compose.connection.waiting.HealthCheck; +import com.palantir.docker.compose.connection.waiting.SuccessOrFailure; + +import java.io.IOException; +import java.net.HttpURLConnection; +import java.net.URL; +import java.util.function.Function; + +public class HttpStatusCodeHealthCheck implements HealthCheck<Container> { + private final Function<Container, String> urlFunction; + private final int expected; + + public HttpStatusCodeHealthCheck(Function<Container, String> urlFunction, int expected) { + this.urlFunction = urlFunction; + this.expected = expected; + } + + @Override + public SuccessOrFailure isHealthy(Container target) { + try { + int responseCode = openConnection(urlFunction.apply(target)).getResponseCode(); + if (responseCode == expected) { + return SuccessOrFailure.success(); + } else { + return SuccessOrFailure.failure("Expected Status code " + expected + " got " + responseCode); + } + } catch (IOException e) { + return SuccessOrFailure.failure("Expected Status code " + expected + " got IOException " + e.getMessage()); + } + } + + protected HttpURLConnection openConnection(String url) throws IOException { + return ((HttpURLConnection) new URL(url).openConnection()); + } +} http://git-wip-us.apache.org/repos/asf/nifi-minifi/blob/f89f4150/minifi-c2/minifi-c2-integration-tests/src/test/java/org/apache/nifi/minifi/c2/integration/test/health/HttpsStatusCodeHealthCheck.java ---------------------------------------------------------------------- diff --git a/minifi-c2/minifi-c2-integration-tests/src/test/java/org/apache/nifi/minifi/c2/integration/test/health/HttpsStatusCodeHealthCheck.java b/minifi-c2/minifi-c2-integration-tests/src/test/java/org/apache/nifi/minifi/c2/integration/test/health/HttpsStatusCodeHealthCheck.java new file mode 100644 index 0000000..9842e78 --- /dev/null +++ b/minifi-c2/minifi-c2-integration-tests/src/test/java/org/apache/nifi/minifi/c2/integration/test/health/HttpsStatusCodeHealthCheck.java @@ -0,0 +1,70 @@ +/* + * 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.integration.test.health; + +import com.palantir.docker.compose.connection.Container; +import com.palantir.docker.compose.connection.DockerPort; +import com.palantir.docker.compose.connection.waiting.HealthCheck; +import com.palantir.docker.compose.connection.waiting.SuccessOrFailure; + +import javax.net.ssl.HttpsURLConnection; +import javax.net.ssl.SSLSocketFactory; +import java.io.IOException; +import java.net.HttpURLConnection; +import java.net.InetSocketAddress; +import java.net.Proxy; +import java.net.URL; +import java.util.List; +import java.util.function.Function; +import java.util.function.Supplier; + +public class HttpsStatusCodeHealthCheck implements HealthCheck<List<Container>> { + private final Function<Container, String> urlFunction; + private final Function<List<Container>, Container> proxyExtractor; + private final Function<List<Container>, Container> serverExtractor; + private final Supplier<SSLSocketFactory> sslSocketFactorySupplier; + private final int expected; + + public HttpsStatusCodeHealthCheck(Function<Container, String> urlFunction, Function<List<Container>, Container> proxyExtractor, + Function<List<Container>, Container> serverExtractor, Supplier<SSLSocketFactory> sslSocketFactorySupplier, int expected) { + this.urlFunction = urlFunction; + this.proxyExtractor = proxyExtractor; + this.serverExtractor = serverExtractor; + this.sslSocketFactorySupplier = sslSocketFactorySupplier; + this.expected = expected; + } + + @Override + public SuccessOrFailure isHealthy(List<Container> target) { + + return new HttpStatusCodeHealthCheck(urlFunction, expected) { + @Override + protected HttpURLConnection openConnection(String url) throws IOException { + DockerPort dockerPort = proxyExtractor.apply(target).port(3128); + return getHttpURLConnection(url, sslSocketFactorySupplier.get(), dockerPort.getIp(), dockerPort.getExternalPort()); + } + }.isHealthy(serverExtractor.apply(target)); + } + + public static HttpURLConnection getHttpURLConnection(String url, SSLSocketFactory sslSocketFactory, String proxyHostname, int proxyPort) throws IOException { + HttpsURLConnection httpURLConnection = (HttpsURLConnection) new URL(url).openConnection( + new Proxy(Proxy.Type.HTTP, new InetSocketAddress(proxyHostname, proxyPort))); + httpURLConnection.setSSLSocketFactory(sslSocketFactory); + return httpURLConnection; + } +} http://git-wip-us.apache.org/repos/asf/nifi-minifi/blob/f89f4150/minifi-c2/minifi-c2-integration-tests/src/test/resources/c2-secure-rest/conf/minifi-c2-context.xml ---------------------------------------------------------------------- diff --git a/minifi-c2/minifi-c2-integration-tests/src/test/resources/c2-secure-rest/conf/minifi-c2-context.xml b/minifi-c2/minifi-c2-integration-tests/src/test/resources/c2-secure-rest/conf/minifi-c2-context.xml new file mode 100644 index 0000000..d648d88 --- /dev/null +++ b/minifi-c2/minifi-c2-integration-tests/src/test/resources/c2-secure-rest/conf/minifi-c2-context.xml @@ -0,0 +1,57 @@ +<?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. + --> + +<beans default-lazy-init="true" + xmlns="http://www.springframework.org/schema/beans" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xmlns:util="http://www.springframework.org/schema/util" + xmlns:context="http://www.springframework.org/schema/context" + xmlns:aop="http://www.springframework.org/schema/aop" + xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd + http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.1.xsd + http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd + http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.1.xsd"> + + <bean id="configService" class="org.apache.nifi.minifi.c2.service.ConfigService" scope="singleton"> + <constructor-arg> + <list> + <bean class="org.apache.nifi.minifi.c2.provider.nifi.rest.NiFiRestConfigurationProvider"> + <constructor-arg> + <bean class="org.apache.nifi.minifi.c2.cache.filesystem.FileSystemConfigurationCache"> + <constructor-arg> + <value>./cache</value> + </constructor-arg> + <constructor-arg> + <value>${class}/${class}</value> + </constructor-arg> + </bean> + </constructor-arg> + <constructor-arg> + <value>https://mocknifi:8443/nifi-api</value> + </constructor-arg> + </bean> + </list> + </constructor-arg> + <constructor-arg> + <bean class="org.apache.nifi.minifi.c2.security.authorization.GrantedAuthorityAuthorizer"> + <constructor-arg value="classpath:authorizations.yaml"/> + </bean> + </constructor-arg> + </bean> +</beans> http://git-wip-us.apache.org/repos/asf/nifi-minifi/blob/f89f4150/minifi-c2/minifi-c2-integration-tests/src/test/resources/c2-secure/conf/authorities.yaml ---------------------------------------------------------------------- diff --git a/minifi-c2/minifi-c2-integration-tests/src/test/resources/c2-secure/conf/authorities.yaml b/minifi-c2/minifi-c2-integration-tests/src/test/resources/c2-secure/conf/authorities.yaml new file mode 100644 index 0000000..c137c00 --- /dev/null +++ b/minifi-c2/minifi-c2-integration-tests/src/test/resources/c2-secure/conf/authorities.yaml @@ -0,0 +1,21 @@ +# 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. + +CN=user1: + - CLASS_RASPI_2 +CN=user2: + - CLASS_RASPI_3 +CN=user3: + - ROLE_SUPERUSER \ 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/c2-secure/conf/authorizations.yaml ---------------------------------------------------------------------- diff --git a/minifi-c2/minifi-c2-integration-tests/src/test/resources/c2-secure/conf/authorizations.yaml b/minifi-c2/minifi-c2-integration-tests/src/test/resources/c2-secure/conf/authorizations.yaml new file mode 100644 index 0000000..fec97d5 --- /dev/null +++ b/minifi-c2/minifi-c2-integration-tests/src/test/resources/c2-secure/conf/authorizations.yaml @@ -0,0 +1,30 @@ +# 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. + +Default Action: deny +Paths: + /c2/config: + Default Action: deny + Actions: + - Authorization: CLASS_RASPI_3 + Query Parameters: + class: raspi3 + Action: allow + - Authorization: CLASS_RASPI_2 + Query Parameters: + class: raspi2 + Action: allow + - Authorization: ROLE_SUPERUSER + Action: allow \ 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/c2-secure/conf/c2.properties ---------------------------------------------------------------------- diff --git a/minifi-c2/minifi-c2-integration-tests/src/test/resources/c2-secure/conf/c2.properties b/minifi-c2/minifi-c2-integration-tests/src/test/resources/c2-secure/conf/c2.properties new file mode 100644 index 0000000..b683350 --- /dev/null +++ b/minifi-c2/minifi-c2-integration-tests/src/test/resources/c2-secure/conf/c2.properties @@ -0,0 +1,27 @@ +# +# 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. +# + +minifi.c2.server.port=10443 + +minifi.c2.server.secure=true +minifi.c2.server.keystore=./conf/keystore.jks +minifi.c2.server.keystoreType=JKS +minifi.c2.server.keystorePasswd=badKeystorePass +minifi.c2.server.keyPasswd=badKeyPass +minifi.c2.server.truststore=./conf/truststore.jks +minifi.c2.server.truststoreType=JKS +minifi.c2.server.truststorePasswd=badTrustPass \ 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/c2-unsecure-rest/conf/minifi-c2-context.xml ---------------------------------------------------------------------- diff --git a/minifi-c2/minifi-c2-integration-tests/src/test/resources/c2-unsecure-rest/conf/minifi-c2-context.xml b/minifi-c2/minifi-c2-integration-tests/src/test/resources/c2-unsecure-rest/conf/minifi-c2-context.xml new file mode 100644 index 0000000..f2e4eee --- /dev/null +++ b/minifi-c2/minifi-c2-integration-tests/src/test/resources/c2-unsecure-rest/conf/minifi-c2-context.xml @@ -0,0 +1,56 @@ +<?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. + --> +<beans default-lazy-init="true" + xmlns="http://www.springframework.org/schema/beans" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xmlns:util="http://www.springframework.org/schema/util" + xmlns:context="http://www.springframework.org/schema/context" + xmlns:aop="http://www.springframework.org/schema/aop" + xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd + http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.1.xsd + http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd + http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.1.xsd"> + + <bean id="configService" class="org.apache.nifi.minifi.c2.service.ConfigService" scope="singleton"> + <constructor-arg> + <list> + <bean class="org.apache.nifi.minifi.c2.provider.nifi.rest.NiFiRestConfigurationProvider"> + <constructor-arg> + <bean class="org.apache.nifi.minifi.c2.cache.filesystem.FileSystemConfigurationCache"> + <constructor-arg> + <value>./cache</value> + </constructor-arg> + <constructor-arg> + <value>${class}/${class}</value> + </constructor-arg> + </bean> + </constructor-arg> + <constructor-arg> + <value>http://mocknifi:8080/nifi-api</value> + </constructor-arg> + </bean> + </list> + </constructor-arg> + <constructor-arg> + <bean class="org.apache.nifi.minifi.c2.security.authorization.GrantedAuthorityAuthorizer"> + <constructor-arg value="classpath:authorizations.yaml"/> + </bean> + </constructor-arg> + </bean> +</beans> http://git-wip-us.apache.org/repos/asf/nifi-minifi/blob/f89f4150/minifi-c2/minifi-c2-integration-tests/src/test/resources/c2/files/raspi2/config.yml.v1 ---------------------------------------------------------------------- diff --git a/minifi-c2/minifi-c2-integration-tests/src/test/resources/c2/files/raspi2/config.yml.v1 b/minifi-c2/minifi-c2-integration-tests/src/test/resources/c2/files/raspi2/config.yml.v1 new file mode 100644 index 0000000..116426f --- /dev/null +++ b/minifi-c2/minifi-c2-integration-tests/src/test/resources/c2/files/raspi2/config.yml.v1 @@ -0,0 +1,63 @@ +# 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. + +MiNiFi Config Version: 3 +Flow Controller: + name: raspi2.v1 + comment: '' +Core Properties: + flow controller graceful shutdown period: 10 sec + flow service write delay interval: 500 ms + administrative yield duration: 30 sec + bored yield duration: 10 millis + max concurrent threads: 1 +FlowFile Repository: + partitions: 256 + checkpoint interval: 2 mins + always sync: false + Swap: + threshold: 20000 + in period: 5 sec + in threads: 1 + out period: 5 sec + out threads: 4 +Content Repository: + content claim max appendable size: 10 MB + content claim max flow files: 100 + always sync: false +Provenance Repository: + provenance rollover time: 1 min +Component Status Repository: + buffer size: 1440 + snapshot frequency: 1 min +Security Properties: + keystore: '' + keystore type: '' + keystore password: '' + key password: '' + truststore: '' + truststore type: '' + truststore password: '' + ssl protocol: '' + Sensitive Props: + key: '' + algorithm: PBEWITHMD5AND256BITAES-CBC-OPENSSL + provider: BC +Processors: [] +Process Groups: [] +Funnels: [] +Connections: [] +Remote Process Groups: [] +NiFi Properties Overrides: {} http://git-wip-us.apache.org/repos/asf/nifi-minifi/blob/f89f4150/minifi-c2/minifi-c2-integration-tests/src/test/resources/c2/files/raspi3/config.yml.v1 ---------------------------------------------------------------------- diff --git a/minifi-c2/minifi-c2-integration-tests/src/test/resources/c2/files/raspi3/config.yml.v1 b/minifi-c2/minifi-c2-integration-tests/src/test/resources/c2/files/raspi3/config.yml.v1 new file mode 100644 index 0000000..690cdaa --- /dev/null +++ b/minifi-c2/minifi-c2-integration-tests/src/test/resources/c2/files/raspi3/config.yml.v1 @@ -0,0 +1,63 @@ +# 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. + +MiNiFi Config Version: 3 +Flow Controller: + name: raspi3.v1 + comment: '' +Core Properties: + flow controller graceful shutdown period: 10 sec + flow service write delay interval: 500 ms + administrative yield duration: 30 sec + bored yield duration: 10 millis + max concurrent threads: 1 +FlowFile Repository: + partitions: 256 + checkpoint interval: 2 mins + always sync: false + Swap: + threshold: 20000 + in period: 5 sec + in threads: 1 + out period: 5 sec + out threads: 4 +Content Repository: + content claim max appendable size: 10 MB + content claim max flow files: 100 + always sync: false +Provenance Repository: + provenance rollover time: 1 min +Component Status Repository: + buffer size: 1440 + snapshot frequency: 1 min +Security Properties: + keystore: '' + keystore type: '' + keystore password: '' + key password: '' + truststore: '' + truststore type: '' + truststore password: '' + ssl protocol: '' + Sensitive Props: + key: '' + algorithm: PBEWITHMD5AND256BITAES-CBC-OPENSSL + provider: BC +Processors: [] +Process Groups: [] +Funnels: [] +Connections: [] +Remote Process Groups: [] +NiFi Properties Overrides: {} http://git-wip-us.apache.org/repos/asf/nifi-minifi/blob/f89f4150/minifi-c2/minifi-c2-integration-tests/src/test/resources/c2/files/raspi3/config.yml.v2 ---------------------------------------------------------------------- diff --git a/minifi-c2/minifi-c2-integration-tests/src/test/resources/c2/files/raspi3/config.yml.v2 b/minifi-c2/minifi-c2-integration-tests/src/test/resources/c2/files/raspi3/config.yml.v2 new file mode 100644 index 0000000..14750b6 --- /dev/null +++ b/minifi-c2/minifi-c2-integration-tests/src/test/resources/c2/files/raspi3/config.yml.v2 @@ -0,0 +1,63 @@ +# 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. + +MiNiFi Config Version: 3 +Flow Controller: + name: raspi3.v2 + comment: '' +Core Properties: + flow controller graceful shutdown period: 10 sec + flow service write delay interval: 500 ms + administrative yield duration: 30 sec + bored yield duration: 10 millis + max concurrent threads: 1 +FlowFile Repository: + partitions: 256 + checkpoint interval: 2 mins + always sync: false + Swap: + threshold: 20000 + in period: 5 sec + in threads: 1 + out period: 5 sec + out threads: 4 +Content Repository: + content claim max appendable size: 10 MB + content claim max flow files: 100 + always sync: false +Provenance Repository: + provenance rollover time: 1 min +Component Status Repository: + buffer size: 1440 + snapshot frequency: 1 min +Security Properties: + keystore: '' + keystore type: '' + keystore password: '' + key password: '' + truststore: '' + truststore type: '' + truststore password: '' + ssl protocol: '' + Sensitive Props: + key: '' + algorithm: PBEWITHMD5AND256BITAES-CBC-OPENSSL + provider: BC +Processors: [] +Process Groups: [] +Funnels: [] +Connections: [] +Remote Process Groups: [] +NiFi Properties Overrides: {} http://git-wip-us.apache.org/repos/asf/nifi-minifi/blob/f89f4150/minifi-c2/minifi-c2-integration-tests/src/test/resources/docker-compose-FileSystemCacheProviderSecureTest.yml ---------------------------------------------------------------------- diff --git a/minifi-c2/minifi-c2-integration-tests/src/test/resources/docker-compose-FileSystemCacheProviderSecureTest.yml b/minifi-c2/minifi-c2-integration-tests/src/test/resources/docker-compose-FileSystemCacheProviderSecureTest.yml new file mode 100644 index 0000000..27768d4 --- /dev/null +++ b/minifi-c2/minifi-c2-integration-tests/src/test/resources/docker-compose-FileSystemCacheProviderSecureTest.yml @@ -0,0 +1,40 @@ +# 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. + +version: "2" + +services: + c2: + image: apacheminific2:${minifi.c2.version} + ports: + - "10443" + hostname: c2 + volumes: + - ./c2/files:/opt/minifi-c2/minifi-c2-${minifi.c2.version}/files + + - ./c2-secure/conf/c2.properties:/opt/minifi-c2/minifi-c2-${minifi.c2.version}/conf/c2.properties + - ./c2-secure/conf/authorities.yaml:/opt/minifi-c2/minifi-c2-${minifi.c2.version}/conf/authorities.yaml + - ./c2-secure/conf/authorizations.yaml:/opt/minifi-c2/minifi-c2-${minifi.c2.version}/conf/authorizations.yaml + + - ./certificates-FileSystemCacheProviderSecureTest/c2/keystore.jks:/opt/minifi-c2/minifi-c2-${minifi.c2.version}/conf/keystore.jks + - ./certificates-FileSystemCacheProviderSecureTest/c2/truststore.jks:/opt/minifi-c2/minifi-c2-${minifi.c2.version}/conf/truststore.jks + + squid: + image: chrisdaish/squid + ports: + - "3128" + hostname: squid + volumes: + - ./squid/squid.conf:/etc/squid/squid.conf \ 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/docker-compose-FileSystemProviderUnsecureTest.yml ---------------------------------------------------------------------- diff --git a/minifi-c2/minifi-c2-integration-tests/src/test/resources/docker-compose-FileSystemProviderUnsecureTest.yml b/minifi-c2/minifi-c2-integration-tests/src/test/resources/docker-compose-FileSystemProviderUnsecureTest.yml new file mode 100644 index 0000000..fe4f8ec --- /dev/null +++ b/minifi-c2/minifi-c2-integration-tests/src/test/resources/docker-compose-FileSystemProviderUnsecureTest.yml @@ -0,0 +1,25 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the \"License\"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an \"AS IS\" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +version: "2" + +services: + c2: + image: apacheminific2:${minifi.c2.version} + ports: + - "10080" + hostname: c2 + volumes: + - ./c2/files:/opt/minifi-c2/minifi-c2-${minifi.c2.version}/files \ 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/docker-compose-NiFiRestConfigurationProviderSecureTest.yml ---------------------------------------------------------------------- diff --git a/minifi-c2/minifi-c2-integration-tests/src/test/resources/docker-compose-NiFiRestConfigurationProviderSecureTest.yml b/minifi-c2/minifi-c2-integration-tests/src/test/resources/docker-compose-NiFiRestConfigurationProviderSecureTest.yml new file mode 100644 index 0000000..8665b7f --- /dev/null +++ b/minifi-c2/minifi-c2-integration-tests/src/test/resources/docker-compose-NiFiRestConfigurationProviderSecureTest.yml @@ -0,0 +1,55 @@ +# 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. + +version: "2" + +services: + c2: + image: apacheminific2:${minifi.c2.version} + ports: + - "10443" + hostname: c2 + volumes: + - ./c2-secure/conf/c2.properties:/opt/minifi-c2/minifi-c2-${minifi.c2.version}/conf/c2.properties + - ./c2-secure/conf/authorities.yaml:/opt/minifi-c2/minifi-c2-${minifi.c2.version}/conf/authorities.yaml + - ./c2-secure/conf/authorizations.yaml:/opt/minifi-c2/minifi-c2-${minifi.c2.version}/conf/authorizations.yaml + - ./c2-secure-rest/conf/minifi-c2-context.xml:/opt/minifi-c2/minifi-c2-${minifi.c2.version}/conf/minifi-c2-context.xml + + - ./certificates-NiFiRestConfigurationProviderSecureTest/c2/keystore.jks:/opt/minifi-c2/minifi-c2-${minifi.c2.version}/conf/keystore.jks + - ./certificates-NiFiRestConfigurationProviderSecureTest/c2/truststore.jks:/opt/minifi-c2/minifi-c2-${minifi.c2.version}/conf/truststore.jks + + squid: + image: chrisdaish/squid + ports: + - "3128" + hostname: squid + volumes: + - ./squid/squid.conf:/etc/squid/squid.conf + + mocknifi: + image: python:2 + ports: + - "8443" + hostname: mocknifi + volumes: + - ./mocknifi-secure/server.py:/root/server.py + - ./mocknifi/www:/var/www + + - ./certificates-NiFiRestConfigurationProviderSecureTest/mocknifi/cert.pem:/root/cert.pem + - ./certificates-NiFiRestConfigurationProviderSecureTest/mocknifi/ca.pem:/root/ca.pem + working_dir: /var/www + entrypoint: + - python + - /root/server.py \ 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/docker-compose-NiFiRestConfigurationProviderUnsecureTest.yml ---------------------------------------------------------------------- diff --git a/minifi-c2/minifi-c2-integration-tests/src/test/resources/docker-compose-NiFiRestConfigurationProviderUnsecureTest.yml b/minifi-c2/minifi-c2-integration-tests/src/test/resources/docker-compose-NiFiRestConfigurationProviderUnsecureTest.yml new file mode 100644 index 0000000..a80428c --- /dev/null +++ b/minifi-c2/minifi-c2-integration-tests/src/test/resources/docker-compose-NiFiRestConfigurationProviderUnsecureTest.yml @@ -0,0 +1,37 @@ +# 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. + +version: "2" + +services: + c2: + image: apacheminific2:${minifi.c2.version} + ports: + - "10080" + hostname: c2 + volumes: + - ./c2-unsecure-rest/conf/minifi-c2-context.xml:/opt/minifi-c2/minifi-c2-${minifi.c2.version}/conf/minifi-c2-context.xml + mocknifi: + image: python:2 + ports: + - "8080" + hostname: mocknifi + volumes: + - ./mocknifi-unsecure/server.py:/root/server.py + - ./mocknifi/www:/var/www + working_dir: /var/www + entrypoint: + - python + - /root/server.py \ 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-secure/server.py ---------------------------------------------------------------------- diff --git a/minifi-c2/minifi-c2-integration-tests/src/test/resources/mocknifi-secure/server.py b/minifi-c2/minifi-c2-integration-tests/src/test/resources/mocknifi-secure/server.py new file mode 100644 index 0000000..fe869a8 --- /dev/null +++ b/minifi-c2/minifi-c2-integration-tests/src/test/resources/mocknifi-secure/server.py @@ -0,0 +1,48 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the \"License\"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an \"AS IS\" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +#!/usr/bin/env python + +import logging + +from argparse import ArgumentParser +from BaseHTTPServer import HTTPServer +from os import chdir +from SimpleHTTPServer import SimpleHTTPRequestHandler +from SocketServer import ThreadingMixIn +from ssl import CERT_REQUIRED, wrap_socket + +# Needs to be threaded or health check hangs the server +class ThreadedHTTPServer(ThreadingMixIn, HTTPServer): + pass + +if __name__ == '__main__': + logging.basicConfig(level=logging.DEBUG) + parser = ArgumentParser(description='Serve up directory with ssl') + parser.add_argument('--dir', default='/var/www') + parser.add_argument('--port', type=int, default=8443) + parser.add_argument('--cert', default='/root/cert.pem') + parser.add_argument('--ca', default='/root/ca.pem') + + logging.debug('About to parse arguments') + args = parser.parse_args() + + logging.debug('Serving directory ' + args.dir + ' via HTTPS at port ' + str(args.port)) + + chdir(args.dir) + + server = ThreadedHTTPServer(('', args.port), SimpleHTTPRequestHandler) + server.socket = wrap_socket(server.socket, certfile=args.cert, ca_certs=args.ca, server_side=True, cert_reqs=CERT_REQUIRED) + server.serve_forever() \ 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-unsecure/server.py ---------------------------------------------------------------------- diff --git a/minifi-c2/minifi-c2-integration-tests/src/test/resources/mocknifi-unsecure/server.py b/minifi-c2/minifi-c2-integration-tests/src/test/resources/mocknifi-unsecure/server.py new file mode 100644 index 0000000..82d5f6a --- /dev/null +++ b/minifi-c2/minifi-c2-integration-tests/src/test/resources/mocknifi-unsecure/server.py @@ -0,0 +1,44 @@ +# 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. + +#!/usr/bin/env python + +import logging + +from argparse import ArgumentParser +from BaseHTTPServer import HTTPServer +from os import chdir +from SimpleHTTPServer import SimpleHTTPRequestHandler +from SocketServer import ThreadingMixIn + +# Needs to be threaded or health check hangs the server +class ThreadedHTTPServer(ThreadingMixIn, HTTPServer): + pass + +if __name__ == '__main__': + logging.basicConfig(level=logging.DEBUG) + parser = ArgumentParser(description='Serve up directory over http') + parser.add_argument('--dir', default='/var/www') + parser.add_argument('--port', type=int, default=8080) + + logging.debug('About to parse arguments') + args = parser.parse_args() + + logging.debug('Serving directory ' + args.dir + ' via HTTP at port ' + str(args.port)) + + chdir(args.dir) + + server = ThreadedHTTPServer(('', args.port), SimpleHTTPRequestHandler) + server.serve_forever() \ 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/flow/templates ---------------------------------------------------------------------- diff --git a/minifi-c2/minifi-c2-integration-tests/src/test/resources/mocknifi/www/nifi-api/flow/templates b/minifi-c2/minifi-c2-integration-tests/src/test/resources/mocknifi/www/nifi-api/flow/templates new file mode 100644 index 0000000..496665b --- /dev/null +++ b/minifi-c2/minifi-c2-integration-tests/src/test/resources/mocknifi/www/nifi-api/flow/templates @@ -0,0 +1,53 @@ +{ + "generated": "15:41:45 EDT", + "templates": [ + { + "id": "f080ec50-ca32-4b36-8453-5a7145bec4c5", + "permissions": { + "canRead": true, + "canWrite": true + }, + "template": { + "description": "", + "encoding-version": "1.0", + "groupId": "8f8eda5e-015a-1000-a9c1-b7e4fe10ae83", + "id": "f080ec50-ca32-4b36-8453-5a7145bec4c5", + "name": "raspi3.v1", + "timestamp": "03/07/2017 11:13:03 EST", + "uri": "http://localhost:8080/nifi-api/templates/f080ec50-ca32-4b36-8453-5a7145bec4c5" + } + }, + { + "id": "87048385-a6ca-42fe-b2d8-6a563cedd036", + "permissions": { + "canRead": true, + "canWrite": true + }, + "template": { + "description": "", + "encoding-version": "1.0", + "groupId": "8f8eda5e-015a-1000-a9c1-b7e4fe10ae83", + "id": "87048385-a6ca-42fe-b2d8-6a563cedd036", + "name": "raspi2.v1", + "timestamp": "03/17/2017 15:41:33 EDT", + "uri": "http://localhost:8080/nifi-api/templates/87048385-a6ca-42fe-b2d8-6a563cedd036" + } + }, + { + "id": "dd737a3e-333e-40df-a0bc-d7e28c8e6843", + "permissions": { + "canRead": true, + "canWrite": true + }, + "template": { + "description": "", + "encoding-version": "1.0", + "groupId": "8f8eda5e-015a-1000-a9c1-b7e4fe10ae83", + "id": "dd737a3e-333e-40df-a0bc-d7e28c8e6843", + "name": "raspi3.v2", + "timestamp": "03/17/2017 13:22:58 EDT", + "uri": "http://localhost:8080/nifi-api/templates/dd737a3e-333e-40df-a0bc-d7e28c8e6843" + } + } + ] +} \ 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/87048385-a6ca-42fe-b2d8-6a563cedd036/download ---------------------------------------------------------------------- diff --git a/minifi-c2/minifi-c2-integration-tests/src/test/resources/mocknifi/www/nifi-api/templates/87048385-a6ca-42fe-b2d8-6a563cedd036/download b/minifi-c2/minifi-c2-integration-tests/src/test/resources/mocknifi/www/nifi-api/templates/87048385-a6ca-42fe-b2d8-6a563cedd036/download new file mode 100644 index 0000000..5d36113 --- /dev/null +++ b/minifi-c2/minifi-c2-integration-tests/src/test/resources/mocknifi/www/nifi-api/templates/87048385-a6ca-42fe-b2d8-6a563cedd036/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>raspi2.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 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 15:41:33 EDT</timestamp> +</template> \ No newline at end of file
