NIFI-1537 Added SNMP processors
This closes #257

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

Branch: refs/heads/0.x
Commit: a6e97740c102e22917f4ebb3e1572e6918a3b55a
Parents: 1398312
Author: Pierre Villard <pierre.villard...@gmail.com>
Authored: Sun Feb 28 10:12:02 2016 +0100
Committer: Oleg Zhurakousky <o...@suitcase.io>
Committed: Sun Jun 19 15:00:33 2016 -0400

----------------------------------------------------------------------
 nifi-assembly/pom.xml                           |   5 +
 .../nifi-snmp-bundle/nifi-snmp-nar/pom.xml      |  35 ++
 .../src/main/resources/META-INF/LICENSE         | 203 +++++++++
 .../src/main/resources/META-INF/NOTICE          |  24 ++
 .../nifi-snmp-processors/pom.xml                |  81 ++++
 .../snmp/processors/AbstractSNMPProcessor.java  | 426 +++++++++++++++++++
 .../apache/nifi/snmp/processors/GetSNMP.java    | 177 ++++++++
 .../apache/nifi/snmp/processors/SNMPGetter.java | 100 +++++
 .../apache/nifi/snmp/processors/SNMPSetter.java |  56 +++
 .../apache/nifi/snmp/processors/SNMPUtils.java  | 268 ++++++++++++
 .../apache/nifi/snmp/processors/SNMPWorker.java |  74 ++++
 .../apache/nifi/snmp/processors/SetSNMP.java    | 224 ++++++++++
 .../org.apache.nifi.processor.Processor         |  16 +
 .../additionalDetails.html                      |  70 +++
 .../additionalDetails.html                      |  58 +++
 .../nifi/snmp/processors/GetSNMPTest.java       | 385 +++++++++++++++++
 .../nifi/snmp/processors/SNMPGetTest.java       | 123 ++++++
 .../nifi/snmp/processors/SNMPUtilsTest.java     | 134 ++++++
 .../nifi/snmp/processors/SNMPWalkTest.java      | 121 ++++++
 .../nifi/snmp/processors/SetSNMPTest.java       | 332 +++++++++++++++
 .../nifi/snmp/processors/TestSnmpAgentV1.java   | 212 +++++++++
 .../nifi/snmp/processors/TestSnmpAgentV2c.java  | 212 +++++++++
 .../nifi/snmp/processors/TestSnmpAgentV3.java   | 255 +++++++++++
 .../nifi/snmp/processors/WalkSNMPTest.java      | 117 +++++
 .../src/test/resources/log4j.properties         |  20 +
 nifi-nar-bundles/nifi-snmp-bundle/pom.xml       |  39 ++
 nifi-nar-bundles/pom.xml                        |   1 +
 pom.xml                                         |   6 +
 28 files changed, 3774 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/nifi/blob/a6e97740/nifi-assembly/pom.xml
----------------------------------------------------------------------
diff --git a/nifi-assembly/pom.xml b/nifi-assembly/pom.xml
index 9d68ba2..f50f6e8 100644
--- a/nifi-assembly/pom.xml
+++ b/nifi-assembly/pom.xml
@@ -336,6 +336,11 @@ language governing permissions and limitations under the 
License. -->
             <groupId>org.apache.nifi</groupId>
             <artifactId>nifi-mqtt-nar</artifactId>
             <type>nar</type>
+       </dependency>
+        <dependency>
+            <groupId>org.apache.nifi</groupId>
+            <artifactId>nifi-snmp-nar</artifactId>
+            <type>nar</type>
         </dependency>
         <dependency>
             <groupId>org.apache.nifi</groupId>

http://git-wip-us.apache.org/repos/asf/nifi/blob/a6e97740/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-nar/pom.xml
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-nar/pom.xml 
b/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-nar/pom.xml
new file mode 100644
index 0000000..38e5f27
--- /dev/null
+++ b/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-nar/pom.xml
@@ -0,0 +1,35 @@
+<?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-snmp-bundle</artifactId>
+        <version>1.0.0-SNAPSHOT</version>
+    </parent>
+    <artifactId>nifi-snmp-nar</artifactId>
+    <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-snmp-processors</artifactId>
+        </dependency>
+    </dependencies>
+</project>

http://git-wip-us.apache.org/repos/asf/nifi/blob/a6e97740/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-nar/src/main/resources/META-INF/LICENSE
----------------------------------------------------------------------
diff --git 
a/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-nar/src/main/resources/META-INF/LICENSE
 
b/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-nar/src/main/resources/META-INF/LICENSE
new file mode 100644
index 0000000..6b0b127
--- /dev/null
+++ 
b/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-nar/src/main/resources/META-INF/LICENSE
@@ -0,0 +1,203 @@
+
+                                 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.
+

http://git-wip-us.apache.org/repos/asf/nifi/blob/a6e97740/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-nar/src/main/resources/META-INF/NOTICE
----------------------------------------------------------------------
diff --git 
a/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-nar/src/main/resources/META-INF/NOTICE
 
b/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-nar/src/main/resources/META-INF/NOTICE
new file mode 100644
index 0000000..e9642a2
--- /dev/null
+++ 
b/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-nar/src/main/resources/META-INF/NOTICE
@@ -0,0 +1,24 @@
+nifi-snmp-nar
+Copyright 2015-2016 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 IO
+    The following NOTICE information applies:
+      Apache Commons IO
+      Copyright 2002-2012 The Apache Software Foundation
+
+  (ASLv2) Apache Commons Lang
+    The following NOTICE information applies:
+      Apache Commons Lang
+      Copyright 2001-2015 The Apache Software Foundation
+
+      This product includes software from the Spring Framework,
+      under the Apache License 2.0 (see: StringUtils.containsWhitespace())

http://git-wip-us.apache.org/repos/asf/nifi/blob/a6e97740/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/pom.xml
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/pom.xml 
b/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/pom.xml
new file mode 100644
index 0000000..bdd7a8e
--- /dev/null
+++ b/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/pom.xml
@@ -0,0 +1,81 @@
+<?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-snmp-bundle</artifactId>
+               <version>1.0.0-SNAPSHOT</version>
+       </parent>
+       <artifactId>nifi-snmp-processors</artifactId>
+       <packaging>jar</packaging>
+
+       <properties>
+               <snmp4j.version>1.10.1</snmp4j.version>
+        <snmp4j-agent.version>1.3.1</snmp4j-agent.version>
+       </properties>
+
+       <dependencies>
+               <dependency>
+            <groupId>org.snmp4j</groupId>
+            <artifactId>snmp4j</artifactId>
+            <version>${snmp4j.version}</version>
+        </dependency>
+        
+        <dependency>
+                   <groupId>org.snmp4j</groupId>
+                   <artifactId>snmp4j-agent</artifactId>
+                   <version>${snmp4j-agent.version}</version>
+                   <scope>test</scope>
+               </dependency>
+        
+               <dependency>
+                       <groupId>org.apache.nifi</groupId>
+                       <artifactId>nifi-api</artifactId>
+               </dependency>
+               
+               <dependency>
+                       <groupId>org.apache.nifi</groupId>
+                       <artifactId>nifi-processor-utils</artifactId>
+               </dependency>
+        
+               <dependency>
+                       <groupId>org.apache.nifi</groupId>
+                       <artifactId>nifi-mock</artifactId>
+                       <scope>test</scope>
+               </dependency>
+       </dependencies>
+
+       <build>
+               <plugins>
+                       <plugin>
+                               <groupId>org.apache.rat</groupId>
+                               <artifactId>apache-rat-plugin</artifactId>
+                               <configuration>
+                                       <excludes>
+                                               <!-- test data -->
+                                               
<exclude>src/test/resources/testdata/*</exclude>
+                                       </excludes>
+                               </configuration>
+                       </plugin>
+                       <plugin>
+                               <groupId>org.apache.maven.plugins</groupId>
+                               <artifactId>maven-surefire-plugin</artifactId>
+                               <configuration>
+                                       <systemPropertyVariables>
+                                               
<java.io.tmpdir>${project.build.directory}</java.io.tmpdir>
+                                       </systemPropertyVariables>
+                               </configuration>
+                       </plugin>
+               </plugins>
+       </build>
+</project>

http://git-wip-us.apache.org/repos/asf/nifi/blob/a6e97740/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/main/java/org/apache/nifi/snmp/processors/AbstractSNMPProcessor.java
----------------------------------------------------------------------
diff --git 
a/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/main/java/org/apache/nifi/snmp/processors/AbstractSNMPProcessor.java
 
b/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/main/java/org/apache/nifi/snmp/processors/AbstractSNMPProcessor.java
new file mode 100644
index 0000000..3fd5bcd
--- /dev/null
+++ 
b/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/main/java/org/apache/nifi/snmp/processors/AbstractSNMPProcessor.java
@@ -0,0 +1,426 @@
+/*
+ * 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.snmp.processors;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+
+import org.apache.nifi.annotation.lifecycle.OnStopped;
+import org.apache.nifi.components.PropertyDescriptor;
+import org.apache.nifi.components.ValidationContext;
+import org.apache.nifi.components.ValidationResult;
+import org.apache.nifi.processor.AbstractProcessor;
+import org.apache.nifi.processor.ProcessContext;
+import org.apache.nifi.processor.ProcessSession;
+import org.apache.nifi.processor.Processor;
+import org.apache.nifi.processor.exception.ProcessException;
+import org.apache.nifi.processor.util.StandardValidators;
+import org.snmp4j.AbstractTarget;
+import org.snmp4j.CommunityTarget;
+import org.snmp4j.Snmp;
+import org.snmp4j.TransportMapping;
+import org.snmp4j.UserTarget;
+import org.snmp4j.mp.MPv3;
+import org.snmp4j.mp.SnmpConstants;
+import org.snmp4j.security.SecurityModels;
+import org.snmp4j.security.SecurityProtocols;
+import org.snmp4j.security.USM;
+import org.snmp4j.security.UsmUser;
+import org.snmp4j.smi.OctetString;
+import org.snmp4j.smi.UdpAddress;
+import org.snmp4j.transport.DefaultUdpTransportMapping;
+
+/**
+ * Base processor that uses SNMP4J client API
+ * (http://www.snmp4j.org/)
+ *
+ * @param <T> the type of {@link SNMPWorker}. Please see {@link SNMPSetter}
+ *            and {@link SNMPGetter}
+ */
+abstract class AbstractSNMPProcessor<T extends SNMPWorker> extends 
AbstractProcessor {
+
+    /** property to define host of the SNMP agent */
+    public static final PropertyDescriptor HOST = new 
PropertyDescriptor.Builder()
+            .name("snmp-hostname")
+            .displayName("Host Name")
+            .description("Network address of SNMP Agent (e.g., localhost)")
+            .required(true)
+            .defaultValue("localhost")
+            .addValidator(StandardValidators.NON_EMPTY_VALIDATOR)
+            .build();
+
+    /** property to define port of the SNMP agent */
+    public static final PropertyDescriptor PORT = new 
PropertyDescriptor.Builder()
+            .name("snmp-port")
+            .displayName("Port")
+            .description("Numeric value identifying Port of SNMP Agent (e.g., 
161)")
+            .required(true)
+            .defaultValue("161")
+            .addValidator(StandardValidators.PORT_VALIDATOR)
+            .build();
+
+    /** property to define SNMP version to use */
+    public static final PropertyDescriptor SNMP_VERSION = new 
PropertyDescriptor.Builder()
+            .name("snmp-version")
+            .displayName("SNMP Version")
+            .description("SNMP Version to use")
+            .required(true)
+            .allowableValues("SNMPv1", "SNMPv2c", "SNMPv3")
+            .defaultValue("SNMPv1")
+            .build();
+
+    /** property to define SNMP community to use */
+    public static final PropertyDescriptor SNMP_COMMUNITY = new 
PropertyDescriptor.Builder()
+            .name("snmp-community")
+            .displayName("SNMP Community (v1 & v2c)")
+            .description("SNMP Community to use (e.g., public)")
+            .required(false)
+            .defaultValue("public")
+            .addValidator(StandardValidators.NON_EMPTY_VALIDATOR)
+            .build();
+
+    /** property to define SNMP security level to use */
+    public static final PropertyDescriptor SNMP_SECURITY_LEVEL = new 
PropertyDescriptor.Builder()
+            .name("snmp-security-level")
+            .displayName("SNMP Security Level")
+            .description("SNMP Security Level to use")
+            .required(true)
+            .allowableValues("noAuthNoPriv", "authNoPriv", "authPriv")
+            .defaultValue("authPriv")
+            .build();
+
+    /** property to define SNMP security name to use */
+    public static final PropertyDescriptor SNMP_SECURITY_NAME = new 
PropertyDescriptor.Builder()
+            .name("snmp-security-name")
+            .displayName("SNMP Security name / user name")
+            .description("Security name used for SNMP exchanges")
+            .required(false)
+            .addValidator(StandardValidators.NON_EMPTY_VALIDATOR)
+            .build();
+
+    /** property to define SNMP authentication protocol to use */
+    public static final PropertyDescriptor SNMP_AUTH_PROTOCOL = new 
PropertyDescriptor.Builder()
+            .name("snmp-authentication-protocol")
+            .displayName("SNMP Authentication Protocol")
+            .description("SNMP Authentication Protocol to use")
+            .required(true)
+            .allowableValues("MD5", "SHA", "")
+            .defaultValue("")
+            .build();
+
+    /** property to define SNMP authentication password to use */
+    public static final PropertyDescriptor SNMP_AUTH_PASSWORD = new 
PropertyDescriptor.Builder()
+            .name("snmp-authentication-passphrase")
+            .displayName("SNMP Authentication pass phrase")
+            .description("Pass phrase used for SNMP authentication protocol")
+            .required(false)
+            .addValidator(StandardValidators.NON_EMPTY_VALIDATOR)
+            .sensitive(true)
+            .build();
+
+    /** property to define SNMP private protocol to use */
+    public static final PropertyDescriptor SNMP_PRIV_PROTOCOL = new 
PropertyDescriptor.Builder()
+            .name("snmp-private-protocol")
+            .displayName("SNMP Private Protocol")
+            .description("SNMP Private Protocol to use")
+            .required(true)
+            .allowableValues("DES", "3DES", "AES128", "AES192", "AES256", "")
+            .defaultValue("")
+            .build();
+
+    /** property to define SNMP private password to use */
+    public static final PropertyDescriptor SNMP_PRIV_PASSWORD = new 
PropertyDescriptor.Builder()
+            .name("snmp-private-protocol-passphrase")
+            .displayName("SNMP Private protocol pass phrase")
+            .description("Pass phrase used for SNMP private protocol")
+            .required(false)
+            .addValidator(StandardValidators.NON_EMPTY_VALIDATOR)
+            .sensitive(true)
+            .build();
+
+    /** property to define the number of SNMP retries when requesting the SNMP 
Agent */
+    public static final PropertyDescriptor SNMP_RETRIES = new 
PropertyDescriptor.Builder()
+            .name("snmp-retries")
+            .displayName("Number of retries")
+            .description("Set the number of retries when requesting the SNMP 
Agent")
+            .required(true)
+            .defaultValue("0")
+            .addValidator(StandardValidators.INTEGER_VALIDATOR)
+            .build();
+
+    /** property to define the timeout when requesting the SNMP Agent */
+    public static final PropertyDescriptor SNMP_TIMEOUT = new 
PropertyDescriptor.Builder()
+            .name("snmp-timeout")
+            .displayName("Timeout (ms)")
+            .description("Set the timeout (in milliseconds) when requesting 
the SNMP Agent")
+            .required(true)
+            .defaultValue("5000")
+            .addValidator(StandardValidators.INTEGER_VALIDATOR)
+            .build();
+
+    /** list of property descriptors */
+    static List<PropertyDescriptor> descriptors = new ArrayList<>();
+
+    /*
+     * Will ensure that list of PropertyDescriptors is build only once, since
+     * all other life cycle methods are invoked multiple times.
+     */
+    static {
+        descriptors.add(HOST);
+        descriptors.add(PORT);
+        descriptors.add(SNMP_VERSION);
+        descriptors.add(SNMP_COMMUNITY);
+        descriptors.add(SNMP_SECURITY_LEVEL);
+        descriptors.add(SNMP_SECURITY_NAME);
+        descriptors.add(SNMP_AUTH_PROTOCOL);
+        descriptors.add(SNMP_AUTH_PASSWORD);
+        descriptors.add(SNMP_PRIV_PROTOCOL);
+        descriptors.add(SNMP_PRIV_PASSWORD);
+        descriptors.add(SNMP_RETRIES);
+        descriptors.add(SNMP_TIMEOUT);
+    }
+
+    /** SNMP target */
+    protected volatile AbstractTarget snmpTarget;
+
+    /** transport mapping */
+    protected volatile TransportMapping transportMapping;
+
+    /** SNMP */
+    protected volatile Snmp snmp;
+
+    /** target resource */
+    protected volatile T targetResource;
+
+    /**
+     * Will builds target resource upon first invocation and will delegate to 
the
+     * implementation of {@link #onTriggerSnmp(ProcessContext, 
ProcessSession)} method for
+     * further processing.
+     */
+    @Override
+    public void onTrigger(ProcessContext context, ProcessSession session) 
throws ProcessException {
+        synchronized (this) {
+            this.buildTargetResource(context);
+        }
+        this.onTriggerSnmp(context, session);
+    }
+
+    /**
+     * Will close current SNMP mapping.
+     */
+    @OnStopped
+    public void close() {
+        try {
+            if (this.targetResource != null) {
+                this.targetResource.close();
+            }
+        } catch (Exception e) {
+            this.getLogger().warn("Failure while closing target resource " + 
this.targetResource, e);
+        }
+        this.targetResource = null;
+
+        try {
+            if (this.transportMapping != null) {
+                this.transportMapping.close();
+            }
+        } catch (IOException e) {
+            this.getLogger().warn("Failure while closing UDP transport 
mapping", e);
+        }
+        this.transportMapping = null;
+
+        try {
+            if (this.snmp != null) {
+                this.snmp.close();
+            }
+        } catch (IOException e) {
+            this.getLogger().warn("Failure while closing UDP transport 
mapping", e);
+        }
+        this.snmp = null;
+    }
+
+    /**
+     * @see 
org.apache.nifi.components.AbstractConfigurableComponent#customValidate(org.apache.nifi.components.ValidationContext)
+     */
+    @Override
+    protected Collection<ValidationResult> customValidate(ValidationContext 
validationContext) {
+        final List<ValidationResult> problems = new 
ArrayList<>(super.customValidate(validationContext));
+
+        final boolean isVersion3 = 
"SNMPv3".equals(validationContext.getProperty(SNMP_VERSION).getValue());
+
+        if(isVersion3) {
+            final boolean isSecurityNameSet = 
validationContext.getProperty(SNMP_SECURITY_NAME).isSet();
+            if(!isSecurityNameSet) {
+                problems.add(new ValidationResult.Builder()
+                        .input("SNMP Security Name")
+                        .valid(false)
+                        .explanation("SNMP Security Name must be set with 
SNMPv3.")
+                        .build());
+            }
+
+            final boolean isAuthProtOK = 
!"".equals(validationContext.getProperty(SNMP_AUTH_PROTOCOL).getValue());
+            final boolean isAuthPwdSet = 
validationContext.getProperty(SNMP_AUTH_PASSWORD).isSet();
+            final boolean isPrivProtOK = 
!"".equals(validationContext.getProperty(SNMP_PRIV_PROTOCOL).getValue());
+            final boolean isPrivPwdSet = 
validationContext.getProperty(SNMP_PRIV_PASSWORD).isSet();
+
+            
switch(validationContext.getProperty(SNMP_SECURITY_LEVEL).getValue()) {
+            case "authNoPriv":
+                if(!isAuthProtOK || !isAuthPwdSet) {
+                    problems.add(new ValidationResult.Builder()
+                            .input("SNMP Security Level")
+                            .valid(false)
+                            .explanation("Authentication protocol and password 
must be set when using authNoPriv security level.")
+                            .build());
+                }
+                break;
+            case "authPriv":
+                if(!isAuthProtOK || !isAuthPwdSet || !isPrivProtOK || 
!isPrivPwdSet) {
+                    problems.add(new ValidationResult.Builder()
+                            .input("SNMP Security Level")
+                            .valid(false)
+                            .explanation("All protocols and passwords must be 
set when using authPriv security level.")
+                            .build());
+                }
+                break;
+            case "noAuthNoPriv":
+            default:
+                break;
+            }
+        } else {
+            final boolean isCommunitySet = 
validationContext.getProperty(SNMP_COMMUNITY).isSet();
+            if(!isCommunitySet) {
+                problems.add(new ValidationResult.Builder()
+                        .input("SNMP Community")
+                        .valid(false)
+                        .explanation("SNMP Community must be set with SNMPv1 
and SNMPv2c.")
+                        .build());
+            }
+        }
+
+        return problems;
+    }
+
+    /**
+     * Delegate method to supplement
+     * {@link #onTrigger(ProcessContext, ProcessSession)}. It is implemented by
+     * sub-classes to perform {@link Processor} specific functionality.
+     *
+     * @param context
+     *            instance of {@link ProcessContext}
+     * @param session
+     *            instance of {@link ProcessSession}
+     * @throws ProcessException Process exception
+     */
+    protected abstract void onTriggerSnmp(ProcessContext context, 
ProcessSession session) throws ProcessException;
+
+    /**
+     * Delegate method to supplement building of target {@link SNMPWorker} (see
+     * {@link SNMPSetter} or {@link SNMPGetter}) and is implemented by
+     * sub-classes.
+     *
+     * @param context
+     *            instance of {@link ProcessContext}
+     * @return new instance of {@link SNMPWorker}
+     */
+    protected abstract T finishBuildingTargetResource(ProcessContext context);
+
+    /**
+     * Builds target resource.
+     * @param context Process context
+     */
+    private void buildTargetResource(ProcessContext context) {
+        if((this.transportMapping == null) || 
!this.transportMapping.isListening() || (this.snmp == null)) {
+            try {
+                this.transportMapping = new DefaultUdpTransportMapping();
+                this.snmp = new Snmp(this.transportMapping);
+
+                
if("SNMPv3".equals(context.getProperty(SNMP_VERSION).getValue())) {
+                    USM usm = new USM(SecurityProtocols.getInstance(), new 
OctetString(MPv3.createLocalEngineID()), 0);
+                    SecurityModels.getInstance().addSecurityModel(usm);
+                }
+
+                this.transportMapping.listen();
+            } catch (Exception e) {
+                throw new IllegalStateException("Failed to initialize UDP 
transport mapping", e);
+            }
+        }
+        if (this.snmpTarget == null) {
+            this.snmpTarget = this.createSnmpTarget(context);
+            this.targetResource = this.finishBuildingTargetResource(context);
+        }
+    }
+
+    /**
+     * Creates {@link AbstractTarget} to request SNMP agent.
+     * @param context Process context
+     * @return the SNMP target
+     */
+    private AbstractTarget createSnmpTarget(ProcessContext context) {
+        AbstractTarget result = null;
+        String snmpVersion = context.getProperty(SNMP_VERSION).getValue();
+        int version = 0;
+        switch (snmpVersion) {
+        case "SNMPv2c":
+            version = SnmpConstants.version2c;
+            break;
+        case "SNMPv3":
+            version = SnmpConstants.version3;
+            break;
+        case "SNMPv1":
+        default:
+            version = SnmpConstants.version1;
+            break;
+        }
+
+        if(version == SnmpConstants.version3) {
+            final String username = 
context.getProperty(SNMP_SECURITY_NAME).getValue();
+            final String authPassword = 
context.getProperty(SNMP_AUTH_PASSWORD).getValue();
+            final String privPassword = 
context.getProperty(SNMP_PRIV_PASSWORD).getValue();
+            final String authProtocol = 
context.getProperty(SNMP_AUTH_PROTOCOL).getValue();
+            final String privProtocol = 
context.getProperty(SNMP_PRIV_PROTOCOL).getValue();
+            OctetString aPwd = authPassword != null ? new 
OctetString(authPassword) : null;
+            OctetString pPwd = privPassword != null ? new 
OctetString(privPassword) : null;
+
+            // add user information
+            this.snmp.getUSM().addUser(new OctetString(username),
+                    new UsmUser(new OctetString(username), 
SNMPUtils.getAuth(authProtocol), aPwd, SNMPUtils.getPriv(privProtocol), pPwd));
+
+            result = new UserTarget();
+
+            ((UserTarget) 
result).setSecurityLevel(SNMPUtils.getSecLevel(context.getProperty(SNMP_SECURITY_LEVEL).getValue()));
+            final String securityName = 
context.getProperty(SNMP_SECURITY_NAME).getValue();
+            if(securityName != null) {
+                ((UserTarget) result).setSecurityName(new 
OctetString(securityName));
+            }
+        } else {
+            result = new CommunityTarget();
+            String community = context.getProperty(SNMP_COMMUNITY).getValue();
+            if(community != null) {
+                ((CommunityTarget) result).setCommunity(new 
OctetString(community));
+            }
+        }
+
+        result.setVersion(version);
+        result.setAddress(new UdpAddress(context.getProperty(HOST).getValue() 
+ "/" + context.getProperty(PORT).getValue()));
+        result.setRetries(context.getProperty(SNMP_RETRIES).asInteger());
+        result.setTimeout(context.getProperty(SNMP_TIMEOUT).asInteger());
+
+        return result;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/nifi/blob/a6e97740/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/main/java/org/apache/nifi/snmp/processors/GetSNMP.java
----------------------------------------------------------------------
diff --git 
a/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/main/java/org/apache/nifi/snmp/processors/GetSNMP.java
 
b/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/main/java/org/apache/nifi/snmp/processors/GetSNMP.java
new file mode 100644
index 0000000..bb59fe7
--- /dev/null
+++ 
b/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/main/java/org/apache/nifi/snmp/processors/GetSNMP.java
@@ -0,0 +1,177 @@
+/*
+ * 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.snmp.processors;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import org.apache.nifi.annotation.behavior.InputRequirement;
+import org.apache.nifi.annotation.behavior.InputRequirement.Requirement;
+import org.apache.nifi.annotation.documentation.CapabilityDescription;
+import org.apache.nifi.annotation.documentation.Tags;
+import org.apache.nifi.components.PropertyDescriptor;
+import org.apache.nifi.flowfile.FlowFile;
+import org.apache.nifi.processor.ProcessContext;
+import org.apache.nifi.processor.ProcessSession;
+import org.apache.nifi.processor.Processor;
+import org.apache.nifi.processor.Relationship;
+import org.apache.nifi.processor.exception.ProcessException;
+import org.snmp4j.PDU;
+import org.snmp4j.event.ResponseEvent;
+import org.snmp4j.smi.OID;
+import org.snmp4j.util.TreeEvent;
+
+/**
+ * Retrieving data from configured SNMP agent which, upon each invocation of
+ * {@link #onTrigger(ProcessContext, ProcessSession)} method, will construct a
+ * {@link FlowFile} containing in its properties the information retrieved.
+ * The output {@link FlowFile} won't have any content.
+ */
+@Tags({ "snmp", "get", "oid", "walk" })
+@InputRequirement(Requirement.INPUT_FORBIDDEN)
+@CapabilityDescription("Retrieves information from SNMP Agent and outputs a 
FlowFile with information in attributes and without any content")
+public class GetSNMP extends AbstractSNMPProcessor<SNMPGetter> {
+
+    /** OID to request (if walk, it is the root ID of the request) */
+    public static final PropertyDescriptor OID = new 
PropertyDescriptor.Builder()
+            .name("snmp-oid")
+            .displayName("OID")
+            .description("The OID to request")
+            .required(true)
+            .addValidator(SNMPUtils.SNMP_OID_VALIDATOR)
+            .build();
+
+    /** SNMP strategy for SNMP Get processor : simple get or walk */
+    public static final PropertyDescriptor SNMP_STRATEGY = new 
PropertyDescriptor.Builder()
+            .name("snmp-strategy")
+            .displayName("SNMP strategy (GET/WALK)")
+            .description("SNMP strategy to use (SNMP Get or SNMP Walk)")
+            .required(true)
+            .allowableValues("GET", "WALK")
+            .defaultValue("GET")
+            .build();
+
+    /** relationship for success */
+    public static final Relationship REL_SUCCESS = new Relationship.Builder()
+            .name("success")
+            .description("All FlowFiles that are received from the SNMP agent 
are routed to this relationship")
+            .build();
+
+    /** relationship for failure */
+    public static final Relationship REL_FAILURE = new Relationship.Builder()
+            .name("failure")
+            .description("All FlowFiles that cannot received from the SNMP 
agent are routed to this relationship")
+            .build();
+
+    /** list of property descriptors */
+    private final static List<PropertyDescriptor> propertyDescriptors;
+
+    /** list of relationships */
+    private final static Set<Relationship> relationships;
+
+    /*
+     * Will ensure that the list of property descriptors is build only once.
+     * Will also create a Set of relationships
+     */
+    static {
+        List<PropertyDescriptor> _propertyDescriptors = new ArrayList<>();
+        _propertyDescriptors.add(OID);
+        _propertyDescriptors.add(SNMP_STRATEGY);
+        _propertyDescriptors.addAll(descriptors);
+        propertyDescriptors = 
Collections.unmodifiableList(_propertyDescriptors);
+
+        Set<Relationship> _relationships = new HashSet<>();
+        _relationships.add(REL_SUCCESS);
+        _relationships.add(REL_FAILURE);
+        relationships = Collections.unmodifiableSet(_relationships);
+    }
+
+    /**
+     * Delegate method to supplement
+     * {@link #onTrigger(ProcessContext, ProcessSession)}. It is implemented by
+     * sub-classes to perform {@link Processor} specific functionality.
+     *
+     * @param context
+     *            instance of {@link ProcessContext}
+     * @param processSession
+     *            instance of {@link ProcessSession}
+     * @throws ProcessException Process exception
+     */
+    @Override
+    protected void onTriggerSnmp(ProcessContext context, ProcessSession 
processSession) throws ProcessException {
+        if("GET".equals(context.getProperty(SNMP_STRATEGY).getValue())) {
+            final ResponseEvent response = this.targetResource.get();
+            if (response.getResponse() != null){
+                FlowFile flowFile = processSession.create();
+                PDU pdu = response.getResponse();
+                flowFile = 
SNMPUtils.updateFlowFileAttributesWithPduProperties(pdu, flowFile, 
processSession);
+                processSession.getProvenanceReporter().receive(flowFile,
+                        this.snmpTarget.getAddress().toString() + "/" + 
context.getProperty(OID).getValue());
+                if(pdu.getErrorStatus() == PDU.noError) {
+                    processSession.transfer(flowFile, REL_SUCCESS);
+                } else {
+                    processSession.transfer(flowFile, REL_FAILURE);
+                }
+            } else {
+                this.getLogger().error("Get request timed out or parameters 
are incorrect.");
+                context.yield();
+            }
+        } else 
if("WALK".equals(context.getProperty(SNMP_STRATEGY).getValue())) {
+            final List<TreeEvent> events = this.targetResource.walk();
+            if((events != null) && !events.isEmpty() && 
(events.get(0).getVariableBindings() != null)) {
+                FlowFile flowFile = processSession.create();
+                for (TreeEvent treeEvent : events) {
+                    flowFile = 
SNMPUtils.updateFlowFileAttributesWithTreeEventProperties(treeEvent, flowFile, 
processSession);
+                }
+                processSession.getProvenanceReporter().receive(flowFile,
+                        this.snmpTarget.getAddress().toString() + "/" + 
context.getProperty(OID).getValue());
+                processSession.transfer(flowFile, REL_SUCCESS);
+            } else {
+                this.getLogger().error("Get request timed out or parameters 
are incorrect.");
+                context.yield();
+            }
+        }
+    }
+
+    /**
+     * Will create an instance of {@link SNMPGetter}
+     */
+    @Override
+    protected SNMPGetter finishBuildingTargetResource(ProcessContext context) {
+        String oid = context.getProperty(OID).getValue();
+        return new SNMPGetter(this.snmp, this.snmpTarget, new OID(oid));
+    }
+
+    /**
+     * get list of supported property descriptors
+     */
+    @Override
+    protected List<PropertyDescriptor> getSupportedPropertyDescriptors() {
+        return propertyDescriptors;
+    }
+
+    /**
+     * get list of relationships
+     */
+    @Override
+    public Set<Relationship> getRelationships() {
+        return relationships;
+    }
+}

http://git-wip-us.apache.org/repos/asf/nifi/blob/a6e97740/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/main/java/org/apache/nifi/snmp/processors/SNMPGetter.java
----------------------------------------------------------------------
diff --git 
a/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/main/java/org/apache/nifi/snmp/processors/SNMPGetter.java
 
b/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/main/java/org/apache/nifi/snmp/processors/SNMPGetter.java
new file mode 100644
index 0000000..a8543cb
--- /dev/null
+++ 
b/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/main/java/org/apache/nifi/snmp/processors/SNMPGetter.java
@@ -0,0 +1,100 @@
+/*
+ * 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.snmp.processors;
+
+import java.io.IOException;
+import java.util.List;
+
+import org.apache.nifi.processor.exception.ProcessException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.snmp4j.AbstractTarget;
+import org.snmp4j.PDU;
+import org.snmp4j.ScopedPDU;
+import org.snmp4j.Snmp;
+import org.snmp4j.event.ResponseEvent;
+import org.snmp4j.mp.SnmpConstants;
+import org.snmp4j.smi.OID;
+import org.snmp4j.smi.VariableBinding;
+import org.snmp4j.util.DefaultPDUFactory;
+import org.snmp4j.util.TreeEvent;
+import org.snmp4j.util.TreeUtils;
+
+/**
+ * Extension of {@link SNMPWorker} to perform SNMP Get and SNMP Walk requests
+ */
+final class SNMPGetter extends SNMPWorker {
+
+    /** logger */
+    private final static Logger logger = 
LoggerFactory.getLogger(SNMPGetter.class);
+
+    /** OID to request */
+    private final OID oid;
+
+    /**
+     * Creates an instance of this getter
+     * @param snmp instance of {@link Snmp}
+     * @param target instance of {@link AbstractTarget} to request
+     * @param oid instance of {@link OID} to request
+     */
+    SNMPGetter(Snmp snmp, AbstractTarget target, OID oid) {
+        super(snmp, target);
+        this.oid = oid;
+        logger.info("Successfully initialized SNMP Getter");
+    }
+
+    /**
+     * Construct the PDU to perform the SNMP Get request and returns
+     * the result in order to create the flow file.
+     * @return {@link ResponseEvent}
+     */
+    public ResponseEvent get() {
+        try {
+            PDU pdu = null;
+            if(this.target.getVersion() == SnmpConstants.version3) {
+                pdu = new ScopedPDU();
+            } else {
+                pdu = new PDU();
+            }
+            pdu.add(new VariableBinding(this.oid));
+            pdu.setType(PDU.GET);
+            return this.snmp.get(pdu, this.target);
+        } catch (IOException e) {
+            logger.error("Failed to get information from SNMP agent; " + this, 
e);
+            throw new ProcessException(e);
+        }
+    }
+
+    /**
+     * Perform a SNMP walk and returns the list of {@link TreeEvent}
+     * @return the list of {@link TreeEvent}
+     */
+    public List<TreeEvent> walk() {
+        TreeUtils treeUtils = new TreeUtils(this.snmp, new 
DefaultPDUFactory());
+        @SuppressWarnings("unchecked")
+        List<TreeEvent> events = treeUtils.getSubtree(this.target, this.oid);
+        return events;
+    }
+
+    /**
+     * @see org.apache.nifi.snmp.processors.SNMPWorker#toString()
+     */
+    @Override
+    public String toString() {
+        return super.toString() + ", OID:" + this.oid.toString();
+    }
+}

http://git-wip-us.apache.org/repos/asf/nifi/blob/a6e97740/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/main/java/org/apache/nifi/snmp/processors/SNMPSetter.java
----------------------------------------------------------------------
diff --git 
a/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/main/java/org/apache/nifi/snmp/processors/SNMPSetter.java
 
b/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/main/java/org/apache/nifi/snmp/processors/SNMPSetter.java
new file mode 100644
index 0000000..1b72bf9
--- /dev/null
+++ 
b/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/main/java/org/apache/nifi/snmp/processors/SNMPSetter.java
@@ -0,0 +1,56 @@
+/*
+ * 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.snmp.processors;
+
+import java.io.IOException;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.snmp4j.AbstractTarget;
+import org.snmp4j.PDU;
+import org.snmp4j.Snmp;
+import org.snmp4j.event.ResponseEvent;
+
+/**
+ * Extension of {@link SNMPWorker} to perform SNMP Set requests
+ */
+final class SNMPSetter extends SNMPWorker {
+
+    /** logger */
+    private final static Logger logger = 
LoggerFactory.getLogger(SNMPSetter.class);
+
+    /**
+     * Creates an instance of this setter
+     * @param snmp instance of {@link Snmp}
+     * @param target instance of {@link AbstractTarget} to request
+     */
+    SNMPSetter(Snmp snmp, AbstractTarget target) {
+        super(snmp, target);
+        logger.info("Successfully initialized SNMP Setter");
+    }
+
+    /**
+     * Executes the SNMP set request and returns the response
+     * @param pdu PDU to send
+     * @return Response event
+     * @throws IOException IO Exception
+     */
+    public ResponseEvent set(PDU pdu) throws IOException {
+        return this.snmp.set(pdu, this.target);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/nifi/blob/a6e97740/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/main/java/org/apache/nifi/snmp/processors/SNMPUtils.java
----------------------------------------------------------------------
diff --git 
a/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/main/java/org/apache/nifi/snmp/processors/SNMPUtils.java
 
b/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/main/java/org/apache/nifi/snmp/processors/SNMPUtils.java
new file mode 100644
index 0000000..d5c0e30
--- /dev/null
+++ 
b/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/main/java/org/apache/nifi/snmp/processors/SNMPUtils.java
@@ -0,0 +1,268 @@
+/*
+ * 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.snmp.processors;
+
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Vector;
+import java.util.regex.Pattern;
+
+import org.apache.nifi.components.ValidationContext;
+import org.apache.nifi.components.ValidationResult;
+import org.apache.nifi.components.Validator;
+import org.apache.nifi.flowfile.FlowFile;
+import org.apache.nifi.processor.ProcessSession;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.snmp4j.PDU;
+import org.snmp4j.security.AuthMD5;
+import org.snmp4j.security.AuthSHA;
+import org.snmp4j.security.Priv3DES;
+import org.snmp4j.security.PrivAES128;
+import org.snmp4j.security.PrivAES192;
+import org.snmp4j.security.PrivAES256;
+import org.snmp4j.security.PrivDES;
+import org.snmp4j.security.SecurityLevel;
+import org.snmp4j.smi.OID;
+import org.snmp4j.smi.VariableBinding;
+import org.snmp4j.util.TreeEvent;
+
+/**
+ * Utility helper class that simplifies interactions with target SNMP API and 
NIFI API.
+ */
+abstract class SNMPUtils {
+
+    /** logger */
+    private final static Logger logger = 
LoggerFactory.getLogger(SNMPUtils.class);
+
+    /** OID Pattern */
+    public final static Pattern OID_PATTERN = Pattern.compile("[[0-9]+\\.]*");
+
+    /** delimiter for properties name */
+    public final static String SNMP_PROP_DELIMITER = "$";
+
+    /** prefix for SNMP properties in flow file */
+    public final static String SNMP_PROP_PREFIX = "snmp" + SNMP_PROP_DELIMITER;
+
+    /** list of properties name when performing simple get */
+    private final static List<String> propertyNames = 
Arrays.asList("snmp$errorIndex", "snmp$errorStatus", "snmp$errorStatusText",
+            "snmp$nonRepeaters", "snmp$requestID", "snmp$type", 
"snmp$variableBindings");
+
+    /** used to validate OID syntax */
+    public static final Validator SNMP_OID_VALIDATOR = new Validator() {
+        @Override
+        public ValidationResult validate(final String subject, final String 
input, final ValidationContext context) {
+            final ValidationResult.Builder builder = new 
ValidationResult.Builder();
+            builder.subject(subject).input(input);
+            if (context.isExpressionLanguageSupported(subject) && 
context.isExpressionLanguagePresent(input)) {
+                return builder.valid(true).explanation("Contains Expression 
Language").build();
+            }
+            try {
+                if (OID_PATTERN.matcher(input).matches()) {
+                    builder.valid(true);
+                } else {
+                    builder.valid(false).explanation(input + "is not a valid 
OID");
+                }
+            } catch (final IllegalArgumentException e) {
+                builder.valid(false).explanation(e.getMessage());
+            }
+            return builder.build();
+        }
+    };
+
+    /**
+     * Updates {@link FlowFile} with attributes representing PDU properties
+     * @param response PDU retried from SNMP Agent
+     * @param flowFile instance of target {@link FlowFile}
+     * @param processSession instance of {@link ProcessSession}
+     * @return updated {@link FlowFile}
+     */
+    public static FlowFile updateFlowFileAttributesWithPduProperties(PDU 
response, FlowFile flowFile, ProcessSession processSession) {
+        if (response != null) {
+            try {
+                Method[] methods = PDU.class.getDeclaredMethods();
+                Map<String, String> attributes = new HashMap<String, String>();
+                for (Method method : methods) {
+                    if (Modifier.isPublic(method.getModifiers()) && 
(method.getParameterTypes().length == 0) && method.getName().startsWith("get")) 
{
+                        String propertyName = 
extractPropertyNameFromMethod(method);
+                        if (isValidSnmpPropertyName(propertyName)) {
+                            Object amqpPropertyValue = method.invoke(response);
+                            if (amqpPropertyValue != null) {
+                                if (propertyName.equals(SNMP_PROP_PREFIX + 
"variableBindings") && (amqpPropertyValue instanceof Vector)) {
+                                    addGetOidValues(attributes, 
amqpPropertyValue);
+                                } else {
+                                    attributes.put(propertyName, 
amqpPropertyValue.toString());
+                                }
+                            }
+                        }
+                    }
+                }
+                flowFile = processSession.putAllAttributes(flowFile, 
attributes);
+            } catch (Exception e) {
+                logger.warn("Failed to update FlowFile with AMQP attributes", 
e);
+            }
+        }
+        return flowFile;
+    }
+
+    /**
+     * Method to add attribute in flow file
+     * @param key attribute key
+     * @param value attribute value
+     * @param flowFile flow file to update
+     * @param processSession session
+     * @return updated flow file
+     */
+    public static FlowFile addAttribute(String key, String value, FlowFile 
flowFile, ProcessSession processSession) {
+        Map<String, String> attributes = new HashMap<String, String>();
+        attributes.put(key, value);
+        flowFile = processSession.putAllAttributes(flowFile, attributes);
+        return flowFile;
+    }
+
+    /**
+     * Method to construct {@link FlowFile} attributes from a {@link TreeEvent}
+     * @param treeEvent a {@link TreeEvent}
+     * @param flowFile instance of the {@link FlowFile} to update
+     * @param processSession instance of {@link ProcessSession}
+     * @return updated {@link FlowFile}
+     */
+    public static FlowFile 
updateFlowFileAttributesWithTreeEventProperties(TreeEvent treeEvent, FlowFile 
flowFile, ProcessSession processSession) {
+        Map<String, String> attributes = new HashMap<String, String>();
+        addWalkOidValues(attributes, treeEvent.getVariableBindings());
+        flowFile = processSession.putAllAttributes(flowFile, attributes);
+        return flowFile;
+    }
+
+    /**
+     * Method to construct {@link FlowFile} attributes from a vector of {@link 
VariableBinding}
+     * @param attributes attributes
+     * @param vector vector of {@link VariableBinding}
+     */
+    private static void addWalkOidValues(Map<String, String> attributes, 
Object vector) {
+        if (vector instanceof VariableBinding[]) {
+            VariableBinding[] variables = (VariableBinding[]) vector;
+            for (VariableBinding variableBinding : variables) {
+                addAttributeFromVariable(variableBinding, attributes);
+            }
+        }
+    }
+
+    /**
+     * Method to construct {@link FlowFile} attributes from a vector of {@link 
VariableBinding}
+     * @param attributes attributes
+     * @param vector vector of {@link VariableBinding}
+     */
+    private static void addGetOidValues(Map<String, String> attributes, Object 
vector) {
+        if (vector instanceof Vector) {
+            @SuppressWarnings("unchecked")
+            Vector<VariableBinding> variables = (Vector<VariableBinding>) 
vector;
+            for (VariableBinding variableBinding : variables) {
+                addAttributeFromVariable(variableBinding, attributes);
+            }
+        }
+    }
+
+    /**
+     * Method to add {@link FlowFile} attributes from a {@link VariableBinding}
+     * @param variableBinding {@link VariableBinding}
+     * @param attributes {@link FlowFile} attributes to update
+     */
+    private static void addAttributeFromVariable(VariableBinding 
variableBinding, Map<String, String> attributes) {
+        attributes.put(SNMP_PROP_PREFIX + variableBinding.getOid() + 
SNMP_PROP_DELIMITER + variableBinding.getVariable().getSyntax(), 
variableBinding.getVariable().toString());
+    }
+
+    /**
+     * Will validate if provided name corresponds to valid SNMP property.
+     * @param name the name of the property
+     * @return 'true' if valid otherwise 'false'
+     */
+    public static boolean isValidSnmpPropertyName(String name) {
+        return propertyNames.contains(name);
+    }
+
+    /**
+     * Method to extract property name from given {@link Method}
+     * @param method method
+     * @return property name
+     */
+    private static String extractPropertyNameFromMethod(Method method) {
+        char c[] = method.getName().substring(3).toCharArray();
+        c[0] = Character.toLowerCase(c[0]);
+        return SNMP_PROP_PREFIX + new String(c);
+    }
+
+    /**
+     * Method to return the private protocol given the property
+     * @param privProtocol property
+     * @return protocol
+     */
+    public static OID getPriv(String privProtocol) {
+        switch (privProtocol) {
+        case "DES":
+            return PrivDES.ID;
+        case "3DES":
+            return Priv3DES.ID;
+        case "AES128":
+            return PrivAES128.ID;
+        case "AES192":
+            return PrivAES192.ID;
+        case "AES256":
+            return PrivAES256.ID;
+        default:
+            return null;
+        }
+    }
+
+    /**
+     * Method to return the authentication protocol given the property
+     * @param authProtocol property
+     * @return protocol
+     */
+    public static OID getAuth(String authProtocol) {
+        switch (authProtocol) {
+        case "SHA":
+            return AuthSHA.ID;
+        case "MD5":
+            return AuthMD5.ID;
+        default:
+            return null;
+        }
+    }
+
+    /**
+     * Method to get security level from string representation of level
+     * @param level level
+     * @return security level as integer
+     */
+    public static int getSecLevel(String level) {
+        switch (level) {
+        case "noAuthNoPriv":
+            return SecurityLevel.NOAUTH_NOPRIV;
+        case "authNoPriv":
+            return SecurityLevel.AUTH_NOPRIV;
+        case "authPriv":
+        default:
+            return SecurityLevel.AUTH_PRIV;
+        }
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/nifi/blob/a6e97740/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/main/java/org/apache/nifi/snmp/processors/SNMPWorker.java
----------------------------------------------------------------------
diff --git 
a/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/main/java/org/apache/nifi/snmp/processors/SNMPWorker.java
 
b/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/main/java/org/apache/nifi/snmp/processors/SNMPWorker.java
new file mode 100644
index 0000000..727c519
--- /dev/null
+++ 
b/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/main/java/org/apache/nifi/snmp/processors/SNMPWorker.java
@@ -0,0 +1,74 @@
+/*
+ * 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.snmp.processors;
+
+import java.io.IOException;
+import java.util.concurrent.TimeoutException;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.snmp4j.AbstractTarget;
+import org.snmp4j.Snmp;
+
+/**
+ * Base class for implementing SNMP workers.
+ *
+ * @see SNMPSetter
+ * @see SNMPGetter
+ */
+abstract class SNMPWorker implements AutoCloseable {
+
+    /** logger */
+    private final static Logger logger = 
LoggerFactory.getLogger(SNMPWorker.class);
+
+    /** SNMP abstraction */
+    protected final Snmp snmp;
+
+    /** Target to request */
+    protected final AbstractTarget target;
+
+    /**
+     * Creates an instance of this worker and initializing it with {@link Snmp}
+     * and {@link AbstractTarget} used by sub-classes to interact with SNMP 
agent.
+     * @param snmp instance of {@link Snmp}
+     * @param target instance of {@link AbstractTarget}
+     */
+    public SNMPWorker(Snmp snmp, AbstractTarget target) {
+        this.snmp = snmp;
+        this.target = target;
+    }
+
+    /**
+     * Closes {@link Snmp} created when instance of this class was created.
+     */
+    @Override
+    public void close() throws TimeoutException, IOException {
+        if (logger.isDebugEnabled()) {
+            logger.debug("Closing SNMP connection");
+        }
+        this.snmp.close();
+    }
+
+    /**
+     * @see java.lang.Object#toString()
+     */
+    @Override
+    public String toString() {
+        return this.getClass().getSimpleName() + ":" + this.snmp.toString();
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/nifi/blob/a6e97740/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/main/java/org/apache/nifi/snmp/processors/SetSNMP.java
----------------------------------------------------------------------
diff --git 
a/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/main/java/org/apache/nifi/snmp/processors/SetSNMP.java
 
b/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/main/java/org/apache/nifi/snmp/processors/SetSNMP.java
new file mode 100644
index 0000000..4674bc6
--- /dev/null
+++ 
b/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/main/java/org/apache/nifi/snmp/processors/SetSNMP.java
@@ -0,0 +1,224 @@
+/*
+ * 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.snmp.processors;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Set;
+
+import org.apache.nifi.annotation.behavior.InputRequirement;
+import org.apache.nifi.annotation.behavior.InputRequirement.Requirement;
+import org.apache.nifi.annotation.documentation.CapabilityDescription;
+import org.apache.nifi.annotation.documentation.Tags;
+import org.apache.nifi.components.PropertyDescriptor;
+import org.apache.nifi.flowfile.FlowFile;
+import org.apache.nifi.processor.ProcessContext;
+import org.apache.nifi.processor.ProcessSession;
+import org.apache.nifi.processor.Relationship;
+import org.apache.nifi.processor.exception.ProcessException;
+import org.snmp4j.PDU;
+import org.snmp4j.ScopedPDU;
+import org.snmp4j.event.ResponseEvent;
+import org.snmp4j.mp.SnmpConstants;
+import org.snmp4j.smi.AbstractVariable;
+import org.snmp4j.smi.AssignableFromInteger;
+import org.snmp4j.smi.AssignableFromLong;
+import org.snmp4j.smi.AssignableFromString;
+import org.snmp4j.smi.OID;
+import org.snmp4j.smi.OctetString;
+import org.snmp4j.smi.Variable;
+import org.snmp4j.smi.VariableBinding;
+
+/**
+ * Performs a SNMP Set operation based on attributes of incoming FlowFile.
+ * Upon each invocation of {@link #onTrigger(ProcessContext, ProcessSession)}
+ * method, it will inspect attributes of FlowFile and look for attributes with
+ * name formatted as "snmp$OID" to set the attribute value to this OID.
+ */
+@Tags({ "snmp", "set", "oid" })
+@InputRequirement(Requirement.INPUT_REQUIRED)
+@CapabilityDescription("Based on incoming FlowFile attributes, the processor 
will execute SNMP Set requests." +
+        " When founding attributes with name like snmp$<OID>, the processor 
will atempt to set the value of" +
+        " attribute to the corresponding OID given in the attribute name")
+public class SetSNMP extends AbstractSNMPProcessor<SNMPSetter> {
+
+    /** relationship for success */
+    public static final Relationship REL_SUCCESS = new Relationship.Builder()
+            .name("success")
+            .description("All FlowFiles that have been successfully used to 
perform SNMP Set are routed to this relationship")
+            .build();
+    /** relationship for failure */
+    public static final Relationship REL_FAILURE = new Relationship.Builder()
+            .name("failure")
+            .description("All FlowFiles that failed during the SNMP Set care 
routed to this relationship")
+            .build();
+
+    /** list of properties descriptors */
+    private final static List<PropertyDescriptor> propertyDescriptors;
+
+    /** list of relationships */
+    private final static Set<Relationship> relationships;
+
+    /*
+     * Will ensure that the list of property descriptors is build only once.
+     * Will also create a Set of relationships
+     */
+    static {
+        List<PropertyDescriptor> _propertyDescriptors = new ArrayList<>();
+        _propertyDescriptors.addAll(descriptors);
+        propertyDescriptors = 
Collections.unmodifiableList(_propertyDescriptors);
+
+        Set<Relationship> _relationships = new HashSet<>();
+        _relationships.add(REL_SUCCESS);
+        _relationships.add(REL_FAILURE);
+        relationships = Collections.unmodifiableSet(_relationships);
+    }
+
+    /**
+     * @see 
org.apache.nifi.snmp.processors.AbstractSNMPProcessor#onTriggerSnmp(org.apache.nifi.processor.ProcessContext,
 org.apache.nifi.processor.ProcessSession)
+     */
+    @Override
+    protected void onTriggerSnmp(ProcessContext context, ProcessSession 
processSession) throws ProcessException {
+        FlowFile flowFile = processSession.get();
+        if (flowFile != null) {
+            // Create the PDU object
+            PDU pdu = null;
+            if(this.snmpTarget.getVersion() == SnmpConstants.version3) {
+                pdu = new ScopedPDU();
+            } else {
+                pdu = new PDU();
+            }
+            if(this.addVariables(pdu, flowFile.getAttributes())) {
+                pdu.setType(PDU.SET);
+                try {
+                    ResponseEvent response = this.targetResource.set(pdu);
+                    if(response.getResponse() == null) {
+                        
processSession.transfer(processSession.penalize(flowFile), REL_FAILURE);
+                        this.getLogger().error("Set request timed out or 
parameters are incorrect.");
+                        context.yield();
+                    } else if(response.getResponse().getErrorStatus() == 
PDU.noError) {
+                        flowFile = 
SNMPUtils.updateFlowFileAttributesWithPduProperties(pdu, flowFile, 
processSession);
+                        processSession.transfer(flowFile, REL_SUCCESS);
+                        processSession.getProvenanceReporter().send(flowFile, 
this.snmpTarget.getAddress().toString());
+                    } else {
+                        final String error = 
response.getResponse().getErrorStatusText();
+                        flowFile = 
SNMPUtils.addAttribute(SNMPUtils.SNMP_PROP_PREFIX + "error", error, flowFile, 
processSession);
+                        
processSession.transfer(processSession.penalize(flowFile), REL_FAILURE);
+                        this.getLogger().error("Failed while executing SNMP 
Set [{}] via " + this.targetResource + ". Error = {}", new 
Object[]{response.getRequest().getVariableBindings(), error});
+                    }
+                } catch (IOException e) {
+                    processSession.transfer(processSession.penalize(flowFile), 
REL_FAILURE);
+                    this.getLogger().error("Failed while executing SNMP Set 
via " + this.targetResource, e);
+                    context.yield();
+                }
+            } else {
+                processSession.transfer(processSession.penalize(flowFile), 
REL_FAILURE);
+                this.getLogger().warn("No attributes found in the FlowFile to 
perform SNMP Set");
+            }
+        }
+    }
+
+    /**
+     * Method to construct {@link VariableBinding} based on {@link FlowFile}
+     * attributes in order to update the {@link PDU} that is going to be sent 
to
+     * the SNMP Agent.
+     * @param pdu {@link PDU} to be sent
+     * @param attributes {@link FlowFile} attributes
+     * @return true if at least one {@link VariableBinding} has been created, 
false otherwise
+     */
+    private boolean addVariables(PDU pdu, Map<String, String> attributes) {
+        boolean result = false;
+        for (Entry<String, String> attributeEntry : attributes.entrySet()) {
+            if 
(attributeEntry.getKey().startsWith(SNMPUtils.SNMP_PROP_PREFIX)) {
+                String[] splits = attributeEntry.getKey().split("\\" + 
SNMPUtils.SNMP_PROP_DELIMITER);
+                String snmpPropName = splits[1];
+                String snmpPropValue = attributeEntry.getValue();
+                if(SNMPUtils.OID_PATTERN.matcher(snmpPropName).matches()) {
+                    Variable var = null;
+                    if (splits.length == 2) { // no SMI syntax defined
+                        var = new OctetString(snmpPropValue);
+                    } else {
+                        int smiSyntax = Integer.valueOf(splits[2]);
+                        var = this.stringToVariable(snmpPropValue, smiSyntax);
+                    }
+                    if(var != null) {
+                        VariableBinding varBind = new VariableBinding(new 
OID(snmpPropName), var);
+                        pdu.add(varBind);
+                        result = true;
+                    }
+                }
+            }
+        }
+        return result;
+    }
+
+    /**
+     * Method to create the variable from the attribute value and the given 
SMI syntax value
+     * @param value attribute value
+     * @param smiSyntax attribute SMI Syntax
+     * @return variable
+     */
+    private Variable stringToVariable(String value, int smiSyntax) {
+        Variable var = AbstractVariable.createFromSyntax(smiSyntax);
+        try {
+            if (var instanceof AssignableFromString) {
+                ((AssignableFromString) var).setValue(value);
+            } else if (var instanceof AssignableFromInteger) {
+                ((AssignableFromInteger) var).setValue(Integer.valueOf(value));
+            } else if (var instanceof AssignableFromLong) {
+                ((AssignableFromLong) var).setValue(Long.valueOf(value));
+            } else {
+                this.getLogger().error("Unsupported conversion of [" + value 
+"] to " + var.getSyntaxString());
+                var = null;
+            }
+        } catch (IllegalArgumentException e) {
+            this.getLogger().error("Unsupported conversion of [" + value +"] 
to " + var.getSyntaxString(), e);
+            var = null;
+        }
+        return var;
+    }
+
+    /**
+     * @see 
org.apache.nifi.components.AbstractConfigurableComponent#getSupportedPropertyDescriptors()
+     */
+    @Override
+    protected List<PropertyDescriptor> getSupportedPropertyDescriptors() {
+        return propertyDescriptors;
+    }
+
+    /**
+     * @see 
org.apache.nifi.processor.AbstractSessionFactoryProcessor#getRelationships()
+     */
+    @Override
+    public Set<Relationship> getRelationships() {
+        return relationships;
+    }
+
+    /**
+     * @see 
org.apache.nifi.snmp.processors.AbstractSNMPProcessor#finishBuildingTargetResource(org.apache.nifi.processor.ProcessContext)
+     */
+    @Override
+    protected SNMPSetter finishBuildingTargetResource(ProcessContext context) {
+        return new SNMPSetter(this.snmp, this.snmpTarget);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/nifi/blob/a6e97740/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/main/resources/META-INF/services/org.apache.nifi.processor.Processor
----------------------------------------------------------------------
diff --git 
a/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/main/resources/META-INF/services/org.apache.nifi.processor.Processor
 
b/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/main/resources/META-INF/services/org.apache.nifi.processor.Processor
new file mode 100644
index 0000000..c3fcde0
--- /dev/null
+++ 
b/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/main/resources/META-INF/services/org.apache.nifi.processor.Processor
@@ -0,0 +1,16 @@
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements.  See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License.  You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+org.apache.nifi.snmp.processors.GetSNMP
+org.apache.nifi.snmp.processors.SetSNMP

http://git-wip-us.apache.org/repos/asf/nifi/blob/a6e97740/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/main/resources/docs/org.apache.nifi.snmp.processors.GetSNMP/additionalDetails.html
----------------------------------------------------------------------
diff --git 
a/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/main/resources/docs/org.apache.nifi.snmp.processors.GetSNMP/additionalDetails.html
 
b/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/main/resources/docs/org.apache.nifi.snmp.processors.GetSNMP/additionalDetails.html
new file mode 100644
index 0000000..3a9add6
--- /dev/null
+++ 
b/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/main/resources/docs/org.apache.nifi.snmp.processors.GetSNMP/additionalDetails.html
@@ -0,0 +1,70 @@
+<!DOCTYPE html>
+<html lang="en">
+<!--
+  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.
+-->
+<head>
+    <meta charset="utf-8" />
+    <title>GetSNMP</title>
+    <link rel="stylesheet" href="../../css/component-usage.css" 
type="text/css" />
+</head>
+
+<body>
+<h2>Summary</h2>
+<p>
+    This processor polls a SNMP agent to get information for a given OID 
(Strategy = GET) or for all the sub-tree associated to a given OID
+    (Strategy = WALK). This processors supports SNMPv1, SNMPv2c and SNMPv3. 
The component is based on <a href="http://www.snmp4j.org/";>SNMP4J</a>.
+</p>
+<p>
+    When the processor is triggered, it sends the SNMP request and gets the 
information associated to request OID(s). Once response is received
+    from the SNMP agent, a FlowFile is constructed. The FlowFile content is 
empty, all the information is written in the FlowFile attributes.
+    In case of a single GET request, the properties associated to the received 
PDU are transfered into the FlowFile as attributes. In case of a
+    WALK request, only the couples "OID/value" are transferred into the 
FlowFile as attributes. SNMP attributes names are prefixed with
+    <i>snmp$</i> prefix.
+</p>
+<p>
+    Regarding the attributes representing the couples "OID/value", the 
attribute name has the following format:
+    <ul><li>snmp$<i>OID</i>$<i>SMI_Syntax_Value</i></li></ul>
+    where OID is the request OID, and SMI_Syntax_Value is the integer 
representing the type of the value associated to the OID. This value is
+    provided to allow the SetSNMP processor setting values in the correct type.
+</p>
+<h2>SNMP Properties</h2>
+<p>
+    In case of a single SNMP Get request, the following is the list of 
available standard SNMP properties which may come with the PDU:
+    <i>("snmp$errorIndex", "snmp$errorStatus", "snmp$errorStatusText", 
"snmp$nonRepeaters", "snmp$requestID", "snmp$type")</i>
+</p>
+<h2>Configuration Details</h2>
+<p>
+    At the time of writing this document it only defines the essential 
configuration properties which are suitable for most cases. 
+    Other properties will be defined later as this component progresses.
+    Configuring GetSNMP:
+</p>
+<ul>
+    <li><b>Host</b> - [REQUIRED] the name of the host where the SNMP agent is 
running. (default is localhost)</li>
+    <li><b>Port</b> - [REQUIRED] the port number on which the SNMP agent is 
listening. (default is 161)</li>
+    <li><b>OID</b> - [REQUIRED] the root OID to request.</li>
+    <li><b>Version</b> - [REQUIRED] the SNMP version to use (SNMPv1 [default], 
or SNMPv2c, or SNMPv3)</li>
+    <li><b>Community</b> - [REQUIRED if SNMPv1 or SNMPv2c] the SNMP community 
to use. (default is public)</li>
+    <li><b>Security Level</b> - [REQUIRED if SNMPv3] the security level to 
use. (default is authPriv)</li>
+    <li><b>Security Name</b> - [REQUIRED if SNMPv3] the security name (user 
name) to use.</li>
+    <li><b>Authentication Protocol</b> - [REQUIRED if SNMPv3 and authNoPriv or 
authPriv] the authentication protocol to use.</li>
+    <li><b>Authentication Password</b> - [REQUIRED if SNMPv3 and authNoPriv or 
authPriv] the authentication password to use.</li>
+    <li><b>Private Protocol</b> - [REQUIRED if SNMPv3 and authPriv] the 
private protocol to use.</li>
+    <li><b>Private Password</b> - [REQUIRED if SNMPv3 and authPriv] the 
private password to use.</li>
+    <li><b>Retries</b> - [REQUIRED] Sets the number of retries to be performed 
before a request is timed out. (default is 0)</li>
+    <li><b>Timeout</b> - [REQUIRED] Sets  timeout in milliseconds before a 
confirmed request is resent or timed out. (default is 5000)</li>
+</ul>
+
+</body>
+</html>
\ No newline at end of file

Reply via email to