You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nifi.apache.org by al...@apache.org on 2017/05/15 13:44:47 UTC
[3/4] nifi-minifi git commit: MINIFI-272 - Delegating C2 Provider,
Caching ConfigService, Tests Proxy auth, caching fixes Added C2 readme
http://git-wip-us.apache.org/repos/asf/nifi-minifi/blob/4dc0ce30/minifi-c2/minifi-c2-integration-tests/src/test/java/org/apache/nifi/minifi/c2/integration/test/DelegatingConfigurationProviderUnsecureTest.java
----------------------------------------------------------------------
diff --git a/minifi-c2/minifi-c2-integration-tests/src/test/java/org/apache/nifi/minifi/c2/integration/test/DelegatingConfigurationProviderUnsecureTest.java b/minifi-c2/minifi-c2-integration-tests/src/test/java/org/apache/nifi/minifi/c2/integration/test/DelegatingConfigurationProviderUnsecureTest.java
new file mode 100644
index 0000000..8394427
--- /dev/null
+++ b/minifi-c2/minifi-c2-integration-tests/src/test/java/org/apache/nifi/minifi/c2/integration/test/DelegatingConfigurationProviderUnsecureTest.java
@@ -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.
+ */
+
+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 DelegatingConfigurationProviderUnsecureTest extends AbstractTestUnsecure {
+ @ClassRule
+ public static DockerComposeRule docker = DockerComposeRule.builder()
+ .file("target/test-classes/docker-compose-DelegatingProviderUnsecureTest.yml")
+ .waitingForService("c2-upstream", new HttpStatusCodeHealthCheck(DelegatingConfigurationProviderUnsecureTest::getUnsecureConfigUrl, 400))
+ .waitingForService("c2", new HttpStatusCodeHealthCheck(DelegatingConfigurationProviderUnsecureTest::getUnsecureConfigUrl, 400))
+ .build();
+
+ @Before
+ public void setup() {
+ super.setup(docker);
+ }
+}
http://git-wip-us.apache.org/repos/asf/nifi-minifi/blob/4dc0ce30/minifi-c2/minifi-c2-integration-tests/src/test/resources/c2-secure-delegating/conf/minifi-c2-context.xml
----------------------------------------------------------------------
diff --git a/minifi-c2/minifi-c2-integration-tests/src/test/resources/c2-secure-delegating/conf/minifi-c2-context.xml b/minifi-c2/minifi-c2-integration-tests/src/test/resources/c2-secure-delegating/conf/minifi-c2-context.xml
new file mode 100644
index 0000000..e3e4976
--- /dev/null
+++ b/minifi-c2/minifi-c2-integration-tests/src/test/resources/c2-secure-delegating/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.delegating.DelegatingConfigurationProvider">
+ <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://c2-upstream:10443</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/4dc0ce30/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
index d648d88..42c98ea 100644
--- 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
@@ -45,6 +45,9 @@
<constructor-arg>
<value>https://mocknifi:8443/nifi-api</value>
</constructor-arg>
+ <constructor-arg>
+ <value>${class}.v${version}</value>
+ </constructor-arg>
</bean>
</list>
</constructor-arg>
http://git-wip-us.apache.org/repos/asf/nifi-minifi/blob/4dc0ce30/minifi-c2/minifi-c2-integration-tests/src/test/resources/c2-unsecure-delegating/conf/minifi-c2-context.xml
----------------------------------------------------------------------
diff --git a/minifi-c2/minifi-c2-integration-tests/src/test/resources/c2-unsecure-delegating/conf/minifi-c2-context.xml b/minifi-c2/minifi-c2-integration-tests/src/test/resources/c2-unsecure-delegating/conf/minifi-c2-context.xml
new file mode 100644
index 0000000..a246219
--- /dev/null
+++ b/minifi-c2/minifi-c2-integration-tests/src/test/resources/c2-unsecure-delegating/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.delegating.DelegatingConfigurationProvider">
+ <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://c2-upstream:10080</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/4dc0ce30/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
index f2e4eee..3834cc8 100644
--- 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
@@ -44,6 +44,9 @@
<constructor-arg>
<value>http://mocknifi:8080/nifi-api</value>
</constructor-arg>
+ <constructor-arg>
+ <value>${class}.v${version}</value>
+ </constructor-arg>
</bean>
</list>
</constructor-arg>
http://git-wip-us.apache.org/repos/asf/nifi-minifi/blob/4dc0ce30/minifi-c2/minifi-c2-integration-tests/src/test/resources/c2-upstream-secure/conf/authorities.yaml
----------------------------------------------------------------------
diff --git a/minifi-c2/minifi-c2-integration-tests/src/test/resources/c2-upstream-secure/conf/authorities.yaml b/minifi-c2/minifi-c2-integration-tests/src/test/resources/c2-upstream-secure/conf/authorities.yaml
new file mode 100644
index 0000000..22be134
--- /dev/null
+++ b/minifi-c2/minifi-c2-integration-tests/src/test/resources/c2-upstream-secure/conf/authorities.yaml
@@ -0,0 +1,17 @@
+# 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=c2, OU=NIFI:
+ - C2
http://git-wip-us.apache.org/repos/asf/nifi-minifi/blob/4dc0ce30/minifi-c2/minifi-c2-integration-tests/src/test/resources/c2-upstream-secure/conf/authorizations.yaml
----------------------------------------------------------------------
diff --git a/minifi-c2/minifi-c2-integration-tests/src/test/resources/c2-upstream-secure/conf/authorizations.yaml b/minifi-c2/minifi-c2-integration-tests/src/test/resources/c2-upstream-secure/conf/authorizations.yaml
new file mode 100644
index 0000000..6d626f7
--- /dev/null
+++ b/minifi-c2/minifi-c2-integration-tests/src/test/resources/c2-upstream-secure/conf/authorizations.yaml
@@ -0,0 +1,32 @@
+# 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: C2
+ Query Parameters:
+ class: raspi4
+ Action: deny
+ - Authorization: C2
+ Action: allow
+
+ /c2/config/contentTypes:
+ Default Action: deny
+ Actions:
+ - Authorization: C2
+ Action: allow
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/nifi-minifi/blob/4dc0ce30/minifi-c2/minifi-c2-integration-tests/src/test/resources/c2/files/raspi2/config.text.yml.v1
----------------------------------------------------------------------
diff --git a/minifi-c2/minifi-c2-integration-tests/src/test/resources/c2/files/raspi2/config.text.yml.v1 b/minifi-c2/minifi-c2-integration-tests/src/test/resources/c2/files/raspi2/config.text.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.text.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/4dc0ce30/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
deleted file mode 100644
index 116426f..0000000
--- a/minifi-c2/minifi-c2-integration-tests/src/test/resources/c2/files/raspi2/config.yml.v1
+++ /dev/null
@@ -1,63 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements. See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.
-# The ASF licenses this file to You under the Apache License, Version 2.0
-# (the \"License\"); you may not use this file except in compliance with
-# the License. You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an \"AS IS\" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-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/4dc0ce30/minifi-c2/minifi-c2-integration-tests/src/test/resources/c2/files/raspi3/config.text.yml.v1
----------------------------------------------------------------------
diff --git a/minifi-c2/minifi-c2-integration-tests/src/test/resources/c2/files/raspi3/config.text.yml.v1 b/minifi-c2/minifi-c2-integration-tests/src/test/resources/c2/files/raspi3/config.text.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.text.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/4dc0ce30/minifi-c2/minifi-c2-integration-tests/src/test/resources/c2/files/raspi3/config.text.yml.v2
----------------------------------------------------------------------
diff --git a/minifi-c2/minifi-c2-integration-tests/src/test/resources/c2/files/raspi3/config.text.yml.v2 b/minifi-c2/minifi-c2-integration-tests/src/test/resources/c2/files/raspi3/config.text.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.text.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/4dc0ce30/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
deleted file mode 100644
index 690cdaa..0000000
--- a/minifi-c2/minifi-c2-integration-tests/src/test/resources/c2/files/raspi3/config.yml.v1
+++ /dev/null
@@ -1,63 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements. See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.
-# The ASF licenses this file to You under the Apache License, Version 2.0
-# (the \"License\"); you may not use this file except in compliance with
-# the License. You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an \"AS IS\" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-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/4dc0ce30/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
deleted file mode 100644
index 14750b6..0000000
--- a/minifi-c2/minifi-c2-integration-tests/src/test/resources/c2/files/raspi3/config.yml.v2
+++ /dev/null
@@ -1,63 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements. See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.
-# The ASF licenses this file to You under the Apache License, Version 2.0
-# (the \"License\"); you may not use this file except in compliance with
-# the License. You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an \"AS IS\" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-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/4dc0ce30/minifi-c2/minifi-c2-integration-tests/src/test/resources/docker-compose-DelegatingProviderSecureTest.yml
----------------------------------------------------------------------
diff --git a/minifi-c2/minifi-c2-integration-tests/src/test/resources/docker-compose-DelegatingProviderSecureTest.yml b/minifi-c2/minifi-c2-integration-tests/src/test/resources/docker-compose-DelegatingProviderSecureTest.yml
new file mode 100644
index 0000000..2c19308
--- /dev/null
+++ b/minifi-c2/minifi-c2-integration-tests/src/test/resources/docker-compose-DelegatingProviderSecureTest.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-upstream:
+ image: apacheminific2:${minifi.c2.version}
+ ports:
+ - "10443"
+ hostname: c2-upstream
+ 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-upstream-secure/conf/authorities.yaml:/opt/minifi-c2/minifi-c2-${minifi.c2.version}/conf/authorities.yaml
+ - ./c2-upstream-secure/conf/authorizations.yaml:/opt/minifi-c2/minifi-c2-${minifi.c2.version}/conf/authorizations.yaml
+
+ - ./certificates-DelegatingConfigurationProviderSecureTest/c2-upstream/keystore.jks:/opt/minifi-c2/minifi-c2-${minifi.c2.version}/conf/keystore.jks
+ - ./certificates-DelegatingConfigurationProviderSecureTest/c2-upstream/truststore.jks:/opt/minifi-c2/minifi-c2-${minifi.c2.version}/conf/truststore.jks
+
+ c2:
+ image: apacheminific2:${minifi.c2.version}
+ ports:
+ - "10443"
+ hostname: c2
+ volumes:
+ - ./c2-secure-delegating/conf/minifi-c2-context.xml:/opt/minifi-c2/minifi-c2-${minifi.c2.version}/conf/minifi-c2-context.xml
+
+ - ./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-DelegatingConfigurationProviderSecureTest/c2/keystore.jks:/opt/minifi-c2/minifi-c2-${minifi.c2.version}/conf/keystore.jks
+ - ./certificates-DelegatingConfigurationProviderSecureTest/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/4dc0ce30/minifi-c2/minifi-c2-integration-tests/src/test/resources/docker-compose-DelegatingProviderUnsecureTest.yml
----------------------------------------------------------------------
diff --git a/minifi-c2/minifi-c2-integration-tests/src/test/resources/docker-compose-DelegatingProviderUnsecureTest.yml b/minifi-c2/minifi-c2-integration-tests/src/test/resources/docker-compose-DelegatingProviderUnsecureTest.yml
new file mode 100644
index 0000000..a5d0da4
--- /dev/null
+++ b/minifi-c2/minifi-c2-integration-tests/src/test/resources/docker-compose-DelegatingProviderUnsecureTest.yml
@@ -0,0 +1,32 @@
+# 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-upstream:
+ image: apacheminific2:${minifi.c2.version}
+ ports:
+ - "10080"
+ hostname: c2-upstream
+ volumes:
+ - ./c2/files:/opt/minifi-c2/minifi-c2-${minifi.c2.version}/files
+ c2:
+ image: apacheminific2:${minifi.c2.version}
+ ports:
+ - "10080"
+ hostname: c2
+ volumes:
+ - ./c2-unsecure-delegating/conf/minifi-c2-context.xml:/opt/minifi-c2/minifi-c2-${minifi.c2.version}/conf/minifi-c2-context.xml
http://git-wip-us.apache.org/repos/asf/nifi-minifi/blob/4dc0ce30/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
index 5c8b1f8..abace06 100644
--- 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
@@ -57,10 +57,8 @@ public class JettyServer {
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 {
+ if (properties.isSecure()) {
+ SslContextFactory sslContextFactory = properties.getSslContextFactory();
HttpConfiguration config = new HttpConfiguration();
config.setSecureScheme("https");
config.setSecurePort(port);
@@ -72,6 +70,8 @@ public class JettyServer {
serverConnector.setPort(port);
server.addConnector(serverConnector);
+ } else {
+ server = new Server(port);
}
server.setHandler(handlers);
http://git-wip-us.apache.org/repos/asf/nifi-minifi/blob/4dc0ce30/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
index b0864ac..f65a86b 100644
--- 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
@@ -26,21 +26,21 @@ import java.util.List;
import java.util.Map;
public class CacheConfigurationProvider implements ConfigurationProvider {
- private final String contentType;
+ private final List<String> contentTypes;
private final ConfigurationCache configurationCache;
- public CacheConfigurationProvider(String contentType, ConfigurationCache configurationCache) {
- this.contentType = contentType;
+ public CacheConfigurationProvider(List<String> contentTypes, ConfigurationCache configurationCache) {
+ this.contentTypes = contentTypes;
this.configurationCache = configurationCache;
}
@Override
- public String getContentType() {
- return contentType;
+ public List<String> getContentTypes() {
+ return contentTypes;
}
@Override
- public Configuration getConfiguration(Integer version, Map<String, List<String>> parameters) throws ConfigurationProviderException {
- return configurationCache.getCacheFileInfo(parameters).getConfiguration(version);
+ public Configuration getConfiguration(String contentType, Integer version, Map<String, List<String>> parameters) throws ConfigurationProviderException {
+ return configurationCache.getCacheFileInfo(contentType, parameters).getConfiguration(version);
}
}
http://git-wip-us.apache.org/repos/asf/nifi-minifi/blob/4dc0ce30/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
index d038194..bcc37e9 100644
--- 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
@@ -21,10 +21,10 @@ 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.Arrays;
import java.util.List;
import java.util.Map;
@@ -34,6 +34,7 @@ import static org.mockito.Mockito.when;
public class CacheConfigurationProviderTest {
public static final String TEST_CONTENT_TYPE = "test/contenttype";
+ public static final String TEST_CONTENT_TYPE_2 = "test/contenttype2";
private CacheConfigurationProvider cacheConfigurationProvider;
private ConfigurationCache configConfigurationCache;
@@ -41,25 +42,30 @@ public class CacheConfigurationProviderTest {
@Before
public void setup() {
configConfigurationCache = mock(ConfigurationCache.class);
- cacheConfigurationProvider = new CacheConfigurationProvider(TEST_CONTENT_TYPE, configConfigurationCache);
+ cacheConfigurationProvider = new CacheConfigurationProvider(Arrays.asList(TEST_CONTENT_TYPE, TEST_CONTENT_TYPE_2), configConfigurationCache);
}
@Test
public void testContentType() {
- assertEquals(TEST_CONTENT_TYPE, cacheConfigurationProvider.getContentType());
+ assertEquals(Arrays.asList(TEST_CONTENT_TYPE, TEST_CONTENT_TYPE_2), cacheConfigurationProvider.getContentTypes());
}
@Test
public void testGetConfiguration() throws ConfigurationProviderException {
int version = 99;
- Map<String, List<String>> parameters = mock(Map.class);
ConfigurationCacheFileInfo configurationCacheFileInfo = mock(ConfigurationCacheFileInfo.class);
+ ConfigurationCacheFileInfo configurationCacheFileInfo2 = mock(ConfigurationCacheFileInfo.class);
WriteableConfiguration configuration = mock(WriteableConfiguration.class);
+ WriteableConfiguration configuration2 = mock(WriteableConfiguration.class);
- when(configConfigurationCache.getCacheFileInfo(parameters)).thenReturn(configurationCacheFileInfo);
+ Map<String, List<String>> parameters = mock(Map.class);
+ when(configConfigurationCache.getCacheFileInfo(TEST_CONTENT_TYPE, parameters)).thenReturn(configurationCacheFileInfo);
+ when(configConfigurationCache.getCacheFileInfo(TEST_CONTENT_TYPE_2, parameters)).thenReturn(configurationCacheFileInfo2);
when(configurationCacheFileInfo.getConfiguration(version)).thenReturn(configuration);
+ when(configurationCacheFileInfo2.getConfiguration(version)).thenReturn(configuration2);
- assertEquals(configuration, cacheConfigurationProvider.getConfiguration(version, parameters));
+ assertEquals(configuration, cacheConfigurationProvider.getConfiguration(TEST_CONTENT_TYPE, version, parameters));
+ assertEquals(configuration2, cacheConfigurationProvider.getConfiguration(TEST_CONTENT_TYPE_2, version, parameters));
}
}
http://git-wip-us.apache.org/repos/asf/nifi-minifi/blob/4dc0ce30/minifi-c2/minifi-c2-provider/minifi-c2-provider-delegating/pom.xml
----------------------------------------------------------------------
diff --git a/minifi-c2/minifi-c2-provider/minifi-c2-provider-delegating/pom.xml b/minifi-c2/minifi-c2-provider/minifi-c2-provider-delegating/pom.xml
new file mode 100644
index 0000000..4b7e7ab
--- /dev/null
+++ b/minifi-c2/minifi-c2-provider/minifi-c2-provider-delegating/pom.xml
@@ -0,0 +1,53 @@
+<?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-delegating</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.apache.nifi.minifi</groupId>
+ <artifactId>minifi-c2-provider-util</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>com.fasterxml.jackson.core</groupId>
+ <artifactId>jackson-databind</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>commons-io</groupId>
+ <artifactId>commons-io</artifactId>
+ </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/4dc0ce30/minifi-c2/minifi-c2-provider/minifi-c2-provider-delegating/src/main/java/org/apache/nifi/minifi/c2/provider/delegating/DelegatingConfigurationProvider.java
----------------------------------------------------------------------
diff --git a/minifi-c2/minifi-c2-provider/minifi-c2-provider-delegating/src/main/java/org/apache/nifi/minifi/c2/provider/delegating/DelegatingConfigurationProvider.java b/minifi-c2/minifi-c2-provider/minifi-c2-provider-delegating/src/main/java/org/apache/nifi/minifi/c2/provider/delegating/DelegatingConfigurationProvider.java
new file mode 100644
index 0000000..04f6017
--- /dev/null
+++ b/minifi-c2/minifi-c2-provider/minifi-c2-provider-delegating/src/main/java/org/apache/nifi/minifi/c2/provider/delegating/DelegatingConfigurationProvider.java
@@ -0,0 +1,171 @@
+/*
+ * 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.delegating;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+import org.apache.commons.io.IOUtils;
+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.security.authorization.AuthorizationException;
+import org.apache.nifi.minifi.c2.provider.util.HttpConnector;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.UnsupportedEncodingException;
+import java.net.HttpURLConnection;
+import java.net.URLEncoder;
+import java.nio.charset.StandardCharsets;
+import java.security.GeneralSecurityException;
+import java.util.Comparator;
+import java.util.List;
+import java.util.Map;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+public class DelegatingConfigurationProvider implements ConfigurationProvider {
+ public static final Pattern errorPattern = Pattern.compile("^Server returned HTTP response code: ([0-9]+) for URL:.*");
+ private static final Logger logger = LoggerFactory.getLogger(DelegatingConfigurationProvider.class);
+ private final ConfigurationCache configurationCache;
+ private final HttpConnector httpConnector;
+ private final ObjectMapper objectMapper;
+
+ public DelegatingConfigurationProvider(ConfigurationCache configurationCache, String delegateUrl) throws InvalidParameterException, GeneralSecurityException, IOException {
+ this(configurationCache, new HttpConnector(delegateUrl));
+ }
+
+ public DelegatingConfigurationProvider(ConfigurationCache configurationCache, HttpConnector httpConnector) {
+ this.configurationCache = configurationCache;
+ this.httpConnector = httpConnector;
+ this.objectMapper = new ObjectMapper();
+ }
+
+ @Override
+ public List<String> getContentTypes() throws ConfigurationProviderException {
+ try {
+ HttpURLConnection httpURLConnection = httpConnector.get("/c2/config/contentTypes");
+ try {
+ List<String> contentTypes = objectMapper.readValue(httpURLConnection.getInputStream(), List.class);
+ if (logger.isDebugEnabled()) {
+ logger.debug("Got content types: " + contentTypes);
+ }
+ return contentTypes;
+ } finally {
+ httpURLConnection.disconnect();
+ }
+ } catch (IOException e) {
+ throw new ConfigurationProviderException("Unable to get content types from delegate.", e);
+ }
+ }
+
+ @Override
+ public Configuration getConfiguration(String contentType, Integer version, Map<String, List<String>> parameters) throws ConfigurationProviderException {
+ HttpURLConnection remoteC2ServerConnection = null;
+ try {
+ if (version == null) {
+ remoteC2ServerConnection = getDelegateConnection(contentType, parameters);
+ version = Integer.parseInt(remoteC2ServerConnection.getHeaderField("X-Content-Version"));
+ if (logger.isDebugEnabled()) {
+ logger.debug("Got current version " + version + " from upstream.");
+ }
+ }
+ ConfigurationCacheFileInfo cacheFileInfo = configurationCache.getCacheFileInfo(contentType, parameters);
+ WriteableConfiguration configuration = cacheFileInfo.getConfiguration(version);
+ if (!configuration.exists()) {
+ if (remoteC2ServerConnection == null) {
+ remoteC2ServerConnection = getDelegateConnection(contentType, parameters);
+ }
+ try (InputStream inputStream = remoteC2ServerConnection.getInputStream();
+ OutputStream outputStream = configuration.getOutputStream()) {
+ IOUtils.copy(inputStream, outputStream);
+ } catch (IOException e) {
+ throw new ConfigurationProviderException("Unable to copy remote configuration to cache.", e);
+ }
+ }
+ return configuration;
+ } finally {
+ if (remoteC2ServerConnection != null) {
+ remoteC2ServerConnection.disconnect();
+ }
+ }
+ }
+
+ protected HttpURLConnection getDelegateConnection(String contentType, Map<String, List<String>> parameters) throws ConfigurationProviderException {
+ StringBuilder queryStringBuilder = new StringBuilder();
+ try {
+ parameters.entrySet().stream().sorted(Comparator.comparing(Map.Entry::getKey)).forEachOrdered(e -> e.getValue().stream().sorted().forEachOrdered(v -> {
+ try {
+ queryStringBuilder.append(URLEncoder.encode(e.getKey(), "UTF-8")).append("=").append(URLEncoder.encode(v, "UTF-8"));
+ } catch (UnsupportedEncodingException ex) {
+ throw new ConfigurationProviderException("Unsupported encoding.", ex).wrap();
+ }
+ queryStringBuilder.append("&");
+ }));
+ } catch (ConfigurationProviderException.Wrapper e) {
+ throw e.unwrap();
+ }
+ String url = "/c2/config";
+ if (queryStringBuilder.length() > 0) {
+ queryStringBuilder.setLength(queryStringBuilder.length() - 1);
+ url = url + "?" + queryStringBuilder.toString();
+ }
+ HttpURLConnection httpURLConnection = httpConnector.get(url);
+ httpURLConnection.setRequestProperty("Accepts", contentType);
+ try {
+ int responseCode;
+ try {
+ responseCode = httpURLConnection.getResponseCode();
+ } catch (IOException e) {
+ Matcher matcher = errorPattern.matcher(e.getMessage());
+ if (matcher.matches()) {
+ responseCode = Integer.parseInt(matcher.group(1));
+ } else {
+ throw e;
+ }
+ }
+ if (responseCode >= 400) {
+ String message = "";
+ InputStream inputStream = httpURLConnection.getErrorStream();
+ if (inputStream != null) {
+ try {
+ message = IOUtils.toString(inputStream, StandardCharsets.UTF_8);
+ } finally {
+ inputStream.close();
+ }
+ }
+ if (responseCode == 400) {
+ throw new InvalidParameterException(message);
+ } else if (responseCode == 403) {
+ throw new AuthorizationException("Got authorization exception from upstream server " + message);
+ } else {
+ throw new ConfigurationProviderException(message);
+ }
+ }
+ } catch (IOException e) {
+ throw new ConfigurationProviderException("Unable to get response code from upstream server.", e);
+ }
+ return httpURLConnection;
+ }
+}
http://git-wip-us.apache.org/repos/asf/nifi-minifi/blob/4dc0ce30/minifi-c2/minifi-c2-provider/minifi-c2-provider-delegating/src/test/java/org/apache/nifi/minifi/c2/provider/delegating/DelegatingConfigurationProviderTest.java
----------------------------------------------------------------------
diff --git a/minifi-c2/minifi-c2-provider/minifi-c2-provider-delegating/src/test/java/org/apache/nifi/minifi/c2/provider/delegating/DelegatingConfigurationProviderTest.java b/minifi-c2/minifi-c2-provider/minifi-c2-provider-delegating/src/test/java/org/apache/nifi/minifi/c2/provider/delegating/DelegatingConfigurationProviderTest.java
new file mode 100644
index 0000000..3127ca7
--- /dev/null
+++ b/minifi-c2/minifi-c2-provider/minifi-c2-provider-delegating/src/test/java/org/apache/nifi/minifi/c2/provider/delegating/DelegatingConfigurationProviderTest.java
@@ -0,0 +1,195 @@
+/*
+ * 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.delegating;
+
+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.security.authorization.AuthorizationException;
+import org.apache.nifi.minifi.c2.provider.util.HttpConnector;
+import org.junit.Before;
+import org.junit.Test;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.net.HttpURLConnection;
+import java.nio.charset.StandardCharsets;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import static org.junit.Assert.assertArrayEquals;
+import static org.junit.Assert.assertEquals;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+public class DelegatingConfigurationProviderTest {
+ private ConfigurationCache configurationCache;
+ private HttpConnector httpConnector;
+ private HttpURLConnection httpURLConnection;
+ private DelegatingConfigurationProvider delegatingConfigurationProvider;
+ private Map<String, List<String>> parameters;
+ private Integer version;
+ private String endpointPath;
+ private String contentType;
+
+ @Before
+ public void setup() throws ConfigurationProviderException {
+ contentType = "text/yml";
+ version = 2;
+ parameters = new HashMap<>();
+ parameters.put("net", Collections.singletonList("edge"));
+ parameters.put("class", Collections.singletonList("raspi3"));
+ parameters.put("version", Collections.singletonList(Integer.toString(version)));
+ endpointPath = "/c2/config?class=raspi3&net=edge&version=2";
+ initMocks();
+ }
+
+ public void initMocks() throws ConfigurationProviderException {
+ configurationCache = mock(ConfigurationCache.class);
+ httpConnector = mock(HttpConnector.class);
+ httpURLConnection = mock(HttpURLConnection.class);
+ delegatingConfigurationProvider = new DelegatingConfigurationProvider(configurationCache, httpConnector);
+ when(httpConnector.get(endpointPath)).thenReturn(httpURLConnection);
+ }
+
+ @Test
+ public void testGetDelegateConnectionNoParameters() throws ConfigurationProviderException {
+ endpointPath = "/c2/config";
+ initMocks();
+ assertEquals(httpURLConnection, delegatingConfigurationProvider.getDelegateConnection(contentType, Collections.emptyMap()));
+ verify(httpURLConnection).setRequestProperty("Accepts", contentType);
+ }
+
+ @Test
+ public void testGetDelegateConnectionParameters() throws ConfigurationProviderException {
+ assertEquals(httpURLConnection, delegatingConfigurationProvider.getDelegateConnection(contentType, parameters));
+ verify(httpURLConnection).setRequestProperty("Accepts", contentType);
+ }
+
+ @Test(expected = AuthorizationException.class)
+ public void testGetDelegateConnection403() throws ConfigurationProviderException, IOException {
+ when(httpURLConnection.getResponseCode()).thenReturn(403);
+ delegatingConfigurationProvider.getDelegateConnection(contentType, parameters);
+ }
+
+ @Test(expected = InvalidParameterException.class)
+ public void testGetDelegateConnection400() throws IOException, ConfigurationProviderException {
+ when(httpURLConnection.getResponseCode()).thenThrow(new IOException("Server returned HTTP response code: 400 for URL: " + endpointPath));
+ delegatingConfigurationProvider.getDelegateConnection(contentType, parameters);
+ }
+
+ @Test(expected = ConfigurationProviderException.class)
+ public void testGetDelegateConnection401() throws IOException, ConfigurationProviderException {
+ when(httpURLConnection.getResponseCode()).thenReturn(401);
+ delegatingConfigurationProvider.getDelegateConnection(contentType, parameters);
+ }
+
+ @Test(expected = ConfigurationProviderException.class)
+ public void testGetContentTypesMalformed() throws ConfigurationProviderException, IOException {
+ endpointPath = "/c2/config/contentTypes";
+ initMocks();
+ when(httpURLConnection.getInputStream()).thenReturn(new ByteArrayInputStream("[malformed".getBytes(StandardCharsets.UTF_8)));
+ delegatingConfigurationProvider.getContentTypes();
+ }
+
+ @Test(expected = ConfigurationProviderException.class)
+ public void testGetContentTypesIOE() throws ConfigurationProviderException, IOException {
+ endpointPath = "/c2/config/contentTypes";
+ initMocks();
+ when(httpURLConnection.getInputStream()).thenThrow(new IOException());
+ delegatingConfigurationProvider.getContentTypes();
+ }
+
+ @Test
+ public void testGetContentTypes() throws ConfigurationProviderException, IOException {
+ endpointPath = "/c2/config/contentTypes";
+ initMocks();
+ List<String> contentTypes = Arrays.asList(contentType, "application/json");
+ when(httpURLConnection.getInputStream()).thenReturn(new ByteArrayInputStream(("[\"" + String.join("\", \"", contentTypes) + "\"]").getBytes(StandardCharsets.UTF_8)));
+ assertEquals(contentTypes, delegatingConfigurationProvider.getContentTypes());
+ }
+
+ @Test
+ public void testGetConfigurationExistsWithVersion() throws ConfigurationProviderException {
+ ConfigurationCacheFileInfo configurationCacheFileInfo = mock(ConfigurationCacheFileInfo.class);
+ WriteableConfiguration configuration = mock(WriteableConfiguration.class);
+ when(configurationCache.getCacheFileInfo(contentType, parameters)).thenReturn(configurationCacheFileInfo);
+ when(configurationCacheFileInfo.getConfiguration(version)).thenReturn(configuration);
+ when(configuration.exists()).thenReturn(true);
+
+ assertEquals(configuration, delegatingConfigurationProvider.getConfiguration(contentType, version, parameters));
+ }
+
+ @Test
+ public void testGetConfigurationDoesntExistWithVersion() throws ConfigurationProviderException, IOException {
+ ConfigurationCacheFileInfo configurationCacheFileInfo = mock(ConfigurationCacheFileInfo.class);
+ WriteableConfiguration configuration = mock(WriteableConfiguration.class);
+ byte[] payload = "payload".getBytes(StandardCharsets.UTF_8);
+ ByteArrayOutputStream output = new ByteArrayOutputStream();
+ when(httpURLConnection.getInputStream()).thenReturn(new ByteArrayInputStream(payload));
+ when(configuration.getOutputStream()).thenReturn(output);
+ when(configurationCache.getCacheFileInfo(contentType, parameters)).thenReturn(configurationCacheFileInfo);
+ when(configurationCacheFileInfo.getConfiguration(version)).thenReturn(configuration);
+ when(configuration.exists()).thenReturn(false);
+
+ assertEquals(configuration, delegatingConfigurationProvider.getConfiguration(contentType, version, parameters));
+ assertArrayEquals(payload, output.toByteArray());
+ }
+
+ @Test
+ public void testGetConfigurationExistsWithNoVersion() throws ConfigurationProviderException {
+ parameters.remove("version");
+ endpointPath = "/c2/config?class=raspi3&net=edge";
+ initMocks();
+ ConfigurationCacheFileInfo configurationCacheFileInfo = mock(ConfigurationCacheFileInfo.class);
+ WriteableConfiguration configuration = mock(WriteableConfiguration.class);
+ when(httpURLConnection.getHeaderField("X-Content-Version")).thenReturn("2");
+ when(configurationCache.getCacheFileInfo(contentType, parameters)).thenReturn(configurationCacheFileInfo);
+ when(configurationCacheFileInfo.getConfiguration(version)).thenReturn(configuration);
+ when(configuration.exists()).thenReturn(true);
+
+ assertEquals(configuration, delegatingConfigurationProvider.getConfiguration(contentType, null, parameters));
+ }
+
+ @Test
+ public void testGetConfigurationDoesntExistWithNoVersion() throws ConfigurationProviderException, IOException {
+ parameters.remove("version");
+ endpointPath = "/c2/config?class=raspi3&net=edge";
+ initMocks();
+ ConfigurationCacheFileInfo configurationCacheFileInfo = mock(ConfigurationCacheFileInfo.class);
+ WriteableConfiguration configuration = mock(WriteableConfiguration.class);
+ byte[] payload = "payload".getBytes(StandardCharsets.UTF_8);
+ ByteArrayOutputStream output = new ByteArrayOutputStream();
+ when(httpURLConnection.getInputStream()).thenReturn(new ByteArrayInputStream(payload));
+ when(configuration.getOutputStream()).thenReturn(output);
+ when(httpURLConnection.getHeaderField("X-Content-Version")).thenReturn("2");
+ when(configurationCache.getCacheFileInfo(contentType, parameters)).thenReturn(configurationCacheFileInfo);
+ when(configurationCacheFileInfo.getConfiguration(version)).thenReturn(configuration);
+ when(configuration.exists()).thenReturn(false);
+
+ assertEquals(configuration, delegatingConfigurationProvider.getConfiguration(contentType, null, parameters));
+ assertArrayEquals(payload, output.toByteArray());
+ }
+}
http://git-wip-us.apache.org/repos/asf/nifi-minifi/blob/4dc0ce30/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
index 8595246..43c5225 100644
--- 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
@@ -32,6 +32,11 @@ limitations under the License.
<version>${project.version}</version>
</dependency>
<dependency>
+ <groupId>org.apache.nifi.minifi</groupId>
+ <artifactId>minifi-c2-provider-util</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>2.8.7</version>
http://git-wip-us.apache.org/repos/asf/nifi-minifi/blob/4dc0ce30/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
index 77175d7..8f0bf2c 100644
--- 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
@@ -23,9 +23,9 @@ 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.c2.provider.util.HttpConnector;
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;
@@ -38,12 +38,17 @@ import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.security.GeneralSecurityException;
+import java.util.Arrays;
+import java.util.Collections;
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.regex.Matcher;
+import java.util.regex.Pattern;
+import java.util.stream.Collectors;
import java.util.stream.Stream;
import java.util.stream.StreamSupport;
@@ -52,32 +57,58 @@ public class NiFiRestConfigurationProvider implements ConfigurationProvider {
private static final Logger logger = LoggerFactory.getLogger(NiFiRestConfigurationProvider.class);
private final JsonFactory jsonFactory = new JsonFactory();
private final ConfigurationCache configurationCache;
- private final NiFiRestConnector niFiRestConnector;
+ private final HttpConnector httpConnector;
+ private final String templateNamePattern;
- public NiFiRestConfigurationProvider(ConfigurationCache configurationCache, String nifiUrl) throws InvalidParameterException, GeneralSecurityException, IOException {
- this(configurationCache, new NiFiRestConnector(nifiUrl));
+ public NiFiRestConfigurationProvider(ConfigurationCache configurationCache, String nifiUrl, String templateNamePattern) throws InvalidParameterException, GeneralSecurityException, IOException {
+ this(configurationCache, new HttpConnector(nifiUrl), templateNamePattern);
}
- public NiFiRestConfigurationProvider(ConfigurationCache configurationCache, NiFiRestConnector niFiRestConnector) {
+ public NiFiRestConfigurationProvider(ConfigurationCache configurationCache, HttpConnector httpConnector, String templateNamePattern) {
this.configurationCache = configurationCache;
- this.niFiRestConnector = niFiRestConnector;
+ this.httpConnector = httpConnector;
+ this.templateNamePattern = templateNamePattern;
}
@Override
- public String getContentType() {
- return CONTENT_TYPE;
+ public List<String> getContentTypes() {
+ return Collections.singletonList(CONTENT_TYPE);
}
@Override
- public Configuration getConfiguration(Integer version, Map<String, List<String>> parameters) throws ConfigurationProviderException {
- ConfigurationCacheFileInfo configurationCacheFileInfo = configurationCache.getCacheFileInfo(parameters);
+ public Configuration getConfiguration(String contentType, Integer version, Map<String, List<String>> parameters) throws ConfigurationProviderException {
+ if (!CONTENT_TYPE.equals(contentType)) {
+ throw new ConfigurationProviderException("Unsupported content type: " + contentType + " supported value is " + CONTENT_TYPE);
+ }
+ String filename = templateNamePattern;
+ for (Map.Entry<String, List<String>> entry : parameters.entrySet()) {
+ if (entry.getValue().size() != 1) {
+ throw new InvalidParameterException("Multiple values for same parameter not supported in this provider.");
+ }
+ filename = filename.replaceAll(Pattern.quote("${" + entry.getKey() + "}"), entry.getValue().get(0));
+ }
+ int index = filename.indexOf("${");
+ while (index != -1) {
+ int endIndex = filename.indexOf("}", index);
+ if (endIndex == -1) {
+ break;
+ }
+ String variable = filename.substring(index + 2, endIndex);
+ if (!"version".equals(variable)) {
+ throw new InvalidParameterException("Found unsubstituted parameter " + variable);
+ }
+ index = endIndex + 1;
+ }
+
String id = null;
if (version == null) {
- Pair<String, Integer> maxIdAndVersion = getMaxIdAndVersion(configurationCacheFileInfo);
+ String filenamePattern = Arrays.stream(filename.split(Pattern.quote("${version}"), -1)).map(Pattern::quote).collect(Collectors.joining("([0-9+])"));
+ Pair<String, Integer> maxIdAndVersion = getMaxIdAndVersion(filenamePattern);
id = maxIdAndVersion.getFirst();
version = maxIdAndVersion.getSecond();
}
- WriteableConfiguration configuration = configurationCacheFileInfo.getConfiguration(version);
+ filename = filename.replaceAll(Pattern.quote("${version}"), Integer.toString(version));
+ WriteableConfiguration configuration = configurationCache.getCacheFileInfo(contentType, parameters).getConfiguration(version);
if (configuration.exists()) {
if (logger.isDebugEnabled()) {
logger.debug("Configuration " + configuration + " exists and can be served from configurationCache.");
@@ -88,11 +119,18 @@ public class NiFiRestConfigurationProvider implements ConfigurationProvider {
}
if (id == null) {
try {
- String filename = configuration.getName();
+ String tmpFilename = templateNamePattern;
+ for (Map.Entry<String, List<String>> entry : parameters.entrySet()) {
+ if (entry.getValue().size() != 1) {
+ throw new InvalidParameterException("Multiple values for same parameter not supported in this provider.");
+ }
+ tmpFilename = tmpFilename.replaceAll(Pattern.quote("${" + entry.getKey() + "}"), entry.getValue().get(0));
+ }
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));
+ String finalFilename = filename;
+ id = streamCloseablePair.getFirst().filter(p -> finalFilename.equals(p.getSecond())).map(Pair::getFirst).findFirst()
+ .orElseThrow(() -> new InvalidParameterException("Unable to find template named " + finalFilename));
} finally {
streamCloseablePair.getSecond().close();
}
@@ -101,7 +139,7 @@ public class NiFiRestConfigurationProvider implements ConfigurationProvider {
}
}
- HttpURLConnection urlConnection = niFiRestConnector.get("/templates/" + id + "/download");
+ HttpURLConnection urlConnection = httpConnector.get("/templates/" + id + "/download");
try (InputStream inputStream = urlConnection.getInputStream()){
ConfigSchema configSchema = ConfigMain.transformTemplateToSchema(inputStream);
@@ -118,27 +156,28 @@ public class NiFiRestConfigurationProvider implements ConfigurationProvider {
}
private Pair<Stream<Pair<String, String>>, Closeable> getIdAndFilenameStream() throws ConfigurationProviderException, IOException {
- TemplatesIterator templatesIterator = new TemplatesIterator(niFiRestConnector, jsonFactory);
+ TemplatesIterator templatesIterator = new TemplatesIterator(httpConnector, 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 {
+ private Pair<Stream<Pair<String, Integer>>, Closeable> getIdAndVersionStream(String filenamePattern) throws ConfigurationProviderException, IOException {
+ Pattern filename = Pattern.compile(filenamePattern);
Pair<Stream<Pair<String, String>>, Closeable> streamCloseablePair = getIdAndFilenameStream();
return new Pair<>(streamCloseablePair.getFirst().map(p -> {
- Integer version = configurationCacheFileInfo.getVersionIfMatch(p.getSecond());
- if (version == null) {
+ Matcher matcher = filename.matcher(p.getSecond());
+ if (!matcher.matches()) {
return null;
}
- return new Pair<>(p.getFirst(), version);
+ return new Pair<>(p.getFirst(), Integer.parseInt(matcher.group(1)));
}).filter(Objects::nonNull), streamCloseablePair.getSecond());
}
- private Pair<String, Integer> getMaxIdAndVersion(ConfigurationCacheFileInfo configurationCacheFileInfo) throws ConfigurationProviderException {
+ private Pair<String, Integer> getMaxIdAndVersion(String filenamePattern) throws ConfigurationProviderException {
try {
- Pair<Stream<Pair<String, Integer>>, Closeable> streamCloseablePair = getIdAndVersionStream(configurationCacheFileInfo);
+ Pair<Stream<Pair<String, Integer>>, Closeable> streamCloseablePair = getIdAndVersionStream(filenamePattern);
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]+"));
+ .orElseThrow(() -> new ConfigurationProviderException("Didn't find any templates that matched " + filenamePattern));
} finally {
streamCloseablePair.getSecond().close();
}
http://git-wip-us.apache.org/repos/asf/nifi-minifi/blob/4dc0ce30/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
deleted file mode 100644
index 9a0befc..0000000
--- a/minifi-c2/minifi-c2-provider/minifi-c2-provider-nifi-rest/src/main/java/org/apache/nifi/minifi/c2/provider/nifi/rest/NiFiRestConnector.java
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.nifi.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/4dc0ce30/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
index afe6c6e..947a853 100644
--- 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
@@ -22,6 +22,7 @@ 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 org.apache.nifi.minifi.c2.provider.util.HttpConnector;
import java.io.Closeable;
import java.io.IOException;
@@ -38,8 +39,8 @@ public class TemplatesIterator implements Iterator<Pair<String, String>>, Closea
private final JsonParser parser;
private Pair<String, String> next;
- public TemplatesIterator(NiFiRestConnector niFiRestConnector, JsonFactory jsonFactory) throws ConfigurationProviderException, IOException {
- urlConnection = niFiRestConnector.get(FLOW_TEMPLATES);
+ public TemplatesIterator(HttpConnector httpConnector, JsonFactory jsonFactory) throws ConfigurationProviderException, IOException {
+ urlConnection = httpConnector.get(FLOW_TEMPLATES);
inputStream = urlConnection.getInputStream();
parser = jsonFactory.createParser(inputStream);
while (parser.nextToken() != JsonToken.END_OBJECT) {
http://git-wip-us.apache.org/repos/asf/nifi-minifi/blob/4dc0ce30/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
index 2cb3a8d..efc7f6c 100644
--- 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
@@ -18,6 +18,7 @@
package org.apache.nifi.minifi.c2.provider.nifi.rest;
import org.apache.nifi.minifi.c2.api.cache.ConfigurationCache;
+import org.apache.nifi.minifi.c2.provider.util.HttpConnector;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
@@ -25,6 +26,7 @@ import org.junit.Test;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
+import java.util.Collections;
import java.util.Comparator;
import static org.junit.Assert.assertEquals;
@@ -32,15 +34,15 @@ import static org.mockito.Mockito.mock;
public class NiFiRestConfigurationProviderTest {
private ConfigurationCache configConfigurationCache;
- private NiFiRestConnector niFiRestConnector;
+ private HttpConnector httpConnector;
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);
+ httpConnector = mock(HttpConnector.class);
+ niFiRestConfigurationProvider = new NiFiRestConfigurationProvider(configConfigurationCache, httpConnector, "${class}.v${version}");
cachePath = Files.createTempDirectory(NiFiRestConfigurationProviderTest.class.getCanonicalName());
}
@@ -59,8 +61,6 @@ public class NiFiRestConfigurationProviderTest {
@Test
public void testContentType() {
- assertEquals(NiFiRestConfigurationProvider.CONTENT_TYPE, niFiRestConfigurationProvider.getContentType());
+ assertEquals(Collections.singletonList(NiFiRestConfigurationProvider.CONTENT_TYPE), niFiRestConfigurationProvider.getContentTypes());
}
-
-
}