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