From bd7536b257907d9012084c27dc5cc3595e5dba3d Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Lehel=20Bo=C3=A9r?=
Date: Thu, 20 May 2021 17:08:02 +0200
Subject: [PATCH] NIFI-3328: SendTrapSNMP and ListenTrapSNMP processors added.
---
.../nifi-snmp-processors/pom.xml | 8 +-
.../snmp/configuration/SNMPConfiguration.java | 128 +++++++-
.../SNMPConfigurationBuilder.java | 100 ------
.../configuration/V1TrapConfiguration.java | 117 +++++++
.../V2TrapConfiguration.java} | 16 +-
.../ErrorStatus.java} | 46 ++-
.../SNMPResponseStatus.java} | 71 +++--
.../nifi/snmp/dto/SNMPSingleResponse.java | 2 +-
.../nifi/snmp/dto/SNMPTreeResponse.java | 8 +
.../org/apache/nifi/snmp/dto/UserDetails.java | 58 ++++
.../nifi/snmp/exception/SNMPException.java | 4 +
.../snmp/factory/AbstractSNMPFactory.java | 91 ------
.../snmp/factory/CompositeSNMPFactory.java | 70 -----
.../nifi/snmp/factory/V3SNMPFactory.java | 76 -----
.../nifi/snmp/factory/core/SNMPContext.java | 50 +++
.../factory/core/SNMPFactoryProvider.java | 48 +++
.../SNMPManagerFactory.java} | 32 +-
.../V1V2cSNMPFactory.java} | 26 +-
.../nifi/snmp/factory/core/V3SNMPFactory.java | 77 +++++
.../snmp/factory/trap/V1TrapPDUFactory.java | 58 ++++
.../snmp/factory/trap/V2TrapPDUFactory.java | 54 ++++
.../nifi/snmp/operations/GetSNMPHandler.java | 150 +++++++++
.../operations/SNMPRequestHandlerFactory.java | 38 ---
.../snmp/operations/SNMPResourceHandler.java | 70 +++++
.../snmp/operations/SNMPTrapReceiver.java | 77 +++++
.../operations/SNMPTrapReceiverHandler.java | 124 ++++++++
.../snmp/operations/SendTrapSNMPHandler.java | 75 +++++
.../nifi/snmp/operations/SetSNMPHandler.java | 66 ++++
.../StandardSNMPRequestHandler.java | 148 ---------
.../processors/AbstractSNMPProcessor.java | 269 ++++------------
.../apache/nifi/snmp/processors/GetSNMP.java | 157 +++++++---
.../nifi/snmp/processors/ListenTrapSNMP.java | 143 +++++++++
.../nifi/snmp/processors/SendTrapSNMP.java | 170 ++++++++++
.../apache/nifi/snmp/processors/SetSNMP.java | 68 ++--
.../properties/BasicProperties.java | 77 +++++
.../properties/V1TrapProperties.java | 80 +++++
.../properties/V2TrapProperties.java | 42 +++
.../properties/V3SecurityProperties.java | 130 ++++++++
.../org/apache/nifi/snmp/utils/SNMPUtils.java | 116 ++++---
.../org.apache.nifi.processor.Processor | 2 +
.../additionalDetails.html | 11 +-
.../additionalDetails.html | 54 ++++
.../additionalDetails.html | 45 +++
.../configuration/SNMPConfigurationTest.java | 75 +++++
.../V1TrapConfigurationTest.java | 141 +++++++++
.../nifi/snmp/dto/SNMPTreeResponseTest.java | 165 ++++++++++
.../snmp/factory/SNMPClientFactoryTest.java | 68 ----
.../snmp/factory/core/SNMPContextTest.java | 47 +++
.../factory/core/SNMPFactoryProviderTest.java | 37 +++
.../factory/core/V1V2cSNMPFactoryTest.java | 90 ++++++
.../snmp/factory/core/V3SNMPFactoryTest.java | 107 +++++++
.../factory/trap/V1TrapPDUFactoryTest.java | 59 ++++
.../factory/trap/V2TrapPDUFactoryTest.java | 58 ++++
.../nifi/snmp/helper/SNMPTestUtils.java | 68 ----
.../snmp/helper/TrapConfigurationFactory.java | 46 +++
.../SNMPConfigurationFactory.java} | 16 +-
.../SNMPV1V2cConfigurationFactory.java | 57 ++++
.../SNMPV3ConfigurationFactory.java | 71 +++++
.../testrunners/SNMPTestRunnerFactory.java | 58 ++++
.../testrunners/SNMPV1TestRunnerFactory.java | 93 ++++++
.../testrunners/SNMPV2cTestRunnerFactory.java | 89 ++++++
.../testrunners/SNMPV3TestRunnerFactory.java | 112 +++++++
.../snmp/operations/GetSNMPHandlerTest.java | 271 ++++++++++++++++
.../nifi/snmp/operations/SNMPRequestTest.java | 296 +++++++++++++++---
.../SNMPTrapReceiverHandlerTest.java | 146 +++++++++
.../snmp/operations/SNMPTrapReceiverTest.java | 153 +++++++++
.../snmp/operations/SNMPV1RequestTest.java | 86 -----
.../snmp/operations/SNMPV2CRequestTest.java | 86 -----
.../snmp/operations/SNMPV3RequestTest.java | 135 --------
.../operations/SendTrapSNMPHandlerTest.java | 109 +++++++
.../snmp/operations/SetSNMPHandlerTest.java | 119 +++++++
.../processors/AbstractSNMPProcessorTest.java | 162 ++++++++++
.../processors/GetSNMPIntegrationTest.java | 154 +++++++++
.../nifi/snmp/processors/GetSNMPTest.java | 86 ++---
.../processors/SetSNMPIntegrationTest.java | 112 +++++++
.../nifi/snmp/processors/SetSNMPTest.java | 88 ------
.../processors/TrapSNMPIntegrationTest.java | 108 +++++++
.../nifi/snmp/testagents/TestAgent.java | 5 +
.../src/test/resources/users.json | 16 +
79 files changed, 5243 insertions(+), 1598 deletions(-)
delete mode 100644 nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/main/java/org/apache/nifi/snmp/configuration/SNMPConfigurationBuilder.java
create mode 100644 nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/main/java/org/apache/nifi/snmp/configuration/V1TrapConfiguration.java
rename nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/main/java/org/apache/nifi/snmp/{exception/CreateSNMPClientException.java => configuration/V2TrapConfiguration.java} (65%)
rename nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/main/java/org/apache/nifi/snmp/{exception/CloseSNMPClientException.java => dto/ErrorStatus.java} (79%)
rename nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/main/java/org/apache/nifi/snmp/{operations/SNMPRequestHandler.java => dto/SNMPResponseStatus.java} (61%)
create mode 100644 nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/main/java/org/apache/nifi/snmp/dto/UserDetails.java
delete mode 100644 nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/main/java/org/apache/nifi/snmp/factory/AbstractSNMPFactory.java
delete mode 100644 nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/main/java/org/apache/nifi/snmp/factory/CompositeSNMPFactory.java
delete mode 100644 nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/main/java/org/apache/nifi/snmp/factory/V3SNMPFactory.java
create mode 100644 nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/main/java/org/apache/nifi/snmp/factory/core/SNMPContext.java
create mode 100644 nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/main/java/org/apache/nifi/snmp/factory/core/SNMPFactoryProvider.java
rename nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/main/java/org/apache/nifi/snmp/factory/{V2cSNMPFactory.java => core/SNMPManagerFactory.java} (58%)
rename nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/main/java/org/apache/nifi/snmp/factory/{V1SNMPFactory.java => core/V1V2cSNMPFactory.java} (64%)
create mode 100644 nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/main/java/org/apache/nifi/snmp/factory/core/V3SNMPFactory.java
create mode 100644 nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/main/java/org/apache/nifi/snmp/factory/trap/V1TrapPDUFactory.java
create mode 100644 nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/main/java/org/apache/nifi/snmp/factory/trap/V2TrapPDUFactory.java
create mode 100644 nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/main/java/org/apache/nifi/snmp/operations/GetSNMPHandler.java
delete mode 100644 nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/main/java/org/apache/nifi/snmp/operations/SNMPRequestHandlerFactory.java
create mode 100644 nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/main/java/org/apache/nifi/snmp/operations/SNMPResourceHandler.java
create mode 100644 nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/main/java/org/apache/nifi/snmp/operations/SNMPTrapReceiver.java
create mode 100644 nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/main/java/org/apache/nifi/snmp/operations/SNMPTrapReceiverHandler.java
create mode 100644 nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/main/java/org/apache/nifi/snmp/operations/SendTrapSNMPHandler.java
create mode 100644 nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/main/java/org/apache/nifi/snmp/operations/SetSNMPHandler.java
delete mode 100644 nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/main/java/org/apache/nifi/snmp/operations/StandardSNMPRequestHandler.java
create mode 100644 nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/main/java/org/apache/nifi/snmp/processors/ListenTrapSNMP.java
create mode 100644 nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/main/java/org/apache/nifi/snmp/processors/SendTrapSNMP.java
create mode 100644 nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/main/java/org/apache/nifi/snmp/processors/properties/BasicProperties.java
create mode 100644 nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/main/java/org/apache/nifi/snmp/processors/properties/V1TrapProperties.java
create mode 100644 nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/main/java/org/apache/nifi/snmp/processors/properties/V2TrapProperties.java
create mode 100644 nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/main/java/org/apache/nifi/snmp/processors/properties/V3SecurityProperties.java
create mode 100644 nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/main/resources/docs/org.apache.nifi.snmp.processors.ListenTrapSNMP/additionalDetails.html
create mode 100644 nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/main/resources/docs/org.apache.nifi.snmp.processors.SendTrapSNMP/additionalDetails.html
create mode 100644 nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/test/java/org/apache/nifi/snmp/configuration/SNMPConfigurationTest.java
create mode 100644 nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/test/java/org/apache/nifi/snmp/configuration/V1TrapConfigurationTest.java
create mode 100644 nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/test/java/org/apache/nifi/snmp/dto/SNMPTreeResponseTest.java
delete mode 100644 nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/test/java/org/apache/nifi/snmp/factory/SNMPClientFactoryTest.java
create mode 100644 nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/test/java/org/apache/nifi/snmp/factory/core/SNMPContextTest.java
create mode 100644 nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/test/java/org/apache/nifi/snmp/factory/core/SNMPFactoryProviderTest.java
create mode 100644 nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/test/java/org/apache/nifi/snmp/factory/core/V1V2cSNMPFactoryTest.java
create mode 100644 nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/test/java/org/apache/nifi/snmp/factory/core/V3SNMPFactoryTest.java
create mode 100644 nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/test/java/org/apache/nifi/snmp/factory/trap/V1TrapPDUFactoryTest.java
create mode 100644 nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/test/java/org/apache/nifi/snmp/factory/trap/V2TrapPDUFactoryTest.java
delete mode 100644 nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/test/java/org/apache/nifi/snmp/helper/SNMPTestUtils.java
create mode 100644 nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/test/java/org/apache/nifi/snmp/helper/TrapConfigurationFactory.java
rename nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/{main/java/org/apache/nifi/snmp/factory/SNMPFactory.java => test/java/org/apache/nifi/snmp/helper/configurations/SNMPConfigurationFactory.java} (67%)
create mode 100644 nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/test/java/org/apache/nifi/snmp/helper/configurations/SNMPV1V2cConfigurationFactory.java
create mode 100644 nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/test/java/org/apache/nifi/snmp/helper/configurations/SNMPV3ConfigurationFactory.java
create mode 100644 nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/test/java/org/apache/nifi/snmp/helper/testrunners/SNMPTestRunnerFactory.java
create mode 100644 nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/test/java/org/apache/nifi/snmp/helper/testrunners/SNMPV1TestRunnerFactory.java
create mode 100644 nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/test/java/org/apache/nifi/snmp/helper/testrunners/SNMPV2cTestRunnerFactory.java
create mode 100644 nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/test/java/org/apache/nifi/snmp/helper/testrunners/SNMPV3TestRunnerFactory.java
create mode 100644 nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/test/java/org/apache/nifi/snmp/operations/GetSNMPHandlerTest.java
create mode 100644 nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/test/java/org/apache/nifi/snmp/operations/SNMPTrapReceiverHandlerTest.java
create mode 100644 nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/test/java/org/apache/nifi/snmp/operations/SNMPTrapReceiverTest.java
delete mode 100644 nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/test/java/org/apache/nifi/snmp/operations/SNMPV1RequestTest.java
delete mode 100644 nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/test/java/org/apache/nifi/snmp/operations/SNMPV2CRequestTest.java
delete mode 100644 nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/test/java/org/apache/nifi/snmp/operations/SNMPV3RequestTest.java
create mode 100644 nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/test/java/org/apache/nifi/snmp/operations/SendTrapSNMPHandlerTest.java
create mode 100644 nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/test/java/org/apache/nifi/snmp/operations/SetSNMPHandlerTest.java
create mode 100644 nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/test/java/org/apache/nifi/snmp/processors/AbstractSNMPProcessorTest.java
create mode 100644 nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/test/java/org/apache/nifi/snmp/processors/GetSNMPIntegrationTest.java
create mode 100644 nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/test/java/org/apache/nifi/snmp/processors/SetSNMPIntegrationTest.java
delete mode 100644 nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/test/java/org/apache/nifi/snmp/processors/SetSNMPTest.java
create mode 100644 nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/test/java/org/apache/nifi/snmp/processors/TrapSNMPIntegrationTest.java
create mode 100644 nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/test/resources/users.json
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
index ab5b06efa6..88bc157876 100644
--- a/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/pom.xml
+++ b/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/pom.xml
@@ -51,6 +51,12 @@ language governing permissions and limitations under the License. -->
1.16.0-SNAPSHOTtest
+
+ com.fasterxml.jackson.core
+ jackson-databind
+ 2.12.3
+ compile
+
@@ -61,7 +67,7 @@ language governing permissions and limitations under the License. -->
- src/test/resources/testdata/*
+ src/test/resources/*
diff --git a/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/main/java/org/apache/nifi/snmp/configuration/SNMPConfiguration.java b/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/main/java/org/apache/nifi/snmp/configuration/SNMPConfiguration.java
index aa65ada526..36a371b50d 100644
--- a/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/main/java/org/apache/nifi/snmp/configuration/SNMPConfiguration.java
+++ b/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/main/java/org/apache/nifi/snmp/configuration/SNMPConfiguration.java
@@ -18,10 +18,11 @@ package org.apache.nifi.snmp.configuration;
public class SNMPConfiguration {
- private final String agentHost;
- private final String agentPort;
+ private final int managerPort;
+ private final String targetHost;
+ private final String targetPort;
private final int retries;
- private final int timeout;
+ private final long timeoutInMs;
private final int version;
private final String authProtocol;
private final String authPassphrase;
@@ -31,10 +32,11 @@ public class SNMPConfiguration {
private final String securityLevel;
private final String communityString;
- SNMPConfiguration(final String agentHost,
- final String agentPort,
+ SNMPConfiguration(final int managerPort,
+ final String targetHost,
+ final String targetPort,
final int retries,
- final int timeout,
+ final long timeoutInMs,
final int version,
final String authProtocol,
final String authPassphrase,
@@ -43,10 +45,11 @@ public class SNMPConfiguration {
final String securityName,
final String securityLevel,
final String communityString) {
- this.agentHost = agentHost;
- this.agentPort = agentPort;
+ this.managerPort = managerPort;
+ this.targetHost = targetHost;
+ this.targetPort = targetPort;
this.retries = retries;
- this.timeout = timeout;
+ this.timeoutInMs = timeoutInMs;
this.version = version;
this.authProtocol = authProtocol;
this.authPassphrase = authPassphrase;
@@ -57,20 +60,24 @@ public class SNMPConfiguration {
this.communityString = communityString;
}
- public String getAgentHost() {
- return agentHost;
+ public int getManagerPort() {
+ return managerPort;
}
- public String getAgentPort() {
- return agentPort;
+ public String getTargetHost() {
+ return targetHost;
+ }
+
+ public String getTargetPort() {
+ return targetPort;
}
public int getRetries() {
return retries;
}
- public int getTimeout() {
- return timeout;
+ public long getTimeoutInMs() {
+ return timeoutInMs;
}
public int getVersion() {
@@ -104,4 +111,95 @@ public class SNMPConfiguration {
public String getCommunityString() {
return communityString;
}
+
+ public static Builder builder() {
+ return new Builder();
+ }
+
+ public static class Builder {
+
+ private int managerPort;
+ private String targetHost;
+ private String targetPort;
+ private int retries;
+ private long timeoutInMs = 500L;
+ private int version;
+ private String authProtocol;
+ private String authPassphrase;
+ private String privacyProtocol;
+ private String privacyPassphrase;
+ private String securityName;
+ private String securityLevel;
+ private String communityString;
+
+ public Builder setManagerPort(final int managerPort) {
+ this.managerPort = managerPort;
+ return this;
+ }
+
+ public Builder setTargetHost(final String targetHost) {
+ this.targetHost = targetHost;
+ return this;
+ }
+
+ public Builder setTargetPort(final String targetPort) {
+ this.targetPort = targetPort;
+ return this;
+ }
+
+ public Builder setRetries(final int retries) {
+ this.retries = retries;
+ return this;
+ }
+
+ public Builder setTimeoutInMs(final long timeoutInMs) {
+ this.timeoutInMs = timeoutInMs;
+ return this;
+ }
+
+ public Builder setVersion(final int version) {
+ this.version = version;
+ return this;
+ }
+
+ public Builder setAuthProtocol(final String authProtocol) {
+ this.authProtocol = authProtocol;
+ return this;
+ }
+
+ public Builder setAuthPassphrase(final String authPassphrase) {
+ this.authPassphrase = authPassphrase;
+ return this;
+ }
+
+ public Builder setPrivacyProtocol(final String privacyProtocol) {
+ this.privacyProtocol = privacyProtocol;
+ return this;
+ }
+
+ public Builder setPrivacyPassphrase(final String privacyPassphrase) {
+ this.privacyPassphrase = privacyPassphrase;
+ return this;
+ }
+
+ public Builder setSecurityName(final String securityName) {
+ this.securityName = securityName;
+ return this;
+ }
+
+ public Builder setSecurityLevel(final String securityLevel) {
+ this.securityLevel = securityLevel;
+ return this;
+ }
+
+ public Builder setCommunityString(String communityString) {
+ this.communityString = communityString;
+ return this;
+ }
+
+ public SNMPConfiguration build() {
+ return new SNMPConfiguration(managerPort, targetHost, targetPort, retries, timeoutInMs, version, authProtocol,
+ authPassphrase, privacyProtocol, privacyPassphrase, securityName, securityLevel, communityString);
+ }
+ }
}
diff --git a/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/main/java/org/apache/nifi/snmp/configuration/SNMPConfigurationBuilder.java b/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/main/java/org/apache/nifi/snmp/configuration/SNMPConfigurationBuilder.java
deleted file mode 100644
index dbb7728219..0000000000
--- a/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/main/java/org/apache/nifi/snmp/configuration/SNMPConfigurationBuilder.java
+++ /dev/null
@@ -1,100 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.nifi.snmp.configuration;
-
-public class SNMPConfigurationBuilder {
- private String agentHost;
- private String agentPort;
- private int retries;
- private int timeout;
- private int version;
- private String authProtocol;
- private String authPassphrase;
- private String privacyProtocol;
- private String privacyPassphrase;
- private String securityName;
- private String securityLevel;
- private String communityString;
-
- public SNMPConfigurationBuilder setAgentHost(final String agentHost) {
- this.agentHost = agentHost;
- return this;
- }
-
- public SNMPConfigurationBuilder setAgentPort(final String agentPort) {
- this.agentPort = agentPort;
- return this;
- }
-
- public SNMPConfigurationBuilder setRetries(final int retries) {
- this.retries = retries;
- return this;
- }
-
- public SNMPConfigurationBuilder setTimeout(final int timeout) {
- this.timeout = timeout;
- return this;
- }
-
- public SNMPConfigurationBuilder setVersion(final int version) {
- this.version = version;
- return this;
- }
-
- public SNMPConfigurationBuilder setAuthProtocol(final String authProtocol) {
- this.authProtocol = authProtocol;
- return this;
- }
-
- public SNMPConfigurationBuilder setAuthPassphrase(final String authPassphrase) {
- this.authPassphrase = authPassphrase;
- return this;
- }
-
- public SNMPConfigurationBuilder setPrivacyProtocol(final String privacyProtocol) {
- this.privacyProtocol = privacyProtocol;
- return this;
- }
-
- public SNMPConfigurationBuilder setPrivacyPassphrase(final String privacyPassphrase) {
- this.privacyPassphrase = privacyPassphrase;
- return this;
- }
-
- public SNMPConfigurationBuilder setSecurityName(final String securityName) {
- this.securityName = securityName;
- return this;
- }
-
- public SNMPConfigurationBuilder setSecurityLevel(final String securityLevel) {
- this.securityLevel = securityLevel;
- return this;
- }
-
- public SNMPConfigurationBuilder setCommunityString(final String communityString) {
- this.communityString = communityString;
- return this;
- }
-
- public SNMPConfiguration build() {
- final boolean isValid = agentHost != null && agentPort != null;
- if (!isValid) {
- throw new IllegalStateException("Required properties are not set.");
- }
- return new SNMPConfiguration(agentHost, agentPort, retries, timeout, version, authProtocol, authPassphrase, privacyProtocol, privacyPassphrase, securityName, securityLevel, communityString);
- }
-}
\ No newline at end of file
diff --git a/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/main/java/org/apache/nifi/snmp/configuration/V1TrapConfiguration.java b/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/main/java/org/apache/nifi/snmp/configuration/V1TrapConfiguration.java
new file mode 100644
index 0000000000..896b0d9728
--- /dev/null
+++ b/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/main/java/org/apache/nifi/snmp/configuration/V1TrapConfiguration.java
@@ -0,0 +1,117 @@
+/*
+ * 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.configuration;
+
+import org.apache.nifi.util.StringUtils;
+
+public class V1TrapConfiguration {
+
+ private final String enterpriseOid;
+ private final String agentAddress;
+ private final String genericTrapType;
+ private final String specificTrapType;
+
+ private V1TrapConfiguration(final V1TrapConfiguration.Builder builder) {
+ this.enterpriseOid = builder.enterpriseOid;
+ this.agentAddress = builder.agentAddress;
+ this.genericTrapType = builder.genericTrapType;
+ this.specificTrapType = builder.specificTrapType;
+ }
+
+ public String getEnterpriseOid() {
+ return enterpriseOid;
+ }
+
+ public String getAgentAddress() {
+ return agentAddress;
+ }
+
+ public int getGenericTrapType() {
+ return Integer.parseInt(genericTrapType);
+ }
+
+ public Integer getSpecificTrapType() {
+ if (StringUtils.isNotEmpty(specificTrapType)) {
+ return Integer.parseInt(specificTrapType);
+ }
+ return null;
+ }
+
+ public static V1TrapConfiguration.Builder builder() {
+ return new V1TrapConfiguration.Builder();
+ }
+
+ public static final class Builder {
+ String enterpriseOid;
+ String agentAddress;
+ String genericTrapType;
+ String specificTrapType;
+
+ public Builder enterpriseOid(String enterpriseOid) {
+ this.enterpriseOid = enterpriseOid;
+ return this;
+ }
+
+ public Builder agentAddress(String agentAddress) {
+ this.agentAddress = agentAddress;
+ return this;
+ }
+
+ public Builder genericTrapType(String genericTrapType) {
+ this.genericTrapType = genericTrapType;
+ return this;
+ }
+
+ public Builder specificTrapType(String specificTrapType) {
+ this.specificTrapType = specificTrapType;
+ return this;
+ }
+
+ public V1TrapConfiguration build() {
+ if (StringUtils.isEmpty(enterpriseOid)) {
+ throw new IllegalArgumentException("Enterprise OID must be specified.");
+ }
+ if (StringUtils.isEmpty(agentAddress)) {
+ throw new IllegalArgumentException("Agent address must be specified.");
+ }
+
+ final int parsedGenericTrapType;
+ try {
+ parsedGenericTrapType = Integer.parseInt(genericTrapType);
+ if (parsedGenericTrapType < 0 || parsedGenericTrapType > 6) {
+ throw new IllegalArgumentException("Generic Trap Type must be between 0 and 6.");
+ }
+ } catch (NumberFormatException e) {
+ throw new IllegalArgumentException("Generic Trap Type is not a number.");
+ }
+
+ if (parsedGenericTrapType == 6) {
+ try {
+ final int parsedSpecificTrapType = Integer.parseInt(specificTrapType);
+ if (parsedSpecificTrapType < 0) {
+ throw new IllegalArgumentException("Specific Trap Type must be between 0 and 2147483647.");
+ }
+ } catch (NumberFormatException e) {
+ throw new IllegalArgumentException("Generic Trap Type is [6 - Enterprise Specific] but Specific Trap Type is not provided or not a number.");
+ }
+ } else if (StringUtils.isNotEmpty(specificTrapType)) {
+ throw new IllegalArgumentException("Invalid argument: Generic Trap Type is not [6 - Enterprise Specific] but Specific Trap Type is provided.");
+ }
+ return new V1TrapConfiguration(this);
+ }
+ }
+}
diff --git a/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/main/java/org/apache/nifi/snmp/exception/CreateSNMPClientException.java b/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/main/java/org/apache/nifi/snmp/configuration/V2TrapConfiguration.java
similarity index 65%
rename from nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/main/java/org/apache/nifi/snmp/exception/CreateSNMPClientException.java
rename to nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/main/java/org/apache/nifi/snmp/configuration/V2TrapConfiguration.java
index f803605979..145acbe21c 100644
--- a/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/main/java/org/apache/nifi/snmp/exception/CreateSNMPClientException.java
+++ b/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/main/java/org/apache/nifi/snmp/configuration/V2TrapConfiguration.java
@@ -14,12 +14,20 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.apache.nifi.snmp.exception;
+package org.apache.nifi.snmp.configuration;
-public class CreateSNMPClientException extends SNMPException {
+public class V2TrapConfiguration {
- public CreateSNMPClientException(final String errorMessage) {
- super(errorMessage);
+ private final String trapOidValue;
+
+ public V2TrapConfiguration(final String trapOidValue) {
+ if (trapOidValue.isEmpty()) {
+ throw new IllegalArgumentException("Trap OID Value must be specified.");
+ }
+ this.trapOidValue = trapOidValue;
}
+ public String getTrapOidValue() {
+ return trapOidValue;
+ }
}
diff --git a/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/main/java/org/apache/nifi/snmp/exception/CloseSNMPClientException.java b/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/main/java/org/apache/nifi/snmp/dto/ErrorStatus.java
similarity index 79%
rename from nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/main/java/org/apache/nifi/snmp/exception/CloseSNMPClientException.java
rename to nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/main/java/org/apache/nifi/snmp/dto/ErrorStatus.java
index 4c70250729..2582e13b99 100644
--- a/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/main/java/org/apache/nifi/snmp/exception/CloseSNMPClientException.java
+++ b/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/main/java/org/apache/nifi/snmp/dto/ErrorStatus.java
@@ -1,25 +1,21 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.nifi.snmp.exception;
-
-public class CloseSNMPClientException extends SNMPException {
-
- public CloseSNMPClientException(final String errorMessage) {
- super(errorMessage);
- }
-
-}
+/*
+ * 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.dto;
+
+public enum ErrorStatus {
+ FAILURE, SUCCESS
+}
diff --git a/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/main/java/org/apache/nifi/snmp/operations/SNMPRequestHandler.java b/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/main/java/org/apache/nifi/snmp/dto/SNMPResponseStatus.java
similarity index 61%
rename from nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/main/java/org/apache/nifi/snmp/operations/SNMPRequestHandler.java
rename to nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/main/java/org/apache/nifi/snmp/dto/SNMPResponseStatus.java
index 97759eda0e..8080e7c7fc 100644
--- a/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/main/java/org/apache/nifi/snmp/operations/SNMPRequestHandler.java
+++ b/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/main/java/org/apache/nifi/snmp/dto/SNMPResponseStatus.java
@@ -1,34 +1,37 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.nifi.snmp.operations;
-
-import org.apache.nifi.flowfile.FlowFile;
-import org.apache.nifi.snmp.dto.SNMPSingleResponse;
-import org.apache.nifi.snmp.dto.SNMPTreeResponse;
-
-import java.io.IOException;
-
-public interface SNMPRequestHandler {
-
- SNMPSingleResponse get(final String oid) throws IOException;
-
- SNMPTreeResponse walk(final String oid);
-
- SNMPSingleResponse set(final FlowFile flowfile) throws IOException;
-
- void close();
-}
+/*
+ * 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.dto;
+
+public class SNMPResponseStatus {
+
+ private final String errorMessage;
+ private final ErrorStatus errorStatus;
+
+
+ public SNMPResponseStatus(String errorMessage, ErrorStatus errorStatus) {
+ this.errorMessage = errorMessage;
+ this.errorStatus = errorStatus;
+ }
+
+ public String getErrorMessage() {
+ return errorMessage;
+ }
+
+ public ErrorStatus getErrorStatus() {
+ return errorStatus;
+ }
+}
diff --git a/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/main/java/org/apache/nifi/snmp/dto/SNMPSingleResponse.java b/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/main/java/org/apache/nifi/snmp/dto/SNMPSingleResponse.java
index dabf41a9bb..03f8306de0 100644
--- a/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/main/java/org/apache/nifi/snmp/dto/SNMPSingleResponse.java
+++ b/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/main/java/org/apache/nifi/snmp/dto/SNMPSingleResponse.java
@@ -38,7 +38,6 @@ public class SNMPSingleResponse {
return responsePdu.getErrorStatus() == PDU.noError;
}
-
public Map getAttributes() {
return SNMPUtils.getPduAttributeMap(responsePdu);
}
@@ -65,4 +64,5 @@ public class SNMPSingleResponse {
public boolean isReportPdu() {
return responsePdu.getType() == PDU.REPORT;
}
+
}
diff --git a/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/main/java/org/apache/nifi/snmp/dto/SNMPTreeResponse.java b/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/main/java/org/apache/nifi/snmp/dto/SNMPTreeResponse.java
index c250e8d831..d58116d71a 100644
--- a/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/main/java/org/apache/nifi/snmp/dto/SNMPTreeResponse.java
+++ b/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/main/java/org/apache/nifi/snmp/dto/SNMPTreeResponse.java
@@ -26,6 +26,7 @@ import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.Objects;
+import java.util.Optional;
import java.util.stream.Collectors;
public class SNMPTreeResponse {
@@ -56,4 +57,11 @@ public class SNMPTreeResponse {
.filter(TreeEvent::isError)
.forEach(event -> logger.error("Error occured in SNMP walk event: {}", event.getErrorMessage()));
}
+
+ public boolean isError() {
+ final Optional first = events.stream()
+ .filter(TreeEvent::isError)
+ .findFirst();
+ return first.isPresent();
+ }
}
diff --git a/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/main/java/org/apache/nifi/snmp/dto/UserDetails.java b/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/main/java/org/apache/nifi/snmp/dto/UserDetails.java
new file mode 100644
index 0000000000..26cc9ff5b1
--- /dev/null
+++ b/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/main/java/org/apache/nifi/snmp/dto/UserDetails.java
@@ -0,0 +1,58 @@
+/*
+ * 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.dto;
+
+public class UserDetails {
+
+ private String securityName;
+ private String authProtocol;
+ private String authPassphrase;
+ private String privProtocol;
+ private String privPassphrase;
+
+ public UserDetails() {
+ }
+
+ public UserDetails(final String securityName, final String authProtocol, final String authPassphrase,
+ final String privProtocol, final String privPassphrase) {
+ this.securityName = securityName;
+ this.authProtocol = authProtocol;
+ this.authPassphrase = authPassphrase;
+ this.privProtocol = privProtocol;
+ this.privPassphrase = privPassphrase;
+ }
+
+ public String getSecurityName() {
+ return securityName;
+ }
+
+ public String getAuthProtocol() {
+ return authProtocol;
+ }
+
+ public String getAuthPassphrase() {
+ return authPassphrase;
+ }
+
+ public String getPrivProtocol() {
+ return privProtocol;
+ }
+
+ public String getPrivPassphrase() {
+ return privPassphrase;
+ }
+}
diff --git a/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/main/java/org/apache/nifi/snmp/exception/SNMPException.java b/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/main/java/org/apache/nifi/snmp/exception/SNMPException.java
index 4e842daa90..7b51e0a0d1 100644
--- a/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/main/java/org/apache/nifi/snmp/exception/SNMPException.java
+++ b/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/main/java/org/apache/nifi/snmp/exception/SNMPException.java
@@ -22,4 +22,8 @@ public class SNMPException extends RuntimeException {
super(errorMessage);
}
+ public SNMPException(final Exception exception) {
+ super(exception);
+ }
+
}
diff --git a/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/main/java/org/apache/nifi/snmp/factory/AbstractSNMPFactory.java b/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/main/java/org/apache/nifi/snmp/factory/AbstractSNMPFactory.java
deleted file mode 100644
index baa458885d..0000000000
--- a/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/main/java/org/apache/nifi/snmp/factory/AbstractSNMPFactory.java
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.nifi.snmp.factory;
-
-import org.apache.nifi.snmp.configuration.SNMPConfiguration;
-import org.apache.nifi.snmp.exception.CreateSNMPClientException;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.snmp4j.CommunityTarget;
-import org.snmp4j.Snmp;
-import org.snmp4j.Target;
-import org.snmp4j.UserTarget;
-import org.snmp4j.security.SecurityLevel;
-import org.snmp4j.smi.OctetString;
-import org.snmp4j.smi.UdpAddress;
-import org.snmp4j.transport.DefaultUdpTransportMapping;
-
-import java.io.IOException;
-import java.util.Optional;
-
-public abstract class AbstractSNMPFactory {
-
- private static final Logger logger = LoggerFactory.getLogger(AbstractSNMPFactory.class);
-
- protected AbstractSNMPFactory() {
- // hide implicit constructor
- }
-
- protected static Snmp createSnmpClient() {
- final Snmp snmp;
- try {
- snmp = new Snmp(new DefaultUdpTransportMapping());
- snmp.listen();
- return snmp;
- } catch (IOException e) {
- final String errorMessage = "Creating SNMP client failed.";
- logger.error(errorMessage, e);
- throw new CreateSNMPClientException(errorMessage);
- }
- }
-
- protected static Target createUserTarget(final SNMPConfiguration configuration) {
- final UserTarget userTarget = new UserTarget();
- setupTargetBasicProperties(userTarget, configuration);
-
- final int securityLevel = SecurityLevel.valueOf(configuration.getSecurityLevel()).getSnmpValue();
- userTarget.setSecurityLevel(securityLevel);
-
- final String securityName = configuration.getSecurityName();
- Optional.ofNullable(securityName).map(OctetString::new).ifPresent(userTarget::setSecurityName);
-
- return userTarget;
- }
-
- protected static Target createCommunityTarget(final SNMPConfiguration configuration) {
- final Target communityTarget = new CommunityTarget();
- setupTargetBasicProperties(communityTarget, configuration);
- final String community = configuration.getCommunityString();
-
- Optional.ofNullable(community).map(OctetString::new).ifPresent(communityTarget::setSecurityName);
-
- return communityTarget;
- }
-
- private static void setupTargetBasicProperties(final Target target, final SNMPConfiguration configuration) {
- final int snmpVersion = configuration.getVersion();
- final String host = configuration.getAgentHost();
- final String port = configuration.getAgentPort();
- final int retries = configuration.getRetries();
- final int timeout = configuration.getTimeout();
-
- target.setVersion(snmpVersion);
- target.setAddress(new UdpAddress(host + "/" + port));
- target.setRetries(retries);
- target.setTimeout(timeout);
- }
-}
diff --git a/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/main/java/org/apache/nifi/snmp/factory/CompositeSNMPFactory.java b/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/main/java/org/apache/nifi/snmp/factory/CompositeSNMPFactory.java
deleted file mode 100644
index f1234bc6f2..0000000000
--- a/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/main/java/org/apache/nifi/snmp/factory/CompositeSNMPFactory.java
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.nifi.snmp.factory;
-
-import org.apache.nifi.snmp.configuration.SNMPConfiguration;
-import org.apache.nifi.snmp.exception.InvalidSnmpVersionException;
-import org.snmp4j.Snmp;
-import org.snmp4j.Target;
-
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.List;
-import java.util.Optional;
-
-public class CompositeSNMPFactory implements SNMPFactory {
-
- private static final String INVALID_SNMP_VERSION = "SNMP version is not supported.";
- private static final List FACTORIES;
-
- static {
- final List factories = Arrays.asList(new V1SNMPFactory(), new V2cSNMPFactory(), new V3SNMPFactory());
- FACTORIES = Collections.unmodifiableList(factories);
- }
-
- @Override
- public boolean supports(final int version) {
- return !getMatchingFactory(version).isPresent();
- }
-
- @Override
- public Snmp createSnmpManagerInstance(final SNMPConfiguration configuration) {
- final Optional factory = getMatchingFactory(configuration.getVersion());
- if (!factory.isPresent()) {
- throw new InvalidSnmpVersionException(INVALID_SNMP_VERSION);
- }
- return factory.get().createSnmpManagerInstance(configuration);
- }
-
- @Override
- public Target createTargetInstance(final SNMPConfiguration configuration) {
- final Optional factory = getMatchingFactory(configuration.getVersion());
- if (!factory.isPresent()) {
- throw new InvalidSnmpVersionException(INVALID_SNMP_VERSION);
- }
- return factory.get().createTargetInstance(configuration);
- }
-
- private Optional getMatchingFactory(final int version) {
- for (final SNMPFactory factory : FACTORIES) {
- if (factory.supports(version)) {
- return Optional.of(factory);
- }
- }
- return Optional.empty();
- }
-}
diff --git a/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/main/java/org/apache/nifi/snmp/factory/V3SNMPFactory.java b/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/main/java/org/apache/nifi/snmp/factory/V3SNMPFactory.java
deleted file mode 100644
index 75e34d0c37..0000000000
--- a/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/main/java/org/apache/nifi/snmp/factory/V3SNMPFactory.java
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.nifi.snmp.factory;
-
-import org.apache.nifi.snmp.configuration.SNMPConfiguration;
-import org.apache.nifi.snmp.utils.SNMPUtils;
-import org.snmp4j.Snmp;
-import org.snmp4j.Target;
-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.OID;
-import org.snmp4j.smi.OctetString;
-
-import java.util.Optional;
-
-public class V3SNMPFactory extends AbstractSNMPFactory implements SNMPFactory {
-
- @Override
- public boolean supports(final int version) {
- return SnmpConstants.version3 == version;
- }
-
- @Override
- public Snmp createSnmpManagerInstance(final SNMPConfiguration configuration) {
- final Snmp snmp = createSnmpClient();
-
- // If there's a USM instance associated with the MPv3 bound to this Snmp instance (like an agent running
- // on the same host) it is not null.
- if (snmp.getUSM() == null) {
- final OctetString localEngineId = new OctetString(MPv3.createLocalEngineID());
- final USM usm = new USM(SecurityProtocols.getInstance(), localEngineId, 0);
- SecurityModels.getInstance().addSecurityModel(usm);
- }
-
- final String username = configuration.getSecurityName();
- final OID authProtocol = Optional.ofNullable(configuration.getAuthProtocol())
- .map(SNMPUtils::getAuth).orElse(null);
- final OID privacyProtocol = Optional.ofNullable(configuration.getPrivacyProtocol())
- .map(SNMPUtils::getPriv).orElse(null);
- final String authPassword = configuration.getAuthPassphrase();
- final String privacyPassword = configuration.getPrivacyPassphrase();
- final OctetString authPasswordOctet = authPassword != null ? new OctetString(authPassword) : null;
- final OctetString privacyPasswordOctet = privacyPassword != null ? new OctetString(privacyPassword) : null;
-
- // Add user information.
- snmp.getUSM().addUser(
- new OctetString(username),
- new UsmUser(new OctetString(username), authProtocol, authPasswordOctet,
- privacyProtocol, privacyPasswordOctet));
-
- return snmp;
- }
-
- @Override
- public Target createTargetInstance(final SNMPConfiguration configuration) {
- return createUserTarget(configuration);
- }
-}
diff --git a/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/main/java/org/apache/nifi/snmp/factory/core/SNMPContext.java b/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/main/java/org/apache/nifi/snmp/factory/core/SNMPContext.java
new file mode 100644
index 0000000000..d3dd885613
--- /dev/null
+++ b/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/main/java/org/apache/nifi/snmp/factory/core/SNMPContext.java
@@ -0,0 +1,50 @@
+/*
+ * 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.factory.core;
+
+import org.apache.nifi.snmp.configuration.SNMPConfiguration;
+import org.apache.nifi.snmp.operations.SNMPResourceHandler;
+import org.snmp4j.Snmp;
+import org.snmp4j.Target;
+import org.snmp4j.smi.UdpAddress;
+
+public interface SNMPContext {
+
+ default SNMPResourceHandler createSNMPResourceHandler(final SNMPConfiguration snmpConfiguration) {
+ return new SNMPResourceHandler(
+ createSnmpManagerInstance(snmpConfiguration),
+ createTargetInstance(snmpConfiguration)
+ );
+ }
+
+ default void setupTargetBasicProperties(final Target target, final SNMPConfiguration configuration) {
+ final int snmpVersion = configuration.getVersion();
+ final String host = configuration.getTargetHost();
+ final String port = configuration.getTargetPort();
+ final int retries = configuration.getRetries();
+ final long timeout = configuration.getTimeoutInMs();
+
+ target.setVersion(snmpVersion);
+ target.setAddress(new UdpAddress(host + "/" + port));
+ target.setRetries(retries);
+ target.setTimeout(timeout);
+ }
+
+ Snmp createSnmpManagerInstance(final SNMPConfiguration configuration);
+
+ Target createTargetInstance(final SNMPConfiguration configuration);
+}
diff --git a/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/main/java/org/apache/nifi/snmp/factory/core/SNMPFactoryProvider.java b/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/main/java/org/apache/nifi/snmp/factory/core/SNMPFactoryProvider.java
new file mode 100644
index 0000000000..6cc62aaa03
--- /dev/null
+++ b/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/main/java/org/apache/nifi/snmp/factory/core/SNMPFactoryProvider.java
@@ -0,0 +1,48 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.nifi.snmp.factory.core;
+
+import org.apache.nifi.snmp.exception.InvalidSnmpVersionException;
+import org.snmp4j.mp.SnmpConstants;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Optional;
+
+public class SNMPFactoryProvider {
+
+ private SNMPFactoryProvider() {
+ // not to instantiate
+ }
+
+ private static final String INVALID_SNMP_VERSION = "SNMP version is not supported: %s";
+ private static final Map FACTORIES;
+
+ static {
+ final Map factories = new HashMap<>();
+ factories.put(SnmpConstants.version1, new V1V2cSNMPFactory());
+ factories.put(SnmpConstants.version2c, new V1V2cSNMPFactory());
+ factories.put(SnmpConstants.version3, new V3SNMPFactory());
+ FACTORIES = Collections.unmodifiableMap(factories);
+ }
+
+ public static SNMPContext getFactory(final int version) {
+ return Optional.ofNullable(FACTORIES.get(version))
+ .orElseThrow(() -> new InvalidSnmpVersionException(String.format(INVALID_SNMP_VERSION, version)));
+ }
+}
diff --git a/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/main/java/org/apache/nifi/snmp/factory/V2cSNMPFactory.java b/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/main/java/org/apache/nifi/snmp/factory/core/SNMPManagerFactory.java
similarity index 58%
rename from nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/main/java/org/apache/nifi/snmp/factory/V2cSNMPFactory.java
rename to nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/main/java/org/apache/nifi/snmp/factory/core/SNMPManagerFactory.java
index b34609d72c..17afbb0607 100644
--- a/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/main/java/org/apache/nifi/snmp/factory/V2cSNMPFactory.java
+++ b/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/main/java/org/apache/nifi/snmp/factory/core/SNMPManagerFactory.java
@@ -14,27 +14,29 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.apache.nifi.snmp.factory;
+package org.apache.nifi.snmp.factory.core;
+import org.apache.nifi.processor.exception.ProcessException;
import org.apache.nifi.snmp.configuration.SNMPConfiguration;
import org.snmp4j.Snmp;
-import org.snmp4j.Target;
-import org.snmp4j.mp.SnmpConstants;
+import org.snmp4j.smi.UdpAddress;
+import org.snmp4j.transport.DefaultUdpTransportMapping;
-public class V2cSNMPFactory extends AbstractSNMPFactory implements SNMPFactory {
+import java.io.IOException;
- @Override
- public boolean supports(final int version) {
- return SnmpConstants.version2c == version;
- }
+public class SNMPManagerFactory {
+
+ private static final String LOCALHOST = "127.0.0.1";
- @Override
public Snmp createSnmpManagerInstance(final SNMPConfiguration configuration) {
- return createSnmpClient();
- }
-
- @Override
- public Target createTargetInstance(final SNMPConfiguration configuration) {
- return createCommunityTarget(configuration);
+ final String managerAddress = LOCALHOST + "/" + configuration.getManagerPort();
+ final Snmp snmpManager;
+ try {
+ snmpManager = new Snmp(new DefaultUdpTransportMapping(new UdpAddress(managerAddress)));
+ snmpManager.listen();
+ } catch (IOException e) {
+ throw new ProcessException(e);
+ }
+ return snmpManager;
}
}
diff --git a/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/main/java/org/apache/nifi/snmp/factory/V1SNMPFactory.java b/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/main/java/org/apache/nifi/snmp/factory/core/V1V2cSNMPFactory.java
similarity index 64%
rename from nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/main/java/org/apache/nifi/snmp/factory/V1SNMPFactory.java
rename to nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/main/java/org/apache/nifi/snmp/factory/core/V1V2cSNMPFactory.java
index e0896583cc..636ca4a7ca 100644
--- a/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/main/java/org/apache/nifi/snmp/factory/V1SNMPFactory.java
+++ b/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/main/java/org/apache/nifi/snmp/factory/core/V1V2cSNMPFactory.java
@@ -14,27 +14,25 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.apache.nifi.snmp.factory;
+package org.apache.nifi.snmp.factory.core;
import org.apache.nifi.snmp.configuration.SNMPConfiguration;
-import org.snmp4j.Snmp;
+import org.snmp4j.CommunityTarget;
import org.snmp4j.Target;
-import org.snmp4j.mp.SnmpConstants;
+import org.snmp4j.smi.OctetString;
-public class V1SNMPFactory extends AbstractSNMPFactory implements SNMPFactory {
+import java.util.Optional;
- @Override
- public boolean supports(final int version) {
- return SnmpConstants.version1 == version;
- }
-
- @Override
- public Snmp createSnmpManagerInstance(final SNMPConfiguration configuration) {
- return createSnmpClient();
- }
+public class V1V2cSNMPFactory extends SNMPManagerFactory implements SNMPContext {
@Override
public Target createTargetInstance(final SNMPConfiguration configuration) {
- return createCommunityTarget(configuration);
+ final Target communityTarget = new CommunityTarget();
+ setupTargetBasicProperties(communityTarget, configuration);
+ final String community = configuration.getCommunityString();
+
+ Optional.ofNullable(community).map(OctetString::new).ifPresent(communityTarget::setSecurityName);
+
+ return communityTarget;
}
}
diff --git a/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/main/java/org/apache/nifi/snmp/factory/core/V3SNMPFactory.java b/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/main/java/org/apache/nifi/snmp/factory/core/V3SNMPFactory.java
new file mode 100644
index 0000000000..4bc089730e
--- /dev/null
+++ b/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/main/java/org/apache/nifi/snmp/factory/core/V3SNMPFactory.java
@@ -0,0 +1,77 @@
+/*
+ * 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.factory.core;
+
+import org.apache.nifi.snmp.configuration.SNMPConfiguration;
+import org.apache.nifi.snmp.utils.SNMPUtils;
+import org.snmp4j.Snmp;
+import org.snmp4j.Target;
+import org.snmp4j.UserTarget;
+import org.snmp4j.mp.MPv3;
+import org.snmp4j.security.SecurityLevel;
+import org.snmp4j.security.SecurityModels;
+import org.snmp4j.security.SecurityProtocols;
+import org.snmp4j.security.USM;
+import org.snmp4j.security.UsmUser;
+import org.snmp4j.smi.OID;
+import org.snmp4j.smi.OctetString;
+
+import java.util.Optional;
+
+public class V3SNMPFactory extends SNMPManagerFactory implements SNMPContext {
+
+ @Override
+ public Snmp createSnmpManagerInstance(final SNMPConfiguration configuration) {
+ final Snmp snmpManager = super.createSnmpManagerInstance(configuration);
+
+ // Create USM.
+ final OctetString localEngineId = new OctetString(MPv3.createLocalEngineID());
+ final USM usm = new USM(SecurityProtocols.getInstance(), localEngineId, 0);
+ SecurityModels.getInstance().addSecurityModel(usm);
+
+ Optional.ofNullable(configuration.getSecurityName())
+ .map(OctetString::new)
+ .ifPresent(securityName -> {
+ OID authProtocol = Optional.ofNullable(configuration.getAuthProtocol())
+ .map(SNMPUtils::getAuth).orElse(null);
+ OctetString authPassphrase = Optional.ofNullable(configuration.getAuthPassphrase())
+ .map(OctetString::new).orElse(null);
+ OID privacyProtocol = Optional.ofNullable(configuration.getPrivacyProtocol())
+ .map(SNMPUtils::getPriv).orElse(null);
+ OctetString privacyPassphrase = Optional.ofNullable(configuration.getPrivacyPassphrase())
+ .map(OctetString::new).orElse(null);
+ snmpManager.getUSM().addUser(securityName, new UsmUser(securityName, authProtocol, authPassphrase,
+ privacyProtocol, privacyPassphrase));
+ });
+
+ return snmpManager;
+ }
+
+ @Override
+ public Target createTargetInstance(final SNMPConfiguration configuration) {
+ final UserTarget userTarget = new UserTarget();
+ setupTargetBasicProperties(userTarget, configuration);
+
+ final int securityLevel = SecurityLevel.valueOf(configuration.getSecurityLevel()).getSnmpValue();
+ userTarget.setSecurityLevel(securityLevel);
+
+ final String securityName = configuration.getSecurityName();
+ Optional.ofNullable(securityName).map(OctetString::new).ifPresent(userTarget::setSecurityName);
+
+ return userTarget;
+ }
+}
diff --git a/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/main/java/org/apache/nifi/snmp/factory/trap/V1TrapPDUFactory.java b/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/main/java/org/apache/nifi/snmp/factory/trap/V1TrapPDUFactory.java
new file mode 100644
index 0000000000..a68f2b1e76
--- /dev/null
+++ b/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/main/java/org/apache/nifi/snmp/factory/trap/V1TrapPDUFactory.java
@@ -0,0 +1,58 @@
+/*
+ * 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.factory.trap;
+
+import org.apache.nifi.snmp.configuration.V1TrapConfiguration;
+import org.snmp4j.PDU;
+import org.snmp4j.PDUv1;
+import org.snmp4j.Target;
+import org.snmp4j.smi.IpAddress;
+import org.snmp4j.smi.OID;
+import org.snmp4j.util.DefaultPDUFactory;
+import org.snmp4j.util.PDUFactory;
+
+import java.time.Duration;
+import java.time.Instant;
+import java.util.Optional;
+
+/**
+ * Factory class to create SNMPv1-Trap-PDU for SNMPv1.
+ */
+public class V1TrapPDUFactory {
+
+ private static final PDUFactory v1PduFactory = new DefaultPDUFactory(PDU.V1TRAP);
+
+ final Target target;
+ final Instant startTime;
+
+ public V1TrapPDUFactory(final Target target, final Instant startTime) {
+ this.target = target;
+ this.startTime = startTime;
+ }
+
+ public PDU get(final V1TrapConfiguration v1TrapConfiguration) {
+ final PDUv1 pdu = (PDUv1) v1PduFactory.createPDU(target);
+ Optional.ofNullable(v1TrapConfiguration.getEnterpriseOid()).map(OID::new).ifPresent(pdu::setEnterprise);
+ Optional.ofNullable(v1TrapConfiguration.getAgentAddress()).map(IpAddress::new).ifPresent(pdu::setAgentAddress);
+ pdu.setGenericTrap(v1TrapConfiguration.getGenericTrapType());
+ Optional.ofNullable(v1TrapConfiguration.getSpecificTrapType()).ifPresent(pdu::setSpecificTrap);
+ final long elapsedMillis = Duration.between(startTime, Instant.now()).toMillis();
+ pdu.setTimestamp(elapsedMillis);
+ return pdu;
+ }
+
+}
diff --git a/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/main/java/org/apache/nifi/snmp/factory/trap/V2TrapPDUFactory.java b/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/main/java/org/apache/nifi/snmp/factory/trap/V2TrapPDUFactory.java
new file mode 100644
index 0000000000..7ff58646b0
--- /dev/null
+++ b/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/main/java/org/apache/nifi/snmp/factory/trap/V2TrapPDUFactory.java
@@ -0,0 +1,54 @@
+/*
+ * 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.factory.trap;
+
+import org.apache.nifi.snmp.configuration.V2TrapConfiguration;
+import org.snmp4j.PDU;
+import org.snmp4j.Target;
+import org.snmp4j.mp.SnmpConstants;
+import org.snmp4j.smi.OctetString;
+import org.snmp4j.smi.TimeTicks;
+import org.snmp4j.smi.VariableBinding;
+import org.snmp4j.util.DefaultPDUFactory;
+import org.snmp4j.util.PDUFactory;
+
+import java.time.Duration;
+import java.time.Instant;
+
+/**
+ * Factory class to create SNMPv2-Trap-PDU for SNMPv2c and SNMPv3.
+ */
+public class V2TrapPDUFactory {
+ private static final PDUFactory v2PduFactory = new DefaultPDUFactory(PDU.TRAP);
+
+ final Target target;
+ final Instant startTime;
+
+ public V2TrapPDUFactory(final Target target, final Instant startTime) {
+ this.target = target;
+ this.startTime = startTime;
+ }
+
+ public PDU get(final V2TrapConfiguration v2TrapConfiguration) {
+ final PDU pdu = v2PduFactory.createPDU(target);
+ pdu.add(new VariableBinding(SnmpConstants.snmpTrapOID, new OctetString(v2TrapConfiguration.getTrapOidValue())));
+ final long elapsedMillis = Duration.between(startTime, Instant.now()).toMillis();
+ pdu.add(new VariableBinding(SnmpConstants.sysUpTime, new TimeTicks(elapsedMillis)));
+ return pdu;
+ }
+
+}
\ No newline at end of file
diff --git a/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/main/java/org/apache/nifi/snmp/operations/GetSNMPHandler.java b/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/main/java/org/apache/nifi/snmp/operations/GetSNMPHandler.java
new file mode 100644
index 0000000000..3514dd776f
--- /dev/null
+++ b/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/main/java/org/apache/nifi/snmp/operations/GetSNMPHandler.java
@@ -0,0 +1,150 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.nifi.snmp.operations;
+
+import org.apache.nifi.snmp.dto.SNMPSingleResponse;
+import org.apache.nifi.snmp.dto.SNMPTreeResponse;
+import org.apache.nifi.snmp.exception.RequestTimeoutException;
+import org.apache.nifi.snmp.exception.SNMPWalkException;
+import org.apache.nifi.snmp.utils.SNMPUtils;
+import org.snmp4j.PDU;
+import org.snmp4j.Snmp;
+import org.snmp4j.Target;
+import org.snmp4j.event.ResponseEvent;
+import org.snmp4j.smi.OID;
+import org.snmp4j.smi.VariableBinding;
+import org.snmp4j.util.DefaultPDUFactory;
+import org.snmp4j.util.PDUFactory;
+import org.snmp4j.util.TreeEvent;
+import org.snmp4j.util.TreeUtils;
+
+import java.io.IOException;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Map;
+import java.util.Optional;
+
+import static org.apache.nifi.snmp.operations.SNMPResourceHandler.REQUEST_TIMEOUT_EXCEPTION_TEMPLATE;
+
+public class GetSNMPHandler {
+
+ private static final PDUFactory getPduFactory = new DefaultPDUFactory(PDU.GET);
+
+ protected static final String EMPTY_SUBTREE_EXCEPTION_MESSAGE = "Agent is not available, the %s OID not found or user not found. " +
+ "Please, check if (1) the agent is available, (2) the processor's SNMP version matches the agent version, " +
+ "(3) the OID is correct, (4) The user is valid.";
+
+ protected static final String SNMP_ERROR_EXCEPTION_MESSAGE = "Agent is not available, OID not found or user not found. " +
+ "Please, check if (1) the agent is available, (2) the processor's SNMP version matches the agent version, " +
+ "(3) the OID is correct, (4) The user is valid.";
+
+ protected static final String LEAF_ELEMENT_EXCEPTION_MESSAGE = "OID not found or it is a single leaf element. The leaf element " +
+ "associated with this %s OID does not contain child OIDs. Please check if the OID exists in the agent " +
+ "MIB or specify a parent OID with at least one child element";
+
+ private final SNMPResourceHandler snmpResourceHandler;
+ private TreeUtils treeUtils;
+
+ public GetSNMPHandler(final SNMPResourceHandler snmpResourceHandler) {
+ this.snmpResourceHandler = snmpResourceHandler;
+ this.treeUtils = new TreeUtils(snmpResourceHandler.getSnmpManager(), getPduFactory);
+ }
+
+ public SNMPSingleResponse get(final String oid) throws IOException {
+ final Target target = snmpResourceHandler.getTarget();
+ final Snmp snmpManager = snmpResourceHandler.getSnmpManager();
+
+ final PDU pdu = getPduFactory.createPDU(target);
+ pdu.add(new VariableBinding(new OID(oid)));
+
+ final PDU responsePdu = getResponsePdu(target, snmpManager, pdu);
+ return new SNMPSingleResponse(target, responsePdu);
+ }
+
+ public Optional get(final Map flowFileAttributes) throws IOException {
+ final Target target = snmpResourceHandler.getTarget();
+ final Snmp snmpManager = snmpResourceHandler.getSnmpManager();
+
+ final PDU pdu = getPduFactory.createPDU(target);
+ VariableBinding[] variableBindings = SNMPUtils.addGetVariables(flowFileAttributes);
+ if (variableBindings.length == 0) {
+ return Optional.empty();
+ }
+ pdu.addAll(variableBindings);
+
+ final PDU responsePdu = getResponsePdu(target, snmpManager, pdu);
+ return Optional.of(new SNMPSingleResponse(target, responsePdu));
+ }
+
+ public SNMPTreeResponse walk(final String oid) {
+ final Target target = snmpResourceHandler.getTarget();
+ final List subtree = treeUtils.getSubtree(target, new OID(oid));
+
+ evaluateSubtreeErrors(oid, subtree);
+
+ return new SNMPTreeResponse(target, subtree);
+ }
+
+ public Optional walk(final Map flowFileAttributes) {
+ final Target target = snmpResourceHandler.getTarget();
+ final List subtree;
+
+ final OID[] oids = SNMPUtils.addWalkVariables(flowFileAttributes);
+ if (oids.length == 0) {
+ return Optional.empty();
+ }
+ subtree = treeUtils.walk(target, oids);
+
+ evaluateSubtreeErrors(Arrays.toString(oids), subtree);
+
+ return Optional.of(new SNMPTreeResponse(target, subtree));
+ }
+
+ private PDU getResponsePdu(Target target, Snmp snmpManager, PDU pdu) throws IOException {
+ final ResponseEvent response = snmpManager.get(pdu, target);
+ final PDU responsePdu = response.getResponse();
+ if (responsePdu == null) {
+ throw new RequestTimeoutException(String.format(REQUEST_TIMEOUT_EXCEPTION_TEMPLATE, "read"));
+ }
+ return responsePdu;
+ }
+
+ private void evaluateSubtreeErrors(String oid, List subtree) {
+ if (subtree.isEmpty()) {
+ throw new SNMPWalkException(String.format(EMPTY_SUBTREE_EXCEPTION_MESSAGE, oid));
+ }
+ if (isSnmpError(subtree)) {
+ throw new SNMPWalkException(SNMP_ERROR_EXCEPTION_MESSAGE);
+ }
+ if (isLeafElement(subtree)) {
+ throw new SNMPWalkException(String.format(LEAF_ELEMENT_EXCEPTION_MESSAGE, oid));
+ }
+ }
+
+ private boolean isSnmpError(final List subtree) {
+ return subtree.size() == 1 && subtree.get(0).getVariableBindings() == null;
+ }
+
+ private boolean isLeafElement(final List subtree) {
+ return subtree.size() == 1 && subtree.get(0).getVariableBindings().length == 0;
+ }
+
+ // Visible for testing
+ void setTreeUtils(final TreeUtils treeUtils) {
+ this.treeUtils = treeUtils;
+ }
+}
diff --git a/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/main/java/org/apache/nifi/snmp/operations/SNMPRequestHandlerFactory.java b/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/main/java/org/apache/nifi/snmp/operations/SNMPRequestHandlerFactory.java
deleted file mode 100644
index 6663c4e8a1..0000000000
--- a/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/main/java/org/apache/nifi/snmp/operations/SNMPRequestHandlerFactory.java
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.nifi.snmp.operations;
-
-import org.apache.nifi.snmp.configuration.SNMPConfiguration;
-import org.apache.nifi.snmp.factory.CompositeSNMPFactory;
-import org.apache.nifi.snmp.factory.SNMPFactory;
-import org.snmp4j.Snmp;
-import org.snmp4j.Target;
-
-public final class SNMPRequestHandlerFactory {
-
- public static SNMPRequestHandler createStandardRequestHandler(final SNMPConfiguration configuration) {
- final SNMPFactory snmpFactory = new CompositeSNMPFactory();
- final Snmp snmpClient = snmpFactory.createSnmpManagerInstance(configuration);
- final Target target = snmpFactory.createTargetInstance(configuration);
- return new StandardSNMPRequestHandler(snmpClient, target);
- }
-
- private SNMPRequestHandlerFactory() {
- // This should not be instantiated.
- }
-
-}
diff --git a/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/main/java/org/apache/nifi/snmp/operations/SNMPResourceHandler.java b/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/main/java/org/apache/nifi/snmp/operations/SNMPResourceHandler.java
new file mode 100644
index 0000000000..b19ded6047
--- /dev/null
+++ b/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/main/java/org/apache/nifi/snmp/operations/SNMPResourceHandler.java
@@ -0,0 +1,70 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.nifi.snmp.operations;
+
+import org.apache.nifi.processor.exception.ProcessException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.snmp4j.Snmp;
+import org.snmp4j.Target;
+import org.snmp4j.security.SecurityModels;
+import org.snmp4j.smi.Integer32;
+
+import java.io.IOException;
+
+public class SNMPResourceHandler {
+
+ public static final String INVALID_FLOWFILE_EXCEPTION_MESSAGE = "Could not read the variable bindings from the " +
+ "flowfile. Please, add the OIDs to set in separate properties. E.g. Property name: snmp$1.3.6.1.2.1.1.1.0 " +
+ "Value: Example value. ";
+
+ public static final String REQUEST_TIMEOUT_EXCEPTION_TEMPLATE = "Request timed out. Please check if (1). the " +
+ "agent host and port is correctly set, (2). the agent is running, (3). the agent SNMP version corresponds" +
+ " with the processor's one, (4) the community string is correct and has %1$s access, (5) In case of SNMPv3" +
+ " check if the user credentials are valid and the user in a group with %1$s access.";
+
+ private final Logger logger = LoggerFactory.getLogger(this.getClass());
+ private final Snmp snmpManager;
+ private final Target target;
+
+ public SNMPResourceHandler(final Snmp snmpManager, final Target target) {
+ this.snmpManager = snmpManager;
+ this.target = target;
+ }
+
+ public Snmp getSnmpManager() {
+ return snmpManager;
+ }
+
+ public Target getTarget() {
+ return target;
+ }
+
+ public void close() {
+ try {
+ if (snmpManager.getUSM() != null) {
+ snmpManager.getUSM().removeAllUsers();
+ SecurityModels.getInstance().removeSecurityModel(new Integer32(snmpManager.getUSM().getID()));
+ }
+ snmpManager.close();
+ } catch (IOException e) {
+ final String errorMessage = "Could not close SNMP manager.";
+ logger.error(errorMessage, e);
+ throw new ProcessException(errorMessage);
+ }
+ }
+}
diff --git a/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/main/java/org/apache/nifi/snmp/operations/SNMPTrapReceiver.java b/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/main/java/org/apache/nifi/snmp/operations/SNMPTrapReceiver.java
new file mode 100644
index 0000000000..d2eaf19528
--- /dev/null
+++ b/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/main/java/org/apache/nifi/snmp/operations/SNMPTrapReceiver.java
@@ -0,0 +1,77 @@
+/*
+ * 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.operations;
+
+import org.apache.nifi.flowfile.FlowFile;
+import org.apache.nifi.logging.ComponentLog;
+import org.apache.nifi.processor.ProcessSession;
+import org.apache.nifi.processor.ProcessSessionFactory;
+import org.apache.nifi.snmp.utils.SNMPUtils;
+import org.snmp4j.CommandResponder;
+import org.snmp4j.CommandResponderEvent;
+import org.snmp4j.PDU;
+import org.snmp4j.PDUv1;
+
+import java.util.Map;
+
+import static org.apache.nifi.snmp.processors.ListenTrapSNMP.REL_FAILURE;
+import static org.apache.nifi.snmp.processors.ListenTrapSNMP.REL_SUCCESS;
+
+public class SNMPTrapReceiver implements CommandResponder {
+
+ private final ProcessSessionFactory processSessionFactory;
+ private final ComponentLog logger;
+
+ public SNMPTrapReceiver(final ProcessSessionFactory processSessionFactory, final ComponentLog logger) {
+ this.processSessionFactory = processSessionFactory;
+ this.logger = logger;
+ }
+
+ @Override
+ public void processPdu(final CommandResponderEvent event) {
+ final PDU pdu = event.getPDU();
+ if (isValidTrapPdu(pdu)) {
+ final ProcessSession processSession = processSessionFactory.createSession();
+ final FlowFile flowFile = createFlowFile(processSession, pdu);
+ processSession.getProvenanceReporter().create(flowFile, event.getPeerAddress() + "/" + pdu.getRequestID());
+ if (pdu.getErrorStatus() == PDU.noError) {
+ processSession.transfer(flowFile, REL_SUCCESS);
+ } else {
+ processSession.transfer(flowFile, REL_FAILURE);
+ }
+ processSession.commitAsync();
+ } else {
+ logger.error("Request timed out or parameters are incorrect.");
+ }
+ }
+
+ private FlowFile createFlowFile(final ProcessSession processSession, final PDU pdu) {
+ FlowFile flowFile = processSession.create();
+ final Map attributes;
+ if (pdu instanceof PDUv1) {
+ attributes = SNMPUtils.getV1TrapPduAttributeMap((PDUv1) pdu);
+ } else {
+ attributes = SNMPUtils.getPduAttributeMap(pdu);
+ }
+ flowFile = processSession.putAllAttributes(flowFile, attributes);
+ return flowFile;
+ }
+
+ private boolean isValidTrapPdu(final PDU pdu) {
+ return pdu != null && (pdu.getType() == PDU.V1TRAP || pdu.getType() == PDU.TRAP);
+ }
+}
diff --git a/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/main/java/org/apache/nifi/snmp/operations/SNMPTrapReceiverHandler.java b/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/main/java/org/apache/nifi/snmp/operations/SNMPTrapReceiverHandler.java
new file mode 100644
index 0000000000..53b1ff2eda
--- /dev/null
+++ b/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/main/java/org/apache/nifi/snmp/operations/SNMPTrapReceiverHandler.java
@@ -0,0 +1,124 @@
+/*
+ * 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.operations;
+
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.core.type.TypeReference;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import org.apache.nifi.logging.ComponentLog;
+import org.apache.nifi.processor.ProcessSessionFactory;
+import org.apache.nifi.processor.exception.ProcessException;
+import org.apache.nifi.snmp.configuration.SNMPConfiguration;
+import org.apache.nifi.snmp.dto.UserDetails;
+import org.apache.nifi.snmp.factory.core.SNMPManagerFactory;
+import org.apache.nifi.snmp.utils.SNMPUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.snmp4j.Snmp;
+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.Integer32;
+import org.snmp4j.smi.OctetString;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.util.List;
+import java.util.Scanner;
+
+public class SNMPTrapReceiverHandler {
+
+ private static final Logger logger = LoggerFactory.getLogger(SNMPTrapReceiverHandler.class);
+
+ private final SNMPConfiguration configuration;
+ private final String usmUsersFilePath;
+ private Snmp snmpManager;
+ private boolean isStarted;
+
+ public SNMPTrapReceiverHandler(final SNMPConfiguration configuration, final String usmUsersFilePath) {
+ this.configuration = configuration;
+ this.usmUsersFilePath = usmUsersFilePath;
+ snmpManager = new SNMPManagerFactory().createSnmpManagerInstance(configuration);
+ }
+
+ public void createTrapReceiver(final ProcessSessionFactory processSessionFactory, final ComponentLog logger) {
+ addUsmUsers();
+ SNMPTrapReceiver trapReceiver = new SNMPTrapReceiver(processSessionFactory, logger);
+ snmpManager.addCommandResponder(trapReceiver);
+ isStarted = true;
+ }
+
+ public boolean isStarted() {
+ return isStarted;
+ }
+
+ public void close() {
+ try {
+ if (snmpManager.getUSM() != null) {
+ snmpManager.getUSM().removeAllUsers();
+ SecurityModels.getInstance().removeSecurityModel(new Integer32(snmpManager.getUSM().getID()));
+ }
+ snmpManager.close();
+ isStarted = false;
+ } catch (IOException e) {
+ final String errorMessage = "Could not close SNMP manager.";
+ logger.error(errorMessage, e);
+ throw new ProcessException(errorMessage);
+ }
+ }
+
+ private void addUsmUsers() {
+ if (configuration.getVersion() == SnmpConstants.version3) {
+ USM usm = new USM(SecurityProtocols.getInstance(), new OctetString(MPv3.createLocalEngineID()), 0);
+ SecurityModels.getInstance().addSecurityModel(usm);
+
+ try (Scanner scanner = new Scanner(new File(usmUsersFilePath))) {
+ final String content = scanner.useDelimiter("\\Z").next();
+ final ObjectMapper mapper = new ObjectMapper();
+ final List userDetails = mapper.readValue(content, new TypeReference>() {
+ });
+ userDetails.stream()
+ .map(this::convertToUsmUser)
+ .forEach(user -> snmpManager.getUSM().addUser(user));
+
+ } catch (FileNotFoundException e) {
+ throw new ProcessException("USM user file not found, please check the file path and file permissions.", e);
+ } catch (JsonProcessingException e) {
+ throw new ProcessException("Could not parse USM user file, please check the processor details for examples.", e);
+ }
+ }
+ }
+
+ private UsmUser convertToUsmUser(final UserDetails user) {
+ return new UsmUser(
+ new OctetString(user.getSecurityName()),
+ SNMPUtils.getAuth(user.getAuthProtocol()),
+ new OctetString(user.getAuthPassphrase()),
+ SNMPUtils.getPriv(user.getPrivProtocol()),
+ new OctetString(user.getPrivPassphrase())
+ );
+ }
+
+ // Visible for testing.
+ void setSnmpManager(final Snmp snmpManager) {
+ this.snmpManager = snmpManager;
+ }
+}
diff --git a/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/main/java/org/apache/nifi/snmp/operations/SendTrapSNMPHandler.java b/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/main/java/org/apache/nifi/snmp/operations/SendTrapSNMPHandler.java
new file mode 100644
index 0000000000..f9f608d670
--- /dev/null
+++ b/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/main/java/org/apache/nifi/snmp/operations/SendTrapSNMPHandler.java
@@ -0,0 +1,75 @@
+/*
+ * 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.operations;
+
+import org.apache.nifi.logging.ComponentLog;
+import org.apache.nifi.snmp.configuration.V1TrapConfiguration;
+import org.apache.nifi.snmp.configuration.V2TrapConfiguration;
+import org.apache.nifi.snmp.factory.trap.V1TrapPDUFactory;
+import org.apache.nifi.snmp.factory.trap.V2TrapPDUFactory;
+import org.apache.nifi.snmp.utils.SNMPUtils;
+import org.snmp4j.PDU;
+import org.snmp4j.Snmp;
+import org.snmp4j.Target;
+
+import java.io.IOException;
+import java.time.Instant;
+import java.util.Map;
+
+public class SendTrapSNMPHandler {
+ private final SNMPResourceHandler snmpResourceHandler;
+ private final ComponentLog logger;
+ private final V1TrapPDUFactory v1TrapPDUFactory;
+ private final V2TrapPDUFactory v2TrapPDUFactory;
+
+ public SendTrapSNMPHandler(final SNMPResourceHandler snmpResourceHandler, final Instant startTime, final ComponentLog logger) {
+ this.snmpResourceHandler = snmpResourceHandler;
+ this.logger = logger;
+ v1TrapPDUFactory = createV1TrapPduFactory(startTime);
+ v2TrapPDUFactory = createV2TrapPduFactory(startTime);
+ }
+
+ public void sendTrap(final Map flowFileAttributes, final V1TrapConfiguration trapConfiguration) throws IOException {
+ final PDU pdu = v1TrapPDUFactory.get(trapConfiguration);
+ sendTrap(flowFileAttributes, pdu);
+ }
+
+ public void sendTrap(final Map flowFileAttributes, final V2TrapConfiguration trapConfiguration) throws IOException {
+ final PDU pdu = v2TrapPDUFactory.get(trapConfiguration);
+ sendTrap(flowFileAttributes, pdu);
+ }
+
+ private void sendTrap(Map flowFileAttributes, PDU pdu) throws IOException {
+ final Target target = snmpResourceHandler.getTarget();
+ final Snmp snmpManager = snmpResourceHandler.getSnmpManager();
+
+ final boolean isAnyVariableAdded = SNMPUtils.addVariables(pdu, flowFileAttributes);
+ if (!isAnyVariableAdded) {
+ logger.debug("No optional SNMP specific variables found in flowfile.");
+ }
+
+ snmpManager.send(pdu, target);
+ }
+
+ V1TrapPDUFactory createV1TrapPduFactory(final Instant startTime) {
+ return new V1TrapPDUFactory(snmpResourceHandler.getTarget(), startTime);
+ }
+
+ V2TrapPDUFactory createV2TrapPduFactory(final Instant startTime) {
+ return new V2TrapPDUFactory(snmpResourceHandler.getTarget(), startTime);
+ }
+}
\ No newline at end of file
diff --git a/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/main/java/org/apache/nifi/snmp/operations/SetSNMPHandler.java b/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/main/java/org/apache/nifi/snmp/operations/SetSNMPHandler.java
new file mode 100644
index 0000000000..f77c4eb33d
--- /dev/null
+++ b/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/main/java/org/apache/nifi/snmp/operations/SetSNMPHandler.java
@@ -0,0 +1,66 @@
+/*
+ * 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.operations;
+
+import org.apache.nifi.snmp.dto.SNMPSingleResponse;
+import org.apache.nifi.snmp.exception.RequestTimeoutException;
+import org.apache.nifi.snmp.utils.SNMPUtils;
+import org.snmp4j.PDU;
+import org.snmp4j.Snmp;
+import org.snmp4j.Target;
+import org.snmp4j.event.ResponseEvent;
+import org.snmp4j.util.DefaultPDUFactory;
+import org.snmp4j.util.PDUFactory;
+
+import java.io.IOException;
+import java.util.Map;
+import java.util.Optional;
+
+import static org.apache.nifi.snmp.operations.SNMPResourceHandler.REQUEST_TIMEOUT_EXCEPTION_TEMPLATE;
+
+public class SetSNMPHandler {
+ private static PDUFactory setPduFactory = new DefaultPDUFactory(PDU.SET);
+
+ private final SNMPResourceHandler snmpResourceHandler;
+
+ public SetSNMPHandler(final SNMPResourceHandler snmpResourceHandler) {
+ this.snmpResourceHandler = snmpResourceHandler;
+ }
+
+ public Optional set(final Map flowFileAttributes) throws IOException {
+ Target target = snmpResourceHandler.getTarget();
+ Snmp snmpManager = snmpResourceHandler.getSnmpManager();
+
+ final PDU pdu = setPduFactory.createPDU(target);
+ final boolean isAnySnmpVariableInFlowFile = SNMPUtils.addVariables(pdu, flowFileAttributes);
+ if (isAnySnmpVariableInFlowFile) {
+ final ResponseEvent response = snmpManager.set(pdu, target);
+ final PDU responsePdu = response.getResponse();
+ if (responsePdu == null) {
+ throw new RequestTimeoutException(String.format(REQUEST_TIMEOUT_EXCEPTION_TEMPLATE, "write"));
+ }
+ return Optional.of(new SNMPSingleResponse(target, responsePdu));
+ } else {
+ return Optional.empty();
+ }
+ }
+
+ // visible for testing
+ static void setSetPduFactory(final PDUFactory setPduFactory) {
+ SetSNMPHandler.setPduFactory = setPduFactory;
+ }
+}
diff --git a/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/main/java/org/apache/nifi/snmp/operations/StandardSNMPRequestHandler.java b/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/main/java/org/apache/nifi/snmp/operations/StandardSNMPRequestHandler.java
deleted file mode 100644
index 47ce736b6a..0000000000
--- a/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/main/java/org/apache/nifi/snmp/operations/StandardSNMPRequestHandler.java
+++ /dev/null
@@ -1,148 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.nifi.snmp.operations;
-
-import org.apache.nifi.flowfile.FlowFile;
-import org.apache.nifi.snmp.dto.SNMPSingleResponse;
-import org.apache.nifi.snmp.dto.SNMPTreeResponse;
-import org.apache.nifi.snmp.exception.CloseSNMPClientException;
-import org.apache.nifi.snmp.exception.InvalidFlowFileException;
-import org.apache.nifi.snmp.exception.RequestTimeoutException;
-import org.apache.nifi.snmp.exception.SNMPWalkException;
-import org.apache.nifi.snmp.utils.SNMPUtils;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.snmp4j.PDU;
-import org.snmp4j.Snmp;
-import org.snmp4j.Target;
-import org.snmp4j.event.ResponseEvent;
-import org.snmp4j.security.SecurityModels;
-import org.snmp4j.smi.Integer32;
-import org.snmp4j.smi.OID;
-import org.snmp4j.smi.VariableBinding;
-import org.snmp4j.util.DefaultPDUFactory;
-import org.snmp4j.util.PDUFactory;
-import org.snmp4j.util.TreeEvent;
-import org.snmp4j.util.TreeUtils;
-
-import java.io.IOException;
-import java.util.List;
-
-final class StandardSNMPRequestHandler implements SNMPRequestHandler {
-
- private static final Logger logger = LoggerFactory.getLogger(StandardSNMPRequestHandler.class);
- private static final PDUFactory getPduFactory = new DefaultPDUFactory(PDU.GET);
- private static final PDUFactory setPduFactory = new DefaultPDUFactory(PDU.SET);
- private final Snmp snmpManager;
- private final Target target;
-
- StandardSNMPRequestHandler(final Snmp snmpManager, final Target target) {
- this.snmpManager = snmpManager;
- this.target = target;
- }
-
- /**
- * Construct the PDU to perform the SNMP Get request and returns
- * the result in order to create the flow file.
- *
- * @return {@link ResponseEvent}
- */
- public SNMPSingleResponse get(final String oid) throws IOException {
- final PDU pdu = getPduFactory.createPDU(target);
- pdu.add(new VariableBinding(new OID(oid)));
- final ResponseEvent response = snmpManager.get(pdu, target);
- final PDU responsePdu = response.getResponse();
- if (responsePdu == null) {
- throw new RequestTimeoutException("Request timed out. Please check if (1). the agent host and port is correctly set, " +
- "(2). the agent is running, (3). the agent SNMP version corresponds with the processor's one, (4) the " +
- "community string is correct and has read access, (5) In case of SNMPv3 check if the user credentials " +
- "are valid and the user in a group with read access.");
- }
- return new SNMPSingleResponse(target, responsePdu);
- }
-
- /**
- * Perform a SNMP walk and returns the list of {@link TreeEvent}
- *
- * @return the list of {@link TreeEvent}
- */
- public SNMPTreeResponse walk(final String oid) {
- final TreeUtils treeUtils = new TreeUtils(snmpManager, getPduFactory);
- final List subtree = treeUtils.getSubtree(target, new OID(oid));
- if (subtree.isEmpty()) {
- throw new SNMPWalkException(String.format("The subtree associated with the specified OID %s is empty.", oid));
- }
- if (isSnmpError(subtree)) {
- throw new SNMPWalkException("Agent is not available, OID not found or user not found. Please, check if (1) the " +
- "agent is available, (2) the processor's SNMP version matches the agent version, (3) the OID is " +
- "correct, (4) The user is valid.");
- }
- if (isLeafElement(subtree)) {
- throw new SNMPWalkException(String.format("OID not found or it is a single leaf element. The leaf element " +
- "associated with this %s OID does not contain child OIDs. Please check if the OID exists in the agent " +
- "MIB or specify a parent OID with at least one child element", oid));
- }
-
- return new SNMPTreeResponse(target, subtree);
- }
-
- private boolean isSnmpError(final List subtree) {
- return subtree.size() == 1 && subtree.get(0).getVariableBindings() == null;
- }
-
- private boolean isLeafElement(final List subtree) {
- return subtree.size() == 1 && subtree.get(0).getVariableBindings().length == 0;
- }
-
- /**
- * Executes the SNMP set request and returns the response.
- *
- * @param flowFile FlowFile which contains variables for the PDU
- * @return Response event
- * @throws IOException IO Exception
- */
- public SNMPSingleResponse set(final FlowFile flowFile) throws IOException {
- final PDU pdu = setPduFactory.createPDU(target);
- if (SNMPUtils.addVariables(pdu, flowFile.getAttributes())) {
- final ResponseEvent response = snmpManager.set(pdu, target);
- final PDU responsePdu = response.getResponse();
- if (responsePdu == null) {
- throw new RequestTimeoutException("Request timed out. Please check if (1). the agent host and port is correctly set, " +
- "(2). the agent is running, (3). the agent SNMP version corresponds with the processor's one, (4) the " +
- "community string is correct and has write access, (5) In case of SNMPv3 check if the user credentials " +
- "are valid and the user in a group with write access.");
- }
- return new SNMPSingleResponse(target, responsePdu);
- }
- throw new InvalidFlowFileException("Could not read the variable bindings from the flowfile. Please, " +
- "add the OIDs to set in separate properties. E.g. Property name: snmp$1.3.6.1.2.1.1.1.0 Value: Example value. ");
- }
-
- public void close() {
- try {
- if (snmpManager.getUSM() != null) {
- snmpManager.getUSM().removeAllUsers();
- SecurityModels.getInstance().removeSecurityModel(new Integer32(snmpManager.getUSM().getID()));
- }
- snmpManager.close();
- } catch (IOException e) {
- final String errorMessage = "Could not close SNMP client.";
- logger.error(errorMessage, e);
- throw new CloseSNMPClientException(errorMessage);
- }
- }
-}
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
index 7b9c5d080f..43c3a1095d 100644
--- 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
@@ -19,7 +19,6 @@ package org.apache.nifi.snmp.processors;
import org.apache.nifi.annotation.behavior.RequiresInstanceClassLoading;
import org.apache.nifi.annotation.lifecycle.OnScheduled;
import org.apache.nifi.annotation.lifecycle.OnStopped;
-import org.apache.nifi.components.AllowableValue;
import org.apache.nifi.components.PropertyDescriptor;
import org.apache.nifi.flowfile.FlowFile;
import org.apache.nifi.processor.AbstractProcessor;
@@ -27,21 +26,20 @@ import org.apache.nifi.processor.ProcessContext;
import org.apache.nifi.processor.ProcessSession;
import org.apache.nifi.processor.Relationship;
import org.apache.nifi.processor.util.StandardValidators;
-import org.apache.nifi.reporting.InitializationException;
import org.apache.nifi.snmp.configuration.SNMPConfiguration;
-import org.apache.nifi.snmp.configuration.SNMPConfigurationBuilder;
+import org.apache.nifi.snmp.dto.ErrorStatus;
+import org.apache.nifi.snmp.dto.SNMPResponseStatus;
import org.apache.nifi.snmp.dto.SNMPSingleResponse;
import org.apache.nifi.snmp.dto.SNMPValue;
-import org.apache.nifi.snmp.exception.SNMPException;
+import org.apache.nifi.snmp.factory.core.SNMPFactoryProvider;
import org.apache.nifi.snmp.logging.SLF4JLogFactory;
-import org.apache.nifi.snmp.operations.SNMPRequestHandler;
-import org.apache.nifi.snmp.operations.SNMPRequestHandlerFactory;
+import org.apache.nifi.snmp.operations.SNMPResourceHandler;
+import org.apache.nifi.snmp.processors.properties.BasicProperties;
+import org.apache.nifi.snmp.processors.properties.V3SecurityProperties;
import org.apache.nifi.snmp.utils.SNMPUtils;
import org.snmp4j.log.LogFactory;
import org.snmp4j.mp.SnmpConstants;
-import java.util.HashMap;
-import java.util.Map;
import java.util.Optional;
/**
@@ -55,49 +53,7 @@ abstract class AbstractSNMPProcessor extends AbstractProcessor {
LogFactory.setLogFactory(new SLF4JLogFactory());
}
- private static final String SHA_2_ALGORITHM = "Provides authentication based on the HMAC-SHA-2 algorithm.";
private static final String NO_SUCH_OBJECT = "noSuchObject";
- // SNMP versions
- public static final AllowableValue SNMP_V1 = new AllowableValue("SNMPv1", "v1", "SNMP version 1");
- public static final AllowableValue SNMP_V2C = new AllowableValue("SNMPv2c", "v2c", "SNMP version 2c");
- public static final AllowableValue SNMP_V3 = new AllowableValue("SNMPv3", "v3", "SNMP version 3 with improved security");
-
- // SNMPv3 security levels
- public static final AllowableValue NO_AUTH_NO_PRIV = new AllowableValue("noAuthNoPriv", "noAuthNoPriv",
- "No authentication or encryption.");
- public static final AllowableValue AUTH_NO_PRIV = new AllowableValue("authNoPriv", "authNoPriv",
- "Authentication without encryption.");
- public static final AllowableValue AUTH_PRIV = new AllowableValue("authPriv", "authPriv",
- "Authentication and encryption.");
-
- // SNMPv3 authentication protocols
- public static final AllowableValue MD5 = new AllowableValue("MD5", "MD5",
- "Provides authentication based on the HMAC-MD5 algorithm.");
- public static final AllowableValue SHA = new AllowableValue("SHA", "SHA",
- "Provides authentication based on the HMAC-SHA algorithm.");
- public static final AllowableValue HMAC128SHA224 = new AllowableValue("HMAC128SHA224", "SHA224",
- SHA_2_ALGORITHM);
- public static final AllowableValue HMAC192SHA256 = new AllowableValue("HMAC192SHA256", "SHA256",
- SHA_2_ALGORITHM);
- public static final AllowableValue HMAC256SHA384 = new AllowableValue("HMAC256SHA384", "SHA384",
- SHA_2_ALGORITHM);
- public static final AllowableValue HMAC384SHA512 = new AllowableValue("HMAC384SHA512", "SHA512",
- SHA_2_ALGORITHM);
-
- // SNMPv3 encryption
- public static final AllowableValue DES = new AllowableValue("DES", "DES",
- "Symmetric-key algorithm for the encryption of digital data. DES has been considered insecure" +
- "because of the feasilibity of brute-force attacks. We recommend using the AES encryption protocol.");
- public static final AllowableValue DES3 = new AllowableValue("3DES", "3DES",
- "Symmetric-key block cipher, which applies the DES cipher algorithm three times to each data block." +
- " 3DES has been considered insecure has been deprecated by NIST in 2017. We recommend using the AES encryption protocol.");
-
- private static final String AES_DESCRIPTION = "AES is a symmetric algorithm which uses the same 128, 192, or 256 bit" +
- " key for both encryption and decryption (the security of an AES system increases exponentially with key length).";
-
- public static final AllowableValue AES128 = new AllowableValue("AES128", "AES128", AES_DESCRIPTION);
- public static final AllowableValue AES192 = new AllowableValue("AES192", "AES192", AES_DESCRIPTION);
- public static final AllowableValue AES256 = new AllowableValue("AES256", "AES256", AES_DESCRIPTION);
public static final PropertyDescriptor AGENT_HOST = new PropertyDescriptor.Builder()
.name("snmp-hostname")
@@ -117,136 +73,31 @@ abstract class AbstractSNMPProcessor extends AbstractProcessor {
.addValidator(StandardValidators.PORT_VALIDATOR)
.build();
- public static final PropertyDescriptor SNMP_VERSION = new PropertyDescriptor.Builder()
- .name("snmp-version")
- .displayName("SNMP Version")
- .description("Three significant versions of SNMP have been developed and deployed. " +
- "SNMPv1 is the original version of the protocol. More recent versions, " +
- "SNMPv2c and SNMPv3, feature improvements in performance, flexibility and security.")
- .required(true)
- .allowableValues(SNMP_V1, SNMP_V2C, SNMP_V3)
- .defaultValue(SNMP_V1.getValue())
- .build();
-
- public static final PropertyDescriptor SNMP_COMMUNITY = new PropertyDescriptor.Builder()
- .name("snmp-community")
- .displayName("SNMP Community")
- .description("SNMPv1 and SNMPv2 use communities to establish trust between managers and agents." +
- " Most agents support three community names, one each for read-only, read-write and trap." +
- " These three community strings control different types of activities. The read-only community" +
- " applies to get requests. The read-write community string applies to set requests. The trap" +
- " community string applies to receipt of traps.")
- .required(true)
- .sensitive(true)
- .defaultValue("public")
- .addValidator(StandardValidators.NON_EMPTY_VALIDATOR)
- .dependsOn(SNMP_VERSION, SNMP_V1, SNMP_V2C)
- .build();
-
- public static final PropertyDescriptor SNMP_SECURITY_LEVEL = new PropertyDescriptor.Builder()
- .name("snmp-security-level")
- .displayName("SNMP Security Level")
- .description("SNMP version 3 provides extra security with User Based Security Model (USM). The three levels of security is " +
- "1. Communication without authentication and encryption (NoAuthNoPriv). " +
- "2. Communication with authentication and without encryption (AuthNoPriv). " +
- "3. Communication with authentication and encryption (AuthPriv).")
- .required(true)
- .allowableValues(NO_AUTH_NO_PRIV, AUTH_NO_PRIV, AUTH_PRIV)
- .defaultValue(NO_AUTH_NO_PRIV.getValue())
- .dependsOn(SNMP_VERSION, SNMP_V3)
- .build();
-
- public static final PropertyDescriptor SNMP_SECURITY_NAME = new PropertyDescriptor.Builder()
- .name("snmp-security-name")
- .displayName("SNMP Security Name")
- .description("User name used for SNMP v3 Authentication.")
- .required(true)
- .addValidator(StandardValidators.NON_EMPTY_VALIDATOR)
- .dependsOn(SNMP_VERSION, SNMP_V3)
- .build();
-
- public static final PropertyDescriptor SNMP_AUTH_PROTOCOL = new PropertyDescriptor.Builder()
- .name("snmp-authentication-protocol")
- .displayName("SNMP Authentication Protocol")
- .description("Hash based authentication protocol for secure authentication.")
- .required(true)
- .allowableValues(MD5, SHA, HMAC128SHA224, HMAC192SHA256, HMAC256SHA384, HMAC384SHA512)
- .dependsOn(SNMP_SECURITY_LEVEL, AUTH_NO_PRIV, AUTH_PRIV)
- .build();
-
- public static final PropertyDescriptor SNMP_AUTH_PASSWORD = new PropertyDescriptor.Builder()
- .name("snmp-authentication-passphrase")
- .displayName("SNMP Authentication Passphrase")
- .description("Passphrase used for SNMP authentication protocol.")
- .required(true)
- .addValidator(StandardValidators.NON_EMPTY_VALIDATOR)
- .sensitive(true)
- .dependsOn(SNMP_SECURITY_LEVEL, AUTH_NO_PRIV, AUTH_PRIV)
- .build();
-
- public static final PropertyDescriptor SNMP_PRIVACY_PROTOCOL = new PropertyDescriptor.Builder()
- .name("snmp-private-protocol")
- .displayName("SNMP Privacy Protocol")
- .description("Privacy allows for encryption of SNMP v3 messages to ensure confidentiality of data.")
- .required(true)
- .allowableValues(DES, DES3, AES128, AES192, AES256)
- .dependsOn(SNMP_SECURITY_LEVEL, AUTH_PRIV)
- .build();
-
- public static final PropertyDescriptor SNMP_PRIVACY_PASSWORD = new PropertyDescriptor.Builder()
- .name("snmp-private-protocol-passphrase")
- .displayName("SNMP Privacy Passphrase")
- .description("Passphrase used for SNMP privacy protocol.")
- .required(true)
- .addValidator(StandardValidators.NON_EMPTY_VALIDATOR)
- .sensitive(true)
- .dependsOn(SNMP_SECURITY_LEVEL, AUTH_PRIV)
- .build();
-
- 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(false)
- .defaultValue("0")
- .addValidator(StandardValidators.NON_NEGATIVE_INTEGER_VALIDATOR)
- .build();
-
- 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(false)
- .defaultValue("5000")
- .addValidator(StandardValidators.NON_NEGATIVE_INTEGER_VALIDATOR)
- .build();
-
-
- protected volatile SNMPRequestHandler snmpRequestHandler;
+ protected volatile SNMPResourceHandler snmpResourceHandler;
@OnScheduled
- public void initSnmpManager(final ProcessContext context) throws InitializationException {
- final int version = SNMPUtils.getVersion(context.getProperty(SNMP_VERSION).getValue());
+ public void initSnmpManager(final ProcessContext context) {
+ final int version = SNMPUtils.getVersion(context.getProperty(BasicProperties.SNMP_VERSION).getValue());
final SNMPConfiguration configuration;
- try {
- configuration = new SNMPConfigurationBuilder()
- .setAgentHost(context.getProperty(AGENT_HOST).getValue())
- .setAgentPort(context.getProperty(AGENT_PORT).toString())
- .setRetries(context.getProperty(SNMP_RETRIES).asInteger())
- .setTimeout(context.getProperty(SNMP_TIMEOUT).asInteger())
- .setVersion(version)
- .setAuthProtocol(context.getProperty(SNMP_AUTH_PROTOCOL).getValue())
- .setAuthPassphrase(context.getProperty(SNMP_AUTH_PASSWORD).getValue())
- .setPrivacyProtocol(context.getProperty(SNMP_PRIVACY_PROTOCOL).getValue())
- .setPrivacyPassphrase(context.getProperty(SNMP_PRIVACY_PASSWORD).getValue())
- .setSecurityName(context.getProperty(SNMP_SECURITY_NAME).getValue())
- .setSecurityLevel(context.getProperty(SNMP_SECURITY_LEVEL).getValue())
- .setCommunityString(context.getProperty(SNMP_COMMUNITY).getValue())
- .build();
- } catch (IllegalStateException e) {
- throw new InitializationException(e);
- }
- snmpRequestHandler = SNMPRequestHandlerFactory.createStandardRequestHandler(configuration);
+ final String targetHost = getTargetHost(context);
+ final String targetPort = getTargetPort(context);
+
+ configuration = SNMPConfiguration.builder()
+ .setTargetHost(targetHost)
+ .setTargetPort(targetPort)
+ .setRetries(context.getProperty(BasicProperties.SNMP_RETRIES).asInteger())
+ .setTimeoutInMs(context.getProperty(BasicProperties.SNMP_TIMEOUT).asInteger())
+ .setVersion(version)
+ .setAuthProtocol(context.getProperty(V3SecurityProperties.SNMP_AUTH_PROTOCOL).getValue())
+ .setAuthPassphrase(context.getProperty(V3SecurityProperties.SNMP_AUTH_PASSWORD).getValue())
+ .setPrivacyProtocol(context.getProperty(V3SecurityProperties.SNMP_PRIVACY_PROTOCOL).getValue())
+ .setPrivacyPassphrase(context.getProperty(V3SecurityProperties.SNMP_PRIVACY_PASSWORD).getValue())
+ .setSecurityName(context.getProperty(V3SecurityProperties.SNMP_SECURITY_NAME).getValue())
+ .setSecurityLevel(context.getProperty(V3SecurityProperties.SNMP_SECURITY_LEVEL).getValue())
+ .setCommunityString(context.getProperty(BasicProperties.SNMP_COMMUNITY).getValue())
+ .build();
+
+ snmpResourceHandler = SNMPFactoryProvider.getFactory(version).createSNMPResourceHandler(configuration);
}
/**
@@ -254,61 +105,61 @@ abstract class AbstractSNMPProcessor extends AbstractProcessor {
*/
@OnStopped
public void close() {
- if (snmpRequestHandler != null) {
- snmpRequestHandler.close();
- snmpRequestHandler = null;
+ if (snmpResourceHandler != null) {
+ snmpResourceHandler.close();
+ snmpResourceHandler = null;
}
}
- /**
- * 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
- */
- protected FlowFile addAttribute(final String key, final String value, FlowFile flowFile, final ProcessSession processSession) {
- final Map attributes = new HashMap<>();
- attributes.put(key, value);
- flowFile = processSession.putAllAttributes(flowFile, attributes);
- return flowFile;
+ protected void handleResponse(final ProcessContext context, final ProcessSession processSession, final FlowFile flowFile, final SNMPSingleResponse response,
+ final Relationship success, final Relationship failure, final String provenanceAddress) {
+ final SNMPResponseStatus snmpResponseStatus = processResponse(response);
+ processSession.putAllAttributes(flowFile, response.getAttributes());
+ if (snmpResponseStatus.getErrorStatus() == ErrorStatus.FAILURE) {
+ getLogger().error("SNMP request failed, response error: " + snmpResponseStatus.getErrorMessage());
+ processSession.getProvenanceReporter().modifyAttributes(flowFile, response.getTargetAddress() + provenanceAddress);
+ processSession.transfer(flowFile, failure);
+ context.yield();
+ } else {
+ processSession.getProvenanceReporter().modifyAttributes(flowFile, response.getTargetAddress() + provenanceAddress);
+ processSession.transfer(flowFile, success);
+ }
}
- protected void processResponse(final ProcessSession processSession, FlowFile flowFile, final SNMPSingleResponse response,
- final String provenanceAddress, final Relationship success) {
+ protected SNMPResponseStatus processResponse(final SNMPSingleResponse response) {
if (response.isValid()) {
if (response.isReportPdu()) {
final String oid = response.getVariableBindings().get(0).getOid();
final Optional reportPduErrorMessage = SNMPUtils.getErrorMessage(oid);
if (!reportPduErrorMessage.isPresent()) {
- throw new SNMPException(String.format("SNMP request failed, Report-PDU returned, but no error message found. " +
- "Please, check the OID %s in an online OID repository.", oid));
+ return new SNMPResponseStatus(String.format("Report-PDU returned, but no error message found. " +
+ "Please, check the OID %s in an online OID repository.", oid), ErrorStatus.FAILURE);
}
- throw new SNMPException("SNMPRequest failed, Report-PDU returned. " + reportPduErrorMessage.get());
+ return new SNMPResponseStatus("Report-PDU returned. " + reportPduErrorMessage.get(), ErrorStatus.FAILURE);
}
- checkV2cV3VariableBindings(response);
- flowFile = processSession.putAllAttributes(flowFile, response.getAttributes());
- processSession.transfer(flowFile, success);
- processSession.getProvenanceReporter().receive(flowFile, provenanceAddress);
+ return checkV2cV3VariableBindings(response);
} else {
- final String error = response.getErrorStatusText();
- throw new SNMPException("SNMP request failed, response error: " + error);
+ final String errorMessage = response.getErrorStatusText();
+ return new SNMPResponseStatus(errorMessage, ErrorStatus.FAILURE);
}
}
- private void checkV2cV3VariableBindings(SNMPSingleResponse response) {
- if (response.getVersion() != SnmpConstants.version1) {
+ private SNMPResponseStatus checkV2cV3VariableBindings(SNMPSingleResponse response) {
+ if (response.getVersion() == SnmpConstants.version2c || response.getVersion() == SnmpConstants.version3) {
final Optional firstVariableBinding = response.getVariableBindings().stream().findFirst();
if (firstVariableBinding.isPresent()) {
final String value = firstVariableBinding.get().getVariable();
if (NO_SUCH_OBJECT.equals(value)) {
- throw new SNMPException("SNMP Request failed, OID not found.");
+ return new SNMPResponseStatus("OID not found.", ErrorStatus.FAILURE);
}
} else {
- throw new SNMPException("Empty SNMP response: no variable binding found.");
+ return new SNMPResponseStatus("Empty SNMP response: no variable binding found.", ErrorStatus.FAILURE);
}
}
+ return new SNMPResponseStatus("Successful SNMP Response", ErrorStatus.SUCCESS);
}
+
+ protected abstract String getTargetHost(ProcessContext processContext);
+
+ protected abstract String getTargetPort(ProcessContext processContext);
}
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
index 58a08bde66..2aa29ab8ef 100644
--- 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
@@ -22,6 +22,7 @@ import org.apache.nifi.annotation.behavior.WritesAttribute;
import org.apache.nifi.annotation.behavior.WritesAttributes;
import org.apache.nifi.annotation.documentation.CapabilityDescription;
import org.apache.nifi.annotation.documentation.Tags;
+import org.apache.nifi.annotation.lifecycle.OnScheduled;
import org.apache.nifi.components.AllowableValue;
import org.apache.nifi.components.PropertyDescriptor;
import org.apache.nifi.flowfile.FlowFile;
@@ -31,8 +32,10 @@ import org.apache.nifi.processor.Relationship;
import org.apache.nifi.processor.util.StandardValidators;
import org.apache.nifi.snmp.dto.SNMPSingleResponse;
import org.apache.nifi.snmp.dto.SNMPTreeResponse;
-import org.apache.nifi.snmp.exception.SNMPException;
import org.apache.nifi.snmp.exception.SNMPWalkException;
+import org.apache.nifi.snmp.operations.GetSNMPHandler;
+import org.apache.nifi.snmp.processors.properties.BasicProperties;
+import org.apache.nifi.snmp.processors.properties.V3SecurityProperties;
import org.apache.nifi.snmp.utils.SNMPUtils;
import org.apache.nifi.snmp.validators.OIDValidator;
@@ -41,16 +44,20 @@ import java.util.Arrays;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
+import java.util.Map;
+import java.util.Optional;
import java.util.Set;
/**
- * 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.
+ * Performs an SNMP Get operation based on processor or incoming FlowFile attributes.
+ * Upon each invocation of {@link #onTrigger(ProcessContext, ProcessSession)}
+ * method, in case of a valid incoming FlowFile, it will inspect the attributes of
+ * the FlowFile and look for attributes with name formatted as "snmp$OID" to set the
+ * attribute value to this OID.
* The output {@link FlowFile} won't have any content.
*/
@Tags({"snmp", "get", "oid", "walk"})
-@InputRequirement(Requirement.INPUT_FORBIDDEN)
+@InputRequirement(Requirement.INPUT_ALLOWED)
@CapabilityDescription("Retrieves information from SNMP Agent with SNMP Get request and outputs a FlowFile with information" +
" in attributes and without any content")
@WritesAttributes({
@@ -74,11 +81,12 @@ public class GetSNMP extends AbstractSNMPProcessor {
"A manager-to-agent request to retrieve the value of multiple variables. Snmp WALK also traverses all subnodes " +
"under the specified OID.");
- // 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("Each OID (object identifier) identifies a variable that can be read or set via SNMP.")
+ .description("Each OID (object identifier) identifies a variable that can be read or set via SNMP." +
+ " This value is not taken into account for an input flowfile and will be omitted. Can be set to empty" +
+ "string when the OIDs are provided through flowfile.")
.required(true)
.addValidator(new OIDValidator())
.build();
@@ -95,7 +103,8 @@ public class GetSNMP extends AbstractSNMPProcessor {
public static final PropertyDescriptor TEXTUAL_OID = new PropertyDescriptor.Builder()
.name("snmp-textual-oid")
.displayName("Textual OID")
- .description("The textual OID to request.")
+ .description("The textual form of the numeric OID to request. This property is user defined, not processed and appended to " +
+ "the outgoing flowfile.")
.required(false)
.addValidator(StandardValidators.NON_BLANK_VALIDATOR)
.defaultValue(null)
@@ -114,16 +123,16 @@ public class GetSNMP extends AbstractSNMPProcessor {
protected static final List PROPERTY_DESCRIPTORS = Collections.unmodifiableList(Arrays.asList(
AGENT_HOST,
AGENT_PORT,
- SNMP_VERSION,
- SNMP_COMMUNITY,
- SNMP_SECURITY_LEVEL,
- SNMP_SECURITY_NAME,
- SNMP_AUTH_PROTOCOL,
- SNMP_AUTH_PASSWORD,
- SNMP_PRIVACY_PROTOCOL,
- SNMP_PRIVACY_PASSWORD,
- SNMP_RETRIES,
- SNMP_TIMEOUT,
+ BasicProperties.SNMP_VERSION,
+ BasicProperties.SNMP_COMMUNITY,
+ V3SecurityProperties.SNMP_SECURITY_LEVEL,
+ V3SecurityProperties.SNMP_SECURITY_NAME,
+ V3SecurityProperties.SNMP_AUTH_PROTOCOL,
+ V3SecurityProperties.SNMP_AUTH_PASSWORD,
+ V3SecurityProperties.SNMP_PRIVACY_PROTOCOL,
+ V3SecurityProperties.SNMP_PRIVACY_PASSWORD,
+ BasicProperties.SNMP_RETRIES,
+ BasicProperties.SNMP_TIMEOUT,
OID,
TEXTUAL_OID,
SNMP_STRATEGY
@@ -134,54 +143,100 @@ public class GetSNMP extends AbstractSNMPProcessor {
REL_FAILURE
)));
+ private volatile GetSNMPHandler snmpHandler;
+
+ @OnScheduled
+ public void init(final ProcessContext context) {
+ initSnmpManager(context);
+ snmpHandler = new GetSNMPHandler(snmpResourceHandler);
+ }
+
@Override
public void onTrigger(final ProcessContext context, final ProcessSession processSession) {
final SNMPStrategy snmpStrategy = SNMPStrategy.valueOf(context.getProperty(SNMP_STRATEGY).getValue());
final String oid = context.getProperty(OID).getValue();
+ final FlowFile flowfile = processSession.get();
if (SNMPStrategy.GET == snmpStrategy) {
- performSnmpGet(context, processSession, oid);
+ performSnmpGet(context, processSession, oid, flowfile);
} else if (SNMPStrategy.WALK == snmpStrategy) {
- performSnmpWalk(context, processSession, oid);
+ performSnmpWalk(context, processSession, oid, flowfile);
}
}
- private void performSnmpWalk(final ProcessContext context, final ProcessSession processSession, final String oid) {
+ void performSnmpWalk(final ProcessContext context, final ProcessSession processSession, final String oid,
+ final FlowFile flowFile) {
try {
- final SNMPTreeResponse response = snmpRequestHandler.walk(oid);
- response.logErrors(getLogger());
- FlowFile flowFile = createFlowFileWithTreeEventProperties(response, processSession);
- processSession.getProvenanceReporter().receive(flowFile, response.getTargetAddress() + "/" + oid);
- processSession.transfer(flowFile, REL_SUCCESS);
+ if (flowFile != null) {
+ performSnmpWalkWithFlowFile(processSession, flowFile);
+ } else {
+ performSnmpWalkWithoutFlowFile(processSession, oid);
+ }
} catch (SNMPWalkException e) {
getLogger().error(e.getMessage());
context.yield();
- processSession.rollback();
}
}
- private void performSnmpGet(final ProcessContext context, final ProcessSession processSession, final String oid) {
- final SNMPSingleResponse response;
+ private void performSnmpWalkWithFlowFile(ProcessSession processSession, FlowFile flowFile) {
+ final Optional optionalResponse = snmpHandler.walk(flowFile.getAttributes());
+ if (optionalResponse.isPresent()) {
+ final SNMPTreeResponse response = optionalResponse.get();
+ response.logErrors(getLogger());
+ processSession.putAllAttributes(flowFile, response.getAttributes());
+ processSession.getProvenanceReporter().modifyAttributes(flowFile, response.getTargetAddress() + "/walk");
+ processSession.transfer(flowFile, response.isError() ? REL_FAILURE : REL_SUCCESS);
+ } else {
+ getLogger().warn("No SNMP specific attributes found in flowfile.");
+ processSession.getProvenanceReporter().receive(flowFile, "/walk");
+ processSession.transfer(flowFile, REL_FAILURE);
+ }
+ }
+
+ private void performSnmpWalkWithoutFlowFile(ProcessSession processSession, String oid) {
+ final SNMPTreeResponse response = snmpHandler.walk(oid);
+ response.logErrors(getLogger());
+ final FlowFile outgoingFlowFile = processSession.create();
+ processSession.putAllAttributes(outgoingFlowFile, response.getAttributes());
+ processSession.getProvenanceReporter().create(outgoingFlowFile, response.getTargetAddress() + "/walk");
+ processSession.transfer(outgoingFlowFile, REL_SUCCESS);
+ }
+
+ void performSnmpGet(final ProcessContext context, final ProcessSession processSession, final String oid,
+ final FlowFile flowFile) {
+ final String textualOidKey = SNMPUtils.SNMP_PROP_PREFIX + "textualOid";
+ final Map textualOidMap = Collections.singletonMap(textualOidKey, context.getProperty(TEXTUAL_OID).getValue());
try {
- response = snmpRequestHandler.get(oid);
- final FlowFile flowFile = processSession.create();
- addAttribute(SNMPUtils.SNMP_PROP_PREFIX + "textualOid", context.getProperty(TEXTUAL_OID).getValue(), flowFile, processSession);
- final String provenanceAddress = response.getTargetAddress() + "/" + oid;
- processResponse(processSession, flowFile, response, provenanceAddress, REL_SUCCESS);
- } catch (SNMPException e) {
- getLogger().error(e.getMessage());
- context.yield();
- processSession.rollback();
+ if (flowFile != null) {
+ performSnmpGetWithFlowFile(context, processSession, flowFile, textualOidMap);
+ } else {
+ performSnmpGetWithoutFlowFile(context, processSession, oid, textualOidMap);
+ }
} catch (IOException e) {
- getLogger().error("Failed to send request to the agent. Check if the agent supports the used version.");
+ getLogger().error("Failed to send request to the agent. Check if the agent supports the used version.", e);
context.yield();
- processSession.rollback();
}
}
- @Override
- protected List getSupportedPropertyDescriptors() {
- return PROPERTY_DESCRIPTORS;
+ private void performSnmpGetWithoutFlowFile(ProcessContext context, ProcessSession processSession, String oid, Map textualOidMap) throws IOException {
+ final SNMPSingleResponse response = snmpHandler.get(oid);
+ final FlowFile outgoingFlowFile = processSession.create();
+ processSession.putAllAttributes(outgoingFlowFile, textualOidMap);
+ processSession.getProvenanceReporter().receive(outgoingFlowFile, response.getTargetAddress() + "/get");
+ handleResponse(context, processSession, outgoingFlowFile, response, REL_SUCCESS, REL_FAILURE, "/get");
+ }
+
+ private void performSnmpGetWithFlowFile(ProcessContext context, ProcessSession processSession, FlowFile flowFile, Map textualOidMap) throws IOException {
+ final Optional optionalResponse = snmpHandler.get(flowFile.getAttributes());
+ if (optionalResponse.isPresent()) {
+ final SNMPSingleResponse response = optionalResponse.get();
+ processSession.putAllAttributes(flowFile, textualOidMap);
+ handleResponse(context, processSession, flowFile, response, REL_SUCCESS, REL_FAILURE, "/get");
+ } else {
+ getLogger().warn("No SNMP specific attributes found in flowfile.");
+ processSession.transfer(flowFile, REL_FAILURE);
+ context.yield();
+ }
}
@Override
@@ -189,10 +244,18 @@ public class GetSNMP extends AbstractSNMPProcessor {
return RELATIONSHIPS;
}
- private FlowFile createFlowFileWithTreeEventProperties(final SNMPTreeResponse response, final ProcessSession processSession) {
- FlowFile flowFile = processSession.create();
- flowFile = processSession.putAllAttributes(flowFile, response.getAttributes());
- return flowFile;
+ @Override
+ protected List getSupportedPropertyDescriptors() {
+ return PROPERTY_DESCRIPTORS;
+ }
+
+ protected String getTargetHost(ProcessContext processContext) {
+ return processContext.getProperty(AGENT_HOST).getValue();
+ }
+
+ @Override
+ protected String getTargetPort(ProcessContext processContext) {
+ return processContext.getProperty(AGENT_PORT).getValue();
}
private enum SNMPStrategy {
diff --git a/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/main/java/org/apache/nifi/snmp/processors/ListenTrapSNMP.java b/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/main/java/org/apache/nifi/snmp/processors/ListenTrapSNMP.java
new file mode 100644
index 0000000000..b36ff7d226
--- /dev/null
+++ b/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/main/java/org/apache/nifi/snmp/processors/ListenTrapSNMP.java
@@ -0,0 +1,143 @@
+/*
+ * 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 org.apache.nifi.annotation.behavior.InputRequirement;
+import org.apache.nifi.annotation.behavior.RequiresInstanceClassLoading;
+import org.apache.nifi.annotation.behavior.WritesAttribute;
+import org.apache.nifi.annotation.documentation.CapabilityDescription;
+import org.apache.nifi.annotation.documentation.Tags;
+import org.apache.nifi.annotation.lifecycle.OnScheduled;
+import org.apache.nifi.annotation.lifecycle.OnStopped;
+import org.apache.nifi.components.PropertyDescriptor;
+import org.apache.nifi.flowfile.FlowFile;
+import org.apache.nifi.processor.AbstractSessionFactoryProcessor;
+import org.apache.nifi.processor.ProcessContext;
+import org.apache.nifi.processor.ProcessSessionFactory;
+import org.apache.nifi.processor.Relationship;
+import org.apache.nifi.processor.util.StandardValidators;
+import org.apache.nifi.snmp.configuration.SNMPConfiguration;
+import org.apache.nifi.snmp.operations.SNMPTrapReceiverHandler;
+import org.apache.nifi.snmp.processors.properties.BasicProperties;
+import org.apache.nifi.snmp.processors.properties.V3SecurityProperties;
+import org.apache.nifi.snmp.utils.SNMPUtils;
+
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+/**
+ * Receiving data from a configured SNMP agent which, upon each invocation of
+ * {@link #onTrigger(ProcessContext, ProcessSessionFactory)} method, will construct a
+ * {@link FlowFile} containing in its properties the information retrieved.
+ * The output {@link FlowFile} won't have any content.
+ */
+@Tags({"snmp", "listen", "trap"})
+@InputRequirement(InputRequirement.Requirement.INPUT_FORBIDDEN)
+@CapabilityDescription("Receives information from SNMP Agent and outputs a FlowFile with information in attributes and without any content")
+@WritesAttribute(attribute = SNMPUtils.SNMP_PROP_PREFIX + "*", description = "Attributes retrieved from the SNMP response. It may include:"
+ + " snmp$errorIndex, snmp$errorStatus, snmp$errorStatusText, snmp$nonRepeaters, snmp$requestID, snmp$type, snmp$variableBindings")
+@RequiresInstanceClassLoading
+public class ListenTrapSNMP extends AbstractSessionFactoryProcessor {
+
+ public static final PropertyDescriptor SNMP_MANAGER_PORT = new PropertyDescriptor.Builder()
+ .name("snmp-manager-port")
+ .displayName("SNMP Manager Port")
+ .description("The port where the SNMP Manager listens to the incoming traps.")
+ .required(true)
+ .defaultValue("0")
+ .addValidator(StandardValidators.PORT_VALIDATOR)
+ .build();
+
+ public static final PropertyDescriptor SNMP_USM_USERS_FILE_PATH = new PropertyDescriptor.Builder()
+ .name("snmp-usm-users-file-path")
+ .displayName("SNMP Users File Path")
+ .description("The path of the json file containing the user credentials for SNMPv3. Check Usage for more details.")
+ .required(true)
+ .defaultValue("")
+ .dependsOn(BasicProperties.SNMP_VERSION, BasicProperties.SNMP_V3)
+ .addValidator(StandardValidators.NON_EMPTY_VALIDATOR)
+ .build();
+
+ 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();
+
+ 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();
+
+ protected static final List PROPERTY_DESCRIPTORS = Collections.unmodifiableList(Arrays.asList(
+ SNMP_MANAGER_PORT,
+ BasicProperties.SNMP_VERSION,
+ BasicProperties.SNMP_COMMUNITY,
+ V3SecurityProperties.SNMP_SECURITY_LEVEL,
+ SNMP_USM_USERS_FILE_PATH
+ ));
+
+ private static final Set RELATIONSHIPS = Collections.unmodifiableSet(new HashSet<>(Arrays.asList(
+ REL_SUCCESS,
+ REL_FAILURE
+ )));
+
+ private volatile SNMPTrapReceiverHandler snmpTrapReceiverHandler;
+
+ @OnScheduled
+ public void initSnmpManager(ProcessContext context) {
+ final int version = SNMPUtils.getVersion(context.getProperty(BasicProperties.SNMP_VERSION).getValue());
+ final int managerPort = context.getProperty(SNMP_MANAGER_PORT).asInteger();
+ final String usmUsersFilePath = context.getProperty(SNMP_USM_USERS_FILE_PATH).getValue();
+ SNMPConfiguration configuration;
+
+ configuration = SNMPConfiguration.builder()
+ .setManagerPort(managerPort)
+ .setVersion(version)
+ .setSecurityLevel(context.getProperty(V3SecurityProperties.SNMP_SECURITY_LEVEL).getValue())
+ .setCommunityString(context.getProperty(BasicProperties.SNMP_COMMUNITY).getValue())
+ .build();
+
+ snmpTrapReceiverHandler = new SNMPTrapReceiverHandler(configuration, usmUsersFilePath);
+ }
+
+ @Override
+ public void onTrigger(final ProcessContext context, final ProcessSessionFactory processSessionFactory) {
+ if (!snmpTrapReceiverHandler.isStarted()) {
+ snmpTrapReceiverHandler.createTrapReceiver(processSessionFactory, getLogger());
+ }
+ }
+
+ @OnStopped
+ public void close() {
+ if (snmpTrapReceiverHandler != null) {
+ snmpTrapReceiverHandler.close();
+ }
+ }
+
+ @Override
+ public Set getRelationships() {
+ return RELATIONSHIPS;
+ }
+
+ @Override
+ protected List getSupportedPropertyDescriptors() {
+ return PROPERTY_DESCRIPTORS;
+ }
+}
diff --git a/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/main/java/org/apache/nifi/snmp/processors/SendTrapSNMP.java b/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/main/java/org/apache/nifi/snmp/processors/SendTrapSNMP.java
new file mode 100644
index 0000000000..04b06e62fc
--- /dev/null
+++ b/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/main/java/org/apache/nifi/snmp/processors/SendTrapSNMP.java
@@ -0,0 +1,170 @@
+/*
+ * 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 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.annotation.lifecycle.OnScheduled;
+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.util.StandardValidators;
+import org.apache.nifi.snmp.configuration.V1TrapConfiguration;
+import org.apache.nifi.snmp.configuration.V2TrapConfiguration;
+import org.apache.nifi.snmp.operations.SendTrapSNMPHandler;
+import org.apache.nifi.snmp.processors.properties.BasicProperties;
+import org.apache.nifi.snmp.processors.properties.V1TrapProperties;
+import org.apache.nifi.snmp.processors.properties.V2TrapProperties;
+import org.apache.nifi.snmp.processors.properties.V3SecurityProperties;
+import org.apache.nifi.snmp.utils.SNMPUtils;
+import org.snmp4j.mp.SnmpConstants;
+
+import java.io.IOException;
+import java.time.Instant;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+/**
+ * Sends data to an SNMP manager 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", "send", "trap"})
+@InputRequirement(Requirement.INPUT_ALLOWED)
+@CapabilityDescription("Sends information to SNMP Manager.")
+public class SendTrapSNMP extends AbstractSNMPProcessor {
+
+ public static final PropertyDescriptor SNMP_MANAGER_HOST = new PropertyDescriptor.Builder()
+ .name("snmp-trap-manager-host")
+ .displayName("SNMP Manager Host")
+ .description("The host where the SNMP Manager sends the trap.")
+ .required(true)
+ .defaultValue("localhost")
+ .addValidator(StandardValidators.NON_EMPTY_VALIDATOR)
+ .build();
+
+ public static final PropertyDescriptor SNMP_MANAGER_PORT = new PropertyDescriptor.Builder()
+ .name("snmp-trap-manager-port")
+ .displayName("SNMP Manager Port")
+ .description("The port where the SNMP Manager listens to the incoming traps.")
+ .required(true)
+ .defaultValue("0")
+ .addValidator(StandardValidators.PORT_VALIDATOR)
+ .build();
+
+ 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();
+
+ 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();
+
+ protected static final List PROPERTY_DESCRIPTORS = Collections.unmodifiableList(Arrays.asList(
+ SNMP_MANAGER_HOST,
+ SNMP_MANAGER_PORT,
+ BasicProperties.SNMP_VERSION,
+ BasicProperties.SNMP_COMMUNITY,
+ V3SecurityProperties.SNMP_SECURITY_LEVEL,
+ V3SecurityProperties.SNMP_SECURITY_NAME,
+ V3SecurityProperties.SNMP_AUTH_PROTOCOL,
+ V3SecurityProperties.SNMP_AUTH_PASSWORD,
+ V3SecurityProperties.SNMP_PRIVACY_PROTOCOL,
+ V3SecurityProperties.SNMP_PRIVACY_PASSWORD,
+ BasicProperties.SNMP_RETRIES,
+ BasicProperties.SNMP_TIMEOUT,
+ V1TrapProperties.ENTERPRISE_OID,
+ V1TrapProperties.AGENT_ADDRESS,
+ V1TrapProperties.GENERIC_TRAP_TYPE,
+ V1TrapProperties.SPECIFIC_TRAP_TYPE,
+ V2TrapProperties.TRAP_OID_VALUE
+ ));
+
+ private static final Set RELATIONSHIPS = Collections.unmodifiableSet(new HashSet<>(Arrays.asList(
+ REL_SUCCESS, REL_FAILURE
+ )));
+
+ private volatile SendTrapSNMPHandler snmpHandler;
+
+ @OnScheduled
+ public void init(ProcessContext context) {
+ Instant startTime = Instant.now();
+ initSnmpManager(context);
+ snmpHandler = new SendTrapSNMPHandler(snmpResourceHandler, startTime, getLogger());
+ }
+
+ @Override
+ public void onTrigger(final ProcessContext context, final ProcessSession processSession) {
+ final FlowFile flowFile = processSession.get();
+ if (flowFile != null) {
+ try {
+ final int snmpVersion = SNMPUtils.getVersion(context.getProperty(BasicProperties.SNMP_VERSION).getValue());
+ if (SnmpConstants.version1 == snmpVersion) {
+ V1TrapConfiguration v1TrapConfiguration = V1TrapConfiguration.builder()
+ .enterpriseOid(context.getProperty(V1TrapProperties.ENTERPRISE_OID).evaluateAttributeExpressions(flowFile).getValue())
+ .agentAddress(context.getProperty(V1TrapProperties.AGENT_ADDRESS).evaluateAttributeExpressions(flowFile).getValue())
+ .genericTrapType(context.getProperty(V1TrapProperties.GENERIC_TRAP_TYPE).evaluateAttributeExpressions(flowFile).getValue())
+ .specificTrapType(context.getProperty(V1TrapProperties.SPECIFIC_TRAP_TYPE).evaluateAttributeExpressions(flowFile).getValue())
+ .build();
+ snmpHandler.sendTrap(flowFile.getAttributes(), v1TrapConfiguration);
+ } else {
+ V2TrapConfiguration v2TrapConfiguration = new V2TrapConfiguration(
+ context.getProperty(V2TrapProperties.TRAP_OID_VALUE).evaluateAttributeExpressions(flowFile).getValue()
+ );
+ snmpHandler.sendTrap(flowFile.getAttributes(), v2TrapConfiguration);
+ }
+ processSession.transfer(flowFile, REL_SUCCESS);
+ } catch (IOException e) {
+ getLogger().error("Failed to send request to the agent. Check if the agent supports the used version.", e);
+ processSession.transfer(processSession.penalize(flowFile), REL_FAILURE);
+ } catch (IllegalArgumentException e) {
+ getLogger().error("Invalid trap configuration.", e);
+ processSession.transfer(processSession.penalize(flowFile), REL_FAILURE);
+ }
+ }
+ }
+
+ @Override
+ public Set getRelationships() {
+ return RELATIONSHIPS;
+ }
+
+ @Override
+ protected List getSupportedPropertyDescriptors() {
+ return PROPERTY_DESCRIPTORS;
+ }
+
+ @Override
+ protected String getTargetHost(ProcessContext processContext) {
+ return processContext.getProperty(SNMP_MANAGER_HOST).getValue();
+ }
+
+ @Override
+ protected String getTargetPort(ProcessContext processContext) {
+ return processContext.getProperty(SNMP_MANAGER_PORT).getValue();
+ }
+}
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
index ab5ca72359..74d18a071a 100644
--- 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
@@ -22,13 +22,16 @@ import org.apache.nifi.annotation.behavior.WritesAttribute;
import org.apache.nifi.annotation.behavior.WritesAttributes;
import org.apache.nifi.annotation.documentation.CapabilityDescription;
import org.apache.nifi.annotation.documentation.Tags;
+import org.apache.nifi.annotation.lifecycle.OnScheduled;
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.snmp.dto.SNMPSingleResponse;
-import org.apache.nifi.snmp.exception.SNMPException;
+import org.apache.nifi.snmp.operations.SetSNMPHandler;
+import org.apache.nifi.snmp.processors.properties.BasicProperties;
+import org.apache.nifi.snmp.processors.properties.V3SecurityProperties;
import org.apache.nifi.snmp.utils.SNMPUtils;
import java.io.IOException;
@@ -36,19 +39,21 @@ import java.util.Arrays;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
+import java.util.Optional;
import java.util.Set;
/**
- * Performs a SNMP Set operation based on attributes of incoming FlowFile.
+ * Performs an 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.
+ * The output {@link FlowFile} won't have any content.
*/
@Tags({"snmp", "set", "oid"})
@InputRequirement(Requirement.INPUT_REQUIRED)
@CapabilityDescription("Based on incoming FlowFile attributes, the processor will execute SNMP Set requests." +
" When finding attributes with the name snmp$, the processor will attempt to set the value of" +
- " the attribute to the corresponding OID given in the attribute name")
+ " the attribute to the corresponding OID given in the attribute name.")
@WritesAttributes({
@WritesAttribute(attribute = SNMPUtils.SNMP_PROP_PREFIX + "", description = "Response variable binding: OID (e.g. 1.3.6.1.4.1.343) and its value."),
@WritesAttribute(attribute = SNMPUtils.SNMP_PROP_PREFIX + "errorIndex", description = "Denotes the variable binding in which the error occured."),
@@ -74,16 +79,16 @@ public class SetSNMP extends AbstractSNMPProcessor {
private static final List PROPERTY_DESCRIPTORS = Collections.unmodifiableList(Arrays.asList(
AGENT_HOST,
AGENT_PORT,
- SNMP_VERSION,
- SNMP_COMMUNITY,
- SNMP_SECURITY_LEVEL,
- SNMP_SECURITY_NAME,
- SNMP_AUTH_PROTOCOL,
- SNMP_AUTH_PASSWORD,
- SNMP_PRIVACY_PROTOCOL,
- SNMP_PRIVACY_PASSWORD,
- SNMP_RETRIES,
- SNMP_TIMEOUT
+ BasicProperties.SNMP_VERSION,
+ BasicProperties.SNMP_COMMUNITY,
+ V3SecurityProperties.SNMP_SECURITY_LEVEL,
+ V3SecurityProperties.SNMP_SECURITY_NAME,
+ V3SecurityProperties.SNMP_AUTH_PROTOCOL,
+ V3SecurityProperties.SNMP_AUTH_PASSWORD,
+ V3SecurityProperties.SNMP_PRIVACY_PROTOCOL,
+ V3SecurityProperties.SNMP_PRIVACY_PASSWORD,
+ BasicProperties.SNMP_RETRIES,
+ BasicProperties.SNMP_TIMEOUT
));
private static final Set RELATIONSHIPS = Collections.unmodifiableSet(new HashSet<>(Arrays.asList(
@@ -91,19 +96,34 @@ public class SetSNMP extends AbstractSNMPProcessor {
REL_FAILURE
)));
+ private volatile SetSNMPHandler snmpHandler;
+
+ @OnScheduled
+ public void init(final ProcessContext context) {
+ initSnmpManager(context);
+ snmpHandler = new SetSNMPHandler(snmpResourceHandler);
+ }
+
@Override
public void onTrigger(final ProcessContext context, final ProcessSession processSession) {
final FlowFile flowFile = processSession.get();
if (flowFile != null) {
try {
- final SNMPSingleResponse response = snmpRequestHandler.set(flowFile);
- processResponse(processSession, flowFile, response, response.getTargetAddress(), REL_SUCCESS);
- } catch (SNMPException e) {
- getLogger().error(e.getMessage());
- processError(context, processSession, flowFile);
+ final Optional optionalResponse = snmpHandler.set(flowFile.getAttributes());
+ if (optionalResponse.isPresent()) {
+ processSession.remove(flowFile);
+ final FlowFile outgoingFlowFile = processSession.create();
+ final SNMPSingleResponse response = optionalResponse.get();
+ processSession.getProvenanceReporter().receive(outgoingFlowFile, "/set");
+ handleResponse(context, processSession, outgoingFlowFile, response, REL_SUCCESS, REL_FAILURE, "/set");
+ } else {
+ getLogger().warn("No SNMP specific attributes found in flowfile.");
+ processSession.transfer(flowFile, REL_FAILURE);
+ }
} catch (IOException e) {
getLogger().error("Failed to send request to the agent. Check if the agent supports the used version.");
- processError(context, processSession, flowFile);
+ processSession.transfer(processSession.penalize(flowFile), REL_FAILURE);
+ context.yield();
}
}
}
@@ -118,9 +138,13 @@ public class SetSNMP extends AbstractSNMPProcessor {
return RELATIONSHIPS;
}
+ @Override
+ protected String getTargetHost(ProcessContext processContext) {
+ return processContext.getProperty(AGENT_HOST).getValue();
+ }
- private void processError(final ProcessContext context, final ProcessSession processSession, final FlowFile flowFile) {
- processSession.transfer(processSession.penalize(flowFile), REL_FAILURE);
- context.yield();
+ @Override
+ protected String getTargetPort(ProcessContext processContext) {
+ return processContext.getProperty(AGENT_PORT).getValue();
}
}
diff --git a/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/main/java/org/apache/nifi/snmp/processors/properties/BasicProperties.java b/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/main/java/org/apache/nifi/snmp/processors/properties/BasicProperties.java
new file mode 100644
index 0000000000..ccc6677781
--- /dev/null
+++ b/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/main/java/org/apache/nifi/snmp/processors/properties/BasicProperties.java
@@ -0,0 +1,77 @@
+/*
+ * 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.properties;
+
+import org.apache.nifi.components.AllowableValue;
+import org.apache.nifi.components.PropertyDescriptor;
+import org.apache.nifi.processor.util.StandardValidators;
+
+public class BasicProperties {
+
+ private BasicProperties() {
+ // Utility class, not needed to instantiate.
+ }
+
+ public static final AllowableValue SNMP_V1 = new AllowableValue("SNMPv1", "v1", "SNMP version 1");
+ public static final AllowableValue SNMP_V2C = new AllowableValue("SNMPv2c", "v2c", "SNMP version 2c");
+ public static final AllowableValue SNMP_V3 = new AllowableValue("SNMPv3", "v3", "SNMP version 3 with improved security");
+
+
+ public static final PropertyDescriptor SNMP_VERSION = new PropertyDescriptor.Builder()
+ .name("snmp-version")
+ .displayName("SNMP Version")
+ .description("Three significant versions of SNMP have been developed and deployed. " +
+ "SNMPv1 is the original version of the protocol. More recent versions, " +
+ "SNMPv2c and SNMPv3, feature improvements in performance, flexibility and security.")
+ .required(true)
+ .allowableValues(SNMP_V1, SNMP_V2C, SNMP_V3)
+ .defaultValue(SNMP_V1.getValue())
+ .build();
+
+ public static final PropertyDescriptor SNMP_COMMUNITY = new PropertyDescriptor.Builder()
+ .name("snmp-community")
+ .displayName("SNMP Community")
+ .description("SNMPv1 and SNMPv2 use communities to establish trust between managers and agents." +
+ " Most agents support three community names, one each for read-only, read-write and trap." +
+ " These three community strings control different types of activities. The read-only community" +
+ " applies to get requests. The read-write community string applies to set requests. The trap" +
+ " community string applies to receipt of traps.")
+ .required(true)
+ .sensitive(true)
+ .defaultValue("public")
+ .addValidator(StandardValidators.NON_EMPTY_VALIDATOR)
+ .dependsOn(SNMP_VERSION, SNMP_V1, SNMP_V2C)
+ .build();
+
+ 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(false)
+ .defaultValue("0")
+ .addValidator(StandardValidators.NON_NEGATIVE_INTEGER_VALIDATOR)
+ .build();
+
+ public static final PropertyDescriptor SNMP_TIMEOUT = new PropertyDescriptor.Builder()
+ .name("snmp-timeout")
+ .displayName("Timeout (ms)")
+ .description("Set the timeout in ms when requesting the SNMP Agent.")
+ .required(false)
+ .defaultValue("5000")
+ .addValidator(StandardValidators.POSITIVE_INTEGER_VALIDATOR)
+ .build();
+}
diff --git a/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/main/java/org/apache/nifi/snmp/processors/properties/V1TrapProperties.java b/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/main/java/org/apache/nifi/snmp/processors/properties/V1TrapProperties.java
new file mode 100644
index 0000000000..bcdf122189
--- /dev/null
+++ b/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/main/java/org/apache/nifi/snmp/processors/properties/V1TrapProperties.java
@@ -0,0 +1,80 @@
+/*
+ * 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.properties;
+
+import org.apache.nifi.components.AllowableValue;
+import org.apache.nifi.components.PropertyDescriptor;
+import org.apache.nifi.expression.ExpressionLanguageScope;
+import org.apache.nifi.processor.util.StandardValidators;
+
+import static org.apache.nifi.snmp.processors.properties.BasicProperties.SNMP_V1;
+import static org.apache.nifi.snmp.processors.properties.BasicProperties.SNMP_VERSION;
+
+
+public class V1TrapProperties {
+
+ private V1TrapProperties() {
+ // Utility class, not needed to instantiate.
+ }
+
+ private static final AllowableValue GENERIC_TRAP_TYPE_ENTERPRISE_SPECIFIC = new AllowableValue("6", "Enterprise Specific",
+ "An enterpriseSpecific trap signifies that a particular enterprise-specific trap has occurred which " +
+ "can be defined in the Specific Trap Type field.");
+
+ public static final PropertyDescriptor ENTERPRISE_OID = new PropertyDescriptor.Builder()
+ .name("snmp-trap-enterprise-oid")
+ .displayName("Enterprise OID")
+ .description("Enterprise is the vendor identification (OID) for the network management sub-system that generated the trap.")
+ .required(true)
+ .addValidator(StandardValidators.NON_EMPTY_VALIDATOR)
+ .dependsOn(SNMP_VERSION, SNMP_V1)
+ .expressionLanguageSupported(ExpressionLanguageScope.FLOWFILE_ATTRIBUTES)
+ .build();
+
+ public static final PropertyDescriptor AGENT_ADDRESS = new PropertyDescriptor.Builder()
+ .name("snmp-trap-agent-address")
+ .displayName("SNMP Trap Agent Address")
+ .description("The address where the SNMP Manager sends the trap.")
+ .required(true)
+ .defaultValue("0")
+ .addValidator(StandardValidators.NON_EMPTY_VALIDATOR)
+ .dependsOn(SNMP_VERSION, SNMP_V1)
+ .expressionLanguageSupported(ExpressionLanguageScope.FLOWFILE_ATTRIBUTES)
+ .build();
+
+ public static final PropertyDescriptor GENERIC_TRAP_TYPE = new PropertyDescriptor.Builder()
+ .name("snmp-trap-generic-type")
+ .displayName("Generic Trap Type")
+ .description("Generic trap type is an integer in the range of 0 to 6. See processor usage for details.")
+ .required(false)
+ .addValidator(StandardValidators.createLongValidator(0, 6, true))
+ .dependsOn(SNMP_VERSION, SNMP_V1)
+ .expressionLanguageSupported(ExpressionLanguageScope.FLOWFILE_ATTRIBUTES)
+ .build();
+
+ public static final PropertyDescriptor SPECIFIC_TRAP_TYPE = new PropertyDescriptor.Builder()
+ .name("snmp-trap-specific-type")
+ .displayName("Specific Trap Type")
+ .description("Specific trap type is a number that further specifies the nature of the event that generated " +
+ "the trap in the case of traps of generic type 6 (enterpriseSpecific). The interpretation of this " +
+ "code is vendor-specific.")
+ .required(true)
+ .addValidator(StandardValidators.POSITIVE_INTEGER_VALIDATOR)
+ .dependsOn(SNMP_VERSION, SNMP_V1)
+ .expressionLanguageSupported(ExpressionLanguageScope.FLOWFILE_ATTRIBUTES)
+ .build();
+}
diff --git a/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/main/java/org/apache/nifi/snmp/processors/properties/V2TrapProperties.java b/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/main/java/org/apache/nifi/snmp/processors/properties/V2TrapProperties.java
new file mode 100644
index 0000000000..1866bb5e0e
--- /dev/null
+++ b/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/main/java/org/apache/nifi/snmp/processors/properties/V2TrapProperties.java
@@ -0,0 +1,42 @@
+/*
+ * 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.properties;
+
+import org.apache.nifi.components.PropertyDescriptor;
+import org.apache.nifi.expression.ExpressionLanguageScope;
+import org.apache.nifi.processor.util.StandardValidators;
+
+import static org.apache.nifi.snmp.processors.properties.BasicProperties.SNMP_V2C;
+import static org.apache.nifi.snmp.processors.properties.BasicProperties.SNMP_V3;
+import static org.apache.nifi.snmp.processors.properties.BasicProperties.SNMP_VERSION;
+
+public class V2TrapProperties {
+
+ private V2TrapProperties() {
+ // Utility class, not needed to instantiate.
+ }
+
+ public static final PropertyDescriptor TRAP_OID_VALUE = new PropertyDescriptor.Builder()
+ .name("snmp-trap-oid-value")
+ .displayName("Trap OID Value")
+ .description("The value of the trap OID.")
+ .required(true)
+ .addValidator(StandardValidators.NON_EMPTY_VALIDATOR)
+ .dependsOn(SNMP_VERSION, SNMP_V2C, SNMP_V3)
+ .expressionLanguageSupported(ExpressionLanguageScope.FLOWFILE_ATTRIBUTES)
+ .build();
+}
diff --git a/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/main/java/org/apache/nifi/snmp/processors/properties/V3SecurityProperties.java b/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/main/java/org/apache/nifi/snmp/processors/properties/V3SecurityProperties.java
new file mode 100644
index 0000000000..07688d7b15
--- /dev/null
+++ b/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/main/java/org/apache/nifi/snmp/processors/properties/V3SecurityProperties.java
@@ -0,0 +1,130 @@
+/*
+ * 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.properties;
+
+import org.apache.nifi.components.AllowableValue;
+import org.apache.nifi.components.PropertyDescriptor;
+import org.apache.nifi.processor.util.StandardValidators;
+import org.snmp4j.security.SecurityLevel;
+
+import static org.apache.nifi.snmp.processors.properties.BasicProperties.SNMP_V3;
+import static org.apache.nifi.snmp.processors.properties.BasicProperties.SNMP_VERSION;
+
+public class V3SecurityProperties {
+
+ private V3SecurityProperties() {
+ // Utility class, not needed to instantiate.
+ }
+
+ private static final String SHA_2_ALGORITHM = "Provides authentication based on the HMAC-SHA-2 algorithm.";
+ private static final String AES_DESCRIPTION = "AES is a symmetric algorithm which uses the same 128, 192, or 256 bit" +
+ " key for both encryption and decryption (the security of an AES system increases exponentially with key length).";
+
+ // SNMPv3 security levels
+ public static final AllowableValue NO_AUTH_NO_PRIV = new AllowableValue(SecurityLevel.noAuthNoPriv.name(), SecurityLevel.noAuthNoPriv.name(),
+ "No authentication or encryption.");
+ public static final AllowableValue AUTH_NO_PRIV = new AllowableValue(SecurityLevel.authNoPriv.name(), SecurityLevel.authNoPriv.name(),
+ "Authentication without encryption.");
+ public static final AllowableValue AUTH_PRIV = new AllowableValue(SecurityLevel.authPriv.name(), SecurityLevel.authPriv.name(),
+ "Authentication and encryption.");
+
+ // SNMPv3 authentication protocols
+ public static final AllowableValue MD5 = new AllowableValue("MD5", "MD5",
+ "Provides authentication based on the HMAC-MD5 algorithm.");
+ public static final AllowableValue SHA = new AllowableValue("SHA", "SHA",
+ "Provides authentication based on the HMAC-SHA algorithm.");
+ public static final AllowableValue HMAC128SHA224 = new AllowableValue("HMAC128SHA224", "SHA224",
+ SHA_2_ALGORITHM);
+ public static final AllowableValue HMAC192SHA256 = new AllowableValue("HMAC192SHA256", "SHA256",
+ SHA_2_ALGORITHM);
+ public static final AllowableValue HMAC256SHA384 = new AllowableValue("HMAC256SHA384", "SHA384",
+ SHA_2_ALGORITHM);
+ public static final AllowableValue HMAC384SHA512 = new AllowableValue("HMAC384SHA512", "SHA512",
+ SHA_2_ALGORITHM);
+
+ // SNMPv3 encryption
+ public static final AllowableValue DES = new AllowableValue("DES", "DES",
+ "Symmetric-key algorithm for the encryption of digital data. DES has been considered insecure" +
+ "because of the feasilibity of brute-force attacks. We recommend using the AES encryption protocol.");
+ public static final AllowableValue DES3 = new AllowableValue("3DES", "3DES",
+ "Symmetric-key block cipher, which applies the DES cipher algorithm three times to each data block." +
+ " 3DES has been considered insecure has been deprecated by NIST in 2017. We recommend using the AES encryption protocol.");
+
+ public static final AllowableValue AES128 = new AllowableValue("AES128", "AES128", AES_DESCRIPTION);
+ public static final AllowableValue AES192 = new AllowableValue("AES192", "AES192", AES_DESCRIPTION);
+ public static final AllowableValue AES256 = new AllowableValue("AES256", "AES256", AES_DESCRIPTION);
+
+ public static final PropertyDescriptor SNMP_SECURITY_LEVEL = new PropertyDescriptor.Builder()
+ .name("snmp-security-level")
+ .displayName("SNMP Security Level")
+ .description("SNMP version 3 provides extra security with User Based Security Model (USM). The three levels of security is " +
+ "1. Communication without authentication and encryption (NoAuthNoPriv). " +
+ "2. Communication with authentication and without encryption (AuthNoPriv). " +
+ "3. Communication with authentication and encryption (AuthPriv).")
+ .required(true)
+ .allowableValues(NO_AUTH_NO_PRIV, AUTH_NO_PRIV, AUTH_PRIV)
+ .defaultValue(NO_AUTH_NO_PRIV.getValue())
+ .dependsOn(SNMP_VERSION, SNMP_V3)
+ .build();
+
+ public static final PropertyDescriptor SNMP_SECURITY_NAME = new PropertyDescriptor.Builder()
+ .name("snmp-security-name")
+ .displayName("SNMP Security Name")
+ .description("User name used for SNMP v3 Authentication.")
+ .required(true)
+ .addValidator(StandardValidators.NON_EMPTY_VALIDATOR)
+ .dependsOn(SNMP_VERSION, SNMP_V3)
+ .build();
+
+ public static final PropertyDescriptor SNMP_AUTH_PROTOCOL = new PropertyDescriptor.Builder()
+ .name("snmp-authentication-protocol")
+ .displayName("SNMP Authentication Protocol")
+ .description("Hash based authentication protocol for secure authentication.")
+ .required(true)
+ .allowableValues(MD5, SHA, HMAC128SHA224, HMAC192SHA256, HMAC256SHA384, HMAC384SHA512)
+ .dependsOn(SNMP_SECURITY_LEVEL, AUTH_NO_PRIV, AUTH_PRIV)
+ .build();
+
+ public static final PropertyDescriptor SNMP_AUTH_PASSWORD = new PropertyDescriptor.Builder()
+ .name("snmp-authentication-passphrase")
+ .displayName("SNMP Authentication Passphrase")
+ .description("Passphrase used for SNMP authentication protocol.")
+ .required(true)
+ .addValidator(StandardValidators.NON_EMPTY_VALIDATOR)
+ .sensitive(true)
+ .dependsOn(SNMP_SECURITY_LEVEL, AUTH_NO_PRIV, AUTH_PRIV)
+ .build();
+
+ public static final PropertyDescriptor SNMP_PRIVACY_PROTOCOL = new PropertyDescriptor.Builder()
+ .name("snmp-private-protocol")
+ .displayName("SNMP Privacy Protocol")
+ .description("Privacy allows for encryption of SNMP v3 messages to ensure confidentiality of data.")
+ .required(true)
+ .allowableValues(DES, DES3, AES128, AES192, AES256)
+ .dependsOn(SNMP_SECURITY_LEVEL, AUTH_PRIV)
+ .build();
+
+ public static final PropertyDescriptor SNMP_PRIVACY_PASSWORD = new PropertyDescriptor.Builder()
+ .name("snmp-private-protocol-passphrase")
+ .displayName("SNMP Privacy Passphrase")
+ .description("Passphrase used for SNMP privacy protocol.")
+ .required(true)
+ .addValidator(StandardValidators.NON_EMPTY_VALIDATOR)
+ .sensitive(true)
+ .dependsOn(SNMP_SECURITY_LEVEL, AUTH_PRIV)
+ .build();
+}
diff --git a/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/main/java/org/apache/nifi/snmp/utils/SNMPUtils.java b/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/main/java/org/apache/nifi/snmp/utils/SNMPUtils.java
index 788b73ba75..a14e195d8c 100644
--- a/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/main/java/org/apache/nifi/snmp/utils/SNMPUtils.java
+++ b/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/main/java/org/apache/nifi/snmp/utils/SNMPUtils.java
@@ -16,13 +16,13 @@
*/
package org.apache.nifi.snmp.utils;
-import org.apache.nifi.flowfile.FlowFile;
import org.apache.nifi.snmp.exception.InvalidAuthProtocolException;
import org.apache.nifi.snmp.exception.InvalidPrivProtocolException;
import org.apache.nifi.snmp.exception.InvalidSnmpVersionException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.snmp4j.PDU;
+import org.snmp4j.PDUv1;
import org.snmp4j.mp.SnmpConstants;
import org.snmp4j.security.AuthHMAC128SHA224;
import org.snmp4j.security.AuthHMAC192SHA256;
@@ -44,6 +44,7 @@ import org.snmp4j.smi.OctetString;
import org.snmp4j.smi.Variable;
import org.snmp4j.smi.VariableBinding;
+import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
@@ -67,8 +68,8 @@ public final class SNMPUtils {
private static final Map AUTH_MAP;
private static final Map PRIV_MAP;
- private static final Map VERSION_MAP;
private static final Map REPORT_MAP;
+ private static final Map VERSION_MAP;
private SNMPUtils() {
// hide implicit constructor
@@ -132,12 +133,18 @@ public final class SNMPUtils {
return attributes;
}
- /**
- * Method to construct {@link FlowFile} attributes from a vector of {@link VariableBinding}
- *
- * @param variableBindings list of {@link VariableBinding}
- * @return the attributes map
- */
+ public static Map getV1TrapPduAttributeMap(final PDUv1 v1TrapPdu) {
+ final Map trapAttributes = getPduAttributeMap(v1TrapPdu);
+
+ trapAttributes.computeIfAbsent(SNMP_PROP_PREFIX + "enterprise", v -> String.valueOf(v1TrapPdu.getEnterprise()));
+ trapAttributes.computeIfAbsent(SNMP_PROP_PREFIX + "agentAddress", v -> String.valueOf(v1TrapPdu.getAgentAddress()));
+ trapAttributes.computeIfAbsent(SNMP_PROP_PREFIX + "genericTrapType", v -> String.valueOf(v1TrapPdu.getGenericTrap()));
+ trapAttributes.computeIfAbsent(SNMP_PROP_PREFIX + "specificTrapType", v -> String.valueOf(v1TrapPdu.getSpecificTrap()));
+ trapAttributes.computeIfAbsent(SNMP_PROP_PREFIX + "timestamp", v -> String.valueOf(v1TrapPdu.getTimestamp()));
+
+ return trapAttributes;
+ }
+
public static Map createWalkOidValuesMap(final List variableBindings) {
final Map attributes = new HashMap<>();
variableBindings.forEach(vb -> addAttributeFromVariable(vb, attributes));
@@ -159,46 +166,72 @@ public final class SNMPUtils {
throw new InvalidAuthProtocolException("Invalid authentication protocol provided.");
}
- public static int getVersion(final String snmpVersion) {
- return Optional.ofNullable(VERSION_MAP.get(snmpVersion))
- .orElseThrow(() -> new InvalidSnmpVersionException("Invalid SNMP version provided."));
- }
-
- /**
- * 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
- */
public static boolean addVariables(final PDU pdu, final Map attributes) {
boolean result = false;
- for (Map.Entry attributeEntry : attributes.entrySet()) {
- if (attributeEntry.getKey().startsWith(SNMPUtils.SNMP_PROP_PREFIX)) {
- final String[] splits = attributeEntry.getKey().split("\\" + SNMPUtils.SNMP_PROP_DELIMITER);
- final String snmpPropName = splits[1];
- final String snmpPropValue = attributeEntry.getValue();
- if (SNMPUtils.OID_PATTERN.matcher(snmpPropName).matches()) {
- final Optional var;
- if (splits.length == 2) { // no SMI syntax defined
- var = Optional.of(new OctetString(snmpPropValue));
- } else {
- final int smiSyntax = Integer.parseInt(splits[2]);
- var = SNMPUtils.stringToVariable(snmpPropValue, smiSyntax);
- }
- if (var.isPresent()) {
- final VariableBinding varBind = new VariableBinding(new OID(snmpPropName), var.get());
- pdu.add(varBind);
- result = true;
+ try {
+ for (Map.Entry attributeEntry : attributes.entrySet()) {
+ if (attributeEntry.getKey().startsWith(SNMPUtils.SNMP_PROP_PREFIX)) {
+ final String[] splits = attributeEntry.getKey().split("\\" + SNMPUtils.SNMP_PROP_DELIMITER);
+ final String snmpPropName = splits[1];
+ final String snmpPropValue = attributeEntry.getValue();
+ if (SNMPUtils.OID_PATTERN.matcher(snmpPropName).matches()) {
+ final Optional var;
+ if (splits.length == 2) { // no SMI syntax defined
+ var = Optional.of(new OctetString(snmpPropValue));
+ } else {
+ final int smiSyntax = Integer.parseInt(splits[2]);
+ var = SNMPUtils.stringToVariable(snmpPropValue, smiSyntax);
+ }
+ if (var.isPresent()) {
+ final VariableBinding varBind = new VariableBinding(new OID(snmpPropName), var.get());
+ pdu.add(varBind);
+ result = true;
+ }
}
}
}
+ } catch (ArrayIndexOutOfBoundsException e) {
+ return false;
}
return result;
}
+ public static VariableBinding[] addGetVariables(final Map attributes) {
+ List variableBindings = new ArrayList<>();
+ try {
+ for (Map.Entry attributeEntry : attributes.entrySet()) {
+ if (attributeEntry.getKey().startsWith(SNMPUtils.SNMP_PROP_PREFIX)) {
+ final String[] splits = attributeEntry.getKey().split("\\" + SNMPUtils.SNMP_PROP_DELIMITER);
+ final String snmpPropName = splits[1];
+ if (SNMPUtils.OID_PATTERN.matcher(snmpPropName).matches()) {
+ variableBindings.add(new VariableBinding(new OID(snmpPropName)));
+ }
+ }
+ }
+ } catch (ArrayIndexOutOfBoundsException e) {
+ return new VariableBinding[0];
+ }
+ return variableBindings.toArray(new VariableBinding[0]);
+ }
+
+ public static OID[] addWalkVariables(final Map attributes) {
+ List oids = new ArrayList<>();
+ try {
+ for (Map.Entry attributeEntry : attributes.entrySet()) {
+ if (attributeEntry.getKey().startsWith(SNMPUtils.SNMP_PROP_PREFIX)) {
+ final String[] splits = attributeEntry.getKey().split("\\" + SNMPUtils.SNMP_PROP_DELIMITER);
+ final String snmpPropName = splits[1];
+ if (SNMPUtils.OID_PATTERN.matcher(snmpPropName).matches()) {
+ oids.add(new OID(snmpPropName));
+ }
+ }
+ }
+ } catch (ArrayIndexOutOfBoundsException e) {
+ return new OID[0];
+ }
+ return oids.toArray(new OID[0]);
+ }
+
private static void addAttributeFromVariable(final VariableBinding variableBinding, final Map attributes) {
attributes.put(SNMP_PROP_PREFIX + variableBinding.getOid() + SNMP_PROP_DELIMITER + variableBinding.getVariable().getSyntax(), variableBinding.getVariable().toString());
}
@@ -231,4 +264,9 @@ public final class SNMPUtils {
}
return errorMessage.map(s -> oid + ": " + s);
}
+
+ public static int getVersion(final String snmpVersion) {
+ return Optional.ofNullable(VERSION_MAP.get(snmpVersion))
+ .orElseThrow(() -> new InvalidSnmpVersionException("Invalid SNMP version provided."));
+ }
}
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
index c3fcde09ab..03592712e9 100644
--- 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
@@ -14,3 +14,5 @@
# limitations under the License.
org.apache.nifi.snmp.processors.GetSNMP
org.apache.nifi.snmp.processors.SetSNMP
+org.apache.nifi.snmp.processors.SendTrapSNMP
+org.apache.nifi.snmp.processors.ListenTrapSNMP
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
index 24f982c081..1607987ffb 100644
--- 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
@@ -23,12 +23,19 @@
Summary
- 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
+ This processor polls a SNMP agent to get information for a given OID or OIDs (Strategy = GET) or for all the sub-tree
+ associated to a given OID or OIDs
(Strategy = WALK). This processors supports SNMPv1, SNMPv2c and SNMPv3. The component is based on SNMP4J.
+ The processor can compile the SNMP Get PDU from the attributes of an input flowfile (multiple OIDs can be specified)
+ or from a single OID specified in the processor property. In the former case, the processor will only consider the
+ OIDs specified in the flowfile.
+ The processor is looking for attributes prefixed with snmp$. If such an attribute is found, the attribute name is split using
+ the $ character. The second element must respect the OID format to be considered as a valid OID. The flowfile attribute
+ value can be empty (it will be later filled with the retrieved value and written into the outgoing flowfile).
+
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
diff --git a/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/main/resources/docs/org.apache.nifi.snmp.processors.ListenTrapSNMP/additionalDetails.html b/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/main/resources/docs/org.apache.nifi.snmp.processors.ListenTrapSNMP/additionalDetails.html
new file mode 100644
index 0000000000..37aaa668f7
--- /dev/null
+++ b/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/main/resources/docs/org.apache.nifi.snmp.processors.ListenTrapSNMP/additionalDetails.html
@@ -0,0 +1,54 @@
+
+
+
+
+
+ ListenTrapSNMP
+
+
+
+
+
Summary
+
+ This processor listens to SNMP traps and creates a flowfile from the trap PDU.
+ The versions SNMPv1, SNMPv2c and SNMPv3 are supproted. The component is based on SNMP4J.
+
+
+ In case of SNMPv3, users can be specified in a json file. E.g.:
+
+
+
\ No newline at end of file
diff --git a/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/main/resources/docs/org.apache.nifi.snmp.processors.SendTrapSNMP/additionalDetails.html b/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/main/resources/docs/org.apache.nifi.snmp.processors.SendTrapSNMP/additionalDetails.html
new file mode 100644
index 0000000000..ef9ed95bb6
--- /dev/null
+++ b/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/main/resources/docs/org.apache.nifi.snmp.processors.SendTrapSNMP/additionalDetails.html
@@ -0,0 +1,45 @@
+
+
+
+
+
+ SendTrapSNMP
+
+
+
+
+
Summary
+
+ This processor generates and transmits SNMP Traps to the specified SNMP manager. Attributes can be given
+ as processor properties, either predefined or dynamically using Expression Language from flowfiles.
+ Flowfile properties with snmp prefix (e.g. snmp$1.2.3.4.5 - OID) value can be used to define additional PDU variables.
+
+
+ The allowable Generic Trap Types are:
+
+
Cold Start
+
Warm Start
+
Link Down
+
Link Up
+
Authentication Failure
+
EGP Neighbor Loss
+
Enterprise Specific
+
+
+ Specific trap type can set in case of Enterprise Specific generic trap type is chosen.
+
+
+
\ No newline at end of file
diff --git a/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/test/java/org/apache/nifi/snmp/configuration/SNMPConfigurationTest.java b/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/test/java/org/apache/nifi/snmp/configuration/SNMPConfigurationTest.java
new file mode 100644
index 0000000000..e5cd4d38bc
--- /dev/null
+++ b/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/test/java/org/apache/nifi/snmp/configuration/SNMPConfigurationTest.java
@@ -0,0 +1,75 @@
+/*
+ * 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.configuration;
+
+import org.apache.nifi.remote.io.socket.NetworkUtils;
+import org.junit.Test;
+import org.snmp4j.mp.SnmpConstants;
+
+import static org.apache.nifi.snmp.helper.configurations.SNMPConfigurationFactory.COMMUNITY_STRING;
+import static org.apache.nifi.snmp.helper.configurations.SNMPConfigurationFactory.DEFAULT_HOST;
+import static org.apache.nifi.snmp.helper.configurations.SNMPV3ConfigurationFactory.AUTH_PASSPHRASE;
+import static org.apache.nifi.snmp.helper.configurations.SNMPV3ConfigurationFactory.AUTH_PROTOCOL;
+import static org.apache.nifi.snmp.helper.configurations.SNMPV3ConfigurationFactory.PRIV_PASSPHRASE;
+import static org.apache.nifi.snmp.helper.configurations.SNMPV3ConfigurationFactory.PRIV_PROTOCOL;
+import static org.apache.nifi.snmp.helper.configurations.SNMPV3ConfigurationFactory.SECURITY_LEVEL;
+import static org.apache.nifi.snmp.helper.configurations.SNMPV3ConfigurationFactory.SECURITY_NAME;
+import static org.junit.Assert.assertEquals;
+
+public class SNMPConfigurationTest {
+
+ private static final int MANAGER_PORT = NetworkUtils.availablePort();
+ private static final String TARGET_PORT = "55556";
+ private static final int RETRIES = 3;
+ private static final int VERSION = SnmpConstants.version3;
+ private static final int TIMEOUT_IN_MS = 3000;
+
+ @Test
+ public void testMembersAreSetCorrectly() {
+ final SNMPConfiguration snmpConfiguration = SNMPConfiguration.builder()
+ .setManagerPort(MANAGER_PORT)
+ .setTargetHost(DEFAULT_HOST)
+ .setTargetPort(TARGET_PORT)
+ .setRetries(RETRIES)
+ .setTimeoutInMs(TIMEOUT_IN_MS)
+ .setVersion(VERSION)
+ .setCommunityString(COMMUNITY_STRING)
+ .setSecurityLevel(SECURITY_LEVEL)
+ .setSecurityName(SECURITY_NAME)
+ .setAuthProtocol(AUTH_PROTOCOL)
+ .setAuthPassphrase(AUTH_PASSPHRASE)
+ .setPrivacyProtocol(PRIV_PROTOCOL)
+ .setPrivacyPassphrase(PRIV_PASSPHRASE)
+ .build();
+
+ assertEquals(MANAGER_PORT, snmpConfiguration.getManagerPort());
+ assertEquals(DEFAULT_HOST, snmpConfiguration.getTargetHost());
+ assertEquals(TARGET_PORT, snmpConfiguration.getTargetPort());
+ assertEquals(RETRIES, snmpConfiguration.getRetries());
+ assertEquals(TIMEOUT_IN_MS, snmpConfiguration.getTimeoutInMs());
+ assertEquals(VERSION, snmpConfiguration.getVersion());
+ assertEquals(COMMUNITY_STRING, snmpConfiguration.getCommunityString());
+ assertEquals(SECURITY_LEVEL, snmpConfiguration.getSecurityLevel());
+ assertEquals(SECURITY_NAME, snmpConfiguration.getSecurityName());
+ assertEquals(AUTH_PROTOCOL, snmpConfiguration.getAuthProtocol());
+ assertEquals(AUTH_PASSPHRASE, snmpConfiguration.getAuthPassphrase());
+ assertEquals(PRIV_PROTOCOL, snmpConfiguration.getPrivacyProtocol());
+ assertEquals(PRIV_PASSPHRASE, snmpConfiguration.getPrivacyPassphrase());
+
+ }
+
+}
diff --git a/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/test/java/org/apache/nifi/snmp/configuration/V1TrapConfigurationTest.java b/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/test/java/org/apache/nifi/snmp/configuration/V1TrapConfigurationTest.java
new file mode 100644
index 0000000000..1575113165
--- /dev/null
+++ b/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/test/java/org/apache/nifi/snmp/configuration/V1TrapConfigurationTest.java
@@ -0,0 +1,141 @@
+/*
+ * 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.configuration;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.ExpectedException;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertThrows;
+
+public class V1TrapConfigurationTest {
+
+ private static final String AGENT_ADDRESS = "127.0.0.1";
+ private static final String ENTERPRISE_OID = "1.3.6.1.4.1.8072.2.3.0.1";
+ private static final int GENERIC_TRAP_TYPE = 6;
+ private static final Integer SPECIFIC_TRAP_TYPE = 2;
+
+ @Rule
+ public ExpectedException exceptionRule = ExpectedException.none();
+
+ @Test
+ public void testMembersAreSetCorrectly() {
+ final V1TrapConfiguration v1TrapConfiguration = V1TrapConfiguration.builder()
+ .enterpriseOid(ENTERPRISE_OID)
+ .agentAddress(AGENT_ADDRESS)
+ .genericTrapType(String.valueOf(GENERIC_TRAP_TYPE))
+ .specificTrapType(String.valueOf(SPECIFIC_TRAP_TYPE))
+ .build();
+
+ assertEquals(ENTERPRISE_OID, v1TrapConfiguration.getEnterpriseOid());
+ assertEquals(AGENT_ADDRESS, v1TrapConfiguration.getAgentAddress());
+ assertEquals(GENERIC_TRAP_TYPE, v1TrapConfiguration.getGenericTrapType());
+ assertEquals(SPECIFIC_TRAP_TYPE, v1TrapConfiguration.getSpecificTrapType());
+ }
+
+ @Test
+ public void testRequireNonNullEnterpriseOid() {
+ exceptionRule.expect(IllegalArgumentException.class);
+ exceptionRule.expectMessage("Enterprise OID must be specified.");
+ V1TrapConfiguration.builder()
+ .agentAddress(AGENT_ADDRESS)
+ .genericTrapType(String.valueOf(GENERIC_TRAP_TYPE))
+ .specificTrapType(String.valueOf(SPECIFIC_TRAP_TYPE))
+ .build();
+ }
+
+ @Test
+ public void testRequireNonNullAgentAddress() {
+ exceptionRule.expect(IllegalArgumentException.class);
+ exceptionRule.expectMessage("Agent address must be specified.");
+ V1TrapConfiguration.builder()
+ .enterpriseOid(ENTERPRISE_OID)
+ .genericTrapType(String.valueOf(GENERIC_TRAP_TYPE))
+ .specificTrapType(String.valueOf(SPECIFIC_TRAP_TYPE))
+ .build();
+ }
+
+ @Test
+ public void testGenericTypeIsNegative() {
+ final IllegalArgumentException exception = assertThrows(IllegalArgumentException.class, () -> V1TrapConfiguration.builder()
+ .agentAddress(AGENT_ADDRESS)
+ .enterpriseOid(ENTERPRISE_OID)
+ .genericTrapType("-1")
+ .build()
+ );
+ assertEquals("Generic Trap Type must be between 0 and 6.", exception.getMessage());
+ }
+
+ @Test
+ public void testGenericTypeIsGreaterThan6() {
+ final IllegalArgumentException exception = assertThrows(IllegalArgumentException.class, () -> V1TrapConfiguration.builder()
+ .agentAddress(AGENT_ADDRESS)
+ .enterpriseOid(ENTERPRISE_OID)
+ .genericTrapType("7")
+ .build()
+ );
+ assertEquals("Generic Trap Type must be between 0 and 6.", exception.getMessage());
+ }
+
+ @Test
+ public void testGenericTypeIsNotANumber() {
+ final IllegalArgumentException exception = assertThrows(IllegalArgumentException.class, () -> V1TrapConfiguration.builder()
+ .agentAddress(AGENT_ADDRESS)
+ .enterpriseOid(ENTERPRISE_OID)
+ .genericTrapType("invalid")
+ .build()
+ );
+ assertEquals("Generic Trap Type is not a number.", exception.getMessage());
+ }
+
+ @Test
+ public void testSpecificTrapTypeIsNegative() {
+ final IllegalArgumentException exception = assertThrows(IllegalArgumentException.class, () -> V1TrapConfiguration.builder()
+ .agentAddress(AGENT_ADDRESS)
+ .enterpriseOid(ENTERPRISE_OID)
+ .genericTrapType(String.valueOf(GENERIC_TRAP_TYPE))
+ .specificTrapType("-1")
+ .build()
+ );
+ assertEquals("Specific Trap Type must be between 0 and 2147483647.", exception.getMessage());
+ }
+
+ @Test
+ public void testGenericTrapTypeIsEnterpriseSpecificButSpecificTrapTypeIsNotSet() {
+ final IllegalArgumentException exception = assertThrows(IllegalArgumentException.class, () -> V1TrapConfiguration.builder()
+ .agentAddress(AGENT_ADDRESS)
+ .enterpriseOid(ENTERPRISE_OID)
+ .genericTrapType(String.valueOf(GENERIC_TRAP_TYPE))
+ .build()
+ );
+ assertEquals("Generic Trap Type is [6 - Enterprise Specific] but Specific Trap Type is not provided or not a number.", exception.getMessage());
+ }
+
+ @Test
+ public void testGenericTrapTypeIsNotEnterpriseSpecificButSpecificTrapTypeIsSet() {
+ final IllegalArgumentException exception = assertThrows(IllegalArgumentException.class, () -> V1TrapConfiguration.builder()
+ .agentAddress(AGENT_ADDRESS)
+ .enterpriseOid(ENTERPRISE_OID)
+ .genericTrapType("5")
+ .specificTrapType("123")
+ .build()
+ );
+ assertEquals("Invalid argument: Generic Trap Type is not [6 - Enterprise Specific] but Specific Trap Type is provided.", exception.getMessage());
+ }
+
+}
diff --git a/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/test/java/org/apache/nifi/snmp/dto/SNMPTreeResponseTest.java b/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/test/java/org/apache/nifi/snmp/dto/SNMPTreeResponseTest.java
new file mode 100644
index 0000000000..1a325bf5c1
--- /dev/null
+++ b/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/test/java/org/apache/nifi/snmp/dto/SNMPTreeResponseTest.java
@@ -0,0 +1,165 @@
+/*
+ * 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.dto;
+
+import org.apache.nifi.util.LogMessage;
+import org.apache.nifi.util.MockComponentLog;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.mockito.Mock;
+import org.snmp4j.CommunityTarget;
+import org.snmp4j.Target;
+import org.snmp4j.smi.OID;
+import org.snmp4j.smi.OctetString;
+import org.snmp4j.smi.UdpAddress;
+import org.snmp4j.smi.VariableBinding;
+import org.snmp4j.util.TreeEvent;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import static org.junit.Assert.assertEquals;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+public class SNMPTreeResponseTest {
+
+ private static final String SNMP_SEPARATOR = "$";
+ private static final String SNMP_PREFIX = "snmp" + SNMP_SEPARATOR;
+ private static final String VB_SYNTAX = "4";
+
+ private static final String OID_1 = "1.3.6.1.4.1.32437.1.5.1.4.2.0";
+ private static final String OID_2 = "1.3.6.1.4.1.32437.1.5.1.4.3.0";
+ private static final String OID_3 = "1.3.6.1.4.1.32437.1.5.1.4.4.0";
+ private static final String OID_1_VALUE = "OID_1_VALUE";
+ private static final String OID_2_VALUE = "OID_2_VALUE";
+ private static final String OID_3_VALUE = "OID_3_VALUE";
+
+ private static final String TARGET_ADDRESS = "127.0.0.1/50555";
+
+ private static VariableBinding[] vbs1;
+ private static VariableBinding[] vbs2;
+ private static VariableBinding[] vbs3;
+ private static Map vbMap;
+ @Mock
+ private static Target target;
+
+ @BeforeClass
+ public static void setUp() {
+ vbMap = new HashMap<>();
+ vbMap.put(SNMP_PREFIX + OID_1 + SNMP_SEPARATOR + VB_SYNTAX, OID_1_VALUE);
+ vbMap.put(SNMP_PREFIX + OID_2 + SNMP_SEPARATOR + VB_SYNTAX, OID_2_VALUE);
+ vbMap.put(SNMP_PREFIX + OID_3 + SNMP_SEPARATOR + VB_SYNTAX, OID_3_VALUE);
+
+ target = new CommunityTarget();
+ target.setAddress(new UdpAddress(TARGET_ADDRESS));
+
+ vbs1 = new VariableBinding[]{
+ new VariableBinding(new OID(OID_1), new OctetString(OID_1_VALUE)),
+ };
+ vbs2 = new VariableBinding[]{
+ new VariableBinding(new OID(OID_2), new OctetString(OID_2_VALUE)),
+ };
+ vbs3 = new VariableBinding[]{
+ new VariableBinding(new OID(OID_3), new OctetString(OID_3_VALUE))
+ };
+ }
+
+ @Test
+ public void testGetAttributes() {
+ final TreeEvent treeEvent1 = mock(TreeEvent.class);
+ when(treeEvent1.getVariableBindings()).thenReturn(vbs1);
+ final TreeEvent treeEvent2 = mock(TreeEvent.class);
+ when(treeEvent2.getVariableBindings()).thenReturn(vbs2);
+ final TreeEvent treeEvent3 = mock(TreeEvent.class);
+ when(treeEvent3.getVariableBindings()).thenReturn(vbs3);
+
+ final List treeEvents = new ArrayList<>();
+ Collections.addAll(treeEvents, treeEvent1, treeEvent2, treeEvent3);
+
+ final SNMPTreeResponse snmpTreeResponse = new SNMPTreeResponse(target, treeEvents);
+ final Map attributes = snmpTreeResponse.getAttributes();
+
+ assertEquals(3, attributes.size());
+ assertEquals(vbMap, attributes);
+ }
+
+ @Test
+ public void testGetAttributesFlattensEmptyVariableBindingArrays() {
+ final TreeEvent emptyTreeEvent = mock(TreeEvent.class);
+ when(emptyTreeEvent.getVariableBindings()).thenReturn(new VariableBinding[0]);
+ final TreeEvent normalTreeEvent = mock(TreeEvent.class);
+ when(normalTreeEvent.getVariableBindings()).thenReturn(vbs1);
+
+ final List treeEvents = new ArrayList<>();
+ Collections.addAll(treeEvents, emptyTreeEvent, normalTreeEvent);
+
+ final SNMPTreeResponse snmpTreeResponse = new SNMPTreeResponse(target, treeEvents);
+ final Map attributes = snmpTreeResponse.getAttributes();
+
+ assertEquals(1, attributes.size());
+ assertEquals(OID_1_VALUE, attributes.get(SNMP_PREFIX + OID_1 + SNMP_SEPARATOR + VB_SYNTAX));
+ }
+
+ @Test
+ public void testGetAttributesFiltersNullVariableBindings() {
+ final TreeEvent nullTreeEvent = mock(TreeEvent.class);
+ when(nullTreeEvent.getVariableBindings()).thenReturn(null);
+ final TreeEvent normalTreeEvent = mock(TreeEvent.class);
+ when(normalTreeEvent.getVariableBindings()).thenReturn(vbs1);
+
+ final List treeEvents = new ArrayList<>();
+ Collections.addAll(treeEvents, nullTreeEvent, normalTreeEvent);
+
+ final SNMPTreeResponse snmpTreeResponse = new SNMPTreeResponse(target, treeEvents);
+ final Map attributes = snmpTreeResponse.getAttributes();
+
+ assertEquals(1, attributes.size());
+ assertEquals(OID_1_VALUE, attributes.get(SNMP_PREFIX + OID_1 + SNMP_SEPARATOR + VB_SYNTAX));
+ }
+
+ @Test
+ public void testGetTargetAddress() {
+ final TreeEvent treeEvent = mock(TreeEvent.class);
+ final List treeEvents = new ArrayList<>();
+ treeEvents.add(treeEvent);
+ final SNMPTreeResponse snmpTreeResponse = new SNMPTreeResponse(target, treeEvents);
+ final String actualTargetAddress = snmpTreeResponse.getTargetAddress();
+
+ assertEquals(TARGET_ADDRESS, actualTargetAddress);
+ }
+
+ @Test
+ public void testLogErrors() {
+ final MockComponentLog logger = new MockComponentLog("id1", new Object());
+
+
+ final List treeEvents = new ArrayList<>();
+ final TreeEvent treeEvent = mock(TreeEvent.class);
+ when(treeEvent.isError()).thenReturn(true);
+ when(treeEvent.getErrorMessage()).thenReturn("ERROR MESSAGE");
+ treeEvents.add(treeEvent);
+ final SNMPTreeResponse snmpTreeResponse = new SNMPTreeResponse(target, treeEvents);
+ snmpTreeResponse.logErrors(logger);
+
+ final List errorMessages = logger.getErrorMessages();
+ System.out.println("asd");
+ }
+}
diff --git a/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/test/java/org/apache/nifi/snmp/factory/SNMPClientFactoryTest.java b/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/test/java/org/apache/nifi/snmp/factory/SNMPClientFactoryTest.java
deleted file mode 100644
index 50719fc451..0000000000
--- a/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/test/java/org/apache/nifi/snmp/factory/SNMPClientFactoryTest.java
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.nifi.snmp.factory;
-
-import org.apache.nifi.snmp.configuration.SNMPConfiguration;
-import org.apache.nifi.snmp.configuration.SNMPConfigurationBuilder;
-import org.junit.jupiter.api.Test;
-import org.snmp4j.Snmp;
-import org.snmp4j.mp.SnmpConstants;
-import org.snmp4j.security.UsmUser;
-import org.snmp4j.smi.OID;
-import org.snmp4j.smi.OctetString;
-
-import static org.hamcrest.CoreMatchers.equalTo;
-import static org.hamcrest.CoreMatchers.is;
-import static org.hamcrest.MatcherAssert.assertThat;
-
-public class SNMPClientFactoryTest {
-
- private final SNMPConfigurationBuilder configurationBuilder = new SNMPConfigurationBuilder()
- .setAgentHost("127.0.0.1")
- .setAgentPort("12345")
- .setRetries(1)
- .setTimeout(1000)
- .setSecurityLevel("noAuthNoPriv")
- .setSecurityName("userName")
- .setAuthProtocol("SHA")
- .setAuthPassphrase("authPassword")
- .setPrivacyProtocol("DES")
- .setPrivacyPassphrase("privacyPassword")
- .setCommunityString("public");
-
- @Test
- public void testSnmpV3ClientWithoutCorrespondingAgentDoesNotHaveUSM() {
- final SNMPConfiguration configuration = configurationBuilder
- .setVersion(SnmpConstants.version3)
- .build();
-
-
- final SNMPFactory snmpFactory = new CompositeSNMPFactory();
- final Snmp snmpManager = snmpFactory.createSnmpManagerInstance(configuration);
- final UsmUser user = snmpManager.getUSM().getUserTable().getUser(new OctetString("userName")).getUsmUser();
-
- final OID usmHMACSHAAuthProtocol = new OID("1.3.6.1.6.3.10.1.1.3");
- final OID usmDESPrivProtocol = new OID("1.3.6.1.6.3.10.1.2.2");
-
- assertThat("userName", is(equalTo(user.getSecurityName().toString())));
- assertThat(usmHMACSHAAuthProtocol, is(equalTo(user.getAuthenticationProtocol())));
- assertThat("authPassword", is(equalTo(user.getAuthenticationPassphrase().toString())));
- assertThat(usmDESPrivProtocol, is(equalTo(user.getPrivacyProtocol())));
- assertThat("privacyPassword", is(equalTo(user.getPrivacyPassphrase().toString())));
- assertThat(3, is(equalTo(user.getSecurityModel())));
- }
-}
diff --git a/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/test/java/org/apache/nifi/snmp/factory/core/SNMPContextTest.java b/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/test/java/org/apache/nifi/snmp/factory/core/SNMPContextTest.java
new file mode 100644
index 0000000000..0d073aca63
--- /dev/null
+++ b/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/test/java/org/apache/nifi/snmp/factory/core/SNMPContextTest.java
@@ -0,0 +1,47 @@
+/*
+ * 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.factory.core;
+
+import org.apache.nifi.snmp.configuration.SNMPConfiguration;
+import org.junit.Test;
+import org.snmp4j.Snmp;
+import org.snmp4j.Target;
+
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+public class SNMPContextTest {
+
+ @Test
+ public void testCreateSNMPContext() {
+ final SNMPContext snmpContext = spy(SNMPContext.class);
+ final Snmp mockSnmpManager = mock(Snmp.class);
+ final Target mockTarget = mock(Target.class);
+ final SNMPConfiguration snmpConfiguration = mock(SNMPConfiguration.class);
+
+ when(snmpContext.createSnmpManagerInstance(snmpConfiguration)).thenReturn(mockSnmpManager);
+ when(snmpContext.createTargetInstance(snmpConfiguration)).thenReturn(mockTarget);
+
+ snmpContext.createSNMPResourceHandler(snmpConfiguration);
+
+ verify(snmpContext).createSnmpManagerInstance(snmpConfiguration);
+ verify(snmpContext).createTargetInstance(snmpConfiguration);
+ }
+
+}
diff --git a/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/test/java/org/apache/nifi/snmp/factory/core/SNMPFactoryProviderTest.java b/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/test/java/org/apache/nifi/snmp/factory/core/SNMPFactoryProviderTest.java
new file mode 100644
index 0000000000..eaf23efe89
--- /dev/null
+++ b/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/test/java/org/apache/nifi/snmp/factory/core/SNMPFactoryProviderTest.java
@@ -0,0 +1,37 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.nifi.snmp.factory.core;
+
+import org.junit.Test;
+import org.snmp4j.mp.SnmpConstants;
+
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.core.IsInstanceOf.instanceOf;
+
+public class SNMPFactoryProviderTest {
+
+ @Test
+ public void testCreateFactoryByVersion() {
+ final SNMPContext snmpV1V2cFactoryFromVersion1 = SNMPFactoryProvider.getFactory(SnmpConstants.version1);
+ final SNMPContext snmpV1V2cFactoryFromVersion2c = SNMPFactoryProvider.getFactory(SnmpConstants.version2c);
+ final SNMPContext snmpV3Factory = SNMPFactoryProvider.getFactory(SnmpConstants.version3);
+ assertThat(snmpV1V2cFactoryFromVersion1, instanceOf(V1V2cSNMPFactory.class));
+ assertThat(snmpV1V2cFactoryFromVersion2c, instanceOf(V1V2cSNMPFactory.class));
+ assertThat(snmpV3Factory, instanceOf(V3SNMPFactory.class));
+ }
+
+}
diff --git a/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/test/java/org/apache/nifi/snmp/factory/core/V1V2cSNMPFactoryTest.java b/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/test/java/org/apache/nifi/snmp/factory/core/V1V2cSNMPFactoryTest.java
new file mode 100644
index 0000000000..281bbecbe7
--- /dev/null
+++ b/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/test/java/org/apache/nifi/snmp/factory/core/V1V2cSNMPFactoryTest.java
@@ -0,0 +1,90 @@
+/*
+ * 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.factory.core;
+
+import org.apache.nifi.remote.io.socket.NetworkUtils;
+import org.apache.nifi.snmp.configuration.SNMPConfiguration;
+import org.apache.nifi.util.StringUtils;
+import org.junit.Test;
+import org.snmp4j.CommunityTarget;
+import org.snmp4j.Snmp;
+import org.snmp4j.Target;
+import org.snmp4j.security.SecurityLevel;
+
+import static org.apache.nifi.snmp.helper.configurations.SNMPConfigurationFactory.DEFAULT_HOST;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.core.IsInstanceOf.instanceOf;
+import static org.junit.Assert.assertEquals;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.verify;
+
+public class V1V2cSNMPFactoryTest {
+
+ private static final int RETRIES = 3;
+
+ @Test
+ public void testFactoryCreatesV1V2Configuration() {
+ final V1V2cSNMPFactory snmpFactory = new V1V2cSNMPFactory();
+ final int managerPort = NetworkUtils.availablePort();
+ final String targetPort = String.valueOf(NetworkUtils.availablePort());
+ final SNMPConfiguration snmpConfiguration = getSnmpConfiguration(managerPort, targetPort);
+
+ final Target target = snmpFactory.createTargetInstance(snmpConfiguration);
+
+ assertThat(target, instanceOf(CommunityTarget.class));
+ assertEquals(DEFAULT_HOST + "/" + targetPort, target.getAddress().toString());
+ assertEquals(RETRIES, target.getRetries());
+ assertEquals(1, target.getSecurityLevel());
+ assertEquals(StringUtils.EMPTY, target.getSecurityName().toString());
+ }
+
+ @Test
+ public void testFactoryCreatesSnmpManager() {
+ final V1V2cSNMPFactory snmpFactory = new V1V2cSNMPFactory();
+ final int managerPort = NetworkUtils.availablePort();
+ final String targetPort = String.valueOf(NetworkUtils.availablePort());
+ final SNMPConfiguration snmpConfiguration = getSnmpConfiguration(managerPort, targetPort);
+
+ final Snmp snmpManager = snmpFactory.createSnmpManagerInstance(snmpConfiguration);
+
+ final String address = snmpManager.getMessageDispatcher().getTransportMappings().iterator().next().getListenAddress().toString();
+ assertEquals(DEFAULT_HOST + "/" + managerPort, address);
+ }
+
+ @Test
+ public void testFactoryCreatesResourceHandler() {
+ final V1V2cSNMPFactory snmpFactory = spy(V1V2cSNMPFactory.class);
+ final int managerPort = NetworkUtils.availablePort();
+ final String targetPort = String.valueOf(NetworkUtils.availablePort());
+ final SNMPConfiguration snmpConfiguration = getSnmpConfiguration(managerPort, targetPort);
+
+ snmpFactory.createSNMPResourceHandler(snmpConfiguration);
+
+ verify(snmpFactory).createTargetInstance(snmpConfiguration);
+ verify(snmpFactory).createSnmpManagerInstance(snmpConfiguration);
+ }
+
+ private SNMPConfiguration getSnmpConfiguration(int managerPort, String targetPort) {
+ return new SNMPConfiguration.Builder()
+ .setRetries(RETRIES)
+ .setManagerPort(managerPort)
+ .setTargetHost(DEFAULT_HOST)
+ .setTargetPort(targetPort)
+ .setSecurityLevel(SecurityLevel.noAuthNoPriv.name())
+ .build();
+ }
+}
diff --git a/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/test/java/org/apache/nifi/snmp/factory/core/V3SNMPFactoryTest.java b/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/test/java/org/apache/nifi/snmp/factory/core/V3SNMPFactoryTest.java
new file mode 100644
index 0000000000..7962389881
--- /dev/null
+++ b/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/test/java/org/apache/nifi/snmp/factory/core/V3SNMPFactoryTest.java
@@ -0,0 +1,107 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.nifi.snmp.factory.core;
+
+import org.apache.nifi.remote.io.socket.NetworkUtils;
+import org.apache.nifi.snmp.configuration.SNMPConfiguration;
+import org.junit.Test;
+import org.snmp4j.Snmp;
+import org.snmp4j.Target;
+import org.snmp4j.UserTarget;
+import org.snmp4j.security.SecurityLevel;
+import org.snmp4j.security.SecurityModels;
+import org.snmp4j.security.USM;
+import org.snmp4j.smi.Integer32;
+import org.snmp4j.smi.OctetString;
+
+import static org.apache.nifi.snmp.helper.configurations.SNMPConfigurationFactory.DEFAULT_HOST;
+import static org.apache.nifi.snmp.helper.configurations.SNMPV3ConfigurationFactory.AUTH_PASSPHRASE;
+import static org.apache.nifi.snmp.helper.configurations.SNMPV3ConfigurationFactory.AUTH_PROTOCOL;
+import static org.apache.nifi.snmp.helper.configurations.SNMPV3ConfigurationFactory.PRIV_PASSPHRASE;
+import static org.apache.nifi.snmp.helper.configurations.SNMPV3ConfigurationFactory.PRIV_PROTOCOL;
+import static org.apache.nifi.snmp.helper.configurations.SNMPV3ConfigurationFactory.SECURITY_NAME;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.core.IsInstanceOf.instanceOf;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.verify;
+
+public class V3SNMPFactoryTest {
+
+ private static final int RETRIES = 3;
+ private static final int EXPECTED_SECURITY_LEVEL = 3;
+
+ @Test
+ public void testFactoryCreatesTarget() {
+ final V3SNMPFactory snmpFactory = new V3SNMPFactory();
+ final int managerPort = NetworkUtils.availablePort();
+ final String targetPort = String.valueOf(NetworkUtils.availablePort());
+ final SNMPConfiguration snmpConfiguration = getSnmpConfiguration(managerPort, targetPort);
+
+ final Target target = snmpFactory.createTargetInstance(snmpConfiguration);
+
+ assertThat(target, instanceOf(UserTarget.class));
+ assertEquals(DEFAULT_HOST + "/" + targetPort, target.getAddress().toString());
+ assertEquals(RETRIES, target.getRetries());
+ assertEquals(EXPECTED_SECURITY_LEVEL, target.getSecurityLevel());
+ assertEquals(SECURITY_NAME, target.getSecurityName().toString());
+ }
+
+ @Test
+ public void testFactoryCreatesSnmpManager() {
+ final V3SNMPFactory snmpFactory = new V3SNMPFactory();
+ final int managerPort = NetworkUtils.availablePort();
+ final String targetPort = String.valueOf(NetworkUtils.availablePort());
+ final SNMPConfiguration snmpConfiguration = getSnmpConfiguration(managerPort, targetPort);
+
+ final Snmp snmpManager = snmpFactory.createSnmpManagerInstance(snmpConfiguration);
+
+ final String address = snmpManager.getMessageDispatcher().getTransportMappings().iterator().next().getListenAddress().toString();
+ USM usm = (USM) SecurityModels.getInstance().getSecurityModel(new Integer32(3));
+ assertEquals(DEFAULT_HOST + "/" + managerPort, address);
+ assertTrue(usm.hasUser(null, new OctetString("SHAAES128")));
+ }
+
+ @Test
+ public void testFactoryCreatesResourceHandler() {
+ final V3SNMPFactory snmpFactory = spy(V3SNMPFactory.class);
+ final int managerPort = NetworkUtils.availablePort();
+ final String targetPort = String.valueOf(NetworkUtils.availablePort());
+ final SNMPConfiguration snmpConfiguration = getSnmpConfiguration(managerPort, targetPort);
+ snmpFactory.createSNMPResourceHandler(snmpConfiguration);
+
+ verify(snmpFactory).createTargetInstance(snmpConfiguration);
+ verify(snmpFactory).createSnmpManagerInstance(snmpConfiguration);
+ }
+
+ private SNMPConfiguration getSnmpConfiguration(int managerPort, String targetPort) {
+ return new SNMPConfiguration.Builder()
+ .setRetries(RETRIES)
+ .setManagerPort(managerPort)
+ .setTargetHost(DEFAULT_HOST)
+ .setTargetPort(targetPort)
+ .setSecurityLevel(SecurityLevel.authPriv.name())
+ .setSecurityName(SECURITY_NAME)
+ .setAuthProtocol(AUTH_PROTOCOL)
+ .setAuthPassphrase(AUTH_PASSPHRASE)
+ .setPrivacyProtocol(PRIV_PROTOCOL)
+ .setPrivacyPassphrase(PRIV_PASSPHRASE)
+ .build();
+ }
+
+}
diff --git a/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/test/java/org/apache/nifi/snmp/factory/trap/V1TrapPDUFactoryTest.java b/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/test/java/org/apache/nifi/snmp/factory/trap/V1TrapPDUFactoryTest.java
new file mode 100644
index 0000000000..3cd699d76d
--- /dev/null
+++ b/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/test/java/org/apache/nifi/snmp/factory/trap/V1TrapPDUFactoryTest.java
@@ -0,0 +1,59 @@
+/*
+ * 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.factory.trap;
+
+import org.apache.nifi.snmp.configuration.V1TrapConfiguration;
+import org.junit.Test;
+import org.snmp4j.PDU;
+import org.snmp4j.PDUv1;
+import org.snmp4j.Target;
+
+import java.time.Instant;
+
+import static org.junit.Assert.assertEquals;
+import static org.mockito.Mockito.mock;
+
+public class V1TrapPDUFactoryTest {
+
+ private static final String AGENT_ADDRESS = "127.0.0.1";
+ private static final String ENTERPRISE_OID = "1.3.6.1.4.1.8072.2.3.0.1";
+ private static final int GENERIC_TRAP_TYPE = 6;
+ private static final int SPECIFIC_TRAP_TYPE = 2;
+
+ @Test
+ public void testCreateV1TrapPdu() {
+ final Target mockTarget = mock(Target.class);
+ final V1TrapConfiguration v1TrapConfiguration = V1TrapConfiguration.builder()
+ .enterpriseOid(ENTERPRISE_OID)
+ .agentAddress(AGENT_ADDRESS)
+ .genericTrapType(String.valueOf(GENERIC_TRAP_TYPE))
+ .specificTrapType(String.valueOf(SPECIFIC_TRAP_TYPE))
+ .build();
+
+ final V1TrapPDUFactory v1TrapPduFactory = new V1TrapPDUFactory(mockTarget, Instant.now());
+ final PDU pdu = v1TrapPduFactory.get(v1TrapConfiguration);
+
+ assertEquals(PDU.V1TRAP, pdu.getType());
+
+ final PDUv1 pduV1 = (PDUv1) pdu;
+
+ assertEquals(ENTERPRISE_OID, pduV1.getEnterprise().toString());
+ assertEquals(AGENT_ADDRESS, pduV1.getAgentAddress().toString());
+ assertEquals(GENERIC_TRAP_TYPE, pduV1.getGenericTrap());
+ assertEquals(SPECIFIC_TRAP_TYPE, pduV1.getSpecificTrap());
+ }
+}
diff --git a/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/test/java/org/apache/nifi/snmp/factory/trap/V2TrapPDUFactoryTest.java b/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/test/java/org/apache/nifi/snmp/factory/trap/V2TrapPDUFactoryTest.java
new file mode 100644
index 0000000000..64b81e9dd8
--- /dev/null
+++ b/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/test/java/org/apache/nifi/snmp/factory/trap/V2TrapPDUFactoryTest.java
@@ -0,0 +1,58 @@
+/*
+ * 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.factory.trap;
+
+import org.apache.nifi.snmp.configuration.V2TrapConfiguration;
+import org.junit.Test;
+import org.snmp4j.PDU;
+import org.snmp4j.Target;
+import org.snmp4j.mp.SnmpConstants;
+import org.snmp4j.smi.VariableBinding;
+
+import java.time.Instant;
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.Set;
+import java.util.Vector;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+
+import static org.junit.Assert.assertTrue;
+import static org.mockito.Mockito.mock;
+
+public class V2TrapPDUFactoryTest {
+
+ private static final String TRAP_OID = "1.3.6.1.4.1.8072.2.3.0.1";
+
+ @Test
+ public void testCreateV2TrapPdu() {
+ final Target mockTarget = mock(Target.class);
+ final V2TrapConfiguration v2TrapConfiguration = new V2TrapConfiguration(TRAP_OID);
+ final V2TrapPDUFactory v2TrapPduFactory = new V2TrapPDUFactory(mockTarget, Instant.now());
+
+ final PDU pdu = v2TrapPduFactory.get(v2TrapConfiguration);
+
+ final Vector extends VariableBinding> variableBindings = pdu.getVariableBindings();
+
+ Set expected = new HashSet<>(Arrays.asList(SnmpConstants.snmpTrapOID.toString(), TRAP_OID));
+ Set actual = variableBindings.stream()
+ .flatMap(c -> Stream.of(c.getOid().toString(), c.getVariable().toString()))
+ .collect(Collectors.toSet());
+ assertTrue(actual.containsAll(expected));
+ }
+
+}
diff --git a/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/test/java/org/apache/nifi/snmp/helper/SNMPTestUtils.java b/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/test/java/org/apache/nifi/snmp/helper/SNMPTestUtils.java
deleted file mode 100644
index 492690fa4f..0000000000
--- a/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/test/java/org/apache/nifi/snmp/helper/SNMPTestUtils.java
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.nifi.snmp.helper;
-
-import org.snmp4j.CommunityTarget;
-import org.snmp4j.Snmp;
-import org.snmp4j.UserTarget;
-import org.snmp4j.security.UsmUser;
-import org.snmp4j.smi.OID;
-import org.snmp4j.smi.OctetString;
-import org.snmp4j.smi.UdpAddress;
-import org.snmp4j.transport.DefaultUdpTransportMapping;
-
-import java.io.IOException;
-
-public class SNMPTestUtils {
-
- public static Snmp createSnmpClient() throws IOException {
- final DefaultUdpTransportMapping transportMapping = new DefaultUdpTransportMapping();
- transportMapping.listen();
- return new Snmp(transportMapping);
- }
-
- public static CommunityTarget createCommTarget(final String community, final String address, final int version) {
- final CommunityTarget target = new CommunityTarget();
- target.setVersion(version);
- target.setCommunity(new OctetString(community));
- target.setAddress(new UdpAddress(address));
- target.setRetries(0);
- target.setTimeout(500);
- return target;
- }
-
- public static UserTarget createUserTarget(final String address, final int securityLevel, final String securityName, final int version) {
- final UserTarget target = new UserTarget();
- target.setVersion(version);
- target.setSecurityLevel(securityLevel);
- target.setSecurityName(new OctetString(securityName));
- target.setAddress(new UdpAddress(address));
- target.setRetries(0);
- target.setTimeout(500);
- return target;
- }
-
- public static UserTarget prepareUser(final Snmp snmp, final int version, final String address, final int securityLevel, final String securityName,
- final OID auth, final OID priv, final String authPwd, final String privPwd) {
- snmp.getUSM().removeAllUsers();
- final OctetString aPwd = authPwd != null ? new OctetString(authPwd) : null;
- final OctetString pPwd = privPwd != null ? new OctetString(privPwd) : null;
- snmp.getUSM().addUser(new OctetString(securityName), new UsmUser(new OctetString(securityName), auth, aPwd, priv, pPwd));
- return createUserTarget(address, securityLevel, securityName, version);
- }
-
-}
diff --git a/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/test/java/org/apache/nifi/snmp/helper/TrapConfigurationFactory.java b/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/test/java/org/apache/nifi/snmp/helper/TrapConfigurationFactory.java
new file mode 100644
index 0000000000..dff77e8e79
--- /dev/null
+++ b/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/test/java/org/apache/nifi/snmp/helper/TrapConfigurationFactory.java
@@ -0,0 +1,46 @@
+/*
+ * 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.helper;
+
+import org.apache.nifi.snmp.configuration.V1TrapConfiguration;
+import org.apache.nifi.snmp.configuration.V2TrapConfiguration;
+import org.snmp4j.PDUv1;
+
+public class TrapConfigurationFactory {
+
+ // v1 specific
+ private static final String ENTERPRISE_OID = "1.3.5.7.11";
+ private static final String AGENT_ADDRESS = "1.2.3.4";
+ private static final String GENERIC_TRAP_TYPE = String.valueOf(PDUv1.ENTERPRISE_SPECIFIC);
+ private static final String SPECIFIC_TRAP_TYPE = "2";
+
+ // v2c/v3 specific
+ private static final String TRAP_OID_VALUE = "testTrapOidValue";
+
+ public static V1TrapConfiguration getV1TrapConfiguration() {
+ return V1TrapConfiguration.builder()
+ .enterpriseOid(ENTERPRISE_OID)
+ .agentAddress(AGENT_ADDRESS)
+ .genericTrapType(GENERIC_TRAP_TYPE)
+ .specificTrapType(SPECIFIC_TRAP_TYPE)
+ .build();
+ }
+
+ public static V2TrapConfiguration getV2TrapConfiguration() {
+ return new V2TrapConfiguration(TRAP_OID_VALUE);
+ }
+}
diff --git a/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/main/java/org/apache/nifi/snmp/factory/SNMPFactory.java b/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/test/java/org/apache/nifi/snmp/helper/configurations/SNMPConfigurationFactory.java
similarity index 67%
rename from nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/main/java/org/apache/nifi/snmp/factory/SNMPFactory.java
rename to nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/test/java/org/apache/nifi/snmp/helper/configurations/SNMPConfigurationFactory.java
index 442c03e092..89e8bd4db5 100644
--- a/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/main/java/org/apache/nifi/snmp/factory/SNMPFactory.java
+++ b/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/test/java/org/apache/nifi/snmp/helper/configurations/SNMPConfigurationFactory.java
@@ -14,17 +14,19 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.apache.nifi.snmp.factory;
+package org.apache.nifi.snmp.helper.configurations;
import org.apache.nifi.snmp.configuration.SNMPConfiguration;
-import org.snmp4j.Snmp;
-import org.snmp4j.Target;
-public interface SNMPFactory {
+public interface SNMPConfigurationFactory {
- boolean supports(final int version);
+ String DEFAULT_HOST = "127.0.0.1";
+ String COMMUNITY_STRING = "public";
- Snmp createSnmpManagerInstance(final SNMPConfiguration configuration);
+ SNMPConfiguration createSnmpGetSetConfiguration(int agentPort);
+
+ SNMPConfiguration createSnmpGetSetConfigWithCustomHost(final String host, final int agentPort);
+
+ SNMPConfiguration createSnmpListenTrapConfig(final int managerPort);
- Target createTargetInstance(final SNMPConfiguration configuration);
}
diff --git a/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/test/java/org/apache/nifi/snmp/helper/configurations/SNMPV1V2cConfigurationFactory.java b/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/test/java/org/apache/nifi/snmp/helper/configurations/SNMPV1V2cConfigurationFactory.java
new file mode 100644
index 0000000000..72591bec15
--- /dev/null
+++ b/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/test/java/org/apache/nifi/snmp/helper/configurations/SNMPV1V2cConfigurationFactory.java
@@ -0,0 +1,57 @@
+/*
+ * 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.helper.configurations;
+
+import org.apache.nifi.snmp.configuration.SNMPConfiguration;
+
+public class SNMPV1V2cConfigurationFactory implements SNMPConfigurationFactory {
+
+ private int snmpVersion;
+
+ public SNMPV1V2cConfigurationFactory(int snmpVersion) {
+ this.snmpVersion = snmpVersion;
+ }
+
+ @Override
+ public SNMPConfiguration createSnmpGetSetConfiguration(final int agentPort) {
+ return SNMPConfiguration.builder()
+ .setTargetHost(DEFAULT_HOST)
+ .setTargetPort(String.valueOf(agentPort))
+ .setCommunityString(COMMUNITY_STRING)
+ .setVersion(snmpVersion)
+ .build();
+ }
+
+ @Override
+ public SNMPConfiguration createSnmpGetSetConfigWithCustomHost(final String host, final int agentPort) {
+ return SNMPConfiguration.builder()
+ .setTargetHost(host)
+ .setTargetPort(String.valueOf(agentPort))
+ .setCommunityString(COMMUNITY_STRING)
+ .setVersion(snmpVersion)
+ .build();
+ }
+
+ @Override
+ public SNMPConfiguration createSnmpListenTrapConfig(final int managerPort) {
+ return SNMPConfiguration.builder()
+ .setManagerPort(managerPort)
+ .setCommunityString(COMMUNITY_STRING)
+ .setVersion(snmpVersion)
+ .build();
+ }
+}
diff --git a/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/test/java/org/apache/nifi/snmp/helper/configurations/SNMPV3ConfigurationFactory.java b/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/test/java/org/apache/nifi/snmp/helper/configurations/SNMPV3ConfigurationFactory.java
new file mode 100644
index 0000000000..7a278f5bbc
--- /dev/null
+++ b/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/test/java/org/apache/nifi/snmp/helper/configurations/SNMPV3ConfigurationFactory.java
@@ -0,0 +1,71 @@
+/*
+ * 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.helper.configurations;
+
+import org.apache.nifi.snmp.configuration.SNMPConfiguration;
+import org.snmp4j.mp.SnmpConstants;
+
+public class SNMPV3ConfigurationFactory implements SNMPConfigurationFactory {
+
+ // V3 security (users are set in test agents)
+ public static final String SECURITY_LEVEL = "authPriv";
+ public static final String SECURITY_NAME = "SHAAES128";
+ public static final String AUTH_PROTOCOL = "SHA";
+ public static final String AUTH_PASSPHRASE = "SHAAES128AuthPassphrase";
+ public static final String PRIV_PROTOCOL = "AES128";
+ public static final String PRIV_PASSPHRASE = "SHAAES128PrivPassphrase";
+
+ @Override
+ public SNMPConfiguration createSnmpGetSetConfiguration(final int agentPort) {
+ return SNMPConfiguration.builder()
+ .setTargetHost(DEFAULT_HOST)
+ .setTargetPort(String.valueOf(agentPort))
+ .setCommunityString(COMMUNITY_STRING)
+ .setVersion(SnmpConstants.version3)
+ .setSecurityLevel(SECURITY_LEVEL)
+ .setSecurityName(SECURITY_NAME)
+ .setAuthProtocol(AUTH_PROTOCOL)
+ .setAuthPassphrase(AUTH_PASSPHRASE)
+ .setPrivacyProtocol(PRIV_PROTOCOL)
+ .setPrivacyPassphrase(PRIV_PASSPHRASE)
+ .build();
+ }
+
+ @Override
+ public SNMPConfiguration createSnmpGetSetConfigWithCustomHost(final String host, final int agentPort) {
+ return SNMPConfiguration.builder()
+ .setTargetHost(host)
+ .setTargetPort(String.valueOf(agentPort))
+ .setCommunityString(COMMUNITY_STRING)
+ .setVersion(SnmpConstants.version3)
+ .setSecurityLevel(SECURITY_LEVEL)
+ .setSecurityName(SECURITY_NAME)
+ .setAuthProtocol(AUTH_PROTOCOL)
+ .setAuthPassphrase(AUTH_PASSPHRASE)
+ .setPrivacyProtocol(PRIV_PROTOCOL)
+ .setPrivacyPassphrase(PRIV_PASSPHRASE)
+ .build();
+ }
+
+ @Override
+ public SNMPConfiguration createSnmpListenTrapConfig(final int managerPort) {
+ return SNMPConfiguration.builder()
+ .setManagerPort(managerPort)
+ .setVersion(SnmpConstants.version3)
+ .build();
+ }
+}
diff --git a/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/test/java/org/apache/nifi/snmp/helper/testrunners/SNMPTestRunnerFactory.java b/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/test/java/org/apache/nifi/snmp/helper/testrunners/SNMPTestRunnerFactory.java
new file mode 100644
index 0000000000..4096f45a00
--- /dev/null
+++ b/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/test/java/org/apache/nifi/snmp/helper/testrunners/SNMPTestRunnerFactory.java
@@ -0,0 +1,58 @@
+/*
+ * 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.helper.testrunners;
+
+import org.apache.nifi.snmp.exception.InvalidSnmpVersionException;
+import org.apache.nifi.util.MockFlowFile;
+import org.apache.nifi.util.TestRunner;
+import org.snmp4j.mp.SnmpConstants;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import static org.apache.nifi.snmp.utils.SNMPUtils.SNMP_PROP_PREFIX;
+
+public interface SNMPTestRunnerFactory {
+
+ TestRunner createSnmpGetTestRunner(final int agentPort, final String oid, final String strategy);
+
+ TestRunner createSnmpSetTestRunner(final int agentPort, final String oid, final String oidValue);
+
+ TestRunner createSnmpSendTrapTestRunner(final int managerPort, final String oid, final String oidValue);
+
+ TestRunner createSnmpListenTrapTestRunner(final int managerPort);
+
+ default MockFlowFile getFlowFile(String oid, String oidValue) {
+ final MockFlowFile flowFile = new MockFlowFile(1L);
+ final Map attributes = new HashMap<>();
+ attributes.put(SNMP_PROP_PREFIX + oid, oidValue);
+ flowFile.putAttributes(attributes);
+ return flowFile;
+ }
+
+ default String getVersionName(final int version) {
+ if (version == SnmpConstants.version1) {
+ return "SNMPv1";
+ } else if (version == SnmpConstants.version2c) {
+ return "SNMPv2c";
+ } else if (version == SnmpConstants.version3) {
+ return "SNMPv3";
+ } else {
+ throw new InvalidSnmpVersionException("Invalid SNMP version");
+ }
+ }
+}
diff --git a/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/test/java/org/apache/nifi/snmp/helper/testrunners/SNMPV1TestRunnerFactory.java b/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/test/java/org/apache/nifi/snmp/helper/testrunners/SNMPV1TestRunnerFactory.java
new file mode 100644
index 0000000000..4bb17b5318
--- /dev/null
+++ b/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/test/java/org/apache/nifi/snmp/helper/testrunners/SNMPV1TestRunnerFactory.java
@@ -0,0 +1,93 @@
+/*
+ * 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.helper.testrunners;
+
+import org.apache.nifi.snmp.configuration.SNMPConfiguration;
+import org.apache.nifi.snmp.configuration.V1TrapConfiguration;
+import org.apache.nifi.snmp.helper.TrapConfigurationFactory;
+import org.apache.nifi.snmp.helper.configurations.SNMPConfigurationFactory;
+import org.apache.nifi.snmp.helper.configurations.SNMPV1V2cConfigurationFactory;
+import org.apache.nifi.snmp.processors.GetSNMP;
+import org.apache.nifi.snmp.processors.ListenTrapSNMP;
+import org.apache.nifi.snmp.processors.SendTrapSNMP;
+import org.apache.nifi.snmp.processors.SetSNMP;
+import org.apache.nifi.snmp.processors.properties.BasicProperties;
+import org.apache.nifi.snmp.processors.properties.V1TrapProperties;
+import org.apache.nifi.util.MockFlowFile;
+import org.apache.nifi.util.TestRunner;
+import org.apache.nifi.util.TestRunners;
+import org.snmp4j.mp.SnmpConstants;
+
+public class SNMPV1TestRunnerFactory implements SNMPTestRunnerFactory {
+
+
+ private static final SNMPConfigurationFactory snmpV1V2ConfigurationFactory = new SNMPV1V2cConfigurationFactory(SnmpConstants.version1);
+
+ @Override
+ public TestRunner createSnmpGetTestRunner(final int agentPort, final String oid, final String strategy) {
+ final TestRunner runner = TestRunners.newTestRunner(GetSNMP.class);
+ final SNMPConfiguration snmpConfiguration = snmpV1V2ConfigurationFactory.createSnmpGetSetConfiguration(agentPort);
+ runner.setProperty(GetSNMP.AGENT_HOST, snmpConfiguration.getTargetHost());
+ runner.setProperty(GetSNMP.AGENT_PORT, snmpConfiguration.getTargetPort());
+ runner.setProperty(BasicProperties.SNMP_COMMUNITY, snmpConfiguration.getCommunityString());
+ runner.setProperty(BasicProperties.SNMP_VERSION, getVersionName(snmpConfiguration.getVersion()));
+ runner.setProperty(GetSNMP.SNMP_STRATEGY, strategy);
+ runner.setProperty(GetSNMP.OID, oid);
+ return runner;
+ }
+
+ @Override
+ public TestRunner createSnmpSetTestRunner(final int agentPort, final String oid, final String oidValue) {
+ final TestRunner runner = TestRunners.newTestRunner(SetSNMP.class);
+ final SNMPConfiguration snmpConfiguration = snmpV1V2ConfigurationFactory.createSnmpGetSetConfiguration(agentPort);
+ runner.setProperty(SetSNMP.AGENT_HOST, snmpConfiguration.getTargetHost());
+ runner.setProperty(SetSNMP.AGENT_PORT, snmpConfiguration.getTargetPort());
+ runner.setProperty(BasicProperties.SNMP_COMMUNITY, snmpConfiguration.getCommunityString());
+ runner.setProperty(BasicProperties.SNMP_VERSION, getVersionName(snmpConfiguration.getVersion()));
+ final MockFlowFile flowFile = getFlowFile(oid, oidValue);
+ runner.enqueue(flowFile);
+ return runner;
+ }
+
+ @Override
+ public TestRunner createSnmpSendTrapTestRunner(final int managerPort, final String oid, final String oidValue) {
+ final TestRunner runner = TestRunners.newTestRunner(SendTrapSNMP.class);
+ final SNMPConfiguration snmpConfiguration = snmpV1V2ConfigurationFactory.createSnmpGetSetConfiguration(managerPort);
+ final V1TrapConfiguration trapConfiguration = TrapConfigurationFactory.getV1TrapConfiguration();
+ runner.setProperty(SendTrapSNMP.SNMP_MANAGER_HOST, snmpConfiguration.getTargetHost());
+ runner.setProperty(SendTrapSNMP.SNMP_MANAGER_PORT, snmpConfiguration.getTargetPort());
+ runner.setProperty(BasicProperties.SNMP_COMMUNITY, snmpConfiguration.getCommunityString());
+ runner.setProperty(BasicProperties.SNMP_VERSION, getVersionName(snmpConfiguration.getVersion()));
+ runner.setProperty(V1TrapProperties.ENTERPRISE_OID, trapConfiguration.getEnterpriseOid());
+ runner.setProperty(V1TrapProperties.AGENT_ADDRESS, trapConfiguration.getAgentAddress());
+ runner.setProperty(V1TrapProperties.GENERIC_TRAP_TYPE, String.valueOf(trapConfiguration.getGenericTrapType()));
+ runner.setProperty(V1TrapProperties.SPECIFIC_TRAP_TYPE, String.valueOf(trapConfiguration.getSpecificTrapType()));
+ final MockFlowFile flowFile = getFlowFile(oid, oidValue);
+ runner.enqueue(flowFile);
+ return runner;
+ }
+
+ @Override
+ public TestRunner createSnmpListenTrapTestRunner(final int managerPort) {
+ final TestRunner runner = TestRunners.newTestRunner(ListenTrapSNMP.class);
+ final SNMPConfiguration snmpConfiguration = snmpV1V2ConfigurationFactory.createSnmpListenTrapConfig(managerPort);
+ runner.setProperty(ListenTrapSNMP.SNMP_MANAGER_PORT, String.valueOf(snmpConfiguration.getManagerPort()));
+ runner.setProperty(BasicProperties.SNMP_COMMUNITY, snmpConfiguration.getCommunityString());
+ runner.setProperty(BasicProperties.SNMP_VERSION, getVersionName(snmpConfiguration.getVersion()));
+ return runner;
+ }
+}
diff --git a/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/test/java/org/apache/nifi/snmp/helper/testrunners/SNMPV2cTestRunnerFactory.java b/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/test/java/org/apache/nifi/snmp/helper/testrunners/SNMPV2cTestRunnerFactory.java
new file mode 100644
index 0000000000..63fc49e6b2
--- /dev/null
+++ b/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/test/java/org/apache/nifi/snmp/helper/testrunners/SNMPV2cTestRunnerFactory.java
@@ -0,0 +1,89 @@
+/*
+ * 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.helper.testrunners;
+
+import org.apache.nifi.snmp.configuration.SNMPConfiguration;
+import org.apache.nifi.snmp.configuration.V2TrapConfiguration;
+import org.apache.nifi.snmp.helper.TrapConfigurationFactory;
+import org.apache.nifi.snmp.helper.configurations.SNMPConfigurationFactory;
+import org.apache.nifi.snmp.helper.configurations.SNMPV1V2cConfigurationFactory;
+import org.apache.nifi.snmp.processors.GetSNMP;
+import org.apache.nifi.snmp.processors.ListenTrapSNMP;
+import org.apache.nifi.snmp.processors.SendTrapSNMP;
+import org.apache.nifi.snmp.processors.SetSNMP;
+import org.apache.nifi.snmp.processors.properties.BasicProperties;
+import org.apache.nifi.snmp.processors.properties.V2TrapProperties;
+import org.apache.nifi.util.MockFlowFile;
+import org.apache.nifi.util.TestRunner;
+import org.apache.nifi.util.TestRunners;
+import org.snmp4j.mp.SnmpConstants;
+
+public class SNMPV2cTestRunnerFactory implements SNMPTestRunnerFactory {
+
+ private static final SNMPConfigurationFactory snmpV2cConfigurationFactory = new SNMPV1V2cConfigurationFactory(SnmpConstants.version2c);
+
+ @Override
+ public TestRunner createSnmpGetTestRunner(int agentPort, String oid, String strategy) {
+ final TestRunner runner = TestRunners.newTestRunner(GetSNMP.class);
+ final SNMPConfiguration snmpConfiguration = snmpV2cConfigurationFactory.createSnmpGetSetConfiguration(agentPort);
+ runner.setProperty(GetSNMP.OID, oid);
+ runner.setProperty(GetSNMP.AGENT_HOST, snmpConfiguration.getTargetHost());
+ runner.setProperty(GetSNMP.AGENT_PORT, snmpConfiguration.getTargetPort());
+ runner.setProperty(BasicProperties.SNMP_COMMUNITY, snmpConfiguration.getCommunityString());
+ runner.setProperty(BasicProperties.SNMP_VERSION, getVersionName(snmpConfiguration.getVersion()));
+ runner.setProperty(GetSNMP.SNMP_STRATEGY, strategy);
+ return runner;
+ }
+
+ @Override
+ public TestRunner createSnmpSetTestRunner(int agentPort, String oid, String oidValue) {
+ final TestRunner runner = TestRunners.newTestRunner(SetSNMP.class);
+ final SNMPConfiguration snmpConfiguration = snmpV2cConfigurationFactory.createSnmpGetSetConfiguration(agentPort);
+ runner.setProperty(SetSNMP.AGENT_HOST, snmpConfiguration.getTargetHost());
+ runner.setProperty(SetSNMP.AGENT_PORT, snmpConfiguration.getTargetPort());
+ runner.setProperty(BasicProperties.SNMP_COMMUNITY, snmpConfiguration.getCommunityString());
+ runner.setProperty(BasicProperties.SNMP_VERSION, getVersionName(snmpConfiguration.getVersion()));
+ final MockFlowFile flowFile = getFlowFile(oid, oidValue);
+ runner.enqueue(flowFile);
+ return runner;
+ }
+
+ @Override
+ public TestRunner createSnmpSendTrapTestRunner(int managerPort, final String oid, final String oidValue) {
+ final TestRunner runner = TestRunners.newTestRunner(SendTrapSNMP.class);
+ final SNMPConfiguration snmpConfiguration = snmpV2cConfigurationFactory.createSnmpGetSetConfiguration(managerPort);
+ final V2TrapConfiguration trapConfiguration = TrapConfigurationFactory.getV2TrapConfiguration();
+ runner.setProperty(SendTrapSNMP.SNMP_MANAGER_HOST, snmpConfiguration.getTargetHost());
+ runner.setProperty(SendTrapSNMP.SNMP_MANAGER_PORT, snmpConfiguration.getTargetPort());
+ runner.setProperty(BasicProperties.SNMP_COMMUNITY, snmpConfiguration.getCommunityString());
+ runner.setProperty(BasicProperties.SNMP_VERSION, getVersionName(snmpConfiguration.getVersion()));
+ runner.setProperty(V2TrapProperties.TRAP_OID_VALUE, trapConfiguration.getTrapOidValue());
+ final MockFlowFile flowFile = getFlowFile(oid, oidValue);
+ runner.enqueue(flowFile);
+ return runner;
+ }
+
+ @Override
+ public TestRunner createSnmpListenTrapTestRunner(int managerPort) {
+ final TestRunner runner = TestRunners.newTestRunner(ListenTrapSNMP.class);
+ final SNMPConfiguration snmpConfiguration = snmpV2cConfigurationFactory.createSnmpListenTrapConfig(managerPort);
+ runner.setProperty(ListenTrapSNMP.SNMP_MANAGER_PORT, String.valueOf(snmpConfiguration.getManagerPort()));
+ runner.setProperty(BasicProperties.SNMP_COMMUNITY, snmpConfiguration.getCommunityString());
+ runner.setProperty(BasicProperties.SNMP_VERSION, getVersionName(snmpConfiguration.getVersion()));
+ return runner;
+ }
+}
diff --git a/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/test/java/org/apache/nifi/snmp/helper/testrunners/SNMPV3TestRunnerFactory.java b/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/test/java/org/apache/nifi/snmp/helper/testrunners/SNMPV3TestRunnerFactory.java
new file mode 100644
index 0000000000..998766e21f
--- /dev/null
+++ b/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/test/java/org/apache/nifi/snmp/helper/testrunners/SNMPV3TestRunnerFactory.java
@@ -0,0 +1,112 @@
+/*
+ * 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.helper.testrunners;
+
+import org.apache.nifi.snmp.configuration.SNMPConfiguration;
+import org.apache.nifi.snmp.configuration.V2TrapConfiguration;
+import org.apache.nifi.snmp.helper.TrapConfigurationFactory;
+import org.apache.nifi.snmp.helper.configurations.SNMPConfigurationFactory;
+import org.apache.nifi.snmp.helper.configurations.SNMPV3ConfigurationFactory;
+import org.apache.nifi.snmp.processors.GetSNMP;
+import org.apache.nifi.snmp.processors.ListenTrapSNMP;
+import org.apache.nifi.snmp.processors.SendTrapSNMP;
+import org.apache.nifi.snmp.processors.SetSNMP;
+import org.apache.nifi.snmp.processors.properties.BasicProperties;
+import org.apache.nifi.snmp.processors.properties.V2TrapProperties;
+import org.apache.nifi.snmp.processors.properties.V3SecurityProperties;
+import org.apache.nifi.util.MockFlowFile;
+import org.apache.nifi.util.TestRunner;
+import org.apache.nifi.util.TestRunners;
+
+public class SNMPV3TestRunnerFactory implements SNMPTestRunnerFactory {
+
+ private static final String USM_USERS_FILE_PATH = "src/test/resources/usm.json";
+ private static final SNMPConfigurationFactory snmpV3ConfigurationFactory = new SNMPV3ConfigurationFactory();
+
+ @Override
+ public TestRunner createSnmpGetTestRunner(int agentPort, String oid, String strategy) {
+ final TestRunner runner = TestRunners.newTestRunner(GetSNMP.class);
+ final SNMPConfiguration snmpConfiguration = snmpV3ConfigurationFactory.createSnmpGetSetConfiguration(agentPort);
+ runner.setProperty(GetSNMP.OID, oid);
+ runner.setProperty(GetSNMP.SNMP_STRATEGY, strategy);
+ runner.setProperty(GetSNMP.AGENT_HOST, snmpConfiguration.getTargetHost());
+ runner.setProperty(GetSNMP.AGENT_PORT, snmpConfiguration.getTargetPort());
+ runner.setProperty(BasicProperties.SNMP_COMMUNITY, snmpConfiguration.getCommunityString());
+ runner.setProperty(BasicProperties.SNMP_VERSION, getVersionName(snmpConfiguration.getVersion()));
+ runner.setProperty(V3SecurityProperties.SNMP_SECURITY_LEVEL, snmpConfiguration.getSecurityLevel());
+ runner.setProperty(V3SecurityProperties.SNMP_SECURITY_NAME, snmpConfiguration.getSecurityName());
+ runner.setProperty(V3SecurityProperties.SNMP_AUTH_PROTOCOL, snmpConfiguration.getAuthProtocol());
+ runner.setProperty(V3SecurityProperties.SNMP_AUTH_PASSWORD, snmpConfiguration.getAuthPassphrase());
+ runner.setProperty(V3SecurityProperties.SNMP_PRIVACY_PROTOCOL, snmpConfiguration.getPrivacyProtocol());
+ runner.setProperty(V3SecurityProperties.SNMP_PRIVACY_PASSWORD, snmpConfiguration.getPrivacyPassphrase());
+ return runner;
+ }
+
+ @Override
+ public TestRunner createSnmpSetTestRunner(int agentPort, String oid, String oidValue) {
+ final TestRunner runner = TestRunners.newTestRunner(SetSNMP.class);
+ final SNMPConfiguration snmpConfiguration = snmpV3ConfigurationFactory.createSnmpGetSetConfiguration(agentPort);
+ runner.setProperty(SetSNMP.AGENT_HOST, snmpConfiguration.getTargetHost());
+ runner.setProperty(SetSNMP.AGENT_PORT, snmpConfiguration.getTargetPort());
+ runner.setProperty(BasicProperties.SNMP_COMMUNITY, snmpConfiguration.getCommunityString());
+ runner.setProperty(BasicProperties.SNMP_VERSION, getVersionName(snmpConfiguration.getVersion()));
+ runner.setProperty(V3SecurityProperties.SNMP_SECURITY_LEVEL, snmpConfiguration.getSecurityLevel());
+ runner.setProperty(V3SecurityProperties.SNMP_SECURITY_NAME, snmpConfiguration.getSecurityName());
+ runner.setProperty(V3SecurityProperties.SNMP_AUTH_PROTOCOL, snmpConfiguration.getAuthProtocol());
+ runner.setProperty(V3SecurityProperties.SNMP_AUTH_PASSWORD, snmpConfiguration.getAuthPassphrase());
+ runner.setProperty(V3SecurityProperties.SNMP_PRIVACY_PROTOCOL, snmpConfiguration.getPrivacyProtocol());
+ runner.setProperty(V3SecurityProperties.SNMP_PRIVACY_PASSWORD, snmpConfiguration.getPrivacyPassphrase());
+ final MockFlowFile flowFile = getFlowFile(oid, oidValue);
+ runner.enqueue(flowFile);
+ return runner;
+ }
+
+ @Override
+ public TestRunner createSnmpSendTrapTestRunner(int managerPort, final String oid, final String oidValue) {
+ final TestRunner runner = TestRunners.newTestRunner(SendTrapSNMP.class);
+ final SNMPConfiguration snmpConfiguration = snmpV3ConfigurationFactory.createSnmpGetSetConfiguration(managerPort);
+ final V2TrapConfiguration trapConfiguration = TrapConfigurationFactory.getV2TrapConfiguration();
+ runner.setProperty(SendTrapSNMP.SNMP_MANAGER_HOST, snmpConfiguration.getTargetHost());
+ runner.setProperty(SendTrapSNMP.SNMP_MANAGER_PORT, snmpConfiguration.getTargetPort());
+ runner.setProperty(BasicProperties.SNMP_COMMUNITY, snmpConfiguration.getCommunityString());
+ runner.setProperty(BasicProperties.SNMP_VERSION, getVersionName(snmpConfiguration.getVersion()));
+ runner.setProperty(V2TrapProperties.TRAP_OID_VALUE, trapConfiguration.getTrapOidValue());
+
+ runner.setProperty(V3SecurityProperties.SNMP_SECURITY_LEVEL, snmpConfiguration.getSecurityLevel());
+ runner.setProperty(V3SecurityProperties.SNMP_SECURITY_NAME, snmpConfiguration.getSecurityName());
+ runner.setProperty(V3SecurityProperties.SNMP_AUTH_PROTOCOL, snmpConfiguration.getAuthProtocol());
+ runner.setProperty(V3SecurityProperties.SNMP_AUTH_PASSWORD, snmpConfiguration.getAuthPassphrase());
+ runner.setProperty(V3SecurityProperties.SNMP_PRIVACY_PROTOCOL, snmpConfiguration.getPrivacyProtocol());
+ runner.setProperty(V3SecurityProperties.SNMP_PRIVACY_PASSWORD, snmpConfiguration.getPrivacyPassphrase());
+
+ final MockFlowFile flowFile = getFlowFile(oid, oidValue);
+ runner.enqueue(flowFile);
+
+ return runner;
+ }
+
+ @Override
+ public TestRunner createSnmpListenTrapTestRunner(int managerPort) {
+ final TestRunner runner = TestRunners.newTestRunner(ListenTrapSNMP.class);
+ final SNMPConfiguration snmpConfiguration = snmpV3ConfigurationFactory.createSnmpListenTrapConfig(managerPort);
+ runner.setProperty(ListenTrapSNMP.SNMP_MANAGER_PORT, String.valueOf(snmpConfiguration.getManagerPort()));
+ runner.setProperty(BasicProperties.SNMP_VERSION, getVersionName(snmpConfiguration.getVersion()));
+ runner.setProperty(ListenTrapSNMP.SNMP_USM_USERS_FILE_PATH, USM_USERS_FILE_PATH);
+
+ return runner;
+ }
+}
diff --git a/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/test/java/org/apache/nifi/snmp/operations/GetSNMPHandlerTest.java b/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/test/java/org/apache/nifi/snmp/operations/GetSNMPHandlerTest.java
new file mode 100644
index 0000000000..8c98ec100b
--- /dev/null
+++ b/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/test/java/org/apache/nifi/snmp/operations/GetSNMPHandlerTest.java
@@ -0,0 +1,271 @@
+/*
+ * 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.operations;
+
+import org.apache.nifi.snmp.dto.SNMPSingleResponse;
+import org.apache.nifi.snmp.dto.SNMPTreeResponse;
+import org.apache.nifi.snmp.exception.RequestTimeoutException;
+import org.apache.nifi.snmp.exception.SNMPWalkException;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.ArgumentCaptor;
+import org.mockito.Mockito;
+import org.snmp4j.PDU;
+import org.snmp4j.Snmp;
+import org.snmp4j.Target;
+import org.snmp4j.event.ResponseEvent;
+import org.snmp4j.smi.OID;
+import org.snmp4j.smi.OctetString;
+import org.snmp4j.smi.VariableBinding;
+import org.snmp4j.util.TreeEvent;
+import org.snmp4j.util.TreeUtils;
+
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Optional;
+
+import static org.apache.nifi.snmp.operations.GetSNMPHandler.EMPTY_SUBTREE_EXCEPTION_MESSAGE;
+import static org.apache.nifi.snmp.operations.GetSNMPHandler.LEAF_ELEMENT_EXCEPTION_MESSAGE;
+import static org.apache.nifi.snmp.operations.GetSNMPHandler.SNMP_ERROR_EXCEPTION_MESSAGE;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+public class GetSNMPHandlerTest {
+
+ private static final String OID = "1.3.6.1.4.1.343";
+
+ private Target mockTarget;
+ private Snmp mockSnmpManager;
+ private SNMPResourceHandler snmpResourceHandler;
+
+ @Before
+ public void init() {
+ mockTarget = mock(Target.class);
+ mockSnmpManager = mock(Snmp.class);
+ snmpResourceHandler = new SNMPResourceHandler(mockSnmpManager, mockTarget);
+ }
+
+ @Test
+ public void testGetSnmpWithEmptyFlowFile() throws IOException {
+ final ResponseEvent mockResponseEvent = mock(ResponseEvent.class);
+ final PDU mockPdu = mock(PDU.class);
+ when(mockResponseEvent.getResponse()).thenReturn(mockPdu);
+ when(mockSnmpManager.get(any(PDU.class), any(Target.class))).thenReturn(mockResponseEvent);
+
+ final GetSNMPHandler getSNMPHandler = new GetSNMPHandler(snmpResourceHandler);
+ getSNMPHandler.get(OID);
+
+ ArgumentCaptor captor = ArgumentCaptor.forClass(PDU.class);
+ Mockito.verify(mockSnmpManager).get(captor.capture(), any(Target.class));
+
+ final PDU pdu = captor.getValue();
+ assertEquals(1, pdu.getVariableBindings().size());
+ assertEquals(OID, pdu.getVariableBindings().get(0).getOid().toString());
+ }
+
+ @Test
+ public void testGetSnmpWithInvalidFlowFile() throws IOException {
+ final Map invalidFlowFileAttributes = new HashMap<>();
+ invalidFlowFileAttributes.put("invalid", "flowfile attribute");
+
+ final ResponseEvent mockResponseEvent = mock(ResponseEvent.class);
+ final PDU mockPdu = mock(PDU.class);
+ when(mockResponseEvent.getResponse()).thenReturn(mockPdu);
+ when(mockSnmpManager.get(any(PDU.class), any(Target.class))).thenReturn(mockResponseEvent);
+
+ final GetSNMPHandler getSNMPHandler = new GetSNMPHandler(snmpResourceHandler);
+ final Optional optionalResponse = getSNMPHandler.get(invalidFlowFileAttributes);
+
+ assertFalse(optionalResponse.isPresent());
+ }
+
+ @Test
+ public void testGetSnmpWithValidFlowFile() throws IOException {
+ final String flowFileOid = "1.3.6.1.2.1.1.1.0";
+ final Map flowFileAttributes = new HashMap<>();
+ flowFileAttributes.put("snmp$" + flowFileOid, "OID value");
+
+ final ResponseEvent mockResponseEvent = mock(ResponseEvent.class);
+ final PDU mockPdu = mock(PDU.class);
+ when(mockResponseEvent.getResponse()).thenReturn(mockPdu);
+ when(mockSnmpManager.get(any(PDU.class), any(Target.class))).thenReturn(mockResponseEvent);
+
+ final GetSNMPHandler getSNMPHandler = new GetSNMPHandler(snmpResourceHandler);
+ getSNMPHandler.get(flowFileAttributes);
+
+ ArgumentCaptor captor = ArgumentCaptor.forClass(PDU.class);
+ Mockito.verify(mockSnmpManager).get(captor.capture(), any(Target.class));
+
+ final PDU pdu = captor.getValue();
+ assertEquals(1, pdu.getVariableBindings().size());
+ assertEquals(flowFileOid, pdu.getVariableBindings().get(0).getOid().toString());
+ assertEquals("Null", pdu.getVariableBindings().get(0).getVariable().toString());
+ }
+
+ @Test
+ public void testGetSnmpWhenTimeout() throws IOException {
+ final ResponseEvent mockResponseEvent = mock(ResponseEvent.class);
+ when(mockResponseEvent.getResponse()).thenReturn(null);
+ when(mockSnmpManager.get(any(PDU.class), any(Target.class))).thenReturn(mockResponseEvent);
+
+ final GetSNMPHandler getSNMPHandler = new GetSNMPHandler(snmpResourceHandler);
+
+ final RequestTimeoutException requestTimeoutException = Assert.assertThrows(
+ RequestTimeoutException.class,
+ () -> getSNMPHandler.get(OID)
+ );
+
+ assertEquals(String.format(SNMPResourceHandler.REQUEST_TIMEOUT_EXCEPTION_TEMPLATE, "read"),
+ requestTimeoutException.getMessage());
+ }
+
+ @SuppressWarnings("unchecked")
+ @Test
+ public void testWalkSnmpWithEmptyFlowFile() {
+ final TreeUtils mockTreeUtils = mock(TreeUtils.class);
+ final TreeEvent mockTreeEvent = mock(TreeEvent.class);
+ final List mockSubtree = (List) mock(List.class);
+
+ final VariableBinding[] variableBindings = new VariableBinding[1];
+ variableBindings[0] = new VariableBinding(new OID(OID), new OctetString("OID value"));
+ when(mockTreeEvent.getVariableBindings()).thenReturn(variableBindings);
+ when(mockSubtree.get(0)).thenReturn(mockTreeEvent);
+ when(mockTreeUtils.getSubtree(mockTarget, new OID(OID))).thenReturn(mockSubtree);
+
+ final GetSNMPHandler getSNMPHandler = new GetSNMPHandler(snmpResourceHandler);
+ getSNMPHandler.setTreeUtils(mockTreeUtils);
+ getSNMPHandler.walk(OID);
+
+ ArgumentCaptor captor = ArgumentCaptor.forClass(OID.class);
+ Mockito.verify(mockTreeUtils).getSubtree(any(Target.class), captor.capture());
+
+ assertEquals(OID, captor.getValue().toString());
+ }
+
+ @Test
+ public void testWalkSnmpWithInvalidFlowFile() {
+ final Map invalidFlowFileAttributes = new HashMap<>();
+ invalidFlowFileAttributes.put("invalid", "flowfile attribute");
+
+ final GetSNMPHandler getSNMPHandler = new GetSNMPHandler(snmpResourceHandler);
+ final Optional optionalResponse = getSNMPHandler.walk(invalidFlowFileAttributes);
+
+ assertFalse(optionalResponse.isPresent());
+ }
+
+ @SuppressWarnings("unchecked")
+ @Test
+ public void testWalkSnmpWithValidFlowFile() {
+ final String flowFileOid = "1.3.6.1.2.1.1.1.0";
+ final Map flowFileAttributes = new HashMap<>();
+ flowFileAttributes.put("snmp$" + flowFileOid, "OID value");
+
+ final TreeUtils mockTreeUtils = mock(TreeUtils.class);
+ final TreeEvent mockTreeEvent = mock(TreeEvent.class);
+ final List mockSubtree = (List) mock(List.class);
+
+ final VariableBinding[] variableBindings = new VariableBinding[1];
+ variableBindings[0] = new VariableBinding(new OID(OID), new OctetString("OID value"));
+ when(mockTreeEvent.getVariableBindings()).thenReturn(variableBindings);
+ when(mockSubtree.get(0)).thenReturn(mockTreeEvent);
+ when(mockSubtree.isEmpty()).thenReturn(false);
+ when(mockTreeUtils.walk(any(Target.class), any(OID[].class))).thenReturn(mockSubtree);
+
+ final GetSNMPHandler getSNMPHandler = new GetSNMPHandler(snmpResourceHandler);
+ getSNMPHandler.setTreeUtils(mockTreeUtils);
+ getSNMPHandler.walk(flowFileAttributes);
+
+ ArgumentCaptor captor = ArgumentCaptor.forClass(OID[].class);
+ Mockito.verify(mockTreeUtils).walk(any(Target.class), captor.capture());
+
+ assertEquals(flowFileOid, captor.getValue()[0].toString());
+ }
+
+ @SuppressWarnings("unchecked")
+ @Test
+ public void testWalkSnmpWithEmptySubtreeThrowsException() {
+ final TreeUtils mockTreeUtils = mock(TreeUtils.class);
+ final List mockSubtree = (List) mock(List.class);
+
+ when(mockSubtree.isEmpty()).thenReturn(true);
+ when(mockTreeUtils.getSubtree(any(Target.class), any(org.snmp4j.smi.OID.class))).thenReturn(mockSubtree);
+
+ final GetSNMPHandler getSNMPHandler = new GetSNMPHandler(snmpResourceHandler);
+ getSNMPHandler.setTreeUtils(mockTreeUtils);
+
+ final SNMPWalkException snmpWalkException = Assert.assertThrows(
+ SNMPWalkException.class,
+ () -> getSNMPHandler.walk(OID)
+ );
+
+ assertEquals(String.format(EMPTY_SUBTREE_EXCEPTION_MESSAGE, OID), snmpWalkException.getMessage());
+ }
+
+ @SuppressWarnings("unchecked")
+ @Test
+ public void testWalkSnmpWithSubtreeErrorThrowsException() {
+ final TreeUtils mockTreeUtils = mock(TreeUtils.class);
+ final TreeEvent mockTreeEvent = mock(TreeEvent.class);
+ final List mockSubtree = (List) mock(List.class);
+
+ when(mockSubtree.get(0)).thenReturn(mockTreeEvent);
+ when(mockSubtree.isEmpty()).thenReturn(false);
+ when(mockSubtree.size()).thenReturn(1);
+ when(mockTreeUtils.getSubtree(any(Target.class), any(org.snmp4j.smi.OID.class))).thenReturn(mockSubtree);
+
+ final GetSNMPHandler getSNMPHandler = new GetSNMPHandler(snmpResourceHandler);
+ getSNMPHandler.setTreeUtils(mockTreeUtils);
+
+ final SNMPWalkException snmpWalkException = Assert.assertThrows(
+ SNMPWalkException.class,
+ () -> getSNMPHandler.walk(OID)
+ );
+
+ assertEquals(SNMP_ERROR_EXCEPTION_MESSAGE, snmpWalkException.getMessage());
+ }
+
+ @SuppressWarnings("unchecked")
+ @Test
+ public void testWalkSnmpWithLeafElementSubtreeThrowsException() {
+ final TreeUtils mockTreeUtils = mock(TreeUtils.class);
+ final TreeEvent mockTreeEvent = mock(TreeEvent.class);
+ final List mockSubtree = (List) mock(List.class);
+
+ final VariableBinding[] variableBindings = new VariableBinding[0];
+ when(mockTreeEvent.getVariableBindings()).thenReturn(variableBindings);
+ when(mockSubtree.get(0)).thenReturn(mockTreeEvent);
+ when(mockSubtree.isEmpty()).thenReturn(false);
+ when(mockSubtree.size()).thenReturn(1);
+ when(mockTreeUtils.getSubtree(any(Target.class), any(org.snmp4j.smi.OID.class))).thenReturn(mockSubtree);
+
+ final GetSNMPHandler getSNMPHandler = new GetSNMPHandler(snmpResourceHandler);
+ getSNMPHandler.setTreeUtils(mockTreeUtils);
+
+ final SNMPWalkException snmpWalkException = Assert.assertThrows(
+ SNMPWalkException.class,
+ () -> getSNMPHandler.walk(OID)
+ );
+
+ assertEquals(String.format(LEAF_ELEMENT_EXCEPTION_MESSAGE, OID), snmpWalkException.getMessage());
+ }
+}
diff --git a/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/test/java/org/apache/nifi/snmp/operations/SNMPRequestTest.java b/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/test/java/org/apache/nifi/snmp/operations/SNMPRequestTest.java
index a3ca32299a..1b1e2574a2 100644
--- a/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/test/java/org/apache/nifi/snmp/operations/SNMPRequestTest.java
+++ b/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/test/java/org/apache/nifi/snmp/operations/SNMPRequestTest.java
@@ -16,45 +16,67 @@
*/
package org.apache.nifi.snmp.operations;
+import org.apache.nifi.snmp.configuration.SNMPConfiguration;
import org.apache.nifi.snmp.dto.SNMPSingleResponse;
import org.apache.nifi.snmp.dto.SNMPTreeResponse;
-import org.apache.nifi.snmp.helper.SNMPTestUtils;
+import org.apache.nifi.snmp.dto.SNMPValue;
+import org.apache.nifi.snmp.exception.RequestTimeoutException;
+import org.apache.nifi.snmp.factory.core.SNMPFactoryProvider;
+import org.apache.nifi.snmp.helper.configurations.SNMPConfigurationFactory;
+import org.apache.nifi.snmp.helper.configurations.SNMPV1V2cConfigurationFactory;
+import org.apache.nifi.snmp.helper.configurations.SNMPV3ConfigurationFactory;
import org.apache.nifi.snmp.testagents.TestAgent;
-import org.apache.nifi.util.MockFlowFile;
-import org.junit.jupiter.api.AfterEach;
-import org.junit.jupiter.api.BeforeEach;
-import org.snmp4j.CommunityTarget;
-import org.snmp4j.Snmp;
+import org.apache.nifi.snmp.testagents.TestSNMPV1Agent;
+import org.apache.nifi.snmp.testagents.TestSNMPV2cAgent;
+import org.apache.nifi.snmp.testagents.TestSNMPV3Agent;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
import org.snmp4j.agent.mo.DefaultMOFactory;
import org.snmp4j.agent.mo.MOAccessImpl;
+import org.snmp4j.mp.SnmpConstants;
import org.snmp4j.smi.OID;
import org.snmp4j.smi.OctetString;
import java.io.IOException;
+import java.util.Arrays;
+import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
+import java.util.HashSet;
import java.util.Map;
+import java.util.Optional;
+import java.util.Set;
import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.stream.Collectors;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.fail;
-public abstract class SNMPRequestTest {
+@RunWith(Parameterized.class)
+public class SNMPRequestTest {
- protected static final String LOCALHOST = "127.0.0.1";
- protected static final String INVALID_HOST = "127.0.0.2";
- protected static final String READ_ONLY_OID_1 = "1.3.6.1.4.1.32437.1.5.1.4.2.0";
- protected static final String READ_ONLY_OID_2 = "1.3.6.1.4.1.32437.1.5.1.4.3.0";
- protected static final String WRITE_ONLY_OID = "1.3.6.1.4.1.32437.1.5.1.4.4.0";
- protected static final String READ_ONLY_OID_VALUE_1 = "TestOID1";
- protected static final String READ_ONLY_OID_VALUE_2 = "TestOID2";
- protected static final String WRITE_ONLY_OID_VALUE = "writeOnlyOID";
- protected static final String SNMP_PROP_DELIMITER = "$";
- protected static final String SNMP_PROP_PREFIX = "snmp" + SNMP_PROP_DELIMITER;
- protected static final String NOT_WRITABLE = "Not writable";
- protected static final String NO_ACCESS = "No access";
- protected static final String SUCCESS = "Success";
- protected static final String EXPECTED_OID_VALUE = "testValue";
+ private static final String LOCALHOST = "127.0.0.1";
+ private static final String INVALID_HOST = "127.0.0.2";
+ private static final String READ_ONLY_OID_1 = "1.3.6.1.4.1.32437.1.5.1.4.2.0";
+ private static final String READ_ONLY_OID_2 = "1.3.6.1.4.1.32437.1.5.1.4.3.0";
+ private static final String WRITE_ONLY_OID = "1.3.6.1.4.1.32437.1.5.1.4.4.0";
+ private static final String WALK_OID = "1.3.6.1.4.1.32437";
+ private static final String INVALID_OID = "1.3.6.1.4.1.32437.0";
+ private static final String READ_ONLY_OID_VALUE_1 = "TestOID1";
+ private static final String READ_ONLY_OID_VALUE_2 = "TestOID2";
+ private static final String WRITE_ONLY_OID_VALUE = "writeOnlyOID";
+ private static final String SNMP_PROP_DELIMITER = "$";
+ private static final String SNMP_PROP_PREFIX = "snmp" + SNMP_PROP_DELIMITER;
+ private static final String NOT_WRITABLE = "Not writable";
+ private static final String NO_ACCESS = "No access";
+ private static final String SUCCESS = "Success";
+ private static final String NO_SUCH_OBJECT = "noSuchObject";
+ private static final String UNABLE_TO_CREATE_OBJECT = "Unable to create object";
+ private static final String TEST_OID_VALUE = "testValue";
+ private static final String NO_SUCH_NAME = "No such name";
protected static final Map WALK_OID_MAP;
static {
@@ -64,53 +86,217 @@ public abstract class SNMPRequestTest {
WALK_OID_MAP = Collections.unmodifiableMap(oidMap);
}
- protected final TestAgent agent = getAgentInstance();
+ private static final SNMPConfigurationFactory snmpV1ConfigurationFactory = new SNMPV1V2cConfigurationFactory(SnmpConstants.version1);
+ private static final SNMPConfigurationFactory snmpv2cConfigurationFactory = new SNMPV1V2cConfigurationFactory(SnmpConstants.version2c);
+ private static final SNMPConfigurationFactory snmpv3ConfigurationFactory = new SNMPV3ConfigurationFactory();
- protected abstract TestAgent getAgentInstance();
+ private static final TestAgent v1TestAgent = new TestSNMPV1Agent(LOCALHOST);
+ private static final TestAgent v2cTestAgent = new TestSNMPV2cAgent(LOCALHOST);
+ private static final TestAgent v3TestAgent = new TestSNMPV3Agent(LOCALHOST);
- @BeforeEach
+ private SNMPResourceHandler snmpResourceHandler;
+
+ static {
+ registerManagedObjects(v1TestAgent);
+ registerManagedObjects(v2cTestAgent);
+ registerManagedObjects(v3TestAgent);
+ }
+
+ @Before
public void initAgent() throws IOException {
agent.start();
- agent.registerManagedObjects(
- DefaultMOFactory.getInstance().createScalar(new OID(READ_ONLY_OID_1), MOAccessImpl.ACCESS_READ_ONLY, new OctetString(READ_ONLY_OID_VALUE_1)),
- DefaultMOFactory.getInstance().createScalar(new OID(READ_ONLY_OID_2), MOAccessImpl.ACCESS_READ_ONLY, new OctetString(READ_ONLY_OID_VALUE_2)),
- DefaultMOFactory.getInstance().createScalar(new OID(WRITE_ONLY_OID), MOAccessImpl.ACCESS_WRITE_ONLY, new OctetString(WRITE_ONLY_OID_VALUE))
- );
}
- @AfterEach
+ @After
public void tearDown() {
agent.stop();
+ agent.unregister();
+ snmpResourceHandler.close();
}
- protected SNMPTreeResponse getTreeEvents(final int port, final int version) throws IOException {
- final Snmp snmp = SNMPTestUtils.createSnmpClient();
- final CommunityTarget target = SNMPTestUtils.createCommTarget("public", LOCALHOST + "/" + port, version);
- final StandardSNMPRequestHandler standardSnmpRequestHandler = new StandardSNMPRequestHandler(snmp, target);
- return standardSnmpRequestHandler.walk("1.3.6.1.4.1.32437");
+ @Parameterized.Parameters
+ public static Collection