NIFI-4037 added InvokeGRPC processor, with proto service IDL
NIFI-4038 added ListenGRPC processor

This closes #1947

Signed-off-by: Tony Kurc <[email protected]>


Project: http://git-wip-us.apache.org/repos/asf/nifi/repo
Commit: http://git-wip-us.apache.org/repos/asf/nifi/commit/58a623df
Tree: http://git-wip-us.apache.org/repos/asf/nifi/tree/58a623df
Diff: http://git-wip-us.apache.org/repos/asf/nifi/diff/58a623df

Branch: refs/heads/master
Commit: 58a623dfa270a77fa6fdd0fb3ac551eda663d64c
Parents: 3bf1d12
Author: m-hogue <[email protected]>
Authored: Wed Jun 14 12:31:35 2017 -0400
Committer: Tony Kurc <[email protected]>
Committed: Thu Jun 29 22:01:22 2017 -0400

----------------------------------------------------------------------
 nifi-assembly/LICENSE                           |  14 +-
 nifi-assembly/NOTICE                            | 337 +++++++----
 nifi-assembly/pom.xml                           |   5 +
 .../nifi-grpc-bundle/nifi-grpc-nar/pom.xml      |  46 ++
 .../nifi-grpc-nar/src/main/resources/LICENSE    | 259 +++++++++
 .../nifi-grpc-nar/src/main/resources/NOTICE     | 302 ++++++++++
 .../nifi-grpc-processors/pom.xml                | 139 +++++
 .../processors/grpc/FlowFileIngestService.java  | 173 ++++++
 .../grpc/FlowFileIngestServiceInterceptor.java  | 150 +++++
 .../apache/nifi/processors/grpc/InvokeGRPC.java | 442 +++++++++++++++
 .../apache/nifi/processors/grpc/ListenGRPC.java | 239 ++++++++
 .../org.apache.nifi.processor.Processor         |  16 +
 .../main/resources/proto/flowfile_service.proto |  59 ++
 .../nifi/processors/grpc/TestGRPCClient.java    | 132 +++++
 .../nifi/processors/grpc/TestGRPCServer.java    | 164 ++++++
 .../nifi/processors/grpc/TestInvokeGRPC.java    | 557 +++++++++++++++++++
 .../nifi/processors/grpc/TestListenGRPC.java    | 401 +++++++++++++
 .../src/test/resources/localhost-ks.jks         | Bin 0 -> 3512 bytes
 .../src/test/resources/localhost-ts.jks         | Bin 0 -> 1816 bytes
 nifi-nar-bundles/nifi-grpc-bundle/pom.xml       |  46 ++
 nifi-nar-bundles/pom.xml                        |   3 +-
 pom.xml                                         |   6 +
 22 files changed, 3395 insertions(+), 95 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/nifi/blob/58a623df/nifi-assembly/LICENSE
----------------------------------------------------------------------
diff --git a/nifi-assembly/LICENSE b/nifi-assembly/LICENSE
index 0c23ee7..1512d2c 100644
--- a/nifi-assembly/LICENSE
+++ b/nifi-assembly/LICENSE
@@ -1083,7 +1083,7 @@ This product bundles HexViewJS available under an MIT 
License
     OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 
THE
     SOFTWARE.
 
-The binary distribution of this product bundles 'Google Protocol Buffers Java 
2.5.0'
+The binary distribution of this product bundles 'Google Protocol Buffers Java 
2.5.0 and 3.3.1'
 which is licensed under a BSD license.
 
   This license applies to all parts of Protocol Buffers except the following:
@@ -1129,6 +1129,18 @@ which is licensed under a BSD license.
   standalone and requires a support library to be linked with it.  This
   support library is itself covered by the above license.
 
+The binary distribution of this product bundles 'The JSR-305 reference 
implementation'
+which is licensed under a BSD license.
+
+  The JSR-305 reference implementation (lib/jsr305.jar) is
+  distributed under the terms of the New BSD license:
+
+    http://www.opensource.org/licenses/bsd-license.php
+
+  See the JSR-305 home page for more information:
+
+    http://code.google.com/p/jsr-305/
+
 This product bundles 'JCraft Jzlib' which is available under a 3-Clause BSD 
License.
 
     Copyright (c) 2002-2014 Atsuhiko Yamanaka, JCraft,Inc. 

http://git-wip-us.apache.org/repos/asf/nifi/blob/58a623df/nifi-assembly/NOTICE
----------------------------------------------------------------------
diff --git a/nifi-assembly/NOTICE b/nifi-assembly/NOTICE
index 0873c21..abad7c8 100644
--- a/nifi-assembly/NOTICE
+++ b/nifi-assembly/NOTICE
@@ -936,11 +936,6 @@ The following binary components are provided under the 
Apache Software License v
         Curator Recipes
         Copyright 2011-2014 The Apache Software Foundation
 
-    (ASLv2) The Netty Project
-      The following NOTICE information applies:
-        The Netty Project
-        Copyright 2011 The Netty Project
-
     (ASLv2) Apache Xerces Java
       The following NOTICE information applies:
         Apache Xerces Java
@@ -1114,124 +1109,280 @@ The following binary components are provided under 
the Apache Software License v
       Grok
       Copyright 2014 Anthony Corbacho, and contributors.
 
+  (ASLv2) gRPC-Java
+    The following NOTICE information applies:
+       Copyright 2014, gRPC Authors All rights reserved.
+
+       Licensed 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.
+
+       -----------------------------------------------------------------------
+
+       This product contains a modified portion of 'OkHttp', an open source
+       HTTP & SPDY client for Android and Java applications, which can be 
obtained
+       at:
+
+         * LICENSE:
+           * okhttp/third_party/okhttp/LICENSE (Apache License 2.0)
+         * HOMEPAGE:
+           * https://github.com/square/okhttp
+         * LOCATION_IN_GRPC:
+           * okhttp/third_party/okhttp
+
+       This product contains a modified portion of 'Netty', an open source
+       networking library, which can be obtained at:
+
+         * LICENSE:
+           * netty/third_party/netty/LICENSE.txt (Apache License 2.0)
+         * HOMEPAGE:
+           * https://netty.io
+         * LOCATION_IN_GRPC:
+    * netty/third_party/netty
+
   (ASLv2) The Netty Project
       The following NOTICE information applies:
 
-                                The Netty Project
-                                =================
+                                   The Netty Project
+                                   =================
+
+       Please visit the Netty web site for more information:
+
+         * http://netty.io/
+
+       Copyright 2014 The Netty Project
+
+       The Netty Project 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.
+
+       Also, please refer to each LICENSE.<component>.txt file, which is 
located in
+       the 'license' directory of the distribution file, for the license terms 
of the
+       components that this product depends on.
+
+       
-------------------------------------------------------------------------------
+       This product contains the extensions to Java Collections Framework 
which has
+       been derived from the works by JSR-166 EG, Doug Lea, and Jason T. 
Greene:
+
+         * LICENSE:
+           * license/LICENSE.jsr166y.txt (Public Domain)
+         * HOMEPAGE:
+           * http://gee.cs.oswego.edu/cgi-bin/viewcvs.cgi/jsr166/
+           * 
http://viewvc.jboss.org/cgi-bin/viewvc.cgi/jbosscache/experimental/jsr166/
+
+       This product contains a modified version of Robert Harder's Public 
Domain
+       Base64 Encoder and Decoder, which can be obtained at:
 
-    Please visit the Netty web site for more information:
+         * LICENSE:
+           * license/LICENSE.base64.txt (Public Domain)
+         * HOMEPAGE:
+           * http://iharder.sourceforge.net/current/java/base64/
 
-      * http://netty.io/
+       This product contains a modified portion of 'Webbit', an event based
+       WebSocket and HTTP server, which can be obtained at:
 
-    Copyright 2011 The Netty Project
+         * LICENSE:
+           * license/LICENSE.webbit.txt (BSD License)
+         * HOMEPAGE:
+           * https://github.com/joewalnes/webbit
 
-    The Netty Project 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:
+       This product contains a modified portion of 'SLF4J', a simple logging
+       facade for Java, which can be obtained at:
 
-    http://www.apache.org/licenses/LICENSE-2.0
+         * LICENSE:
+           * license/LICENSE.slf4j.txt (MIT License)
+         * HOMEPAGE:
+           * http://www.slf4j.org/
 
-    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.
+       This product contains a modified portion of 'Apache Harmony', an open 
source
+       Java SE, which can be obtained at:
 
-    Also, please refer to each LICENSE.<component>.txt file, which is located 
in
-    the 'license' directory of the distribution file, for the license terms of 
the
-    components that this product depends on.
+         * LICENSE:
+           * license/LICENSE.harmony.txt (Apache License 2.0)
+         * HOMEPAGE:
+           * http://archive.apache.org/dist/harmony/
 
-    
-------------------------------------------------------------------------------
-    This product contains the extensions to Java Collections Framework which 
has
-    been derived from the works by JSR-166 EG, Doug Lea, and Jason T. Greene:
+       This product contains a modified portion of 'jbzip2', a Java bzip2 
compression
+       and decompression library written by Matthew J. Francis. It can be 
obtained at:
 
-      * LICENSE:
-        * license/LICENSE.jsr166y.txt (Public Domain)
-      * HOMEPAGE:
-        * http://gee.cs.oswego.edu/cgi-bin/viewcvs.cgi/jsr166/
-        * 
http://viewvc.jboss.org/cgi-bin/viewvc.cgi/jbosscache/experimental/jsr166/
+         * LICENSE:
+           * license/LICENSE.jbzip2.txt (MIT License)
+         * HOMEPAGE:
+           * https://code.google.com/p/jbzip2/
 
-    This product contains a modified version of Robert Harder's Public Domain
-    Base64 Encoder and Decoder, which can be obtained at:
+       This product contains a modified portion of 'libdivsufsort', a C API 
library to construct
+       the suffix array and the Burrows-Wheeler transformed string for any 
input string of
+       a constant-size alphabet written by Yuta Mori. It can be obtained at:
 
-      * LICENSE:
-        * license/LICENSE.base64.txt (Public Domain)
-      * HOMEPAGE:
-        * http://iharder.sourceforge.net/current/java/base64/
+         * LICENSE:
+           * license/LICENSE.libdivsufsort.txt (MIT License)
+         * HOMEPAGE:
+           * https://github.com/y-256/libdivsufsort
 
-    This product contains a modified version of 'JZlib', a re-implementation of
-    zlib in pure Java, which can be obtained at:
+       This product contains a modified portion of Nitsan Wakart's 'JCTools', 
Java Concurrency Tools for the JVM,
+        which can be obtained at:
 
-      * LICENSE:
-        * license/LICENSE.jzlib.txt (BSD Style License)
-      * HOMEPAGE:
-        * http://www.jcraft.com/jzlib/
+         * LICENSE:
+           * license/LICENSE.jctools.txt (ASL2 License)
+         * HOMEPAGE:
+           * https://github.com/JCTools/JCTools
 
-    This product contains a modified version of 'Webbit', a Java event based
-    WebSocket and HTTP server:
+       This product optionally depends on 'JZlib', a re-implementation of zlib 
in
+       pure Java, which can be obtained at:
 
-      * LICENSE:
-        * license/LICENSE.webbit.txt (BSD License)
-      * HOMEPAGE:
-        * https://github.com/joewalnes/webbit
+         * LICENSE:
+           * license/LICENSE.jzlib.txt (BSD style License)
+         * HOMEPAGE:
+           * http://www.jcraft.com/jzlib/
 
-    This product optionally depends on 'Protocol Buffers', Google's data
-    interchange format, which can be obtained at:
+       This product optionally depends on 'Compress-LZF', a Java library for 
encoding and
+       decoding data in LZF format, written by Tatu Saloranta. It can be 
obtained at:
 
-      * LICENSE:
-        * license/LICENSE.protobuf.txt (New BSD License)
-      * HOMEPAGE:
-        * http://code.google.com/p/protobuf/
+         * LICENSE:
+           * license/LICENSE.compress-lzf.txt (Apache License 2.0)
+         * HOMEPAGE:
+           * https://github.com/ning/compress
 
-    This product optionally depends on 'Bouncy Castle Crypto APIs' to generate
-    a temporary self-signed X.509 certificate when the JVM does not provide the
-    equivalent functionality.  It can be obtained at:
+       This product optionally depends on 'lz4', a LZ4 Java compression
+       and decompression library written by Adrien Grand. It can be obtained 
at:
+
+         * LICENSE:
+           * license/LICENSE.lz4.txt (Apache License 2.0)
+         * HOMEPAGE:
+           * https://github.com/jpountz/lz4-java
+
+       This product optionally depends on 'lzma-java', a LZMA Java compression
+       and decompression library, which can be obtained at:
+
+         * LICENSE:
+           * license/LICENSE.lzma-java.txt (Apache License 2.0)
+         * HOMEPAGE:
+           * https://github.com/jponge/lzma-java
 
-      * LICENSE:
-        * license/LICENSE.bouncycastle.txt (MIT License)
-      * HOMEPAGE:
-        * http://www.bouncycastle.org/
+       This product contains a modified portion of 'jfastlz', a Java port of 
FastLZ compression
+       and decompression library written by William Kinney. It can be obtained 
at:
 
-    This product optionally depends on 'SLF4J', a simple logging facade for 
Java,
-    which can be obtained at:
+         * LICENSE:
+           * license/LICENSE.jfastlz.txt (MIT License)
+         * HOMEPAGE:
+           * https://code.google.com/p/jfastlz/
 
-      * LICENSE:
-        * license/LICENSE.slf4j.txt (MIT License)
-      * HOMEPAGE:
-        * http://www.slf4j.org/
+       This product contains a modified portion of and optionally depends on 
'Protocol Buffers', Google's data
+       interchange format, which can be obtained at:
 
-    This product optionally depends on 'Apache Commons Logging', a logging
-    framework, which can be obtained at:
+         * LICENSE:
+           * license/LICENSE.protobuf.txt (New BSD License)
+         * HOMEPAGE:
+           * https://github.com/google/protobuf
 
-      * LICENSE:
-        * license/LICENSE.commons-logging.txt (Apache License 2.0)
-      * HOMEPAGE:
-        * http://commons.apache.org/logging/
+       This product optionally depends on 'Bouncy Castle Crypto APIs' to 
generate
+       a temporary self-signed X.509 certificate when the JVM does not provide 
the
+       equivalent functionality.  It can be obtained at:
 
-    This product optionally depends on 'Apache Log4J', a logging framework,
-    which can be obtained at:
+         * LICENSE:
+           * license/LICENSE.bouncycastle.txt (MIT License)
+         * HOMEPAGE:
+           * http://www.bouncycastle.org/
 
-      * LICENSE:
-        * license/LICENSE.log4j.txt (Apache License 2.0)
-      * HOMEPAGE:
-        * http://logging.apache.org/log4j/
+       This product optionally depends on 'Snappy', a compression library 
produced
+       by Google Inc, which can be obtained at:
 
-    This product optionally depends on 'JBoss Logging', a logging framework,
-    which can be obtained at:
+         * LICENSE:
+           * license/LICENSE.snappy.txt (New BSD License)
+         * HOMEPAGE:
+           * https://github.com/google/snappy
 
-      * LICENSE:
-        * license/LICENSE.jboss-logging.txt (GNU LGPL 2.1)
-      * HOMEPAGE:
-        * http://anonsvn.jboss.org/repos/common/common-logging-spi/
-
-    This product optionally depends on 'Apache Felix', an open source OSGi
-    framework implementation, which can be obtained at:
-
-      * LICENSE:
-        * license/LICENSE.felix.txt (Apache License 2.0)
-      * HOMEPAGE:
-        * http://felix.apache.org/
+       This product optionally depends on 'JBoss Marshalling', an alternative 
Java
+       serialization API, which can be obtained at:
+
+         * LICENSE:
+           * license/LICENSE.jboss-marshalling.txt (GNU LGPL 2.1)
+         * HOMEPAGE:
+           * http://www.jboss.org/jbossmarshalling
+
+       This product optionally depends on 'Caliper', Google's micro-
+       benchmarking framework, which can be obtained at:
+
+         * LICENSE:
+           * license/LICENSE.caliper.txt (Apache License 2.0)
+         * HOMEPAGE:
+           * https://github.com/google/caliper
+
+       This product optionally depends on 'Apache Commons Logging', a logging
+       framework, which can be obtained at:
+
+         * LICENSE:
+           * license/LICENSE.commons-logging.txt (Apache License 2.0)
+         * HOMEPAGE:
+           * http://commons.apache.org/logging/
+
+       This product optionally depends on 'Apache Log4J', a logging framework, 
which
+       can be obtained at:
+
+         * LICENSE:
+           * license/LICENSE.log4j.txt (Apache License 2.0)
+         * HOMEPAGE:
+           * http://logging.apache.org/log4j/
+
+       This product optionally depends on 'Aalto XML', an ultra-high 
performance
+       non-blocking XML processor, which can be obtained at:
+
+         * LICENSE:
+           * license/LICENSE.aalto-xml.txt (Apache License 2.0)
+         * HOMEPAGE:
+           * http://wiki.fasterxml.com/AaltoHome
+
+       This product contains a modified version of 'HPACK', a Java 
implementation of
+       the HTTP/2 HPACK algorithm written by Twitter. It can be obtained at:
+
+         * LICENSE:
+           * license/LICENSE.hpack.txt (Apache License 2.0)
+         * HOMEPAGE:
+           * https://github.com/twitter/hpack
+
+       This product contains a modified portion of 'Apache Commons Lang', a 
Java library
+       provides utilities for the java.lang API, which can be obtained at:
+
+         * LICENSE:
+           * license/LICENSE.commons-lang.txt (Apache License 2.0)
+         * HOMEPAGE:
+      * https://commons.apache.org/proper/commons-lang/
+
+      This product contains a forked and modified version of Tomcat Native
+
+        * LICENSE:
+          * ASL2
+        * HOMEPAGE:
+          * http://tomcat.apache.org/native-doc/
+          * https://svn.apache.org/repos/asf/tomcat/native/
+
+  (ASLv2) Error Prone
+    The following NOTICE information applies:
+      Copyright 2017 Google Inc.
+
+  (ASLv2) Instrumentation
+    The following NOTICE information applies:
+      Copyright 2016 Google Inc.
+
+  (ASLv2) Google APIs
+    The following NOTICE information applies:
+      Copyright 2016 Google Inc.
 
   (ASLv2) Android JSON library
     The following NOTICE information applies:

http://git-wip-us.apache.org/repos/asf/nifi/blob/58a623df/nifi-assembly/pom.xml
----------------------------------------------------------------------
diff --git a/nifi-assembly/pom.xml b/nifi-assembly/pom.xml
index 8f73ec0..e1ac6cb 100755
--- a/nifi-assembly/pom.xml
+++ b/nifi-assembly/pom.xml
@@ -458,6 +458,11 @@
         </dependency>
         <dependency>
             <groupId>org.apache.nifi</groupId>
+            <artifactId>nifi-grpc-nar</artifactId>
+            <type>nar</type>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.nifi</groupId>
             <artifactId>nifi-stateful-analysis-nar</artifactId>
             <type>nar</type>
         </dependency>

http://git-wip-us.apache.org/repos/asf/nifi/blob/58a623df/nifi-nar-bundles/nifi-grpc-bundle/nifi-grpc-nar/pom.xml
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-grpc-bundle/nifi-grpc-nar/pom.xml 
b/nifi-nar-bundles/nifi-grpc-bundle/nifi-grpc-nar/pom.xml
new file mode 100644
index 0000000..11a3239
--- /dev/null
+++ b/nifi-nar-bundles/nifi-grpc-bundle/nifi-grpc-nar/pom.xml
@@ -0,0 +1,46 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  Licensed to the Apache Software Foundation (ASF) under one or more
+  contributor license agreements. See the NOTICE file distributed with
+  this work for additional information regarding copyright ownership.
+  The ASF licenses this file to You under the Apache License, Version 2.0
+  (the "License"); you may not use this file except in compliance with
+  the License. You may obtain a copy of the License at
+  http://www.apache.org/licenses/LICENSE-2.0
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0"; 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"; 
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 
http://maven.apache.org/xsd/maven-4.0.0.xsd";>
+    <modelVersion>4.0.0</modelVersion>
+
+    <parent>
+        <groupId>org.apache.nifi</groupId>
+        <artifactId>nifi-grpc-bundle</artifactId>
+        <version>1.4.0-SNAPSHOT</version>
+    </parent>
+
+    <artifactId>nifi-grpc-nar</artifactId>
+    <version>1.4.0-SNAPSHOT</version>
+    <packaging>nar</packaging>
+    <properties>
+        <maven.javadoc.skip>true</maven.javadoc.skip>
+        <source.skip>true</source.skip>
+    </properties>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.apache.nifi</groupId>
+            <artifactId>nifi-standard-services-api-nar</artifactId>
+            <type>nar</type>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.nifi</groupId>
+            <artifactId>nifi-grpc-processors</artifactId>
+            <version>1.4.0-SNAPSHOT</version>
+        </dependency>
+    </dependencies>
+
+</project>

http://git-wip-us.apache.org/repos/asf/nifi/blob/58a623df/nifi-nar-bundles/nifi-grpc-bundle/nifi-grpc-nar/src/main/resources/LICENSE
----------------------------------------------------------------------
diff --git 
a/nifi-nar-bundles/nifi-grpc-bundle/nifi-grpc-nar/src/main/resources/LICENSE 
b/nifi-nar-bundles/nifi-grpc-bundle/nifi-grpc-nar/src/main/resources/LICENSE
new file mode 100644
index 0000000..7bb71ec
--- /dev/null
+++ b/nifi-nar-bundles/nifi-grpc-bundle/nifi-grpc-nar/src/main/resources/LICENSE
@@ -0,0 +1,259 @@
+                                 Apache License
+                           Version 2.0, January 2004
+                        http://www.apache.org/licenses/
+
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+   1. Definitions.
+
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+   2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+   3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+   4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+   5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+   6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+   7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+   8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+   9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
+
+   END OF TERMS AND CONDITIONS
+
+   APPENDIX: How to apply the Apache License to your work.
+
+      To apply the Apache License to your work, attach the following
+      boilerplate notice, with the fields enclosed by brackets "[]"
+      replaced with your own identifying information. (Don't include
+      the brackets!)  The text should be enclosed in the appropriate
+      comment syntax for the file format. We also recommend that a
+      file or class name and description of purpose be included on the
+      same "printed page" as the copyright notice for easier
+      identification within third-party archives.
+
+   Copyright [yyyy] [name of copyright owner]
+
+   Licensed 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.
+
+The binary distribution of this product bundles 'Google Protocol Buffers Java 
3.3.1'
+which is licensed under a BSD license.
+
+  This license applies to all parts of Protocol Buffers except the following:
+
+    - Atomicops support for generic gcc, located in
+      src/google/protobuf/stubs/atomicops_internals_generic_gcc.h.
+      This file is copyrighted by Red Hat Inc.
+
+    - Atomicops support for AIX/POWER, located in
+      src/google/protobuf/stubs/atomicops_internals_power.h.
+      This file is copyrighted by Bloomberg Finance LP.
+
+  Copyright 2014, Google Inc.  All rights reserved.
+
+  Redistribution and use in source and binary forms, with or without
+  modification, are permitted provided that the following conditions are
+  met:
+
+      * Redistributions of source code must retain the above copyright
+  notice, this list of conditions and the following disclaimer.
+      * Redistributions in binary form must reproduce the above
+  copyright notice, this list of conditions and the following disclaimer
+  in the documentation and/or other materials provided with the
+  distribution.
+      * Neither the name of Google Inc. nor the names of its
+  contributors may be used to endorse or promote products derived from
+  this software without specific prior written permission.
+
+  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+  Code generated by the Protocol Buffer compiler is owned by the owner
+  of the input file used when generating it.  This code is not
+  standalone and requires a support library to be linked with it.  This
+  support library is itself covered by the above license.
+
+The binary distribution of this product bundles 'The JSR-305 reference 
implementation'
+which is licensed under a BSD license.
+
+  The JSR-305 reference implementation (lib/jsr305.jar) is
+  distributed under the terms of the New BSD license:
+
+    http://www.opensource.org/licenses/bsd-license.php
+
+  See the JSR-305 home page for more information:
+
+    http://code.google.com/p/jsr-305/
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/nifi/blob/58a623df/nifi-nar-bundles/nifi-grpc-bundle/nifi-grpc-nar/src/main/resources/NOTICE
----------------------------------------------------------------------
diff --git 
a/nifi-nar-bundles/nifi-grpc-bundle/nifi-grpc-nar/src/main/resources/NOTICE 
b/nifi-nar-bundles/nifi-grpc-bundle/nifi-grpc-nar/src/main/resources/NOTICE
new file mode 100644
index 0000000..37d9d47
--- /dev/null
+++ b/nifi-nar-bundles/nifi-grpc-bundle/nifi-grpc-nar/src/main/resources/NOTICE
@@ -0,0 +1,302 @@
+nifi-grpc-nar
+Copyright 2017 The Apache Software Foundation
+
+This product includes software developed at
+The Apache Software Foundation (http://www.apache.org/).
+
+******************
+Apache Software License v2
+******************
+
+The following binary components are provided under the Apache Software License 
v2
+
+  (ASLv2) Apache Commons Lang
+    The following NOTICE information applies:
+      Apache Commons Lang
+      Copyright 2001-2014 The Apache Software Foundation
+
+      This product includes software from the Spring Framework,
+      under the Apache License 2.0 (see: StringUtils.containsWhitespace())
+
+  (ASLv2) gRPC-Java
+    The following NOTICE information applies:
+       Copyright 2014, gRPC Authors All rights reserved.
+
+       Licensed 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.
+
+       -----------------------------------------------------------------------
+
+       This product contains a modified portion of 'OkHttp', an open source
+       HTTP & SPDY client for Android and Java applications, which can be 
obtained
+       at:
+
+         * LICENSE:
+           * okhttp/third_party/okhttp/LICENSE (Apache License 2.0)
+         * HOMEPAGE:
+           * https://github.com/square/okhttp
+         * LOCATION_IN_GRPC:
+           * okhttp/third_party/okhttp
+
+       This product contains a modified portion of 'Netty', an open source
+       networking library, which can be obtained at:
+
+         * LICENSE:
+           * netty/third_party/netty/LICENSE.txt (Apache License 2.0)
+         * HOMEPAGE:
+           * https://netty.io
+         * LOCATION_IN_GRPC:
+    * netty/third_party/netty
+
+  (ASLv2) The Netty Project
+    The following NOTICE information applies:
+                                   The Netty Project
+                                   =================
+
+       Please visit the Netty web site for more information:
+
+         * http://netty.io/
+
+       Copyright 2014 The Netty Project
+
+       The Netty Project 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.
+
+       Also, please refer to each LICENSE.<component>.txt file, which is 
located in
+       the 'license' directory of the distribution file, for the license terms 
of the
+       components that this product depends on.
+
+       
-------------------------------------------------------------------------------
+       This product contains the extensions to Java Collections Framework 
which has
+       been derived from the works by JSR-166 EG, Doug Lea, and Jason T. 
Greene:
+
+         * LICENSE:
+           * license/LICENSE.jsr166y.txt (Public Domain)
+         * HOMEPAGE:
+           * http://gee.cs.oswego.edu/cgi-bin/viewcvs.cgi/jsr166/
+           * 
http://viewvc.jboss.org/cgi-bin/viewvc.cgi/jbosscache/experimental/jsr166/
+
+       This product contains a modified version of Robert Harder's Public 
Domain
+       Base64 Encoder and Decoder, which can be obtained at:
+
+         * LICENSE:
+           * license/LICENSE.base64.txt (Public Domain)
+         * HOMEPAGE:
+           * http://iharder.sourceforge.net/current/java/base64/
+
+       This product contains a modified portion of 'Webbit', an event based
+       WebSocket and HTTP server, which can be obtained at:
+
+         * LICENSE:
+           * license/LICENSE.webbit.txt (BSD License)
+         * HOMEPAGE:
+           * https://github.com/joewalnes/webbit
+
+       This product contains a modified portion of 'SLF4J', a simple logging
+       facade for Java, which can be obtained at:
+
+         * LICENSE:
+           * license/LICENSE.slf4j.txt (MIT License)
+         * HOMEPAGE:
+           * http://www.slf4j.org/
+
+       This product contains a modified portion of 'Apache Harmony', an open 
source
+       Java SE, which can be obtained at:
+
+         * LICENSE:
+           * license/LICENSE.harmony.txt (Apache License 2.0)
+         * HOMEPAGE:
+           * http://archive.apache.org/dist/harmony/
+
+       This product contains a modified portion of 'jbzip2', a Java bzip2 
compression
+       and decompression library written by Matthew J. Francis. It can be 
obtained at:
+
+         * LICENSE:
+           * license/LICENSE.jbzip2.txt (MIT License)
+         * HOMEPAGE:
+           * https://code.google.com/p/jbzip2/
+
+       This product contains a modified portion of 'libdivsufsort', a C API 
library to construct
+       the suffix array and the Burrows-Wheeler transformed string for any 
input string of
+       a constant-size alphabet written by Yuta Mori. It can be obtained at:
+
+         * LICENSE:
+           * license/LICENSE.libdivsufsort.txt (MIT License)
+         * HOMEPAGE:
+           * https://github.com/y-256/libdivsufsort
+
+       This product contains a modified portion of Nitsan Wakart's 'JCTools', 
Java Concurrency Tools for the JVM,
+        which can be obtained at:
+
+         * LICENSE:
+           * license/LICENSE.jctools.txt (ASL2 License)
+         * HOMEPAGE:
+           * https://github.com/JCTools/JCTools
+
+       This product optionally depends on 'JZlib', a re-implementation of zlib 
in
+       pure Java, which can be obtained at:
+
+         * LICENSE:
+           * license/LICENSE.jzlib.txt (BSD style License)
+         * HOMEPAGE:
+           * http://www.jcraft.com/jzlib/
+
+       This product optionally depends on 'Compress-LZF', a Java library for 
encoding and
+       decoding data in LZF format, written by Tatu Saloranta. It can be 
obtained at:
+
+         * LICENSE:
+           * license/LICENSE.compress-lzf.txt (Apache License 2.0)
+         * HOMEPAGE:
+           * https://github.com/ning/compress
+
+       This product optionally depends on 'lz4', a LZ4 Java compression
+       and decompression library written by Adrien Grand. It can be obtained 
at:
+
+         * LICENSE:
+           * license/LICENSE.lz4.txt (Apache License 2.0)
+         * HOMEPAGE:
+           * https://github.com/jpountz/lz4-java
+
+       This product optionally depends on 'lzma-java', a LZMA Java compression
+       and decompression library, which can be obtained at:
+
+         * LICENSE:
+           * license/LICENSE.lzma-java.txt (Apache License 2.0)
+         * HOMEPAGE:
+           * https://github.com/jponge/lzma-java
+
+       This product contains a modified portion of 'jfastlz', a Java port of 
FastLZ compression
+       and decompression library written by William Kinney. It can be obtained 
at:
+
+         * LICENSE:
+           * license/LICENSE.jfastlz.txt (MIT License)
+         * HOMEPAGE:
+           * https://code.google.com/p/jfastlz/
+
+       This product contains a modified portion of and optionally depends on 
'Protocol Buffers', Google's data
+       interchange format, which can be obtained at:
+
+         * LICENSE:
+           * license/LICENSE.protobuf.txt (New BSD License)
+         * HOMEPAGE:
+           * https://github.com/google/protobuf
+
+       This product optionally depends on 'Bouncy Castle Crypto APIs' to 
generate
+       a temporary self-signed X.509 certificate when the JVM does not provide 
the
+       equivalent functionality.  It can be obtained at:
+
+         * LICENSE:
+           * license/LICENSE.bouncycastle.txt (MIT License)
+         * HOMEPAGE:
+           * http://www.bouncycastle.org/
+
+       This product optionally depends on 'Snappy', a compression library 
produced
+       by Google Inc, which can be obtained at:
+
+         * LICENSE:
+           * license/LICENSE.snappy.txt (New BSD License)
+         * HOMEPAGE:
+           * https://github.com/google/snappy
+
+       This product optionally depends on 'JBoss Marshalling', an alternative 
Java
+       serialization API, which can be obtained at:
+
+         * LICENSE:
+           * license/LICENSE.jboss-marshalling.txt (GNU LGPL 2.1)
+         * HOMEPAGE:
+           * http://www.jboss.org/jbossmarshalling
+
+       This product optionally depends on 'Caliper', Google's micro-
+       benchmarking framework, which can be obtained at:
+
+         * LICENSE:
+           * license/LICENSE.caliper.txt (Apache License 2.0)
+         * HOMEPAGE:
+           * https://github.com/google/caliper
+
+       This product optionally depends on 'Apache Commons Logging', a logging
+       framework, which can be obtained at:
+
+         * LICENSE:
+           * license/LICENSE.commons-logging.txt (Apache License 2.0)
+         * HOMEPAGE:
+           * http://commons.apache.org/logging/
+
+       This product optionally depends on 'Apache Log4J', a logging framework, 
which
+       can be obtained at:
+
+         * LICENSE:
+           * license/LICENSE.log4j.txt (Apache License 2.0)
+         * HOMEPAGE:
+           * http://logging.apache.org/log4j/
+
+       This product optionally depends on 'Aalto XML', an ultra-high 
performance
+       non-blocking XML processor, which can be obtained at:
+
+         * LICENSE:
+           * license/LICENSE.aalto-xml.txt (Apache License 2.0)
+         * HOMEPAGE:
+           * http://wiki.fasterxml.com/AaltoHome
+
+       This product contains a modified version of 'HPACK', a Java 
implementation of
+       the HTTP/2 HPACK algorithm written by Twitter. It can be obtained at:
+
+         * LICENSE:
+           * license/LICENSE.hpack.txt (Apache License 2.0)
+         * HOMEPAGE:
+           * https://github.com/twitter/hpack
+
+       This product contains a modified portion of 'Apache Commons Lang', a 
Java library
+       provides utilities for the java.lang API, which can be obtained at:
+
+         * LICENSE:
+           * license/LICENSE.commons-lang.txt (Apache License 2.0)
+         * HOMEPAGE:
+    * https://commons.apache.org/proper/commons-lang/
+
+    This product contains a forked and modified version of Tomcat Native
+
+      * LICENSE:
+        * ASL2
+      * HOMEPAGE:
+        * http://tomcat.apache.org/native-doc/
+        * https://svn.apache.org/repos/asf/tomcat/native/
+
+  (ASLv2) Guava
+    The following NOTICE information applies:
+      Guava
+      Copyright 2015 The Guava Authors
+
+  (ASLv2) Google GSON
+    The following NOTICE information applies:
+      Copyright 2008 Google Inc.
+
+  (ASLv2) Error Prone
+    The following NOTICE information applies:
+      Copyright 2017 Google Inc.
+
+  (ASLv2) Instrumentation
+    The following NOTICE information applies:
+      Copyright 2016 Google Inc.
+
+  (ASLv2) Google APIs
+    The following NOTICE information applies:
+      Copyright 2016 Google Inc.
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/nifi/blob/58a623df/nifi-nar-bundles/nifi-grpc-bundle/nifi-grpc-processors/pom.xml
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-grpc-bundle/nifi-grpc-processors/pom.xml 
b/nifi-nar-bundles/nifi-grpc-bundle/nifi-grpc-processors/pom.xml
new file mode 100644
index 0000000..04e42fa
--- /dev/null
+++ b/nifi-nar-bundles/nifi-grpc-bundle/nifi-grpc-processors/pom.xml
@@ -0,0 +1,139 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Licensed to the Apache Software Foundation (ASF) under one or more 
contributor 
+license agreements. See the NOTICE file distributed with this work for 
additional 
+information regarding copyright ownership. The ASF licenses this file to 
+You under the Apache License, Version 2.0 (the "License"); you may not use 
+this file except in compliance with the License. You may obtain a copy of 
+the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required 
+by applicable law or agreed to in writing, software distributed under the 
+License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS 
+OF ANY KIND, either express or implied. See the License for the specific 
+language governing permissions and limitations under the License. -->
+<project xmlns="http://maven.apache.org/POM/4.0.0"; 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"; 
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 
http://maven.apache.org/xsd/maven-4.0.0.xsd";>
+    <modelVersion>4.0.0</modelVersion>
+
+    <parent>
+        <groupId>org.apache.nifi</groupId>
+        <artifactId>nifi-grpc-bundle</artifactId>
+        <version>1.4.0-SNAPSHOT</version>
+    </parent>
+
+    <artifactId>nifi-grpc-processors</artifactId>
+    <packaging>jar</packaging>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.apache.nifi</groupId>
+            <artifactId>nifi-api</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.nifi</groupId>
+            <artifactId>nifi-utils</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.nifi</groupId>
+            <artifactId>nifi-ssl-context-service-api</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.commons</groupId>
+            <artifactId>commons-lang3</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>commons-io</groupId>
+            <artifactId>commons-io</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>io.grpc</groupId>
+            <artifactId>grpc-netty</artifactId>
+            <version>1.4.0</version>
+        </dependency>
+        <dependency>
+            <groupId>io.grpc</groupId>
+            <artifactId>grpc-protobuf</artifactId>
+            <version>1.4.0</version>
+        </dependency>
+        <dependency>
+            <groupId>io.grpc</groupId>
+            <artifactId>grpc-stub</artifactId>
+            <version>1.4.0</version>
+        </dependency>
+        <dependency>
+            <groupId>io.netty</groupId>
+            <artifactId>netty-tcnative-boringssl-static</artifactId>
+            <version>2.0.3.Final</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.nifi</groupId>
+            <artifactId>nifi-mock</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.nifi</groupId>
+            <artifactId>nifi-ssl-context-service</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.mockito</groupId>
+            <artifactId>mockito-all</artifactId>
+            <scope>test</scope>
+        </dependency>
+    </dependencies>
+    <build>
+        <extensions>
+            <extension>
+               <groupId>kr.motd.maven</groupId>
+               <artifactId>os-maven-plugin</artifactId>
+               <version>1.4.1.Final</version>
+            </extension>
+        </extensions>
+
+        <plugins>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-checkstyle-plugin</artifactId>
+                <configuration>
+                    
<excludes>**/grpc/FlowFileRequest.java,**/grpc/FlowFileReply.java,**/grpc/FFSProto.java,**/grpc/FlowFileServiceGrpc.java</excludes>
+                </configuration>
+            </plugin>
+            <plugin>
+                <groupId>org.xolstice.maven.plugins</groupId>
+                <artifactId>protobuf-maven-plugin</artifactId>
+                <version>0.5.0</version>
+                <configuration>
+                    
<protocArtifact>com.google.protobuf:protoc:3.2.0:exe:${os.detected.classifier}</protocArtifact>
+                    <pluginId>grpc-java</pluginId>
+                    
<pluginArtifact>io.grpc:protoc-gen-grpc-java:1.3.0:exe:${os.detected.classifier}</pluginArtifact>
+                    
<protoSourceRoot>${basedir}/src/main/resources/proto</protoSourceRoot>
+                </configuration>
+                <executions>
+                    <execution>
+                        <goals>
+                            <goal>compile</goal>
+                            <goal>compile-custom</goal>
+                        </goals>
+                    </execution>
+                </executions>
+            </plugin>
+
+            <plugin>
+                <groupId>org.codehaus.mojo</groupId>
+                <artifactId>build-helper-maven-plugin</artifactId>
+                <version>1.4</version>
+                <executions>
+                    <execution>
+                        <id>test</id>
+                        <phase>generate-sources</phase>
+                        <goals>
+                            <goal>add-source</goal>
+                        </goals>
+                        <configuration>
+                            <sources>
+                                
<source>${basedir}/target/generated-sources</source>
+                            </sources>
+                        </configuration>
+                    </execution>
+                </executions>
+            </plugin>
+        </plugins>
+    </build>
+</project>

http://git-wip-us.apache.org/repos/asf/nifi/blob/58a623df/nifi-nar-bundles/nifi-grpc-bundle/nifi-grpc-processors/src/main/java/org/apache/nifi/processors/grpc/FlowFileIngestService.java
----------------------------------------------------------------------
diff --git 
a/nifi-nar-bundles/nifi-grpc-bundle/nifi-grpc-processors/src/main/java/org/apache/nifi/processors/grpc/FlowFileIngestService.java
 
b/nifi-nar-bundles/nifi-grpc-bundle/nifi-grpc-processors/src/main/java/org/apache/nifi/processors/grpc/FlowFileIngestService.java
new file mode 100644
index 0000000..c4097b0
--- /dev/null
+++ 
b/nifi-nar-bundles/nifi-grpc-bundle/nifi-grpc-processors/src/main/java/org/apache/nifi/processors/grpc/FlowFileIngestService.java
@@ -0,0 +1,173 @@
+/*
+ * 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.processors.grpc;
+
+import com.google.common.collect.Maps;
+import com.google.protobuf.ByteString;
+
+import org.apache.commons.io.IOUtils;
+import org.apache.nifi.flowfile.FlowFile;
+import org.apache.nifi.flowfile.attributes.CoreAttributes;
+import org.apache.nifi.logging.ComponentLog;
+import org.apache.nifi.processor.ProcessContext;
+import org.apache.nifi.processor.ProcessSession;
+import org.apache.nifi.processor.ProcessSessionFactory;
+
+import java.io.BufferedOutputStream;
+import java.io.InputStream;
+import java.util.Map;
+import java.util.UUID;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.concurrent.atomic.AtomicLong;
+import java.util.concurrent.atomic.AtomicReference;
+
+import io.grpc.stub.StreamObserver;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+/**
+ * Simple gRPC service that handles receipt of FlowFileRequest messages from 
external-to-NiFi gRPC
+ * clients.
+ */
+// NOTE: you may need to add the sources generated after running `maven clean 
compile` to your IDE
+// configured source directories. Otherwise, the classes generated when the 
proto is compiled won't
+// be accessible from here. For IntelliJ, open this module's settings and mark 
the following as source directories:
+//
+// * target/generated-sources/protobuf/grpc-java
+// * target/generated-sources/protobuf/java
+public class FlowFileIngestService extends 
FlowFileServiceGrpc.FlowFileServiceImplBase {
+    public static final String SERVICE_NAME = "grpc://FlowFileIngestService";
+    public static final int FILES_BEFORE_CHECKING_DESTINATION_SPACE = 5;
+
+    private final AtomicLong filesReceived = new AtomicLong(0L);
+    private final AtomicBoolean spaceAvailable = new AtomicBoolean(true);
+    private final AtomicReference<ProcessSessionFactory> 
sessionFactoryReference;
+    private final ProcessContext context;
+    private final ComponentLog logger;
+
+    /**
+     * Create a FlowFileIngestService
+     *
+     * @param sessionFactoryReference a reference to a {@link 
ProcessSessionFactory} to route {@link
+     *                                FlowFile}s to process relationships.
+     */
+    public FlowFileIngestService(final ComponentLog logger,
+                                 final AtomicReference<ProcessSessionFactory> 
sessionFactoryReference,
+                                 final ProcessContext context) {
+        this.context = checkNotNull(context);
+        this.sessionFactoryReference = checkNotNull(sessionFactoryReference);
+        this.logger = checkNotNull(logger);
+    }
+
+    /**
+     * Handle receipt of a FlowFileRequest and route it to the appropriate 
process relationship.
+     *
+     * @param request          the flowfile request
+     * @param responseObserver the mechanism by which to reply to the client
+     */
+    @Override
+    public void send(final org.apache.nifi.processors.grpc.FlowFileRequest 
request, final StreamObserver<FlowFileReply> responseObserver) {
+        final FlowFileReply.Builder replyBuilder = FlowFileReply.newBuilder();
+
+        final String remoteHost = 
FlowFileIngestServiceInterceptor.REMOTE_HOST_KEY.get();
+        final String remoteDN = 
FlowFileIngestServiceInterceptor.REMOTE_DN_KEY.get();
+
+        // block until we have a session factory (occurs when processor is 
triggered)
+        ProcessSessionFactory sessionFactory = null;
+        while (sessionFactory == null) {
+            sessionFactory = sessionFactoryReference.get();
+            if (sessionFactory == null) {
+                try {
+                    Thread.sleep(10);
+                } catch (final InterruptedException e) {
+                }
+            }
+        }
+
+        final ProcessSession session = sessionFactory.createSession();
+
+        // if there's no space available, reject the request.
+        final long n = filesReceived.getAndIncrement() % 
FILES_BEFORE_CHECKING_DESTINATION_SPACE;
+        if (n == 0 || !spaceAvailable.get()) {
+            if (context.getAvailableRelationships().isEmpty()) {
+                spaceAvailable.set(false);
+                final String message = "Received request from " + remoteHost + 
" but no space available; Indicating Service Unavailable";
+                if (logger.isDebugEnabled()) {
+                    logger.debug(message);
+                }
+                final FlowFileReply reply = 
replyBuilder.setResponseCode(FlowFileReply.ResponseCode.ERROR)
+                        .setBody(message)
+                        .build();
+                responseObserver.onNext(reply);
+                responseObserver.onCompleted();
+                return;
+            } else {
+                spaceAvailable.set(true);
+            }
+        }
+
+        if (logger.isDebugEnabled()) {
+            logger.debug("Received request from " + remoteHost);
+        }
+
+        final long startNanos = System.nanoTime();
+        FlowFile flowFile = session.create();
+        // push the attributes provided onto the created flowfile
+        final Map<String, String> attributes = Maps.newHashMap();
+        attributes.putAll(request.getAttributesMap());
+        String sourceSystemFlowFileIdentifier = 
attributes.get(CoreAttributes.UUID.key());
+        if (sourceSystemFlowFileIdentifier != null) {
+            sourceSystemFlowFileIdentifier = "urn:nifi:" + 
sourceSystemFlowFileIdentifier;
+
+            // If we receveied a UUID, we want to give the FlowFile a new UUID 
and register the sending system's
+            // identifier as the SourceSystemFlowFileIdentifier field in the 
Provenance RECEIVE event
+            attributes.put(CoreAttributes.UUID.key(), 
UUID.randomUUID().toString());
+        }
+        flowFile = session.putAllAttributes(flowFile, attributes);
+        final ByteString content = request.getContent();
+        final InputStream contentStream = content.newInput();
+
+        // write the provided content to the flowfile
+        flowFile = session.write(flowFile, out -> {
+            try (final BufferedOutputStream bos = new 
BufferedOutputStream(out, 65536)) {
+                IOUtils.copy(contentStream, bos);
+            }
+        });
+        final long transferNanos = System.nanoTime() - startNanos;
+        final long transferMillis = 
TimeUnit.MILLISECONDS.convert(transferNanos, TimeUnit.NANOSECONDS);
+
+        session.getProvenanceReporter().receive(flowFile,
+                SERVICE_NAME,
+                sourceSystemFlowFileIdentifier,
+                "Remote DN=" + remoteDN,
+                transferMillis);
+        flowFile = session.putAttribute(flowFile, ListenGRPC.REMOTE_HOST, 
remoteHost);
+        flowFile = session.putAttribute(flowFile, ListenGRPC.REMOTE_USER_DN, 
remoteDN);
+
+        // register success
+        session.transfer(flowFile, ListenGRPC.REL_SUCCESS);
+        session.commit();
+
+        // reply to client
+        final FlowFileReply reply = 
replyBuilder.setResponseCode(FlowFileReply.ResponseCode.SUCCESS)
+                .setBody("FlowFile successfully received.")
+                .build();
+        responseObserver.onNext(reply);
+        responseObserver.onCompleted();
+    }
+}

http://git-wip-us.apache.org/repos/asf/nifi/blob/58a623df/nifi-nar-bundles/nifi-grpc-bundle/nifi-grpc-processors/src/main/java/org/apache/nifi/processors/grpc/FlowFileIngestServiceInterceptor.java
----------------------------------------------------------------------
diff --git 
a/nifi-nar-bundles/nifi-grpc-bundle/nifi-grpc-processors/src/main/java/org/apache/nifi/processors/grpc/FlowFileIngestServiceInterceptor.java
 
b/nifi-nar-bundles/nifi-grpc-bundle/nifi-grpc-processors/src/main/java/org/apache/nifi/processors/grpc/FlowFileIngestServiceInterceptor.java
new file mode 100644
index 0000000..d98eee8
--- /dev/null
+++ 
b/nifi-nar-bundles/nifi-grpc-bundle/nifi-grpc-processors/src/main/java/org/apache/nifi/processors/grpc/FlowFileIngestServiceInterceptor.java
@@ -0,0 +1,150 @@
+/*
+ * 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.processors.grpc;
+
+import org.apache.nifi.logging.ComponentLog;
+
+import java.net.InetSocketAddress;
+import java.net.SocketAddress;
+import java.util.regex.Pattern;
+
+import javax.net.ssl.SSLPeerUnverifiedException;
+import javax.net.ssl.SSLSession;
+import javax.security.cert.X509Certificate;
+
+import io.grpc.Attributes;
+import io.grpc.Context;
+import io.grpc.Contexts;
+import io.grpc.Grpc;
+import io.grpc.Metadata;
+import io.grpc.ServerCall;
+import io.grpc.ServerCallHandler;
+import io.grpc.ServerInterceptor;
+import io.grpc.Status;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+/**
+ * Simple gRPC service call interceptor that enforces various controls
+ */
+public class FlowFileIngestServiceInterceptor implements ServerInterceptor {
+    public static final String DEFAULT_FOUND_SUBJECT = "none";
+    private static final String UNKNOWN_IP = "unknown-ip";
+    private static final String DN_UNAUTHORIZED = "The client DN does not have 
permission to post FlowFiles to this NiFi. ";
+    private static final ServerCall.Listener IDENTITY_LISTENER = new 
ServerCall.Listener(){};
+
+    public static final Context.Key<String> REMOTE_HOST_KEY = 
Context.key(ListenGRPC.REMOTE_HOST);
+    public static final Context.Key<String> REMOTE_DN_KEY = 
Context.key(ListenGRPC.REMOTE_USER_DN);
+
+    private final ComponentLog logger;
+    private Pattern authorizedDNpattern;
+
+    /**
+     * Create an interceptor that applies various controls per request
+     *
+     * @param logger the {@link ComponentLog} for the ListenGRPC processor
+     */
+    public FlowFileIngestServiceInterceptor(final ComponentLog logger) {
+        this.logger = checkNotNull(logger);
+    }
+
+    /**
+     * Enforce that the requestor DN matches the provided pattern.
+     *
+     * @param authorizedDNPattern the pattern which DNs must match
+     *
+     * @return this
+     */
+    public FlowFileIngestServiceInterceptor enforceDNPattern(final Pattern 
authorizedDNPattern) {
+        this.authorizedDNpattern = checkNotNull(authorizedDNPattern);
+        return this;
+    }
+
+    /**
+     * Intercept incoming and outgoing messages and enforce any necessary 
controls
+     *
+     * @param call the request message
+     * @param headers the request metadata
+     * @param next the next interceptor in the interceptor chain prior to the 
service implementation
+     * @param <I> The message request type (e.g. ReqT)
+     * @param <O> The message reply type (e.g. RespT)
+     *
+     * @return a listener for the incoming call.
+     */
+    @Override
+    public <I, O> ServerCall.Listener<I> interceptCall(
+            final ServerCall<I, O> call,
+            final Metadata headers,
+            final ServerCallHandler<I, O> next) {
+
+        final Attributes attributes = call.getAttributes();
+        final SocketAddress socketAddress = 
attributes.get(Grpc.TRANSPORT_ATTR_REMOTE_ADDR);
+        final String clientIp = clientIp(socketAddress);
+        String foundSubject = DEFAULT_FOUND_SUBJECT;
+
+        // enforce that the DN on the client cert matches the configured 
pattern
+        final SSLSession sslSession = 
attributes.get(Grpc.TRANSPORT_ATTR_SSL_SESSION);
+        if(this.authorizedDNpattern != null && sslSession != null) {
+            try {
+                final X509Certificate[] certs = 
sslSession.getPeerCertificateChain();
+                if(certs != null && certs.length > 0) {
+                    for (final X509Certificate cert : certs) {
+                        foundSubject = cert.getSubjectDN().getName();
+                        
if(authorizedDNpattern.matcher(foundSubject).matches()) {
+                            break;
+                        } else {
+                            logger.warn("Rejecting transfer attempt from " + 
foundSubject + " because the DN is not authorized, host=" + clientIp);
+                            
call.close(Status.PERMISSION_DENIED.withDescription(DN_UNAUTHORIZED + 
foundSubject), headers);
+                            return IDENTITY_LISTENER;
+                        }
+                    }
+                }
+            } catch (final SSLPeerUnverifiedException e) {
+                logger.debug("skipping DN authorization for request from {}.", 
new Object[] {clientIp}, e);
+            }
+        }
+        // contextualize the DN and IP for use in the RPC implementation
+        final Context context = Context.current()
+                .withValue(REMOTE_HOST_KEY, clientIp)
+                .withValue(REMOTE_DN_KEY, foundSubject);
+
+        // if we got to this point, there were no errors, call the next 
interceptor in the chain
+        return Contexts.interceptCall(context, call, headers, next);
+    }
+
+    /**
+     * Grabs the client IP from the socket address pulled from the request 
metadata, or UNKNOWN
+     * if it's not possible to determine.
+     *
+     * @param socketAddress the socket address pulled from the gRPC request
+     * @return the client IP
+     */
+    private String clientIp(final SocketAddress socketAddress) {
+        if (socketAddress == null) {
+            return UNKNOWN_IP;
+        }
+
+        if (!(socketAddress instanceof InetSocketAddress)) {
+            return socketAddress.toString();
+        }
+
+        final InetSocketAddress inetSocketAddress = (InetSocketAddress) 
socketAddress;
+        final String hostString = inetSocketAddress.getHostString();
+        return hostString == null ? UNKNOWN_IP : hostString;
+    }
+
+}

Reply via email to