You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nifi.apache.org by tu...@apache.org on 2021/05/19 21:32:07 UTC
[nifi] branch main updated: NIFI-8325: Complete SNMP refactor: SNMP
GET and SET processors reworked, unit tests added
This is an automated email from the ASF dual-hosted git repository.
turcsanyi pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/nifi.git
The following commit(s) were added to refs/heads/main by this push:
new a3eaf0a NIFI-8325: Complete SNMP refactor: SNMP GET and SET processors reworked, unit tests added
a3eaf0a is described below
commit a3eaf0a37a939b42106bee2e24482e44f0d30763
Author: Lehel Boér <Le...@hotmail.com>
AuthorDate: Tue Mar 23 23:17:40 2021 +0100
NIFI-8325: Complete SNMP refactor: SNMP GET and SET processors reworked, unit tests added
This closes #5028.
Signed-off-by: Peter Turcsanyi <tu...@apache.org>
---
.../nifi/processor/util/StandardValidators.java | 20 +-
.../nifi-snmp-bundle/nifi-snmp-processors/pom.xml | 8 +-
.../nifi/snmp/configuration/SNMPConfiguration.java | 107 +++++
.../configuration/SNMPConfigurationBuilder.java | 100 +++++
.../apache/nifi/snmp/dto/SNMPSingleResponse.java | 68 +++
.../org/apache/nifi/snmp/dto/SNMPTreeResponse.java | 59 +++
.../java/org/apache/nifi/snmp/dto/SNMPValue.java} | 44 +-
.../snmp/exception/CloseSNMPClientException.java} | 27 +-
.../snmp/exception/CreateSNMPClientException.java} | 27 +-
.../exception/InvalidAuthProtocolException.java} | 28 +-
.../snmp/exception/InvalidFlowFileException.java} | 28 +-
.../exception/InvalidPrivProtocolException.java} | 27 +-
.../exception/InvalidSnmpVersionException.java} | 27 +-
.../snmp/exception/RequestTimeoutException.java} | 28 +-
.../SNMPClientInitializationException.java} | 27 +-
.../apache/nifi/snmp/exception/SNMPException.java} | 27 +-
.../nifi/snmp/exception/SNMPWalkException.java} | 28 +-
.../nifi/snmp/factory/AbstractSNMPFactory.java | 91 ++++
.../nifi/snmp/factory/CompositeSNMPFactory.java | 70 +++
.../org/apache/nifi/snmp/factory/SNMPFactory.java} | 32 +-
.../apache/nifi/snmp/factory/V1SNMPFactory.java} | 40 +-
.../apache/nifi/snmp/factory/V2cSNMPFactory.java} | 40 +-
.../apache/nifi/snmp/factory/V3SNMPFactory.java | 76 ++++
.../apache/nifi/snmp/logging/SLF4JLogAdapter.java | 105 +++++
.../apache/nifi/snmp/logging/SLF4JLogFactory.java | 49 ++
.../nifi/snmp/operations/SNMPRequestHandler.java} | 34 +-
.../operations/SNMPRequestHandlerFactory.java} | 38 +-
.../operations/StandardSNMPRequestHandler.java | 148 ++++++
.../snmp/processors/AbstractSNMPProcessor.java | 496 ++++++++-------------
.../org/apache/nifi/snmp/processors/GetSNMP.java | 244 +++++-----
.../apache/nifi/snmp/processors/SNMPGetter.java | 100 -----
.../apache/nifi/snmp/processors/SNMPSetter.java | 56 ---
.../org/apache/nifi/snmp/processors/SNMPUtils.java | 268 -----------
.../apache/nifi/snmp/processors/SNMPWorker.java | 74 ---
.../org/apache/nifi/snmp/processors/SetSNMP.java | 224 +++-------
.../java/org/apache/nifi/snmp/utils/SNMPUtils.java | 234 ++++++++++
.../apache/nifi/snmp/validators/OIDValidator.java | 47 ++
.../additionalDetails.html | 59 +--
.../additionalDetails.html | 40 +-
.../nifi/snmp/factory/SNMPClientFactoryTest.java | 68 +++
.../org/apache/nifi/snmp/helper/SNMPTestUtils.java | 68 +++
.../nifi/snmp/operations/SNMPRequestTest.java | 130 ++++++
.../nifi/snmp/operations/SNMPV1RequestTest.java | 85 ++++
.../nifi/snmp/operations/SNMPV2CRequestTest.java | 85 ++++
.../nifi/snmp/operations/SNMPV3RequestTest.java | 134 ++++++
.../apache/nifi/snmp/processors/GetSNMPTest.java | 92 ++++
.../apache/nifi/snmp/processors/SNMPUtilsTest.java | 134 ------
.../apache/nifi/snmp/processors/SetSNMPTest.java | 88 ++++
.../org/apache/nifi/snmp/testagents/TestAgent.java | 124 ++++++
.../nifi/snmp/testagents/TestSNMPV1Agent.java | 73 +++
.../nifi/snmp/testagents/TestSNMPV2cAgent.java | 96 ++++
.../nifi/snmp/testagents/TestSNMPV3Agent.java | 117 +++++
.../SNMPTestUtil.java => utils/SNMPUtilsTest.java} | 45 +-
.../src/test/resources/log4j.properties | 20 -
54 files changed, 2901 insertions(+), 1703 deletions(-)
diff --git a/nifi-commons/nifi-utils/src/main/java/org/apache/nifi/processor/util/StandardValidators.java b/nifi-commons/nifi-utils/src/main/java/org/apache/nifi/processor/util/StandardValidators.java
index 0a9a603..fd53401 100644
--- a/nifi-commons/nifi-utils/src/main/java/org/apache/nifi/processor/util/StandardValidators.java
+++ b/nifi-commons/nifi-utils/src/main/java/org/apache/nifi/processor/util/StandardValidators.java
@@ -409,7 +409,7 @@ public class StandardValidators {
Optional<ValidationResult> invalidUri = Arrays.stream(input.split(","))
.filter(uri -> uri != null && !uri.trim().isEmpty())
.map(String::trim)
- .map((uri) -> StandardValidators.URI_VALIDATOR.validate(subject,uri,context)).filter((uri) -> !uri.isValid()).findFirst();
+ .map((uri) -> StandardValidators.URI_VALIDATOR.validate(subject, uri, context)).filter((uri) -> !uri.isValid()).findFirst();
return invalidUri.orElseGet(() -> new ValidationResult.Builder().subject(subject).input(input).explanation("Valid URI(s)").valid(true).build());
};
@@ -577,13 +577,13 @@ public class StandardValidators {
}
public static Validator createListValidator(boolean trimEntries, boolean excludeEmptyEntries,
- Validator elementValidator){
- return createListValidator(trimEntries,excludeEmptyEntries, elementValidator, false);
+ Validator elementValidator) {
+ return createListValidator(trimEntries, excludeEmptyEntries, elementValidator, false);
}
public static Validator createListValidator(boolean trimEntries, boolean excludeEmptyEntries,
- Validator validator,
- boolean ensureElementValidation) {
+ Validator validator,
+ boolean ensureElementValidation) {
return (subject, input, context) -> {
if (context.isExpressionLanguageSupported(subject) && context.isExpressionLanguagePresent(input)) {
return new ValidationResult.Builder().subject(subject).input(input).explanation("Expression Language Present").valid(true).build();
@@ -593,7 +593,7 @@ public class StandardValidators {
return new ValidationResult.Builder().subject(subject).input(null).explanation("List must have at least one non-empty element").valid(false).build();
}
- final String[] list = ensureElementValidation ? input.split(",",-1) : input.split(",");
+ final String[] list = ensureElementValidation ? input.split(",", -1) : input.split(",");
if (list.length == 0) {
return new ValidationResult.Builder().subject(subject).input(null).explanation("List must have at least one non-empty element").valid(false).build();
}
@@ -678,10 +678,10 @@ public class StandardValidators {
* Language will not support FlowFile Attributes but only System/JVM
* Properties
*
- * @param minCapturingGroups minimum capturing groups allowed
- * @param maxCapturingGroups maximum capturing groups allowed
+ * @param minCapturingGroups minimum capturing groups allowed
+ * @param maxCapturingGroups maximum capturing groups allowed
* @param supportAttributeExpressionLanguage whether or not to support
- * expression language
+ * expression language
* @return validator
*/
public static Validator createRegexValidator(final int minCapturingGroups, final int maxCapturingGroups, final boolean supportAttributeExpressionLanguage) {
@@ -835,7 +835,7 @@ public class StandardValidators {
private final boolean allowFileOnly;
public FileExistsValidator(final boolean allowExpressionLanguage) {
- this(allowExpressionLanguage,false);
+ this(allowExpressionLanguage, false);
}
public FileExistsValidator(final boolean allowExpressionLanguage, final boolean fileOnly) {
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 3bed217..61960c8 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
@@ -9,7 +9,8 @@ by applicable law or agreed to in writing, software distributed under the
License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS
OF ANY KIND, either express or implied. See the License for the specific
language governing permissions and limitations under the License. -->
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.apache.nifi</groupId>
@@ -20,8 +21,8 @@ language governing permissions and limitations under the License. -->
<packaging>jar</packaging>
<properties>
- <snmp4j.version>1.10.1</snmp4j.version>
- <snmp4j-agent.version>1.3.1</snmp4j-agent.version>
+ <snmp4j.version>2.8.7</snmp4j.version>
+ <snmp4j-agent.version>2.7.4</snmp4j-agent.version>
</properties>
<dependencies>
@@ -30,7 +31,6 @@ language governing permissions and limitations under the License. -->
<artifactId>snmp4j</artifactId>
<version>${snmp4j.version}</version>
</dependency>
-
<dependency>
<groupId>org.snmp4j</groupId>
<artifactId>snmp4j-agent</artifactId>
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
new file mode 100644
index 0000000..aa65ada
--- /dev/null
+++ b/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/main/java/org/apache/nifi/snmp/configuration/SNMPConfiguration.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.configuration;
+
+public class SNMPConfiguration {
+
+ private final String agentHost;
+ private final String agentPort;
+ private final int retries;
+ private final int timeout;
+ private final int version;
+ private final String authProtocol;
+ private final String authPassphrase;
+ private final String privacyProtocol;
+ private final String privacyPassphrase;
+ private final String securityName;
+ private final String securityLevel;
+ private final String communityString;
+
+ SNMPConfiguration(final String agentHost,
+ final String agentPort,
+ final int retries,
+ final int timeout,
+ final int version,
+ final String authProtocol,
+ final String authPassphrase,
+ final String privacyProtocol,
+ final String privacyPassphrase,
+ final String securityName,
+ final String securityLevel,
+ final String communityString) {
+ this.agentHost = agentHost;
+ this.agentPort = agentPort;
+ this.retries = retries;
+ this.timeout = timeout;
+ this.version = version;
+ this.authProtocol = authProtocol;
+ this.authPassphrase = authPassphrase;
+ this.privacyProtocol = privacyProtocol;
+ this.privacyPassphrase = privacyPassphrase;
+ this.securityName = securityName;
+ this.securityLevel = securityLevel;
+ this.communityString = communityString;
+ }
+
+ public String getAgentHost() {
+ return agentHost;
+ }
+
+ public String getAgentPort() {
+ return agentPort;
+ }
+
+ public int getRetries() {
+ return retries;
+ }
+
+ public int getTimeout() {
+ return timeout;
+ }
+
+ public int getVersion() {
+ return version;
+ }
+
+ public String getAuthProtocol() {
+ return authProtocol;
+ }
+
+ public String getAuthPassphrase() {
+ return authPassphrase;
+ }
+
+ public String getPrivacyProtocol() {
+ return privacyProtocol;
+ }
+
+ public String getPrivacyPassphrase() {
+ return privacyPassphrase;
+ }
+
+ public String getSecurityName() {
+ return securityName;
+ }
+
+ public String getSecurityLevel() {
+ return securityLevel;
+ }
+
+ public String getCommunityString() {
+ return 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
new file mode 100644
index 0000000..dbb7728
--- /dev/null
+++ b/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/main/java/org/apache/nifi/snmp/configuration/SNMPConfigurationBuilder.java
@@ -0,0 +1,100 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.nifi.snmp.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/dto/SNMPSingleResponse.java b/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/main/java/org/apache/nifi/snmp/dto/SNMPSingleResponse.java
new file mode 100644
index 0000000..dabf41a
--- /dev/null
+++ b/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/main/java/org/apache/nifi/snmp/dto/SNMPSingleResponse.java
@@ -0,0 +1,68 @@
+/*
+ * 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.snmp.utils.SNMPUtils;
+import org.snmp4j.PDU;
+import org.snmp4j.Target;
+
+import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
+
+public class SNMPSingleResponse {
+
+ private final Target target;
+ private final PDU responsePdu;
+
+ public SNMPSingleResponse(final Target target, final PDU responsePdu) {
+ this.target = target;
+ this.responsePdu = responsePdu;
+ }
+
+ public boolean isValid() {
+ return responsePdu.getErrorStatus() == PDU.noError;
+ }
+
+
+ public Map<String, String> getAttributes() {
+ return SNMPUtils.getPduAttributeMap(responsePdu);
+ }
+
+ public List<SNMPValue> getVariableBindings() {
+ return responsePdu.getVariableBindings()
+ .stream()
+ .map(p -> new SNMPValue(p.getOid().toString(), p.getVariable().toString()))
+ .collect(Collectors.toList());
+ }
+
+ public String getErrorStatusText() {
+ return responsePdu.getErrorStatusText();
+ }
+
+ public String getTargetAddress() {
+ return target.getAddress().toString();
+ }
+
+ public int getVersion() {
+ return target.getVersion();
+ }
+
+ 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
new file mode 100644
index 0000000..c250e8d
--- /dev/null
+++ b/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/main/java/org/apache/nifi/snmp/dto/SNMPTreeResponse.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.dto;
+
+import org.apache.nifi.logging.ComponentLog;
+import org.apache.nifi.snmp.utils.SNMPUtils;
+import org.snmp4j.Target;
+import org.snmp4j.smi.VariableBinding;
+import org.snmp4j.util.TreeEvent;
+
+import java.util.Arrays;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+import java.util.stream.Collectors;
+
+public class SNMPTreeResponse {
+
+ private final Target target;
+ private final List<TreeEvent> events;
+
+ public SNMPTreeResponse(final Target target, final List<TreeEvent> events) {
+ this.target = target;
+ this.events = events;
+ }
+
+ public Map<String, String> getAttributes() {
+ final List<VariableBinding> variableBindings = events.stream()
+ .map(TreeEvent::getVariableBindings)
+ .filter(Objects::nonNull)
+ .flatMap(Arrays::stream)
+ .collect(Collectors.toList());
+ return SNMPUtils.createWalkOidValuesMap(variableBindings);
+ }
+
+ public String getTargetAddress() {
+ return target.getAddress().toString();
+ }
+
+ public void logErrors(final ComponentLog logger) {
+ events.stream()
+ .filter(TreeEvent::isError)
+ .forEach(event -> logger.error("Error occured in SNMP walk event: {}", event.getErrorMessage()));
+ }
+}
diff --git a/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/test/java/org/apache/nifi/snmp/processors/SNMPTestUtil.java b/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/main/java/org/apache/nifi/snmp/dto/SNMPValue.java
similarity index 55%
copy from nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/test/java/org/apache/nifi/snmp/processors/SNMPTestUtil.java
copy to nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/main/java/org/apache/nifi/snmp/dto/SNMPValue.java
index e2850a1..2822880 100644
--- a/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/test/java/org/apache/nifi/snmp/processors/SNMPTestUtil.java
+++ b/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/main/java/org/apache/nifi/snmp/dto/SNMPValue.java
@@ -14,31 +14,31 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.apache.nifi.snmp.processors;
+package org.apache.nifi.snmp.dto;
-import java.io.IOException;
-import java.net.ServerSocket;
+public class SNMPValue {
-public class SNMPTestUtil {
+ private final String oid;
+ private final String variable;
- /**
- * Will determine an available port.
- */
- public static synchronized int availablePort() {
- ServerSocket s = null;
- try {
- s = new ServerSocket(0);
- s.setReuseAddress(true);
- return s.getLocalPort();
- } catch (Exception e) {
- throw new IllegalStateException("Failed to discover available port.", e);
- } finally {
- try {
- s.close();
- } catch (IOException e) {
- // ignore
- }
- }
+ public SNMPValue(final String oid, final String variable) {
+ this.oid = oid;
+ this.variable = variable;
}
+ public String getOid() {
+ return oid;
+ }
+
+ public String getVariable() {
+ return variable;
+ }
+
+ @Override
+ public String toString() {
+ return "SNMPValue{" +
+ "oid='" + oid + '\'' +
+ ", variable='" + variable + '\'' +
+ '}';
+ }
}
diff --git a/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/test/java/org/apache/nifi/snmp/processors/SNMPTestUtil.java b/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/main/java/org/apache/nifi/snmp/exception/CloseSNMPClientException.java
similarity index 55%
copy from nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/test/java/org/apache/nifi/snmp/processors/SNMPTestUtil.java
copy to nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/main/java/org/apache/nifi/snmp/exception/CloseSNMPClientException.java
index e2850a1..4c70250 100644
--- a/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/test/java/org/apache/nifi/snmp/processors/SNMPTestUtil.java
+++ b/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/main/java/org/apache/nifi/snmp/exception/CloseSNMPClientException.java
@@ -14,31 +14,12 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.apache.nifi.snmp.processors;
+package org.apache.nifi.snmp.exception;
-import java.io.IOException;
-import java.net.ServerSocket;
+public class CloseSNMPClientException extends SNMPException {
-public class SNMPTestUtil {
-
- /**
- * Will determine an available port.
- */
- public static synchronized int availablePort() {
- ServerSocket s = null;
- try {
- s = new ServerSocket(0);
- s.setReuseAddress(true);
- return s.getLocalPort();
- } catch (Exception e) {
- throw new IllegalStateException("Failed to discover available port.", e);
- } finally {
- try {
- s.close();
- } catch (IOException e) {
- // ignore
- }
- }
+ public CloseSNMPClientException(final String errorMessage) {
+ super(errorMessage);
}
}
diff --git a/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/test/java/org/apache/nifi/snmp/processors/SNMPTestUtil.java b/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/main/java/org/apache/nifi/snmp/exception/CreateSNMPClientException.java
similarity index 55%
copy from nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/test/java/org/apache/nifi/snmp/processors/SNMPTestUtil.java
copy to nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/main/java/org/apache/nifi/snmp/exception/CreateSNMPClientException.java
index e2850a1..f803605 100644
--- a/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/test/java/org/apache/nifi/snmp/processors/SNMPTestUtil.java
+++ b/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/main/java/org/apache/nifi/snmp/exception/CreateSNMPClientException.java
@@ -14,31 +14,12 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.apache.nifi.snmp.processors;
+package org.apache.nifi.snmp.exception;
-import java.io.IOException;
-import java.net.ServerSocket;
+public class CreateSNMPClientException extends SNMPException {
-public class SNMPTestUtil {
-
- /**
- * Will determine an available port.
- */
- public static synchronized int availablePort() {
- ServerSocket s = null;
- try {
- s = new ServerSocket(0);
- s.setReuseAddress(true);
- return s.getLocalPort();
- } catch (Exception e) {
- throw new IllegalStateException("Failed to discover available port.", e);
- } finally {
- try {
- s.close();
- } catch (IOException e) {
- // ignore
- }
- }
+ public CreateSNMPClientException(final String errorMessage) {
+ super(errorMessage);
}
}
diff --git a/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/test/java/org/apache/nifi/snmp/processors/SNMPTestUtil.java b/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/main/java/org/apache/nifi/snmp/exception/InvalidAuthProtocolException.java
similarity index 55%
copy from nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/test/java/org/apache/nifi/snmp/processors/SNMPTestUtil.java
copy to nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/main/java/org/apache/nifi/snmp/exception/InvalidAuthProtocolException.java
index e2850a1..ed96817 100644
--- a/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/test/java/org/apache/nifi/snmp/processors/SNMPTestUtil.java
+++ b/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/main/java/org/apache/nifi/snmp/exception/InvalidAuthProtocolException.java
@@ -14,31 +14,13 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.apache.nifi.snmp.processors;
+package org.apache.nifi.snmp.exception;
-import java.io.IOException;
-import java.net.ServerSocket;
+public class InvalidAuthProtocolException extends SNMPException {
-public class SNMPTestUtil {
-
- /**
- * Will determine an available port.
- */
- public static synchronized int availablePort() {
- ServerSocket s = null;
- try {
- s = new ServerSocket(0);
- s.setReuseAddress(true);
- return s.getLocalPort();
- } catch (Exception e) {
- throw new IllegalStateException("Failed to discover available port.", e);
- } finally {
- try {
- s.close();
- } catch (IOException e) {
- // ignore
- }
- }
+ public InvalidAuthProtocolException(final String errorMessage) {
+ super(errorMessage);
}
+
}
diff --git a/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/test/java/org/apache/nifi/snmp/processors/SNMPTestUtil.java b/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/main/java/org/apache/nifi/snmp/exception/InvalidFlowFileException.java
similarity index 55%
copy from nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/test/java/org/apache/nifi/snmp/processors/SNMPTestUtil.java
copy to nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/main/java/org/apache/nifi/snmp/exception/InvalidFlowFileException.java
index e2850a1..153e725 100644
--- a/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/test/java/org/apache/nifi/snmp/processors/SNMPTestUtil.java
+++ b/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/main/java/org/apache/nifi/snmp/exception/InvalidFlowFileException.java
@@ -14,31 +14,11 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.apache.nifi.snmp.processors;
+package org.apache.nifi.snmp.exception;
-import java.io.IOException;
-import java.net.ServerSocket;
+public class InvalidFlowFileException extends SNMPException {
-public class SNMPTestUtil {
-
- /**
- * Will determine an available port.
- */
- public static synchronized int availablePort() {
- ServerSocket s = null;
- try {
- s = new ServerSocket(0);
- s.setReuseAddress(true);
- return s.getLocalPort();
- } catch (Exception e) {
- throw new IllegalStateException("Failed to discover available port.", e);
- } finally {
- try {
- s.close();
- } catch (IOException e) {
- // ignore
- }
- }
+ public InvalidFlowFileException(final String errorMessage) {
+ super(errorMessage);
}
-
}
diff --git a/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/test/java/org/apache/nifi/snmp/processors/SNMPTestUtil.java b/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/main/java/org/apache/nifi/snmp/exception/InvalidPrivProtocolException.java
similarity index 55%
copy from nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/test/java/org/apache/nifi/snmp/processors/SNMPTestUtil.java
copy to nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/main/java/org/apache/nifi/snmp/exception/InvalidPrivProtocolException.java
index e2850a1..056009c 100644
--- a/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/test/java/org/apache/nifi/snmp/processors/SNMPTestUtil.java
+++ b/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/main/java/org/apache/nifi/snmp/exception/InvalidPrivProtocolException.java
@@ -14,31 +14,12 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.apache.nifi.snmp.processors;
+package org.apache.nifi.snmp.exception;
-import java.io.IOException;
-import java.net.ServerSocket;
+public class InvalidPrivProtocolException extends SNMPException {
-public class SNMPTestUtil {
-
- /**
- * Will determine an available port.
- */
- public static synchronized int availablePort() {
- ServerSocket s = null;
- try {
- s = new ServerSocket(0);
- s.setReuseAddress(true);
- return s.getLocalPort();
- } catch (Exception e) {
- throw new IllegalStateException("Failed to discover available port.", e);
- } finally {
- try {
- s.close();
- } catch (IOException e) {
- // ignore
- }
- }
+ public InvalidPrivProtocolException(final String errorMessage) {
+ super(errorMessage);
}
}
diff --git a/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/test/java/org/apache/nifi/snmp/processors/SNMPTestUtil.java b/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/main/java/org/apache/nifi/snmp/exception/InvalidSnmpVersionException.java
similarity index 55%
copy from nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/test/java/org/apache/nifi/snmp/processors/SNMPTestUtil.java
copy to nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/main/java/org/apache/nifi/snmp/exception/InvalidSnmpVersionException.java
index e2850a1..1c240dd 100644
--- a/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/test/java/org/apache/nifi/snmp/processors/SNMPTestUtil.java
+++ b/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/main/java/org/apache/nifi/snmp/exception/InvalidSnmpVersionException.java
@@ -14,31 +14,12 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.apache.nifi.snmp.processors;
+package org.apache.nifi.snmp.exception;
-import java.io.IOException;
-import java.net.ServerSocket;
+public class InvalidSnmpVersionException extends SNMPException {
-public class SNMPTestUtil {
-
- /**
- * Will determine an available port.
- */
- public static synchronized int availablePort() {
- ServerSocket s = null;
- try {
- s = new ServerSocket(0);
- s.setReuseAddress(true);
- return s.getLocalPort();
- } catch (Exception e) {
- throw new IllegalStateException("Failed to discover available port.", e);
- } finally {
- try {
- s.close();
- } catch (IOException e) {
- // ignore
- }
- }
+ public InvalidSnmpVersionException(final String errorMessage) {
+ super(errorMessage);
}
}
diff --git a/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/test/java/org/apache/nifi/snmp/processors/SNMPTestUtil.java b/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/main/java/org/apache/nifi/snmp/exception/RequestTimeoutException.java
similarity index 54%
copy from nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/test/java/org/apache/nifi/snmp/processors/SNMPTestUtil.java
copy to nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/main/java/org/apache/nifi/snmp/exception/RequestTimeoutException.java
index e2850a1..94a537a 100644
--- a/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/test/java/org/apache/nifi/snmp/processors/SNMPTestUtil.java
+++ b/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/main/java/org/apache/nifi/snmp/exception/RequestTimeoutException.java
@@ -14,31 +14,11 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.apache.nifi.snmp.processors;
+package org.apache.nifi.snmp.exception;
-import java.io.IOException;
-import java.net.ServerSocket;
+public class RequestTimeoutException extends SNMPException {
-public class SNMPTestUtil {
-
- /**
- * Will determine an available port.
- */
- public static synchronized int availablePort() {
- ServerSocket s = null;
- try {
- s = new ServerSocket(0);
- s.setReuseAddress(true);
- return s.getLocalPort();
- } catch (Exception e) {
- throw new IllegalStateException("Failed to discover available port.", e);
- } finally {
- try {
- s.close();
- } catch (IOException e) {
- // ignore
- }
- }
+ public RequestTimeoutException(final String errorMessage) {
+ super(errorMessage);
}
-
}
diff --git a/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/test/java/org/apache/nifi/snmp/processors/SNMPTestUtil.java b/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/main/java/org/apache/nifi/snmp/exception/SNMPClientInitializationException.java
similarity index 55%
copy from nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/test/java/org/apache/nifi/snmp/processors/SNMPTestUtil.java
copy to nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/main/java/org/apache/nifi/snmp/exception/SNMPClientInitializationException.java
index e2850a1..f4ad608 100644
--- a/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/test/java/org/apache/nifi/snmp/processors/SNMPTestUtil.java
+++ b/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/main/java/org/apache/nifi/snmp/exception/SNMPClientInitializationException.java
@@ -14,31 +14,12 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.apache.nifi.snmp.processors;
+package org.apache.nifi.snmp.exception;
-import java.io.IOException;
-import java.net.ServerSocket;
+public class SNMPClientInitializationException extends SNMPException {
-public class SNMPTestUtil {
-
- /**
- * Will determine an available port.
- */
- public static synchronized int availablePort() {
- ServerSocket s = null;
- try {
- s = new ServerSocket(0);
- s.setReuseAddress(true);
- return s.getLocalPort();
- } catch (Exception e) {
- throw new IllegalStateException("Failed to discover available port.", e);
- } finally {
- try {
- s.close();
- } catch (IOException e) {
- // ignore
- }
- }
+ public SNMPClientInitializationException(final String errorMessage) {
+ super(errorMessage);
}
}
diff --git a/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/test/java/org/apache/nifi/snmp/processors/SNMPTestUtil.java b/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/main/java/org/apache/nifi/snmp/exception/SNMPException.java
similarity index 55%
copy from nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/test/java/org/apache/nifi/snmp/processors/SNMPTestUtil.java
copy to nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/main/java/org/apache/nifi/snmp/exception/SNMPException.java
index e2850a1..4e842da 100644
--- a/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/test/java/org/apache/nifi/snmp/processors/SNMPTestUtil.java
+++ b/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/main/java/org/apache/nifi/snmp/exception/SNMPException.java
@@ -14,31 +14,12 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.apache.nifi.snmp.processors;
+package org.apache.nifi.snmp.exception;
-import java.io.IOException;
-import java.net.ServerSocket;
+public class SNMPException extends RuntimeException {
-public class SNMPTestUtil {
-
- /**
- * Will determine an available port.
- */
- public static synchronized int availablePort() {
- ServerSocket s = null;
- try {
- s = new ServerSocket(0);
- s.setReuseAddress(true);
- return s.getLocalPort();
- } catch (Exception e) {
- throw new IllegalStateException("Failed to discover available port.", e);
- } finally {
- try {
- s.close();
- } catch (IOException e) {
- // ignore
- }
- }
+ public SNMPException(final String errorMessage) {
+ super(errorMessage);
}
}
diff --git a/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/test/java/org/apache/nifi/snmp/processors/SNMPTestUtil.java b/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/main/java/org/apache/nifi/snmp/exception/SNMPWalkException.java
similarity index 54%
copy from nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/test/java/org/apache/nifi/snmp/processors/SNMPTestUtil.java
copy to nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/main/java/org/apache/nifi/snmp/exception/SNMPWalkException.java
index e2850a1..a742430 100644
--- a/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/test/java/org/apache/nifi/snmp/processors/SNMPTestUtil.java
+++ b/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/main/java/org/apache/nifi/snmp/exception/SNMPWalkException.java
@@ -14,31 +14,11 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.apache.nifi.snmp.processors;
+package org.apache.nifi.snmp.exception;
-import java.io.IOException;
-import java.net.ServerSocket;
+public class SNMPWalkException extends SNMPException {
-public class SNMPTestUtil {
-
- /**
- * Will determine an available port.
- */
- public static synchronized int availablePort() {
- ServerSocket s = null;
- try {
- s = new ServerSocket(0);
- s.setReuseAddress(true);
- return s.getLocalPort();
- } catch (Exception e) {
- throw new IllegalStateException("Failed to discover available port.", e);
- } finally {
- try {
- s.close();
- } catch (IOException e) {
- // ignore
- }
- }
+ public SNMPWalkException(final String errorMessage) {
+ super(errorMessage);
}
-
}
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
new file mode 100644
index 0000000..baa4588
--- /dev/null
+++ b/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/main/java/org/apache/nifi/snmp/factory/AbstractSNMPFactory.java
@@ -0,0 +1,91 @@
+/*
+ * 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
new file mode 100644
index 0000000..f1234bc
--- /dev/null
+++ b/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/main/java/org/apache/nifi/snmp/factory/CompositeSNMPFactory.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.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<SNMPFactory> FACTORIES;
+
+ static {
+ final List<SNMPFactory> 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<SNMPFactory> 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<SNMPFactory> factory = getMatchingFactory(configuration.getVersion());
+ if (!factory.isPresent()) {
+ throw new InvalidSnmpVersionException(INVALID_SNMP_VERSION);
+ }
+ return factory.get().createTargetInstance(configuration);
+ }
+
+ private Optional<SNMPFactory> 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/test/java/org/apache/nifi/snmp/processors/SNMPTestUtil.java b/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/main/java/org/apache/nifi/snmp/factory/SNMPFactory.java
similarity index 57%
copy from nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/test/java/org/apache/nifi/snmp/processors/SNMPTestUtil.java
copy to nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/main/java/org/apache/nifi/snmp/factory/SNMPFactory.java
index e2850a1..442c03e 100644
--- a/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/test/java/org/apache/nifi/snmp/processors/SNMPTestUtil.java
+++ b/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/main/java/org/apache/nifi/snmp/factory/SNMPFactory.java
@@ -14,31 +14,17 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.apache.nifi.snmp.processors;
+package org.apache.nifi.snmp.factory;
-import java.io.IOException;
-import java.net.ServerSocket;
+import org.apache.nifi.snmp.configuration.SNMPConfiguration;
+import org.snmp4j.Snmp;
+import org.snmp4j.Target;
-public class SNMPTestUtil {
+public interface SNMPFactory {
- /**
- * Will determine an available port.
- */
- public static synchronized int availablePort() {
- ServerSocket s = null;
- try {
- s = new ServerSocket(0);
- s.setReuseAddress(true);
- return s.getLocalPort();
- } catch (Exception e) {
- throw new IllegalStateException("Failed to discover available port.", e);
- } finally {
- try {
- s.close();
- } catch (IOException e) {
- // ignore
- }
- }
- }
+ boolean supports(final int version);
+ Snmp createSnmpManagerInstance(final SNMPConfiguration configuration);
+
+ Target createTargetInstance(final SNMPConfiguration configuration);
}
diff --git a/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/test/java/org/apache/nifi/snmp/processors/SNMPTestUtil.java b/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/main/java/org/apache/nifi/snmp/factory/V1SNMPFactory.java
similarity index 54%
copy from nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/test/java/org/apache/nifi/snmp/processors/SNMPTestUtil.java
copy to nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/main/java/org/apache/nifi/snmp/factory/V1SNMPFactory.java
index e2850a1..e089658 100644
--- a/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/test/java/org/apache/nifi/snmp/processors/SNMPTestUtil.java
+++ b/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/main/java/org/apache/nifi/snmp/factory/V1SNMPFactory.java
@@ -14,31 +14,27 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.apache.nifi.snmp.processors;
+package org.apache.nifi.snmp.factory;
-import java.io.IOException;
-import java.net.ServerSocket;
+import org.apache.nifi.snmp.configuration.SNMPConfiguration;
+import org.snmp4j.Snmp;
+import org.snmp4j.Target;
+import org.snmp4j.mp.SnmpConstants;
-public class SNMPTestUtil {
+public class V1SNMPFactory extends AbstractSNMPFactory implements SNMPFactory {
- /**
- * Will determine an available port.
- */
- public static synchronized int availablePort() {
- ServerSocket s = null;
- try {
- s = new ServerSocket(0);
- s.setReuseAddress(true);
- return s.getLocalPort();
- } catch (Exception e) {
- throw new IllegalStateException("Failed to discover available port.", e);
- } finally {
- try {
- s.close();
- } catch (IOException e) {
- // ignore
- }
- }
+ @Override
+ public boolean supports(final int version) {
+ return SnmpConstants.version1 == version;
}
+ @Override
+ public Snmp createSnmpManagerInstance(final SNMPConfiguration configuration) {
+ return createSnmpClient();
+ }
+
+ @Override
+ public Target createTargetInstance(final SNMPConfiguration configuration) {
+ return createCommunityTarget(configuration);
+ }
}
diff --git a/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/test/java/org/apache/nifi/snmp/processors/SNMPTestUtil.java b/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/main/java/org/apache/nifi/snmp/factory/V2cSNMPFactory.java
similarity index 54%
copy from nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/test/java/org/apache/nifi/snmp/processors/SNMPTestUtil.java
copy to nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/main/java/org/apache/nifi/snmp/factory/V2cSNMPFactory.java
index e2850a1..b34609d 100644
--- a/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/test/java/org/apache/nifi/snmp/processors/SNMPTestUtil.java
+++ b/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/main/java/org/apache/nifi/snmp/factory/V2cSNMPFactory.java
@@ -14,31 +14,27 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.apache.nifi.snmp.processors;
+package org.apache.nifi.snmp.factory;
-import java.io.IOException;
-import java.net.ServerSocket;
+import org.apache.nifi.snmp.configuration.SNMPConfiguration;
+import org.snmp4j.Snmp;
+import org.snmp4j.Target;
+import org.snmp4j.mp.SnmpConstants;
-public class SNMPTestUtil {
+public class V2cSNMPFactory extends AbstractSNMPFactory implements SNMPFactory {
- /**
- * Will determine an available port.
- */
- public static synchronized int availablePort() {
- ServerSocket s = null;
- try {
- s = new ServerSocket(0);
- s.setReuseAddress(true);
- return s.getLocalPort();
- } catch (Exception e) {
- throw new IllegalStateException("Failed to discover available port.", e);
- } finally {
- try {
- s.close();
- } catch (IOException e) {
- // ignore
- }
- }
+ @Override
+ public boolean supports(final int version) {
+ return SnmpConstants.version2c == version;
}
+ @Override
+ public Snmp createSnmpManagerInstance(final SNMPConfiguration configuration) {
+ return createSnmpClient();
+ }
+
+ @Override
+ public Target createTargetInstance(final SNMPConfiguration configuration) {
+ return createCommunityTarget(configuration);
+ }
}
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
new file mode 100644
index 0000000..75e34d0
--- /dev/null
+++ b/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/main/java/org/apache/nifi/snmp/factory/V3SNMPFactory.java
@@ -0,0 +1,76 @@
+/*
+ * 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/logging/SLF4JLogAdapter.java b/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/main/java/org/apache/nifi/snmp/logging/SLF4JLogAdapter.java
new file mode 100644
index 0000000..0e1eca2
--- /dev/null
+++ b/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/main/java/org/apache/nifi/snmp/logging/SLF4JLogAdapter.java
@@ -0,0 +1,105 @@
+/*_############################################################################
+ _##
+ _## SNMP4J - JavaLogAdapter.java
+ _##
+ _## Copyright (C) 2003-2020 Frank Fock (SNMP4J.org)
+ _##
+ _## Licensed under the Apache License, Version 2.0 (the "License");
+ _## you may not use this file except in compliance with the License.
+ _## You may obtain a copy of the License at
+ _##
+ _## http://www.apache.org/licenses/LICENSE-2.0
+ _##
+ _## Unless required by applicable law or agreed to in writing, software
+ _## distributed under the License is distributed on an "AS IS" BASIS,
+ _## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ _## See the License for the specific language governing permissions and
+ _## limitations under the License.
+ _##
+ _##########################################################################*/
+package org.apache.nifi.snmp.logging;
+
+import org.slf4j.Logger;
+import org.snmp4j.log.LogAdapter;
+import org.snmp4j.log.LogLevel;
+
+import java.io.Serializable;
+import java.util.Iterator;
+import java.util.logging.Handler;
+
+public class SLF4JLogAdapter implements LogAdapter {
+
+ private final Logger logger;
+
+ public SLF4JLogAdapter(final Logger logger) {
+ this.logger = logger;
+ }
+
+ public boolean isDebugEnabled() {
+ return logger.isDebugEnabled();
+ }
+
+ public boolean isInfoEnabled() {
+ return logger.isInfoEnabled();
+ }
+
+ public boolean isWarnEnabled() {
+ return logger.isWarnEnabled();
+ }
+
+
+ public void debug(final Serializable message) {
+ if (isDebugEnabled()) {
+ logger.debug("{}", message);
+ }
+ }
+
+ public void info(final CharSequence message) {
+ if (isInfoEnabled()) {
+ logger.info("{}", message);
+ }
+ }
+
+ public void warn(final Serializable message) {
+ if (isWarnEnabled()) {
+ logger.warn("{}", message);
+ }
+ }
+
+ public void error(final Serializable message) {
+ logger.error("{}", message);
+ }
+
+ public void error(final CharSequence message, final Throwable t) {
+ logger.error("{}", message, t);
+ }
+
+ public void fatal(final Object message) {
+ logger.error("{}", message);
+ }
+
+ public void fatal(final CharSequence message, final Throwable t) {
+ logger.error("{}", message, t);
+ }
+
+
+ public LogLevel getEffectiveLogLevel() {
+ return LogLevel.ALL;
+ }
+
+ public Iterator<Handler> getLogHandler() {
+ throw new UnsupportedOperationException("Log handlers are not supported.");
+ }
+
+ public LogLevel getLogLevel() {
+ return getEffectiveLogLevel();
+ }
+
+ public String getName() {
+ return logger.getName();
+ }
+
+ public void setLogLevel(final LogLevel logLevel) {
+ // no need to set log level
+ }
+}
diff --git a/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/main/java/org/apache/nifi/snmp/logging/SLF4JLogFactory.java b/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/main/java/org/apache/nifi/snmp/logging/SLF4JLogFactory.java
new file mode 100644
index 0000000..e8cf4d1
--- /dev/null
+++ b/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/main/java/org/apache/nifi/snmp/logging/SLF4JLogFactory.java
@@ -0,0 +1,49 @@
+/*_############################################################################
+ _##
+ _## SNMP4J - JavaLogFactory.java
+ _##
+ _## Copyright (C) 2003-2020 Frank Fock (SNMP4J.org)
+ _##
+ _## Licensed under the Apache License, Version 2.0 (the "License");
+ _## you may not use this file except in compliance with the License.
+ _## You may obtain a copy of the License at
+ _##
+ _## http://www.apache.org/licenses/LICENSE-2.0
+ _##
+ _## Unless required by applicable law or agreed to in writing, software
+ _## distributed under the License is distributed on an "AS IS" BASIS,
+ _## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ _## See the License for the specific language governing permissions and
+ _## limitations under the License.
+ _##
+ _##########################################################################*/
+package org.apache.nifi.snmp.logging;
+
+import org.slf4j.LoggerFactory;
+import org.snmp4j.log.LogAdapter;
+import org.snmp4j.log.LogFactory;
+
+import java.util.Iterator;
+
+public class SLF4JLogFactory extends LogFactory {
+
+ @Override
+ protected LogAdapter createLogger(final Class loggerClass) {
+ return new SLF4JLogAdapter(LoggerFactory.getLogger(loggerClass.getName()));
+ }
+
+ @Override
+ protected LogAdapter createLogger(final String className) {
+ return new SLF4JLogAdapter(LoggerFactory.getLogger(className));
+ }
+
+ @Override
+ public LogAdapter getRootLogger() {
+ return new SLF4JLogAdapter(LoggerFactory.getLogger(""));
+ }
+
+ @Override
+ public Iterator loggers() {
+ throw new UnsupportedOperationException("Iterators are currently not supported!");
+ }
+}
diff --git a/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/test/java/org/apache/nifi/snmp/processors/SNMPTestUtil.java b/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/main/java/org/apache/nifi/snmp/operations/SNMPRequestHandler.java
similarity index 56%
copy from nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/test/java/org/apache/nifi/snmp/processors/SNMPTestUtil.java
copy to nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/main/java/org/apache/nifi/snmp/operations/SNMPRequestHandler.java
index e2850a1..97759ed 100644
--- a/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/test/java/org/apache/nifi/snmp/processors/SNMPTestUtil.java
+++ b/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/main/java/org/apache/nifi/snmp/operations/SNMPRequestHandler.java
@@ -14,31 +14,21 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.apache.nifi.snmp.processors;
+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;
-import java.net.ServerSocket;
-public class SNMPTestUtil {
+public interface SNMPRequestHandler {
+
+ SNMPSingleResponse get(final String oid) throws IOException;
+
+ SNMPTreeResponse walk(final String oid);
- /**
- * Will determine an available port.
- */
- public static synchronized int availablePort() {
- ServerSocket s = null;
- try {
- s = new ServerSocket(0);
- s.setReuseAddress(true);
- return s.getLocalPort();
- } catch (Exception e) {
- throw new IllegalStateException("Failed to discover available port.", e);
- } finally {
- try {
- s.close();
- } catch (IOException e) {
- // ignore
- }
- }
- }
+ SNMPSingleResponse set(final FlowFile flowfile) throws IOException;
+ void close();
}
diff --git a/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/test/java/org/apache/nifi/snmp/processors/SNMPTestUtil.java b/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/main/java/org/apache/nifi/snmp/operations/SNMPRequestHandlerFactory.java
similarity index 50%
copy from nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/test/java/org/apache/nifi/snmp/processors/SNMPTestUtil.java
copy to nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/main/java/org/apache/nifi/snmp/operations/SNMPRequestHandlerFactory.java
index e2850a1..6663c4e 100644
--- a/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/test/java/org/apache/nifi/snmp/processors/SNMPTestUtil.java
+++ b/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/main/java/org/apache/nifi/snmp/operations/SNMPRequestHandlerFactory.java
@@ -14,31 +14,25 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.apache.nifi.snmp.processors;
+package org.apache.nifi.snmp.operations;
-import java.io.IOException;
-import java.net.ServerSocket;
+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 class SNMPTestUtil {
+public final class SNMPRequestHandlerFactory {
- /**
- * Will determine an available port.
- */
- public static synchronized int availablePort() {
- ServerSocket s = null;
- try {
- s = new ServerSocket(0);
- s.setReuseAddress(true);
- return s.getLocalPort();
- } catch (Exception e) {
- throw new IllegalStateException("Failed to discover available port.", e);
- } finally {
- try {
- s.close();
- } catch (IOException e) {
- // ignore
- }
- }
+ 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/StandardSNMPRequestHandler.java b/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/main/java/org/apache/nifi/snmp/operations/StandardSNMPRequestHandler.java
new file mode 100644
index 0000000..47ce736
--- /dev/null
+++ b/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/main/java/org/apache/nifi/snmp/operations/StandardSNMPRequestHandler.java
@@ -0,0 +1,148 @@
+/*
+ * 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<TreeEvent> 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<TreeEvent> subtree) {
+ return subtree.size() == 1 && subtree.get(0).getVariableBindings() == null;
+ }
+
+ private boolean isLeafElement(final List<TreeEvent> 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 43a500a..7b9c5d0 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
@@ -16,413 +16,299 @@
*/
package org.apache.nifi.snmp.processors;
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.List;
-
+import org.apache.nifi.annotation.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.components.ValidationContext;
-import org.apache.nifi.components.ValidationResult;
+import org.apache.nifi.flowfile.FlowFile;
import org.apache.nifi.processor.AbstractProcessor;
import org.apache.nifi.processor.ProcessContext;
import org.apache.nifi.processor.ProcessSession;
-import org.apache.nifi.processor.Processor;
-import org.apache.nifi.processor.exception.ProcessException;
+import org.apache.nifi.processor.Relationship;
import org.apache.nifi.processor.util.StandardValidators;
-import org.snmp4j.AbstractTarget;
-import org.snmp4j.CommunityTarget;
-import org.snmp4j.Snmp;
-import org.snmp4j.TransportMapping;
-import org.snmp4j.UserTarget;
-import org.snmp4j.mp.MPv3;
+import org.apache.nifi.reporting.InitializationException;
+import org.apache.nifi.snmp.configuration.SNMPConfiguration;
+import org.apache.nifi.snmp.configuration.SNMPConfigurationBuilder;
+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.logging.SLF4JLogFactory;
+import org.apache.nifi.snmp.operations.SNMPRequestHandler;
+import org.apache.nifi.snmp.operations.SNMPRequestHandlerFactory;
+import org.apache.nifi.snmp.utils.SNMPUtils;
+import org.snmp4j.log.LogFactory;
import org.snmp4j.mp.SnmpConstants;
-import org.snmp4j.security.SecurityModels;
-import org.snmp4j.security.SecurityProtocols;
-import org.snmp4j.security.USM;
-import org.snmp4j.security.UsmUser;
-import org.snmp4j.smi.OctetString;
-import org.snmp4j.smi.UdpAddress;
-import org.snmp4j.transport.DefaultUdpTransportMapping;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Optional;
/**
- * Base processor that uses SNMP4J client API
+ * Base processor that uses SNMP4J client API.
* (http://www.snmp4j.org/)
- *
- * @param <T> the type of {@link SNMPWorker}. Please see {@link SNMPSetter}
- * and {@link SNMPGetter}
*/
-abstract class AbstractSNMPProcessor<T extends SNMPWorker> extends AbstractProcessor {
+@RequiresInstanceClassLoading
+abstract class AbstractSNMPProcessor extends AbstractProcessor {
+
+ static {
+ LogFactory.setLogFactory(new SLF4JLogFactory());
+ }
- /** property to define host of the SNMP agent */
- public static final PropertyDescriptor HOST = new PropertyDescriptor.Builder()
+ 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")
- .displayName("Host Name")
- .description("Network address of SNMP Agent (e.g., localhost)")
+ .displayName("SNMP Agent Hostname")
+ .description("Hostname or network address of the SNMP Agent.")
.required(true)
.defaultValue("localhost")
.addValidator(StandardValidators.NON_EMPTY_VALIDATOR)
.build();
- /** property to define port of the SNMP agent */
- public static final PropertyDescriptor PORT = new PropertyDescriptor.Builder()
+ public static final PropertyDescriptor AGENT_PORT = new PropertyDescriptor.Builder()
.name("snmp-port")
- .displayName("Port")
- .description("Numeric value identifying Port of SNMP Agent (e.g., 161)")
+ .displayName("SNMP Agent Port")
+ .description("Port of the SNMP Agent.")
.required(true)
.defaultValue("161")
.addValidator(StandardValidators.PORT_VALIDATOR)
.build();
- /** property to define SNMP version to use */
public static final PropertyDescriptor SNMP_VERSION = new PropertyDescriptor.Builder()
.name("snmp-version")
.displayName("SNMP Version")
- .description("SNMP Version to use")
+ .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("SNMPv1", "SNMPv2c", "SNMPv3")
- .defaultValue("SNMPv1")
+ .allowableValues(SNMP_V1, SNMP_V2C, SNMP_V3)
+ .defaultValue(SNMP_V1.getValue())
.build();
- /** property to define SNMP community to use */
public static final PropertyDescriptor SNMP_COMMUNITY = new PropertyDescriptor.Builder()
.name("snmp-community")
- .displayName("SNMP Community (v1 & v2c)")
- .description("SNMP Community to use (e.g., public)")
- .required(false)
+ .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();
- /** property to define SNMP security level to use */
public static final PropertyDescriptor SNMP_SECURITY_LEVEL = new PropertyDescriptor.Builder()
.name("snmp-security-level")
.displayName("SNMP Security Level")
- .description("SNMP Security Level to use")
+ .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("noAuthNoPriv", "authNoPriv", "authPriv")
- .defaultValue("authPriv")
+ .allowableValues(NO_AUTH_NO_PRIV, AUTH_NO_PRIV, AUTH_PRIV)
+ .defaultValue(NO_AUTH_NO_PRIV.getValue())
+ .dependsOn(SNMP_VERSION, SNMP_V3)
.build();
- /** property to define SNMP security name to use */
public static final PropertyDescriptor SNMP_SECURITY_NAME = new PropertyDescriptor.Builder()
.name("snmp-security-name")
- .displayName("SNMP Security name / user name")
- .description("Security name used for SNMP exchanges")
- .required(false)
+ .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();
- /** property to define SNMP authentication protocol to use */
public static final PropertyDescriptor SNMP_AUTH_PROTOCOL = new PropertyDescriptor.Builder()
.name("snmp-authentication-protocol")
.displayName("SNMP Authentication Protocol")
- .description("SNMP Authentication Protocol to use")
+ .description("Hash based authentication protocol for secure authentication.")
.required(true)
- .allowableValues("MD5", "SHA", "")
- .defaultValue("")
+ .allowableValues(MD5, SHA, HMAC128SHA224, HMAC192SHA256, HMAC256SHA384, HMAC384SHA512)
+ .dependsOn(SNMP_SECURITY_LEVEL, AUTH_NO_PRIV, AUTH_PRIV)
.build();
- /** property to define SNMP authentication password to use */
public static final PropertyDescriptor SNMP_AUTH_PASSWORD = new PropertyDescriptor.Builder()
.name("snmp-authentication-passphrase")
- .displayName("SNMP Authentication pass phrase")
- .description("Pass phrase used for SNMP authentication protocol")
- .required(false)
+ .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();
- /** property to define SNMP private protocol to use */
- public static final PropertyDescriptor SNMP_PRIV_PROTOCOL = new PropertyDescriptor.Builder()
+ public static final PropertyDescriptor SNMP_PRIVACY_PROTOCOL = new PropertyDescriptor.Builder()
.name("snmp-private-protocol")
- .displayName("SNMP Private Protocol")
- .description("SNMP Private Protocol to use")
+ .displayName("SNMP Privacy Protocol")
+ .description("Privacy allows for encryption of SNMP v3 messages to ensure confidentiality of data.")
.required(true)
- .allowableValues("DES", "3DES", "AES128", "AES192", "AES256", "")
- .defaultValue("")
+ .allowableValues(DES, DES3, AES128, AES192, AES256)
+ .dependsOn(SNMP_SECURITY_LEVEL, AUTH_PRIV)
.build();
- /** property to define SNMP private password to use */
- public static final PropertyDescriptor SNMP_PRIV_PASSWORD = new PropertyDescriptor.Builder()
+ public static final PropertyDescriptor SNMP_PRIVACY_PASSWORD = new PropertyDescriptor.Builder()
.name("snmp-private-protocol-passphrase")
- .displayName("SNMP Private protocol pass phrase")
- .description("Pass phrase used for SNMP private protocol")
- .required(false)
+ .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();
- /** property to define the number of SNMP retries when requesting the SNMP Agent */
public static final PropertyDescriptor SNMP_RETRIES = new PropertyDescriptor.Builder()
.name("snmp-retries")
- .displayName("Number of retries")
- .description("Set the number of retries when requesting the SNMP Agent")
- .required(true)
+ .displayName("Number of Retries")
+ .description("Set the number of retries when requesting the SNMP Agent.")
+ .required(false)
.defaultValue("0")
- .addValidator(StandardValidators.INTEGER_VALIDATOR)
+ .addValidator(StandardValidators.NON_NEGATIVE_INTEGER_VALIDATOR)
.build();
- /** property to define the timeout when requesting the SNMP Agent */
public static final PropertyDescriptor SNMP_TIMEOUT = new PropertyDescriptor.Builder()
.name("snmp-timeout")
.displayName("Timeout (ms)")
- .description("Set the timeout (in milliseconds) when requesting the SNMP Agent")
- .required(true)
+ .description("Set the timeout (in milliseconds) when requesting the SNMP Agent.")
+ .required(false)
.defaultValue("5000")
- .addValidator(StandardValidators.INTEGER_VALIDATOR)
+ .addValidator(StandardValidators.NON_NEGATIVE_INTEGER_VALIDATOR)
.build();
- /** list of property descriptors */
- static List<PropertyDescriptor> descriptors = new ArrayList<>();
- /*
- * Will ensure that list of PropertyDescriptors is build only once, since
- * all other life cycle methods are invoked multiple times.
- */
- static {
- descriptors.add(HOST);
- descriptors.add(PORT);
- descriptors.add(SNMP_VERSION);
- descriptors.add(SNMP_COMMUNITY);
- descriptors.add(SNMP_SECURITY_LEVEL);
- descriptors.add(SNMP_SECURITY_NAME);
- descriptors.add(SNMP_AUTH_PROTOCOL);
- descriptors.add(SNMP_AUTH_PASSWORD);
- descriptors.add(SNMP_PRIV_PROTOCOL);
- descriptors.add(SNMP_PRIV_PASSWORD);
- descriptors.add(SNMP_RETRIES);
- descriptors.add(SNMP_TIMEOUT);
- }
-
- /** SNMP target */
- protected volatile AbstractTarget snmpTarget;
-
- /** transport mapping */
- protected volatile TransportMapping transportMapping;
-
- /** SNMP */
- protected volatile Snmp snmp;
+ protected volatile SNMPRequestHandler snmpRequestHandler;
- /** target resource */
- protected volatile T targetResource;
-
- /**
- * Will builds target resource upon first invocation and will delegate to the
- * implementation of {@link #onTriggerSnmp(ProcessContext, ProcessSession)} method for
- * further processing.
- */
- @Override
- public void onTrigger(ProcessContext context, ProcessSession session) throws ProcessException {
- synchronized (this) {
- this.buildTargetResource(context);
+ @OnScheduled
+ public void initSnmpManager(final ProcessContext context) throws InitializationException {
+ final int version = SNMPUtils.getVersion(context.getProperty(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);
}
- this.onTriggerSnmp(context, session);
+ snmpRequestHandler = SNMPRequestHandlerFactory.createStandardRequestHandler(configuration);
}
/**
- * Will close current SNMP mapping.
+ * Closes the current SNMP mapping.
*/
@OnStopped
public void close() {
- try {
- if (this.targetResource != null) {
- this.targetResource.close();
- }
- } catch (Exception e) {
- this.getLogger().warn("Failure while closing target resource " + this.targetResource, e);
- }
- this.targetResource = null;
-
- try {
- if (this.transportMapping != null) {
- this.transportMapping.close();
- }
- } catch (IOException e) {
- this.getLogger().warn("Failure while closing UDP transport mapping", e);
- }
- this.transportMapping = null;
-
- try {
- if (this.snmp != null) {
- this.snmp.close();
- }
- } catch (IOException e) {
- this.getLogger().warn("Failure while closing UDP transport mapping", e);
+ if (snmpRequestHandler != null) {
+ snmpRequestHandler.close();
+ snmpRequestHandler = null;
}
- this.snmp = null;
}
/**
- * @see org.apache.nifi.components.AbstractConfigurableComponent#customValidate(org.apache.nifi.components.ValidationContext)
+ * 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
*/
- @Override
- protected Collection<ValidationResult> customValidate(ValidationContext validationContext) {
- final List<ValidationResult> problems = new ArrayList<>(super.customValidate(validationContext));
-
- final boolean isVersion3 = "SNMPv3".equals(validationContext.getProperty(SNMP_VERSION).getValue());
-
- if(isVersion3) {
- final boolean isSecurityNameSet = validationContext.getProperty(SNMP_SECURITY_NAME).isSet();
- if(!isSecurityNameSet) {
- problems.add(new ValidationResult.Builder()
- .input("SNMP Security Name")
- .valid(false)
- .explanation("SNMP Security Name must be set with SNMPv3.")
- .build());
- }
-
- final boolean isAuthProtOK = !"".equals(validationContext.getProperty(SNMP_AUTH_PROTOCOL).getValue());
- final boolean isAuthPwdSet = validationContext.getProperty(SNMP_AUTH_PASSWORD).isSet();
- final boolean isPrivProtOK = !"".equals(validationContext.getProperty(SNMP_PRIV_PROTOCOL).getValue());
- final boolean isPrivPwdSet = validationContext.getProperty(SNMP_PRIV_PASSWORD).isSet();
+ protected FlowFile addAttribute(final String key, final String value, FlowFile flowFile, final ProcessSession processSession) {
+ final Map<String, String> attributes = new HashMap<>();
+ attributes.put(key, value);
+ flowFile = processSession.putAllAttributes(flowFile, attributes);
+ return flowFile;
+ }
- switch(validationContext.getProperty(SNMP_SECURITY_LEVEL).getValue()) {
- case "authNoPriv":
- if(!isAuthProtOK || !isAuthPwdSet) {
- problems.add(new ValidationResult.Builder()
- .input("SNMP Security Level")
- .valid(false)
- .explanation("Authentication protocol and password must be set when using authNoPriv security level.")
- .build());
- }
- break;
- case "authPriv":
- if(!isAuthProtOK || !isAuthPwdSet || !isPrivProtOK || !isPrivPwdSet) {
- problems.add(new ValidationResult.Builder()
- .input("SNMP Security Level")
- .valid(false)
- .explanation("All protocols and passwords must be set when using authPriv security level.")
- .build());
+ protected void processResponse(final ProcessSession processSession, FlowFile flowFile, final SNMPSingleResponse response,
+ final String provenanceAddress, final Relationship success) {
+ if (response.isValid()) {
+ if (response.isReportPdu()) {
+ final String oid = response.getVariableBindings().get(0).getOid();
+ final Optional<String> 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));
}
- break;
- case "noAuthNoPriv":
- default:
- break;
+ throw new SNMPException("SNMPRequest failed, Report-PDU returned. " + reportPduErrorMessage.get());
}
+ checkV2cV3VariableBindings(response);
+ flowFile = processSession.putAllAttributes(flowFile, response.getAttributes());
+ processSession.transfer(flowFile, success);
+ processSession.getProvenanceReporter().receive(flowFile, provenanceAddress);
} else {
- final boolean isCommunitySet = validationContext.getProperty(SNMP_COMMUNITY).isSet();
- if(!isCommunitySet) {
- problems.add(new ValidationResult.Builder()
- .input("SNMP Community")
- .valid(false)
- .explanation("SNMP Community must be set with SNMPv1 and SNMPv2c.")
- .build());
- }
+ final String error = response.getErrorStatusText();
+ throw new SNMPException("SNMP request failed, response error: " + error);
}
-
- return problems;
}
- /**
- * Delegate method to supplement
- * {@link #onTrigger(ProcessContext, ProcessSession)}. It is implemented by
- * sub-classes to perform {@link Processor} specific functionality.
- *
- * @param context
- * instance of {@link ProcessContext}
- * @param session
- * instance of {@link ProcessSession}
- * @throws ProcessException Process exception
- */
- protected abstract void onTriggerSnmp(ProcessContext context, ProcessSession session) throws ProcessException;
-
- /**
- * Delegate method to supplement building of target {@link SNMPWorker} (see
- * {@link SNMPSetter} or {@link SNMPGetter}) and is implemented by
- * sub-classes.
- *
- * @param context
- * instance of {@link ProcessContext}
- * @return new instance of {@link SNMPWorker}
- */
- protected abstract T finishBuildingTargetResource(ProcessContext context);
-
- /**
- * Builds target resource.
- * @param context Process context
- */
- private void buildTargetResource(ProcessContext context) {
- if((this.transportMapping == null) || !this.transportMapping.isListening() || (this.snmp == null)) {
- try {
- this.transportMapping = new DefaultUdpTransportMapping();
- this.snmp = new Snmp(this.transportMapping);
-
- if("SNMPv3".equals(context.getProperty(SNMP_VERSION).getValue())) {
- USM usm = new USM(SecurityProtocols.getInstance(), new OctetString(MPv3.createLocalEngineID()), 0);
- SecurityModels.getInstance().addSecurityModel(usm);
+ private void checkV2cV3VariableBindings(SNMPSingleResponse response) {
+ if (response.getVersion() != SnmpConstants.version1) {
+ final Optional<SNMPValue> 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.");
}
-
- this.transportMapping.listen();
- } catch (Exception e) {
- throw new IllegalStateException("Failed to initialize UDP transport mapping", e);
+ } else {
+ throw new SNMPException("Empty SNMP response: no variable binding found.");
}
}
- if (this.snmpTarget == null) {
- this.snmpTarget = this.createSnmpTarget(context);
- }
- if (this.targetResource == null) {
- this.targetResource = this.finishBuildingTargetResource(context);
- }
}
-
- /**
- * Creates {@link AbstractTarget} to request SNMP agent.
- * @param context Process context
- * @return the SNMP target
- */
- private AbstractTarget createSnmpTarget(ProcessContext context) {
- AbstractTarget result = null;
- String snmpVersion = context.getProperty(SNMP_VERSION).getValue();
- int version = 0;
- switch (snmpVersion) {
- case "SNMPv2c":
- version = SnmpConstants.version2c;
- break;
- case "SNMPv3":
- version = SnmpConstants.version3;
- break;
- case "SNMPv1":
- default:
- version = SnmpConstants.version1;
- break;
- }
-
- if(version == SnmpConstants.version3) {
- final String username = context.getProperty(SNMP_SECURITY_NAME).getValue();
- final String authPassword = context.getProperty(SNMP_AUTH_PASSWORD).getValue();
- final String privPassword = context.getProperty(SNMP_PRIV_PASSWORD).getValue();
- final String authProtocol = context.getProperty(SNMP_AUTH_PROTOCOL).getValue();
- final String privProtocol = context.getProperty(SNMP_PRIV_PROTOCOL).getValue();
- OctetString aPwd = authPassword != null ? new OctetString(authPassword) : null;
- OctetString pPwd = privPassword != null ? new OctetString(privPassword) : null;
-
- // add user information
- this.snmp.getUSM().addUser(new OctetString(username),
- new UsmUser(new OctetString(username), SNMPUtils.getAuth(authProtocol), aPwd, SNMPUtils.getPriv(privProtocol), pPwd));
-
- result = new UserTarget();
-
- ((UserTarget) result).setSecurityLevel(SNMPUtils.getSecLevel(context.getProperty(SNMP_SECURITY_LEVEL).getValue()));
- final String securityName = context.getProperty(SNMP_SECURITY_NAME).getValue();
- if(securityName != null) {
- ((UserTarget) result).setSecurityName(new OctetString(securityName));
- }
- } else {
- result = new CommunityTarget();
- String community = context.getProperty(SNMP_COMMUNITY).getValue();
- if(community != null) {
- ((CommunityTarget) result).setCommunity(new OctetString(community));
- }
- }
-
- result.setVersion(version);
- result.setAddress(new UdpAddress(context.getProperty(HOST).getValue() + "/" + context.getProperty(PORT).getValue()));
- result.setRetries(context.getProperty(SNMP_RETRIES).asInteger());
- result.setTimeout(context.getProperty(SNMP_TIMEOUT).asInteger());
-
- return result;
- }
-
}
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 0a4654a..58a08bd 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
@@ -16,30 +16,32 @@
*/
package org.apache.nifi.snmp.processors;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Set;
-
import org.apache.nifi.annotation.behavior.InputRequirement;
import org.apache.nifi.annotation.behavior.InputRequirement.Requirement;
import org.apache.nifi.annotation.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.components.AllowableValue;
import org.apache.nifi.components.PropertyDescriptor;
import org.apache.nifi.flowfile.FlowFile;
import org.apache.nifi.processor.ProcessContext;
import org.apache.nifi.processor.ProcessSession;
-import org.apache.nifi.processor.Processor;
import org.apache.nifi.processor.Relationship;
import org.apache.nifi.processor.util.StandardValidators;
-import org.apache.nifi.processor.exception.ProcessException;
-import org.snmp4j.PDU;
-import org.snmp4j.event.ResponseEvent;
-import org.snmp4j.smi.OID;
-import org.snmp4j.util.TreeEvent;
+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.utils.SNMPUtils;
+import org.apache.nifi.snmp.validators.OIDValidator;
+
+import java.io.IOException;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
/**
* Retrieving data from configured SNMP agent which, upon each invocation of
@@ -47,153 +49,153 @@ import org.snmp4j.util.TreeEvent;
* {@link FlowFile} containing in its properties the information retrieved.
* The output {@link FlowFile} won't have any content.
*/
-@Tags({ "snmp", "get", "oid", "walk" })
+@Tags({"snmp", "get", "oid", "walk"})
@InputRequirement(Requirement.INPUT_FORBIDDEN)
-@CapabilityDescription("Retrieves information from SNMP Agent and outputs a FlowFile with information in attributes and without any content")
+@CapabilityDescription("Retrieves information from SNMP Agent with SNMP Get request and outputs a FlowFile with information" +
+ " in attributes and without any content")
@WritesAttributes({
- @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"),
- @WritesAttribute(attribute=SNMPUtils.SNMP_PROP_PREFIX + "textualOid", description="This attribute will exist if and only if the strategy"
- + " is GET and will be equal to the value given in Textual Oid property.")
+ @WritesAttribute(attribute = SNMPUtils.SNMP_PROP_PREFIX + "<OID>", 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."),
+ @WritesAttribute(attribute = SNMPUtils.SNMP_PROP_PREFIX + "errorStatus", description = "The snmp4j error status of the PDU."),
+ @WritesAttribute(attribute = SNMPUtils.SNMP_PROP_PREFIX + "errorStatusText", description = "The description of error status."),
+ @WritesAttribute(attribute = SNMPUtils.SNMP_PROP_PREFIX + "nonRepeaters", description = "The number of non repeater variable bindings in a GETBULK PDU (currently not supported)."),
+ @WritesAttribute(attribute = SNMPUtils.SNMP_PROP_PREFIX + "requestID", description = "The request ID associated with the PDU."),
+ @WritesAttribute(attribute = SNMPUtils.SNMP_PROP_PREFIX + "type", description = "The snmp4j numeric representation of the type of the PDU."),
+ @WritesAttribute(attribute = SNMPUtils.SNMP_PROP_PREFIX + "typeString", description = "The name of the PDU type."),
+ @WritesAttribute(attribute = SNMPUtils.SNMP_PROP_PREFIX + "textualOid", description = "This attribute will exist if and only if the strategy"
+ + " is GET and will be equal to the value given in Textual Oid property.")
})
-public class GetSNMP extends AbstractSNMPProcessor<SNMPGetter> {
+public class GetSNMP extends AbstractSNMPProcessor {
+
+ // SNMP strategies
+ public static final AllowableValue GET = new AllowableValue("GET", "GET",
+ "A manager-to-agent request to retrieve the value of a variable. A response with the current value returned.");
+ public static final AllowableValue WALK = new AllowableValue("WALK", "WALK",
+ "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) */
+ // OID to request (if walk, it is the root ID of the request).
public static final PropertyDescriptor OID = new PropertyDescriptor.Builder()
.name("snmp-oid")
.displayName("OID")
- .description("The OID to request")
+ .description("Each OID (object identifier) identifies a variable that can be read or set via SNMP.")
+ .required(true)
+ .addValidator(new OIDValidator())
+ .build();
+
+ public static final PropertyDescriptor SNMP_STRATEGY = new PropertyDescriptor.Builder()
+ .name("snmp-strategy")
+ .displayName("SNMP Strategy")
+ .description("SNMP strategy to use (SNMP Get or SNMP Walk)")
.required(true)
- .addValidator(SNMPUtils.SNMP_OID_VALIDATOR)
+ .allowableValues(GET, WALK)
+ .defaultValue(GET.getValue())
.build();
- /** Textual OID to request */
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 OID to request.")
.required(false)
.addValidator(StandardValidators.NON_BLANK_VALIDATOR)
.defaultValue(null)
.build();
- /** SNMP strategy for SNMP Get processor : simple get or walk */
- public static final PropertyDescriptor SNMP_STRATEGY = new PropertyDescriptor.Builder()
- .name("snmp-strategy")
- .displayName("SNMP strategy (GET/WALK)")
- .description("SNMP strategy to use (SNMP Get or SNMP Walk)")
- .required(true)
- .allowableValues("GET", "WALK")
- .defaultValue("GET")
- .build();
-
- /** relationship for success */
public static final Relationship REL_SUCCESS = new Relationship.Builder()
.name("success")
- .description("All FlowFiles that are received from the SNMP agent are routed to this relationship")
+ .description("All FlowFiles that are received from the SNMP agent are routed to this relationship.")
.build();
- /** relationship for failure */
public static final Relationship REL_FAILURE = new Relationship.Builder()
.name("failure")
- .description("All FlowFiles that cannot received from the SNMP agent are routed to this relationship")
+ .description("All FlowFiles that cannot received from the SNMP agent are routed to this relationship.")
.build();
- /** list of property descriptors */
- private final static List<PropertyDescriptor> propertyDescriptors;
-
- /** list of relationships */
- private final static Set<Relationship> relationships;
-
- /*
- * Will ensure that the list of property descriptors is build only once.
- * Will also create a Set of relationships
- */
- static {
- List<PropertyDescriptor> _propertyDescriptors = new ArrayList<>();
- _propertyDescriptors.add(OID);
- _propertyDescriptors.add(TEXTUAL_OID);
- _propertyDescriptors.add(SNMP_STRATEGY);
- _propertyDescriptors.addAll(descriptors);
- propertyDescriptors = Collections.unmodifiableList(_propertyDescriptors);
-
- Set<Relationship> _relationships = new HashSet<>();
- _relationships.add(REL_SUCCESS);
- _relationships.add(REL_FAILURE);
- relationships = Collections.unmodifiableSet(_relationships);
- }
+ protected static final List<PropertyDescriptor> 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,
+ OID,
+ TEXTUAL_OID,
+ SNMP_STRATEGY
+ ));
+
+ private static final Set<Relationship> RELATIONSHIPS = Collections.unmodifiableSet(new HashSet<>(Arrays.asList(
+ REL_SUCCESS,
+ REL_FAILURE
+ )));
- /**
- * Delegate method to supplement
- * {@link #onTrigger(ProcessContext, ProcessSession)}. It is implemented by
- * sub-classes to perform {@link Processor} specific functionality.
- *
- * @param context
- * instance of {@link ProcessContext}
- * @param processSession
- * instance of {@link ProcessSession}
- * @throws ProcessException Process exception
- */
@Override
- protected void onTriggerSnmp(ProcessContext context, ProcessSession processSession) throws ProcessException {
- if("GET".equals(context.getProperty(SNMP_STRATEGY).getValue())) {
- final ResponseEvent response = this.targetResource.get();
- if (response.getResponse() != null){
- FlowFile flowFile = processSession.create();
- PDU pdu = response.getResponse();
- flowFile = SNMPUtils.updateFlowFileAttributesWithPduProperties(pdu, flowFile, processSession);
- flowFile = SNMPUtils.addAttribute(SNMPUtils.SNMP_PROP_PREFIX + "textualOid",
- context.getProperty(TEXTUAL_OID).getValue(), flowFile, processSession);
- processSession.getProvenanceReporter().receive(flowFile,
- this.snmpTarget.getAddress().toString() + "/" + context.getProperty(OID).getValue());
- if(pdu.getErrorStatus() == PDU.noError) {
- processSession.transfer(flowFile, REL_SUCCESS);
- } else {
- processSession.transfer(flowFile, REL_FAILURE);
- }
- } else {
- this.getLogger().error("Get request timed out or parameters are incorrect.");
- context.yield();
- }
- } else if("WALK".equals(context.getProperty(SNMP_STRATEGY).getValue())) {
- final List<TreeEvent> events = this.targetResource.walk();
- if((events != null) && !events.isEmpty() && (events.get(0).getVariableBindings() != null)) {
- FlowFile flowFile = processSession.create();
- for (TreeEvent treeEvent : events) {
- flowFile = SNMPUtils.updateFlowFileAttributesWithTreeEventProperties(treeEvent, flowFile, processSession);
- }
- processSession.getProvenanceReporter().receive(flowFile,
- this.snmpTarget.getAddress().toString() + "/" + context.getProperty(OID).getValue());
- processSession.transfer(flowFile, REL_SUCCESS);
- } else {
- this.getLogger().error("Get request timed out or parameters are incorrect.");
- context.yield();
- }
+ 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();
+
+ if (SNMPStrategy.GET == snmpStrategy) {
+ performSnmpGet(context, processSession, oid);
+ } else if (SNMPStrategy.WALK == snmpStrategy) {
+ performSnmpWalk(context, processSession, oid);
}
}
- /**
- * Will create an instance of {@link SNMPGetter}
- */
- @Override
- protected SNMPGetter finishBuildingTargetResource(ProcessContext context) {
- String oid = context.getProperty(OID).getValue();
- return new SNMPGetter(this.snmp, this.snmpTarget, new OID(oid));
+ private void performSnmpWalk(final ProcessContext context, final ProcessSession processSession, final String oid) {
+ 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);
+ } 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;
+ 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();
+ } catch (IOException e) {
+ getLogger().error("Failed to send request to the agent. Check if the agent supports the used version.");
+ context.yield();
+ processSession.rollback();
+ }
}
- /**
- * get list of supported property descriptors
- */
@Override
protected List<PropertyDescriptor> getSupportedPropertyDescriptors() {
- return propertyDescriptors;
+ return PROPERTY_DESCRIPTORS;
}
- /**
- * get list of relationships
- */
@Override
public Set<Relationship> getRelationships() {
- return relationships;
+ return RELATIONSHIPS;
+ }
+
+ private FlowFile createFlowFileWithTreeEventProperties(final SNMPTreeResponse response, final ProcessSession processSession) {
+ FlowFile flowFile = processSession.create();
+ flowFile = processSession.putAllAttributes(flowFile, response.getAttributes());
+ return flowFile;
+ }
+
+ private enum SNMPStrategy {
+ GET, WALK
}
}
diff --git a/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/main/java/org/apache/nifi/snmp/processors/SNMPGetter.java b/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/main/java/org/apache/nifi/snmp/processors/SNMPGetter.java
deleted file mode 100644
index a8543cb..0000000
--- a/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/main/java/org/apache/nifi/snmp/processors/SNMPGetter.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.processors;
-
-import java.io.IOException;
-import java.util.List;
-
-import org.apache.nifi.processor.exception.ProcessException;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.snmp4j.AbstractTarget;
-import org.snmp4j.PDU;
-import org.snmp4j.ScopedPDU;
-import org.snmp4j.Snmp;
-import org.snmp4j.event.ResponseEvent;
-import org.snmp4j.mp.SnmpConstants;
-import org.snmp4j.smi.OID;
-import org.snmp4j.smi.VariableBinding;
-import org.snmp4j.util.DefaultPDUFactory;
-import org.snmp4j.util.TreeEvent;
-import org.snmp4j.util.TreeUtils;
-
-/**
- * Extension of {@link SNMPWorker} to perform SNMP Get and SNMP Walk requests
- */
-final class SNMPGetter extends SNMPWorker {
-
- /** logger */
- private final static Logger logger = LoggerFactory.getLogger(SNMPGetter.class);
-
- /** OID to request */
- private final OID oid;
-
- /**
- * Creates an instance of this getter
- * @param snmp instance of {@link Snmp}
- * @param target instance of {@link AbstractTarget} to request
- * @param oid instance of {@link OID} to request
- */
- SNMPGetter(Snmp snmp, AbstractTarget target, OID oid) {
- super(snmp, target);
- this.oid = oid;
- logger.info("Successfully initialized SNMP Getter");
- }
-
- /**
- * Construct the PDU to perform the SNMP Get request and returns
- * the result in order to create the flow file.
- * @return {@link ResponseEvent}
- */
- public ResponseEvent get() {
- try {
- PDU pdu = null;
- if(this.target.getVersion() == SnmpConstants.version3) {
- pdu = new ScopedPDU();
- } else {
- pdu = new PDU();
- }
- pdu.add(new VariableBinding(this.oid));
- pdu.setType(PDU.GET);
- return this.snmp.get(pdu, this.target);
- } catch (IOException e) {
- logger.error("Failed to get information from SNMP agent; " + this, e);
- throw new ProcessException(e);
- }
- }
-
- /**
- * Perform a SNMP walk and returns the list of {@link TreeEvent}
- * @return the list of {@link TreeEvent}
- */
- public List<TreeEvent> walk() {
- TreeUtils treeUtils = new TreeUtils(this.snmp, new DefaultPDUFactory());
- @SuppressWarnings("unchecked")
- List<TreeEvent> events = treeUtils.getSubtree(this.target, this.oid);
- return events;
- }
-
- /**
- * @see org.apache.nifi.snmp.processors.SNMPWorker#toString()
- */
- @Override
- public String toString() {
- return super.toString() + ", OID:" + this.oid.toString();
- }
-}
diff --git a/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/main/java/org/apache/nifi/snmp/processors/SNMPSetter.java b/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/main/java/org/apache/nifi/snmp/processors/SNMPSetter.java
deleted file mode 100644
index 1b72bf9..0000000
--- a/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/main/java/org/apache/nifi/snmp/processors/SNMPSetter.java
+++ /dev/null
@@ -1,56 +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.processors;
-
-import java.io.IOException;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.snmp4j.AbstractTarget;
-import org.snmp4j.PDU;
-import org.snmp4j.Snmp;
-import org.snmp4j.event.ResponseEvent;
-
-/**
- * Extension of {@link SNMPWorker} to perform SNMP Set requests
- */
-final class SNMPSetter extends SNMPWorker {
-
- /** logger */
- private final static Logger logger = LoggerFactory.getLogger(SNMPSetter.class);
-
- /**
- * Creates an instance of this setter
- * @param snmp instance of {@link Snmp}
- * @param target instance of {@link AbstractTarget} to request
- */
- SNMPSetter(Snmp snmp, AbstractTarget target) {
- super(snmp, target);
- logger.info("Successfully initialized SNMP Setter");
- }
-
- /**
- * Executes the SNMP set request and returns the response
- * @param pdu PDU to send
- * @return Response event
- * @throws IOException IO Exception
- */
- public ResponseEvent set(PDU pdu) throws IOException {
- return this.snmp.set(pdu, this.target);
- }
-
-}
diff --git a/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/main/java/org/apache/nifi/snmp/processors/SNMPUtils.java b/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/main/java/org/apache/nifi/snmp/processors/SNMPUtils.java
deleted file mode 100644
index d5c0e30..0000000
--- a/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/main/java/org/apache/nifi/snmp/processors/SNMPUtils.java
+++ /dev/null
@@ -1,268 +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.processors;
-
-import java.lang.reflect.Method;
-import java.lang.reflect.Modifier;
-import java.util.Arrays;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Vector;
-import java.util.regex.Pattern;
-
-import org.apache.nifi.components.ValidationContext;
-import org.apache.nifi.components.ValidationResult;
-import org.apache.nifi.components.Validator;
-import org.apache.nifi.flowfile.FlowFile;
-import org.apache.nifi.processor.ProcessSession;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.snmp4j.PDU;
-import org.snmp4j.security.AuthMD5;
-import org.snmp4j.security.AuthSHA;
-import org.snmp4j.security.Priv3DES;
-import org.snmp4j.security.PrivAES128;
-import org.snmp4j.security.PrivAES192;
-import org.snmp4j.security.PrivAES256;
-import org.snmp4j.security.PrivDES;
-import org.snmp4j.security.SecurityLevel;
-import org.snmp4j.smi.OID;
-import org.snmp4j.smi.VariableBinding;
-import org.snmp4j.util.TreeEvent;
-
-/**
- * Utility helper class that simplifies interactions with target SNMP API and NIFI API.
- */
-abstract class SNMPUtils {
-
- /** logger */
- private final static Logger logger = LoggerFactory.getLogger(SNMPUtils.class);
-
- /** OID Pattern */
- public final static Pattern OID_PATTERN = Pattern.compile("[[0-9]+\\.]*");
-
- /** delimiter for properties name */
- public final static String SNMP_PROP_DELIMITER = "$";
-
- /** prefix for SNMP properties in flow file */
- public final static String SNMP_PROP_PREFIX = "snmp" + SNMP_PROP_DELIMITER;
-
- /** list of properties name when performing simple get */
- private final static List<String> propertyNames = Arrays.asList("snmp$errorIndex", "snmp$errorStatus", "snmp$errorStatusText",
- "snmp$nonRepeaters", "snmp$requestID", "snmp$type", "snmp$variableBindings");
-
- /** used to validate OID syntax */
- public static final Validator SNMP_OID_VALIDATOR = new Validator() {
- @Override
- public ValidationResult validate(final String subject, final String input, final ValidationContext context) {
- final ValidationResult.Builder builder = new ValidationResult.Builder();
- builder.subject(subject).input(input);
- if (context.isExpressionLanguageSupported(subject) && context.isExpressionLanguagePresent(input)) {
- return builder.valid(true).explanation("Contains Expression Language").build();
- }
- try {
- if (OID_PATTERN.matcher(input).matches()) {
- builder.valid(true);
- } else {
- builder.valid(false).explanation(input + "is not a valid OID");
- }
- } catch (final IllegalArgumentException e) {
- builder.valid(false).explanation(e.getMessage());
- }
- return builder.build();
- }
- };
-
- /**
- * Updates {@link FlowFile} with attributes representing PDU properties
- * @param response PDU retried from SNMP Agent
- * @param flowFile instance of target {@link FlowFile}
- * @param processSession instance of {@link ProcessSession}
- * @return updated {@link FlowFile}
- */
- public static FlowFile updateFlowFileAttributesWithPduProperties(PDU response, FlowFile flowFile, ProcessSession processSession) {
- if (response != null) {
- try {
- Method[] methods = PDU.class.getDeclaredMethods();
- Map<String, String> attributes = new HashMap<String, String>();
- for (Method method : methods) {
- if (Modifier.isPublic(method.getModifiers()) && (method.getParameterTypes().length == 0) && method.getName().startsWith("get")) {
- String propertyName = extractPropertyNameFromMethod(method);
- if (isValidSnmpPropertyName(propertyName)) {
- Object amqpPropertyValue = method.invoke(response);
- if (amqpPropertyValue != null) {
- if (propertyName.equals(SNMP_PROP_PREFIX + "variableBindings") && (amqpPropertyValue instanceof Vector)) {
- addGetOidValues(attributes, amqpPropertyValue);
- } else {
- attributes.put(propertyName, amqpPropertyValue.toString());
- }
- }
- }
- }
- }
- flowFile = processSession.putAllAttributes(flowFile, attributes);
- } catch (Exception e) {
- logger.warn("Failed to update FlowFile with AMQP attributes", e);
- }
- }
- return flowFile;
- }
-
- /**
- * Method to add attribute in flow file
- * @param key attribute key
- * @param value attribute value
- * @param flowFile flow file to update
- * @param processSession session
- * @return updated flow file
- */
- public static FlowFile addAttribute(String key, String value, FlowFile flowFile, ProcessSession processSession) {
- Map<String, String> attributes = new HashMap<String, String>();
- attributes.put(key, value);
- flowFile = processSession.putAllAttributes(flowFile, attributes);
- return flowFile;
- }
-
- /**
- * Method to construct {@link FlowFile} attributes from a {@link TreeEvent}
- * @param treeEvent a {@link TreeEvent}
- * @param flowFile instance of the {@link FlowFile} to update
- * @param processSession instance of {@link ProcessSession}
- * @return updated {@link FlowFile}
- */
- public static FlowFile updateFlowFileAttributesWithTreeEventProperties(TreeEvent treeEvent, FlowFile flowFile, ProcessSession processSession) {
- Map<String, String> attributes = new HashMap<String, String>();
- addWalkOidValues(attributes, treeEvent.getVariableBindings());
- flowFile = processSession.putAllAttributes(flowFile, attributes);
- return flowFile;
- }
-
- /**
- * Method to construct {@link FlowFile} attributes from a vector of {@link VariableBinding}
- * @param attributes attributes
- * @param vector vector of {@link VariableBinding}
- */
- private static void addWalkOidValues(Map<String, String> attributes, Object vector) {
- if (vector instanceof VariableBinding[]) {
- VariableBinding[] variables = (VariableBinding[]) vector;
- for (VariableBinding variableBinding : variables) {
- addAttributeFromVariable(variableBinding, attributes);
- }
- }
- }
-
- /**
- * Method to construct {@link FlowFile} attributes from a vector of {@link VariableBinding}
- * @param attributes attributes
- * @param vector vector of {@link VariableBinding}
- */
- private static void addGetOidValues(Map<String, String> attributes, Object vector) {
- if (vector instanceof Vector) {
- @SuppressWarnings("unchecked")
- Vector<VariableBinding> variables = (Vector<VariableBinding>) vector;
- for (VariableBinding variableBinding : variables) {
- addAttributeFromVariable(variableBinding, attributes);
- }
- }
- }
-
- /**
- * Method to add {@link FlowFile} attributes from a {@link VariableBinding}
- * @param variableBinding {@link VariableBinding}
- * @param attributes {@link FlowFile} attributes to update
- */
- private static void addAttributeFromVariable(VariableBinding variableBinding, Map<String, String> attributes) {
- attributes.put(SNMP_PROP_PREFIX + variableBinding.getOid() + SNMP_PROP_DELIMITER + variableBinding.getVariable().getSyntax(), variableBinding.getVariable().toString());
- }
-
- /**
- * Will validate if provided name corresponds to valid SNMP property.
- * @param name the name of the property
- * @return 'true' if valid otherwise 'false'
- */
- public static boolean isValidSnmpPropertyName(String name) {
- return propertyNames.contains(name);
- }
-
- /**
- * Method to extract property name from given {@link Method}
- * @param method method
- * @return property name
- */
- private static String extractPropertyNameFromMethod(Method method) {
- char c[] = method.getName().substring(3).toCharArray();
- c[0] = Character.toLowerCase(c[0]);
- return SNMP_PROP_PREFIX + new String(c);
- }
-
- /**
- * Method to return the private protocol given the property
- * @param privProtocol property
- * @return protocol
- */
- public static OID getPriv(String privProtocol) {
- switch (privProtocol) {
- case "DES":
- return PrivDES.ID;
- case "3DES":
- return Priv3DES.ID;
- case "AES128":
- return PrivAES128.ID;
- case "AES192":
- return PrivAES192.ID;
- case "AES256":
- return PrivAES256.ID;
- default:
- return null;
- }
- }
-
- /**
- * Method to return the authentication protocol given the property
- * @param authProtocol property
- * @return protocol
- */
- public static OID getAuth(String authProtocol) {
- switch (authProtocol) {
- case "SHA":
- return AuthSHA.ID;
- case "MD5":
- return AuthMD5.ID;
- default:
- return null;
- }
- }
-
- /**
- * Method to get security level from string representation of level
- * @param level level
- * @return security level as integer
- */
- public static int getSecLevel(String level) {
- switch (level) {
- case "noAuthNoPriv":
- return SecurityLevel.NOAUTH_NOPRIV;
- case "authNoPriv":
- return SecurityLevel.AUTH_NOPRIV;
- case "authPriv":
- default:
- return SecurityLevel.AUTH_PRIV;
- }
- }
-
-}
diff --git a/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/main/java/org/apache/nifi/snmp/processors/SNMPWorker.java b/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/main/java/org/apache/nifi/snmp/processors/SNMPWorker.java
deleted file mode 100644
index 727c519..0000000
--- a/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/main/java/org/apache/nifi/snmp/processors/SNMPWorker.java
+++ /dev/null
@@ -1,74 +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.processors;
-
-import java.io.IOException;
-import java.util.concurrent.TimeoutException;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.snmp4j.AbstractTarget;
-import org.snmp4j.Snmp;
-
-/**
- * Base class for implementing SNMP workers.
- *
- * @see SNMPSetter
- * @see SNMPGetter
- */
-abstract class SNMPWorker implements AutoCloseable {
-
- /** logger */
- private final static Logger logger = LoggerFactory.getLogger(SNMPWorker.class);
-
- /** SNMP abstraction */
- protected final Snmp snmp;
-
- /** Target to request */
- protected final AbstractTarget target;
-
- /**
- * Creates an instance of this worker and initializing it with {@link Snmp}
- * and {@link AbstractTarget} used by sub-classes to interact with SNMP agent.
- * @param snmp instance of {@link Snmp}
- * @param target instance of {@link AbstractTarget}
- */
- public SNMPWorker(Snmp snmp, AbstractTarget target) {
- this.snmp = snmp;
- this.target = target;
- }
-
- /**
- * Closes {@link Snmp} created when instance of this class was created.
- */
- @Override
- public void close() throws TimeoutException, IOException {
- if (logger.isDebugEnabled()) {
- logger.debug("Closing SNMP connection");
- }
- this.snmp.close();
- }
-
- /**
- * @see java.lang.Object#toString()
- */
- @Override
- public String toString() {
- return this.getClass().getSimpleName() + ":" + this.snmp.toString();
- }
-
-}
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 4674bc6..ab5ca72 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
@@ -16,17 +16,10 @@
*/
package org.apache.nifi.snmp.processors;
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.Set;
-
import org.apache.nifi.annotation.behavior.InputRequirement;
import org.apache.nifi.annotation.behavior.InputRequirement.Requirement;
+import org.apache.nifi.annotation.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.components.PropertyDescriptor;
@@ -34,19 +27,16 @@ import org.apache.nifi.flowfile.FlowFile;
import org.apache.nifi.processor.ProcessContext;
import org.apache.nifi.processor.ProcessSession;
import org.apache.nifi.processor.Relationship;
-import org.apache.nifi.processor.exception.ProcessException;
-import org.snmp4j.PDU;
-import org.snmp4j.ScopedPDU;
-import org.snmp4j.event.ResponseEvent;
-import org.snmp4j.mp.SnmpConstants;
-import org.snmp4j.smi.AbstractVariable;
-import org.snmp4j.smi.AssignableFromInteger;
-import org.snmp4j.smi.AssignableFromLong;
-import org.snmp4j.smi.AssignableFromString;
-import org.snmp4j.smi.OID;
-import org.snmp4j.smi.OctetString;
-import org.snmp4j.smi.Variable;
-import org.snmp4j.smi.VariableBinding;
+import org.apache.nifi.snmp.dto.SNMPSingleResponse;
+import org.apache.nifi.snmp.exception.SNMPException;
+import org.apache.nifi.snmp.utils.SNMPUtils;
+
+import java.io.IOException;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
/**
* Performs a SNMP Set operation based on attributes of incoming FlowFile.
@@ -54,171 +44,83 @@ import org.snmp4j.smi.VariableBinding;
* method, it will inspect attributes of FlowFile and look for attributes with
* name formatted as "snmp$OID" to set the attribute value to this OID.
*/
-@Tags({ "snmp", "set", "oid" })
+@Tags({"snmp", "set", "oid"})
@InputRequirement(Requirement.INPUT_REQUIRED)
@CapabilityDescription("Based on incoming FlowFile attributes, the processor will execute SNMP Set requests." +
- " When founding attributes with name like snmp$<OID>, the processor will atempt to set the value of" +
- " attribute to the corresponding OID given in the attribute name")
-public class SetSNMP extends AbstractSNMPProcessor<SNMPSetter> {
+ " When finding attributes with the name snmp$<OID>, the processor will attempt to set the value of" +
+ " the attribute to the corresponding OID given in the attribute name")
+@WritesAttributes({
+ @WritesAttribute(attribute = SNMPUtils.SNMP_PROP_PREFIX + "<OID>", 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."),
+ @WritesAttribute(attribute = SNMPUtils.SNMP_PROP_PREFIX + "errorStatus", description = "The snmp4j error status of the PDU."),
+ @WritesAttribute(attribute = SNMPUtils.SNMP_PROP_PREFIX + "errorStatusText", description = "The description of error status."),
+ @WritesAttribute(attribute = SNMPUtils.SNMP_PROP_PREFIX + "nonRepeaters", description = "The number of non repeater variable bindings in a GETBULK PDU (currently not supported)."),
+ @WritesAttribute(attribute = SNMPUtils.SNMP_PROP_PREFIX + "requestID", description = "The request ID associated with the PDU."),
+ @WritesAttribute(attribute = SNMPUtils.SNMP_PROP_PREFIX + "type", description = "The snmp4j numeric representation of the type of the PDU."),
+ @WritesAttribute(attribute = SNMPUtils.SNMP_PROP_PREFIX + "typeString", description = "The name of the PDU type."),
+})
+public class SetSNMP extends AbstractSNMPProcessor {
- /** relationship for success */
public static final Relationship REL_SUCCESS = new Relationship.Builder()
.name("success")
.description("All FlowFiles that have been successfully used to perform SNMP Set are routed to this relationship")
.build();
- /** relationship for failure */
+
public static final Relationship REL_FAILURE = new Relationship.Builder()
.name("failure")
.description("All FlowFiles that failed during the SNMP Set care routed to this relationship")
.build();
- /** list of properties descriptors */
- private final static List<PropertyDescriptor> propertyDescriptors;
-
- /** list of relationships */
- private final static Set<Relationship> relationships;
+ private static final List<PropertyDescriptor> 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
+ ));
- /*
- * Will ensure that the list of property descriptors is build only once.
- * Will also create a Set of relationships
- */
- static {
- List<PropertyDescriptor> _propertyDescriptors = new ArrayList<>();
- _propertyDescriptors.addAll(descriptors);
- propertyDescriptors = Collections.unmodifiableList(_propertyDescriptors);
+ private static final Set<Relationship> RELATIONSHIPS = Collections.unmodifiableSet(new HashSet<>(Arrays.asList(
+ REL_SUCCESS,
+ REL_FAILURE
+ )));
- Set<Relationship> _relationships = new HashSet<>();
- _relationships.add(REL_SUCCESS);
- _relationships.add(REL_FAILURE);
- relationships = Collections.unmodifiableSet(_relationships);
- }
-
- /**
- * @see org.apache.nifi.snmp.processors.AbstractSNMPProcessor#onTriggerSnmp(org.apache.nifi.processor.ProcessContext, org.apache.nifi.processor.ProcessSession)
- */
@Override
- protected void onTriggerSnmp(ProcessContext context, ProcessSession processSession) throws ProcessException {
- FlowFile flowFile = processSession.get();
+ public void onTrigger(final ProcessContext context, final ProcessSession processSession) {
+ final FlowFile flowFile = processSession.get();
if (flowFile != null) {
- // Create the PDU object
- PDU pdu = null;
- if(this.snmpTarget.getVersion() == SnmpConstants.version3) {
- pdu = new ScopedPDU();
- } else {
- pdu = new PDU();
- }
- if(this.addVariables(pdu, flowFile.getAttributes())) {
- pdu.setType(PDU.SET);
- try {
- ResponseEvent response = this.targetResource.set(pdu);
- if(response.getResponse() == null) {
- processSession.transfer(processSession.penalize(flowFile), REL_FAILURE);
- this.getLogger().error("Set request timed out or parameters are incorrect.");
- context.yield();
- } else if(response.getResponse().getErrorStatus() == PDU.noError) {
- flowFile = SNMPUtils.updateFlowFileAttributesWithPduProperties(pdu, flowFile, processSession);
- processSession.transfer(flowFile, REL_SUCCESS);
- processSession.getProvenanceReporter().send(flowFile, this.snmpTarget.getAddress().toString());
- } else {
- final String error = response.getResponse().getErrorStatusText();
- flowFile = SNMPUtils.addAttribute(SNMPUtils.SNMP_PROP_PREFIX + "error", error, flowFile, processSession);
- processSession.transfer(processSession.penalize(flowFile), REL_FAILURE);
- this.getLogger().error("Failed while executing SNMP Set [{}] via " + this.targetResource + ". Error = {}", new Object[]{response.getRequest().getVariableBindings(), error});
- }
- } catch (IOException e) {
- processSession.transfer(processSession.penalize(flowFile), REL_FAILURE);
- this.getLogger().error("Failed while executing SNMP Set via " + this.targetResource, e);
- context.yield();
- }
- } else {
- processSession.transfer(processSession.penalize(flowFile), REL_FAILURE);
- this.getLogger().warn("No attributes found in the FlowFile to perform SNMP Set");
- }
- }
- }
-
- /**
- * Method to construct {@link VariableBinding} based on {@link FlowFile}
- * attributes in order to update the {@link PDU} that is going to be sent to
- * the SNMP Agent.
- * @param pdu {@link PDU} to be sent
- * @param attributes {@link FlowFile} attributes
- * @return true if at least one {@link VariableBinding} has been created, false otherwise
- */
- private boolean addVariables(PDU pdu, Map<String, String> attributes) {
- boolean result = false;
- for (Entry<String, String> attributeEntry : attributes.entrySet()) {
- if (attributeEntry.getKey().startsWith(SNMPUtils.SNMP_PROP_PREFIX)) {
- String[] splits = attributeEntry.getKey().split("\\" + SNMPUtils.SNMP_PROP_DELIMITER);
- String snmpPropName = splits[1];
- String snmpPropValue = attributeEntry.getValue();
- if(SNMPUtils.OID_PATTERN.matcher(snmpPropName).matches()) {
- Variable var = null;
- if (splits.length == 2) { // no SMI syntax defined
- var = new OctetString(snmpPropValue);
- } else {
- int smiSyntax = Integer.valueOf(splits[2]);
- var = this.stringToVariable(snmpPropValue, smiSyntax);
- }
- if(var != null) {
- VariableBinding varBind = new VariableBinding(new OID(snmpPropName), var);
- pdu.add(varBind);
- result = true;
- }
- }
+ 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);
+ } catch (IOException e) {
+ getLogger().error("Failed to send request to the agent. Check if the agent supports the used version.");
+ processError(context, processSession, flowFile);
}
}
- return result;
}
- /**
- * Method to create the variable from the attribute value and the given SMI syntax value
- * @param value attribute value
- * @param smiSyntax attribute SMI Syntax
- * @return variable
- */
- private Variable stringToVariable(String value, int smiSyntax) {
- Variable var = AbstractVariable.createFromSyntax(smiSyntax);
- try {
- if (var instanceof AssignableFromString) {
- ((AssignableFromString) var).setValue(value);
- } else if (var instanceof AssignableFromInteger) {
- ((AssignableFromInteger) var).setValue(Integer.valueOf(value));
- } else if (var instanceof AssignableFromLong) {
- ((AssignableFromLong) var).setValue(Long.valueOf(value));
- } else {
- this.getLogger().error("Unsupported conversion of [" + value +"] to " + var.getSyntaxString());
- var = null;
- }
- } catch (IllegalArgumentException e) {
- this.getLogger().error("Unsupported conversion of [" + value +"] to " + var.getSyntaxString(), e);
- var = null;
- }
- return var;
- }
-
- /**
- * @see org.apache.nifi.components.AbstractConfigurableComponent#getSupportedPropertyDescriptors()
- */
@Override
- protected List<PropertyDescriptor> getSupportedPropertyDescriptors() {
- return propertyDescriptors;
+ public List<PropertyDescriptor> getSupportedPropertyDescriptors() {
+ return PROPERTY_DESCRIPTORS;
}
- /**
- * @see org.apache.nifi.processor.AbstractSessionFactoryProcessor#getRelationships()
- */
@Override
public Set<Relationship> getRelationships() {
- return relationships;
+ return RELATIONSHIPS;
}
- /**
- * @see org.apache.nifi.snmp.processors.AbstractSNMPProcessor#finishBuildingTargetResource(org.apache.nifi.processor.ProcessContext)
- */
- @Override
- protected SNMPSetter finishBuildingTargetResource(ProcessContext context) {
- return new SNMPSetter(this.snmp, this.snmpTarget);
- }
+ private void processError(final ProcessContext context, final ProcessSession processSession, final FlowFile flowFile) {
+ processSession.transfer(processSession.penalize(flowFile), REL_FAILURE);
+ context.yield();
+ }
}
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
new file mode 100644
index 0000000..788b73b
--- /dev/null
+++ b/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/main/java/org/apache/nifi/snmp/utils/SNMPUtils.java
@@ -0,0 +1,234 @@
+/*
+ * 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.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.mp.SnmpConstants;
+import org.snmp4j.security.AuthHMAC128SHA224;
+import org.snmp4j.security.AuthHMAC192SHA256;
+import org.snmp4j.security.AuthHMAC256SHA384;
+import org.snmp4j.security.AuthHMAC384SHA512;
+import org.snmp4j.security.AuthMD5;
+import org.snmp4j.security.AuthSHA;
+import org.snmp4j.security.Priv3DES;
+import org.snmp4j.security.PrivAES128;
+import org.snmp4j.security.PrivAES192;
+import org.snmp4j.security.PrivAES256;
+import org.snmp4j.security.PrivDES;
+import org.snmp4j.smi.AbstractVariable;
+import org.snmp4j.smi.AssignableFromInteger;
+import org.snmp4j.smi.AssignableFromLong;
+import org.snmp4j.smi.AssignableFromString;
+import org.snmp4j.smi.OID;
+import org.snmp4j.smi.OctetString;
+import org.snmp4j.smi.Variable;
+import org.snmp4j.smi.VariableBinding;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Optional;
+import java.util.Vector;
+import java.util.regex.Pattern;
+import java.util.stream.Collectors;
+
+/**
+ * Utility helper class that simplifies interactions with target SNMP API and NIFI API.
+ */
+public final class SNMPUtils {
+
+ public static final String SNMP_PROP_DELIMITER = "$";
+ public static final String SNMP_PROP_PREFIX = "snmp" + SNMP_PROP_DELIMITER;
+
+ private static final Logger logger = LoggerFactory.getLogger(SNMPUtils.class);
+ private static final String OID_PROP_PATTERN = SNMP_PROP_PREFIX + "%s" + SNMP_PROP_DELIMITER + "%s";
+ private static final Pattern OID_PATTERN = Pattern.compile("[0-9+.]*");
+
+ private static final Map<String, OID> AUTH_MAP;
+ private static final Map<String, OID> PRIV_MAP;
+ private static final Map<String, Integer> VERSION_MAP;
+ private static final Map<String, String> REPORT_MAP;
+
+ private SNMPUtils() {
+ // hide implicit constructor
+ }
+
+ static {
+ final Map<String, String> map = new HashMap<>();
+ map.put("1.3.6.1.6.3.15.1.1.1", "usmStatsUnsupportedSecLevels");
+ map.put("1.3.6.1.6.3.15.1.1.2", "usmStatsNotInTimeWindows");
+ map.put("1.3.6.1.6.3.15.1.1.3", "usmStatsUnknownUserNames");
+ map.put("1.3.6.1.6.3.15.1.1.4", "usmStatsUnknownEngineIDs");
+ map.put("1.3.6.1.6.3.15.1.1.5", "usmStatsWrongDigests");
+ map.put("1.3.6.1.6.3.15.1.1.6", "usmStatsDecryptionErrors");
+ REPORT_MAP = Collections.unmodifiableMap(map);
+ }
+
+ static {
+ final Map<String, OID> map = new HashMap<>();
+ map.put("DES", PrivDES.ID);
+ map.put("3DES", Priv3DES.ID);
+ map.put("AES128", PrivAES128.ID);
+ map.put("AES192", PrivAES192.ID);
+ map.put("AES256", PrivAES256.ID);
+ PRIV_MAP = Collections.unmodifiableMap(map);
+ }
+
+ static {
+ final Map<String, OID> map = new HashMap<>();
+ map.put("SHA", AuthSHA.ID);
+ map.put("MD5", AuthMD5.ID);
+ map.put("HMAC128SHA224", AuthHMAC128SHA224.ID);
+ map.put("HMAC192SHA256", AuthHMAC192SHA256.ID);
+ map.put("HMAC256SHA384", AuthHMAC256SHA384.ID);
+ map.put("HMAC384SHA512", AuthHMAC384SHA512.ID);
+ AUTH_MAP = Collections.unmodifiableMap(map);
+ }
+
+ static {
+ final Map<String, Integer> map = new HashMap<>();
+ map.put("SNMPv1", SnmpConstants.version1);
+ map.put("SNMPv2c", SnmpConstants.version2c);
+ map.put("SNMPv3", SnmpConstants.version3);
+ VERSION_MAP = Collections.unmodifiableMap(map);
+ }
+
+ public static Map<String, String> getPduAttributeMap(final PDU response) {
+ final Vector<? extends VariableBinding> variableBindings = response.getVariableBindings();
+ final Map<String, String> attributes = variableBindings.stream()
+ .collect(Collectors.toMap(k -> String.format(OID_PROP_PATTERN, k.getOid(), k.getSyntax()),
+ v -> v.getVariable().toString()
+ ));
+
+ attributes.computeIfAbsent(SNMP_PROP_PREFIX + "errorIndex", v -> String.valueOf(response.getErrorIndex()));
+ attributes.computeIfAbsent(SNMP_PROP_PREFIX + "errorStatus", v -> String.valueOf(response.getErrorStatus()));
+ attributes.computeIfAbsent(SNMP_PROP_PREFIX + "errorStatusText", v -> response.getErrorStatusText());
+ attributes.computeIfAbsent(SNMP_PROP_PREFIX + "nonRepeaters", v -> String.valueOf(response.getNonRepeaters()));
+ attributes.computeIfAbsent(SNMP_PROP_PREFIX + "requestID", v -> String.valueOf(response.getRequestID()));
+ attributes.computeIfAbsent(SNMP_PROP_PREFIX + "type", v -> String.valueOf(response.getType()));
+ attributes.computeIfAbsent(SNMP_PROP_PREFIX + "typeString", v -> PDU.getTypeString(response.getType()));
+
+ 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<String, String> createWalkOidValuesMap(final List<VariableBinding> variableBindings) {
+ final Map<String, String> attributes = new HashMap<>();
+ variableBindings.forEach(vb -> addAttributeFromVariable(vb, attributes));
+ return attributes;
+ }
+
+ public static OID getPriv(final String privProtocol) {
+ if (PRIV_MAP.containsKey(privProtocol)) {
+ return PRIV_MAP.get(privProtocol);
+ }
+ throw new InvalidPrivProtocolException("Invalid privacy protocol provided.");
+ }
+
+
+ public static OID getAuth(final String authProtocol) {
+ if (AUTH_MAP.containsKey(authProtocol)) {
+ return AUTH_MAP.get(authProtocol);
+ }
+ 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<String, String> attributes) {
+ boolean result = false;
+ for (Map.Entry<String, String> 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<Variable> 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;
+ }
+ }
+ }
+ }
+ return result;
+ }
+
+ private static void addAttributeFromVariable(final VariableBinding variableBinding, final Map<String, String> attributes) {
+ attributes.put(SNMP_PROP_PREFIX + variableBinding.getOid() + SNMP_PROP_DELIMITER + variableBinding.getVariable().getSyntax(), variableBinding.getVariable().toString());
+ }
+
+ private static Optional<Variable> stringToVariable(final String value, final int smiSyntax) {
+ Variable var = AbstractVariable.createFromSyntax(smiSyntax);
+ try {
+ if (var instanceof AssignableFromString) {
+ ((AssignableFromString) var).setValue(value);
+ } else if (var instanceof AssignableFromInteger) {
+ ((AssignableFromInteger) var).setValue(Integer.parseInt(value));
+ } else if (var instanceof AssignableFromLong) {
+ ((AssignableFromLong) var).setValue(Long.parseLong(value));
+ } else {
+ logger.error("Unsupported conversion of [ {} ] to ", var.getSyntaxString());
+ var = null;
+ }
+ } catch (IllegalArgumentException e) {
+ logger.error("Unsupported conversion of [ {} ] to ", var.getSyntaxString(), e);
+ var = null;
+ }
+ return Optional.ofNullable(var);
+ }
+
+ public static Optional<String> getErrorMessage(final String oid) {
+ Optional<String> errorMessage = Optional.ofNullable(REPORT_MAP.get(oid));
+ if (!errorMessage.isPresent() && oid.charAt(oid.length() - 1) == '0') {
+ final String cutLastOidValue = oid.substring(0, oid.length() - 2);
+ errorMessage = Optional.ofNullable(REPORT_MAP.get(cutLastOidValue));
+ }
+ return errorMessage.map(s -> oid + ": " + s);
+ }
+}
diff --git a/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/main/java/org/apache/nifi/snmp/validators/OIDValidator.java b/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/main/java/org/apache/nifi/snmp/validators/OIDValidator.java
new file mode 100644
index 0000000..7cd05ef
--- /dev/null
+++ b/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/main/java/org/apache/nifi/snmp/validators/OIDValidator.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.validators;
+
+import org.apache.nifi.components.ValidationContext;
+import org.apache.nifi.components.ValidationResult;
+import org.apache.nifi.components.Validator;
+
+import java.util.regex.Pattern;
+
+public class OIDValidator implements Validator {
+
+ public static final Pattern OID_PATTERN = Pattern.compile("[0-9+.]*");
+
+ @Override
+ public ValidationResult validate(final String subject, final String input, final ValidationContext context) {
+ final ValidationResult.Builder builder = new ValidationResult.Builder();
+ builder.subject(subject).input(input);
+ if (context.isExpressionLanguageSupported(subject) && context.isExpressionLanguagePresent(input)) {
+ return builder.valid(true).explanation("Contains Expression Language").build();
+ }
+ try {
+ if (OID_PATTERN.matcher(input).matches()) {
+ builder.valid(true);
+ } else {
+ builder.valid(false).explanation(input + " is not a valid OID");
+ }
+ } catch (final IllegalArgumentException e) {
+ builder.valid(false).explanation(e.getMessage());
+ }
+ return builder.build();
+ }
+}
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 1ca8b6a..24f982c 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
@@ -15,56 +15,45 @@
limitations under the License.
-->
<head>
- <meta charset="utf-8" />
+ <meta charset="utf-8"/>
<title>GetSNMP</title>
- <link rel="stylesheet" href="../../../../../css/component-usage.css" type="text/css" />
+ <link rel="stylesheet" href="../../../../../css/component-usage.css" type="text/css"/>
</head>
<body>
<h2>Summary</h2>
<p>
- This processor polls a SNMP agent to get information for a given OID (Strategy = GET) or for all the sub-tree associated to a given OID
- (Strategy = WALK). This processors supports SNMPv1, SNMPv2c and SNMPv3. The component is based on <a href="http://www.snmp4j.org/">SNMP4J</a>.
+ This processor polls a SNMP agent to get information for a given OID (Strategy = GET) or for all the sub-tree
+ associated to a given OID
+ (Strategy = WALK). This processors supports SNMPv1, SNMPv2c and SNMPv3. The component is based on <a
+ href="http://www.snmp4j.org/">SNMP4J</a>.
</p>
<p>
- When the processor is triggered, it sends the SNMP request and gets the information associated to request OID(s). Once response is received
- from the SNMP agent, a FlowFile is constructed. The FlowFile content is empty, all the information is written in the FlowFile attributes.
- In case of a single GET request, the properties associated to the received PDU are transferred into the FlowFile as attributes. In case of a
- WALK request, only the couples "OID/value" are transferred into the FlowFile as attributes. SNMP attributes names are prefixed with
+ When the processor is triggered, it sends the SNMP request and gets the information associated to request OID(s).
+ Once response is received
+ from the SNMP agent, a FlowFile is constructed. The FlowFile content is empty, all the information is written in the
+ FlowFile attributes.
+ In case of a single GET request, the properties associated to the received PDU are transferred into the FlowFile as
+ attributes. In case of a
+ WALK request, only the couples "OID/value" are transferred into the FlowFile as attributes. SNMP attributes names
+ are prefixed with
<i>snmp$</i> prefix.
</p>
<p>
Regarding the attributes representing the couples "OID/value", the attribute name has the following format:
- <ul><li>snmp$<i>OID</i>$<i>SMI_Syntax_Value</i></li></ul>
- where OID is the request OID, and SMI_Syntax_Value is the integer representing the type of the value associated to the OID. This value is
- provided to allow the SetSNMP processor setting values in the correct type.
+<ul>
+ <li>snmp$<i>OID</i>$<i>SMI_Syntax_Value</i></li>
+</ul>
+where OID is the request OID, and SMI_Syntax_Value is the integer representing the type of the value associated to the
+OID. This value is
+provided to allow the SetSNMP processor setting values in the correct type.
</p>
<h2>SNMP Properties</h2>
<p>
- In case of a single SNMP Get request, the following is the list of available standard SNMP properties which may come with the PDU:
- <i>("snmp$errorIndex", "snmp$errorStatus", "snmp$errorStatusText", "snmp$nonRepeaters", "snmp$requestID", "snmp$type")</i>
-</p>
-<h2>Configuration Details</h2>
-<p>
- At the time of writing this document it only defines the essential configuration properties which are suitable for most cases.
- Other properties will be defined later as this component progresses.
- Configuring GetSNMP:
+ In case of a single SNMP Get request, the following is the list of available standard SNMP properties which may come
+ with the PDU:
+ <i>("snmp$errorIndex", "snmp$errorStatus", "snmp$errorStatusText", "snmp$nonRepeaters", "snmp$requestID",
+ "snmp$type")</i>
</p>
-<ul>
- <li><b>Host</b> - [REQUIRED] the name of the host where the SNMP agent is running. (default is localhost)</li>
- <li><b>Port</b> - [REQUIRED] the port number on which the SNMP agent is listening. (default is 161)</li>
- <li><b>OID</b> - [REQUIRED] the root OID to request.</li>
- <li><b>Version</b> - [REQUIRED] the SNMP version to use (SNMPv1 [default], or SNMPv2c, or SNMPv3)</li>
- <li><b>Community</b> - [REQUIRED if SNMPv1 or SNMPv2c] the SNMP community to use. (default is public)</li>
- <li><b>Security Level</b> - [REQUIRED if SNMPv3] the security level to use. (default is authPriv)</li>
- <li><b>Security Name</b> - [REQUIRED if SNMPv3] the security name (user name) to use.</li>
- <li><b>Authentication Protocol</b> - [REQUIRED if SNMPv3 and authNoPriv or authPriv] the authentication protocol to use.</li>
- <li><b>Authentication Password</b> - [REQUIRED if SNMPv3 and authNoPriv or authPriv] the authentication password to use.</li>
- <li><b>Private Protocol</b> - [REQUIRED if SNMPv3 and authPriv] the private protocol to use.</li>
- <li><b>Private Password</b> - [REQUIRED if SNMPv3 and authPriv] the private password to use.</li>
- <li><b>Retries</b> - [REQUIRED] Sets the number of retries to be performed before a request is timed out. (default is 0)</li>
- <li><b>Timeout</b> - [REQUIRED] Sets timeout in milliseconds before a confirmed request is resent or timed out. (default is 5000)</li>
-</ul>
-
</body>
</html>
\ No newline at end of file
diff --git a/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/main/resources/docs/org.apache.nifi.snmp.processors.SetSNMP/additionalDetails.html b/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/main/resources/docs/org.apache.nifi.snmp.processors.SetSNMP/additionalDetails.html
index 4d8430f..cf1bfcc 100644
--- a/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/main/resources/docs/org.apache.nifi.snmp.processors.SetSNMP/additionalDetails.html
+++ b/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/main/resources/docs/org.apache.nifi.snmp.processors.SetSNMP/additionalDetails.html
@@ -15,44 +15,28 @@
limitations under the License.
-->
<head>
- <meta charset="utf-8" />
+ <meta charset="utf-8"/>
<title>SetSNMP</title>
- <link rel="stylesheet" href="../../../../../css/component-usage.css" type="text/css" />
+ <link rel="stylesheet" href="../../../../../css/component-usage.css" type="text/css"/>
</head>
<body>
<h2>Summary</h2>
<p>
- This processor sends SNMP set requests to a SNMP agent in order to update information associated to a given OID. This processor supports
+ This processor sends SNMP set requests to a SNMP agent in order to update information associated to a given OID.
+ This processor supports
SNMPv1, SNMPv2c and SNMPv3. The component is based on <a href="http://www.snmp4j.org/">SNMP4J</a>.
</p>
<p>
- The processor constructs SNMP Set requests by extracting information from FlowFile attributes. The processor is looking for attributes
- prefixed with <i>snmp$</i>. 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. If there is a third element, it must represents the SMI Syntax integer value of
- the type of data associated to the given OID to allow a correct conversion. If there is no third element, the value is considered as a String
+ The processor constructs SNMP Set requests by extracting information from FlowFile attributes. The processor is
+ looking for attributes
+ prefixed with <i>snmp$</i>. 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. If there is a third element, it must represents the SMI
+ Syntax integer value of
+ the type of data associated to the given OID to allow a correct conversion. If there is no third element, the value
+ is considered as a String
and the value will be sent as an OctetString object.
</p>
-<h2>Configuration Details</h2>
-<p>
- At the time of writing this document it only defines the essential configuration properties which are suitable for most cases.
- Other properties will be defined later as this component progresses.
- Configuring SetSNMP:
-</p>
-<ul>
- <li><b>Host</b> - [REQUIRED] the name of the host where the SNMP agent is running. (default is localhost)</li>
- <li><b>Port</b> - [REQUIRED] the port number on which the SNMP agent is listening. (default is 161)</li>
- <li><b>Version</b> - [REQUIRED] the SNMP version to use (SNMPv1 [default], or SNMPv2c, or SNMPv3)</li>
- <li><b>Community</b> - [REQUIRED if SNMPv1 or SNMPv2c] the SNMP community to use. (default is public)</li>
- <li><b>Security Level</b> - [REQUIRED if SNMPv3] the security level to use. (default is authPriv)</li>
- <li><b>Security Name</b> - [REQUIRED if SNMPv3] the security name (user name) to use.</li>
- <li><b>Authentication Protocol</b> - [REQUIRED if SNMPv3 and authNoPriv or authPriv] the authentication protocol to use.</li>
- <li><b>Authentication Password</b> - [REQUIRED if SNMPv3 and authNoPriv or authPriv] the authentication password to use.</li>
- <li><b>Private Protocol</b> - [REQUIRED if SNMPv3 and authPriv] the private protocol to use.</li>
- <li><b>Private Password</b> - [REQUIRED if SNMPv3 and authPriv] the private password to use.</li>
- <li><b>Retries</b> - [REQUIRED] Sets the number of retries to be performed before a request is timed out. (default is 0)</li>
- <li><b>Timeout</b> - [REQUIRED] Sets timeout in milliseconds before a confirmed request is resent or timed out. (default is 5000)</li>
-</ul>
-
</body>
</html>
\ No newline at end of file
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
new file mode 100644
index 0000000..98b40d5
--- /dev/null
+++ b/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/test/java/org/apache/nifi/snmp/factory/SNMPClientFactoryTest.java
@@ -0,0 +1,68 @@
+/*
+ * 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.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/helper/SNMPTestUtils.java b/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/test/java/org/apache/nifi/snmp/helper/SNMPTestUtils.java
new file mode 100644
index 0000000..492690f
--- /dev/null
+++ b/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/test/java/org/apache/nifi/snmp/helper/SNMPTestUtils.java
@@ -0,0 +1,68 @@
+/*
+ * 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/operations/SNMPRequestTest.java b/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/test/java/org/apache/nifi/snmp/operations/SNMPRequestTest.java
new file mode 100644
index 0000000..43c1958
--- /dev/null
+++ b/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/test/java/org/apache/nifi/snmp/operations/SNMPRequestTest.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.operations;
+
+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.testagents.TestAgent;
+import org.apache.nifi.util.MockFlowFile;
+import org.junit.After;
+import org.junit.Before;
+import org.snmp4j.CommunityTarget;
+import org.snmp4j.Snmp;
+import org.snmp4j.agent.mo.DefaultMOFactory;
+import org.snmp4j.agent.mo.MOAccessImpl;
+import org.snmp4j.smi.OID;
+import org.snmp4j.smi.OctetString;
+
+import java.io.IOException;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.concurrent.atomic.AtomicBoolean;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.fail;
+
+public abstract 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";
+ protected static final Map<String, String> WALK_OID_MAP;
+
+ static {
+ final Map<String, String> oidMap = new HashMap<>();
+ oidMap.put(READ_ONLY_OID_1, READ_ONLY_OID_VALUE_1);
+ oidMap.put(READ_ONLY_OID_2, READ_ONLY_OID_VALUE_2);
+ WALK_OID_MAP = Collections.unmodifiableMap(oidMap);
+ }
+
+ protected final TestAgent agent = getAgentInstance();
+
+ protected abstract TestAgent getAgentInstance();
+
+ @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))
+ );
+ }
+
+ @After
+ public void tearDown() {
+ agent.stop();
+ }
+
+ 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");
+ }
+
+ protected SNMPSingleResponse getResponseEvent(final String address, final int port, final int version, final String oid) throws IOException {
+ final Snmp snmp = SNMPTestUtils.createSnmpClient();
+ final CommunityTarget target = SNMPTestUtils.createCommTarget("public", address + "/" + port, version);
+ final StandardSNMPRequestHandler standardSnmpRequestHandler = new StandardSNMPRequestHandler(snmp, target);
+ return standardSnmpRequestHandler.get(oid);
+ }
+
+ protected SNMPSingleResponse getSetResponse(final int port, final int version, final String oid, final String expectedOid) throws IOException {
+ final Snmp snmp = SNMPTestUtils.createSnmpClient();
+ final CommunityTarget target = SNMPTestUtils.createCommTarget("public", LOCALHOST + "/" + port, version);
+ final StandardSNMPRequestHandler standardSnmpRequestHandler = new StandardSNMPRequestHandler(snmp, target);
+
+ final MockFlowFile flowFile = new MockFlowFile(1L);
+ final Map<String, String> attributes = new HashMap<>();
+ attributes.put(SNMP_PROP_PREFIX + oid, expectedOid);
+ flowFile.putAttributes(attributes);
+
+ return standardSnmpRequestHandler.set(flowFile);
+ }
+
+ protected void assertSubTreeContainsOids(SNMPTreeResponse response) {
+ final Map<String, String> attributes = response.getAttributes();
+ attributes.entrySet().forEach(this::checkEntryContainsSubString);
+ }
+
+ private void checkEntryContainsSubString(Map.Entry<String, String> attribute) {
+ final AtomicBoolean isMatch = new AtomicBoolean(false);
+ WALK_OID_MAP.forEach((key, value) -> {
+ if (!isMatch.get() && attribute.getKey().contains(key)) {
+ isMatch.set(true);
+ assertEquals(value, attribute.getValue());
+ }
+ });
+ if (!isMatch.get()) {
+ fail("Expected OID did not found in subtree.");
+ }
+ }
+}
diff --git a/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/test/java/org/apache/nifi/snmp/operations/SNMPV1RequestTest.java b/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/test/java/org/apache/nifi/snmp/operations/SNMPV1RequestTest.java
new file mode 100644
index 0000000..0fdf2c6
--- /dev/null
+++ b/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/test/java/org/apache/nifi/snmp/operations/SNMPV1RequestTest.java
@@ -0,0 +1,85 @@
+/*
+ * 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.testagents.TestAgent;
+import org.apache.nifi.snmp.testagents.TestSNMPV1Agent;
+import org.junit.Test;
+import org.snmp4j.MessageException;
+import org.snmp4j.mp.SnmpConstants;
+
+import java.io.IOException;
+
+import static org.junit.Assert.assertEquals;
+
+public class SNMPV1RequestTest extends SNMPRequestTest {
+
+ private static final String NO_SUCH_NAME = "No such name";
+
+ @Override
+ protected TestAgent getAgentInstance() {
+ return new TestSNMPV1Agent(LOCALHOST);
+ }
+
+ @Test
+ public void testSuccessfulSnmpGet() throws IOException {
+ final SNMPSingleResponse response = getResponseEvent(LOCALHOST, agent.getPort(), SnmpConstants.version1, READ_ONLY_OID_1);
+ assertEquals(READ_ONLY_OID_VALUE_1, response.getVariableBindings().get(0).getVariable());
+ assertEquals(SUCCESS, response.getErrorStatusText());
+ }
+
+ @Test
+ public void testSuccessfulSnmpWalk() throws IOException {
+ final SNMPTreeResponse response = getTreeEvents(agent.getPort(), SnmpConstants.version1);
+ assertSubTreeContainsOids(response);
+ }
+
+ @Test(expected = RequestTimeoutException.class)
+ public void testSnmpGetTimeoutReturnsNull() throws IOException {
+ getResponseEvent(INVALID_HOST, agent.getPort(), SnmpConstants.version1, READ_ONLY_OID_1);
+ }
+
+ @Test(expected = MessageException.class)
+ public void testSnmpGetWithInvalidTargetThrowsException() throws IOException {
+ getResponseEvent(LOCALHOST, agent.getPort(), -1, READ_ONLY_OID_1);
+ }
+
+ @Test
+ public void testSuccessfulSnmpSet() throws IOException {
+ final SNMPSingleResponse response = getSetResponse(agent.getPort(), SnmpConstants.version1, WRITE_ONLY_OID, EXPECTED_OID_VALUE);
+
+ assertEquals(EXPECTED_OID_VALUE, response.getVariableBindings().get(0).getVariable());
+ assertEquals(SUCCESS, response.getErrorStatusText());
+ }
+
+ @Test
+ public void testCannotSetReadOnlyObject() throws IOException {
+ final SNMPSingleResponse response = getSetResponse(agent.getPort(), SnmpConstants.version1, READ_ONLY_OID_1, EXPECTED_OID_VALUE);
+
+ assertEquals(NO_SUCH_NAME, response.getErrorStatusText());
+ }
+
+ @Test
+ public void testCannotGetWriteOnlyObject() throws IOException {
+ final SNMPSingleResponse response = getResponseEvent(LOCALHOST, agent.getPort(), SnmpConstants.version1, WRITE_ONLY_OID);
+
+ assertEquals(NO_SUCH_NAME, response.getErrorStatusText());
+ }
+}
diff --git a/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/test/java/org/apache/nifi/snmp/operations/SNMPV2CRequestTest.java b/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/test/java/org/apache/nifi/snmp/operations/SNMPV2CRequestTest.java
new file mode 100644
index 0000000..2b779c6
--- /dev/null
+++ b/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/test/java/org/apache/nifi/snmp/operations/SNMPV2CRequestTest.java
@@ -0,0 +1,85 @@
+/*
+ * 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.testagents.TestAgent;
+import org.apache.nifi.snmp.testagents.TestSNMPV2cAgent;
+import org.junit.Test;
+import org.snmp4j.MessageException;
+import org.snmp4j.mp.SnmpConstants;
+
+import java.io.IOException;
+
+import static org.junit.Assert.assertEquals;
+
+public class SNMPV2CRequestTest extends SNMPRequestTest {
+
+ @Override
+ protected TestAgent getAgentInstance() {
+ return new TestSNMPV2cAgent(LOCALHOST);
+ }
+
+ @Test
+ public void testSuccessfulSnmpGet() throws IOException {
+ final SNMPSingleResponse response = getResponseEvent(LOCALHOST, agent.getPort(), SnmpConstants.version2c, READ_ONLY_OID_1);
+
+ assertEquals(READ_ONLY_OID_VALUE_1, response.getVariableBindings().get(0).getVariable());
+ assertEquals(SUCCESS, response.getErrorStatusText());
+ }
+
+ @Test
+ public void testSuccessfulSnmpWalk() throws IOException {
+ final SNMPTreeResponse response = getTreeEvents(agent.getPort(), SnmpConstants.version2c);
+
+ assertSubTreeContainsOids(response);
+ }
+
+ @Test(expected = RequestTimeoutException.class)
+ public void testSnmpGetTimeoutReturnsNull() throws IOException {
+ getResponseEvent(INVALID_HOST, agent.getPort(), SnmpConstants.version2c, READ_ONLY_OID_1);
+ }
+
+ @Test(expected = MessageException.class)
+ public void testSnmpGetWithInvalidTargetThrowsException() throws IOException {
+ getResponseEvent(LOCALHOST, agent.getPort(), -1, READ_ONLY_OID_1);
+ }
+
+ @Test
+ public void testSuccessfulSnmpSet() throws IOException {
+ final SNMPSingleResponse response = getSetResponse(agent.getPort(), SnmpConstants.version2c, WRITE_ONLY_OID, EXPECTED_OID_VALUE);
+
+ assertEquals(EXPECTED_OID_VALUE, response.getVariableBindings().get(0).getVariable());
+ assertEquals(SUCCESS, response.getErrorStatusText());
+ }
+
+ @Test
+ public void testCannotSetReadOnlyObject() throws IOException {
+ final SNMPSingleResponse response = getSetResponse(agent.getPort(), SnmpConstants.version2c, READ_ONLY_OID_1, EXPECTED_OID_VALUE);
+
+ assertEquals(NOT_WRITABLE, response.getErrorStatusText());
+ }
+
+ @Test
+ public void testCannotGetWriteOnlyObject() throws IOException {
+ final SNMPSingleResponse response = getResponseEvent(LOCALHOST, agent.getPort(), SnmpConstants.version2c, WRITE_ONLY_OID);
+
+ assertEquals(NO_ACCESS, response.getErrorStatusText());
+ }
+}
diff --git a/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/test/java/org/apache/nifi/snmp/operations/SNMPV3RequestTest.java b/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/test/java/org/apache/nifi/snmp/operations/SNMPV3RequestTest.java
new file mode 100644
index 0000000..3dbe75d
--- /dev/null
+++ b/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/test/java/org/apache/nifi/snmp/operations/SNMPV3RequestTest.java
@@ -0,0 +1,134 @@
+/*
+ * 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.helper.SNMPTestUtils;
+import org.apache.nifi.snmp.testagents.TestAgent;
+import org.apache.nifi.snmp.testagents.TestSNMPV3Agent;
+import org.apache.nifi.util.MockFlowFile;
+import org.junit.Test;
+import org.snmp4j.MessageException;
+import org.snmp4j.SNMP4JSettings;
+import org.snmp4j.Snmp;
+import org.snmp4j.UserTarget;
+import org.snmp4j.mp.SnmpConstants;
+import org.snmp4j.security.AuthSHA;
+import org.snmp4j.security.SecurityLevel;
+
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.Map;
+
+import static org.junit.Assert.assertEquals;
+
+public class SNMPV3RequestTest extends SNMPRequestTest {
+
+ @Override
+ protected TestAgent getAgentInstance() {
+ return new TestSNMPV3Agent(LOCALHOST);
+ }
+
+ @Test
+ public void testSuccessfulSnmpGet() throws IOException {
+ final StandardSNMPRequestHandler standardSnmpRequestHandler = getSnmpV3Getter(LOCALHOST, SnmpConstants.version3,
+ "SHA", "SHAAuthPassword");
+ final SNMPSingleResponse response = standardSnmpRequestHandler.get(READ_ONLY_OID_1);
+ assertEquals(READ_ONLY_OID_VALUE_1, response.getVariableBindings().get(0).getVariable());
+ assertEquals(SUCCESS, response.getErrorStatusText());
+ }
+
+ @Test
+ public void testSuccessfulSnmpWalk() throws IOException {
+ final StandardSNMPRequestHandler standardSnmpRequestHandler = getSnmpV3Getter(LOCALHOST, SnmpConstants.version3,
+ "SHA", "SHAAuthPassword");
+ final SNMPTreeResponse response = standardSnmpRequestHandler.walk("1.3.6.1.4.1.32437");
+
+ assertSubTreeContainsOids(response);
+ }
+
+ @Test(expected = RequestTimeoutException.class)
+ public void testSnmpGetTimeoutReturnsNull() throws IOException {
+ final StandardSNMPRequestHandler standardSnmpRequestHandler = getSnmpV3Getter(INVALID_HOST, SnmpConstants.version3,
+ "SHA", "SHAAuthPassword");
+ standardSnmpRequestHandler.get(READ_ONLY_OID_1);
+ }
+
+ @Test(expected = MessageException.class)
+ public void testSnmpGetWithInvalidTargetThrowsException() throws IOException {
+ final StandardSNMPRequestHandler standardSnmpRequestHandler = getSnmpV3Getter(LOCALHOST, -1, "SHA", "SHAAuthPassword");
+ standardSnmpRequestHandler.get(READ_ONLY_OID_1);
+ }
+
+ @Test
+ public void testSuccessfulSnmpSet() throws IOException {
+ final StandardSNMPRequestHandler standardSnmpRequestHandler = getSnmpV3Getter(LOCALHOST, SnmpConstants.version3,
+ "SHA", "SHAAuthPassword");
+
+ final MockFlowFile flowFile = new MockFlowFile(1L);
+ final Map<String, String> attributes = new HashMap<>();
+ attributes.put(SNMP_PROP_PREFIX + WRITE_ONLY_OID, EXPECTED_OID_VALUE);
+ flowFile.putAttributes(attributes);
+
+ final SNMPSingleResponse response = standardSnmpRequestHandler.set(flowFile);
+
+ assertEquals(EXPECTED_OID_VALUE, response.getVariableBindings().get(0).getVariable());
+
+ }
+
+ @Test
+ public void testCannotSetReadOnlyObject() throws IOException {
+ final StandardSNMPRequestHandler standardSnmpRequestHandler = getSnmpV3Getter(LOCALHOST, SnmpConstants.version3,
+ "SHA", "SHAAuthPassword");
+
+ final MockFlowFile flowFile = new MockFlowFile(1L);
+ final Map<String, String> attributes = new HashMap<>();
+ attributes.put(SNMP_PROP_PREFIX + READ_ONLY_OID_1, EXPECTED_OID_VALUE);
+ flowFile.putAttributes(attributes);
+
+ final SNMPSingleResponse response = standardSnmpRequestHandler.set(flowFile);
+
+ assertEquals(NOT_WRITABLE, response.getErrorStatusText());
+ }
+
+ @Test
+ public void testCannotGetWriteOnlyObject() throws IOException {
+ final StandardSNMPRequestHandler standardSnmpRequestHandler = getSnmpV3Getter(LOCALHOST, SnmpConstants.version3, "SHA", "SHAAuthPassword");
+
+ final SNMPSingleResponse response = standardSnmpRequestHandler.get(WRITE_ONLY_OID);
+
+ assertEquals(NO_ACCESS, response.getErrorStatusText());
+ }
+
+ @Test
+ public void testUnauthorizedUserSnmpGetReturnsNull() throws IOException {
+ final StandardSNMPRequestHandler standardSnmpRequestHandler = getSnmpV3Getter(LOCALHOST, SnmpConstants.version3,
+ "FakeUserName", "FakeAuthPassword");
+ final SNMPSingleResponse response = standardSnmpRequestHandler.get(READ_ONLY_OID_1);
+ assertEquals("Null", response.getVariableBindings().get(0).getVariable());
+ }
+
+ private StandardSNMPRequestHandler getSnmpV3Getter(final String host, final int version, final String sha, final String shaAuthPassword) throws IOException {
+ SNMP4JSettings.setForwardRuntimeExceptions(true);
+ final Snmp snmp = SNMPTestUtils.createSnmpClient();
+ final UserTarget userTarget = SNMPTestUtils.prepareUser(snmp, version, host + "/" + agent.getPort(), SecurityLevel.AUTH_NOPRIV,
+ sha, AuthSHA.ID, null, shaAuthPassword, null);
+ return new StandardSNMPRequestHandler(snmp, userTarget);
+ }
+}
diff --git a/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/test/java/org/apache/nifi/snmp/processors/GetSNMPTest.java b/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/test/java/org/apache/nifi/snmp/processors/GetSNMPTest.java
new file mode 100644
index 0000000..ed14a37
--- /dev/null
+++ b/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/test/java/org/apache/nifi/snmp/processors/GetSNMPTest.java
@@ -0,0 +1,92 @@
+/*
+ * 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.snmp.testagents.TestSNMPV1Agent;
+import org.apache.nifi.snmp.utils.SNMPUtils;
+import org.apache.nifi.util.MockFlowFile;
+import org.apache.nifi.util.TestRunner;
+import org.apache.nifi.util.TestRunners;
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.snmp4j.agent.mo.DefaultMOFactory;
+import org.snmp4j.agent.mo.MOAccessImpl;
+import org.snmp4j.smi.OID;
+import org.snmp4j.smi.OctetString;
+
+import java.io.IOException;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+
+public class GetSNMPTest {
+
+ private static TestSNMPV1Agent snmpV1Agent;
+ private static final OID readOnlyOID1 = new OID("1.3.6.1.4.1.32437.1.5.1.4.2.0");
+ private static final OID readOnlyOID2 = new OID("1.3.6.1.4.1.32437.1.5.1.4.3.0");
+ private static final String OIDValue1 = "TestOID1";
+ private static final String OIDValue2 = "TestOID2";
+ private static final String GET = "GET";
+ private static final String WALK = "WALK";
+
+ @BeforeClass
+ public static void setUp() throws IOException {
+ snmpV1Agent = new TestSNMPV1Agent("127.0.0.1");
+ snmpV1Agent.start();
+ snmpV1Agent.registerManagedObjects(
+ DefaultMOFactory.getInstance().createScalar(new OID(readOnlyOID1), MOAccessImpl.ACCESS_READ_ONLY, new OctetString(OIDValue1)),
+ DefaultMOFactory.getInstance().createScalar(new OID(readOnlyOID2), MOAccessImpl.ACCESS_READ_ONLY, new OctetString(OIDValue2))
+ );
+ }
+
+ @AfterClass
+ public static void tearDown() {
+ snmpV1Agent.stop();
+ }
+
+ @Test
+ public void testSnmpV1Get() {
+ final TestRunner runner = getTestRunner(readOnlyOID1.toString(), String.valueOf(snmpV1Agent.getPort()), GET);
+ runner.run();
+ final MockFlowFile successFF = runner.getFlowFilesForRelationship(GetSNMP.REL_SUCCESS).get(0);
+ assertNotNull(successFF);
+ assertEquals(OIDValue1, successFF.getAttribute(SNMPUtils.SNMP_PROP_PREFIX + readOnlyOID1.toString() + SNMPUtils.SNMP_PROP_DELIMITER + "4"));
+ }
+
+ @Test
+ public void testSnmpV1Walk() {
+ final TestRunner runner = getTestRunner("1.3.6.1.4.1.32437", String.valueOf(snmpV1Agent.getPort()), WALK);
+ runner.run();
+ final MockFlowFile successFF = runner.getFlowFilesForRelationship(GetSNMP.REL_SUCCESS).get(0);
+ assertNotNull(successFF);
+ assertEquals(OIDValue1, successFF.getAttribute(SNMPUtils.SNMP_PROP_PREFIX + readOnlyOID1.toString() + SNMPUtils.SNMP_PROP_DELIMITER + "4"));
+ assertEquals(OIDValue2, successFF.getAttribute(SNMPUtils.SNMP_PROP_PREFIX + readOnlyOID2.toString() + SNMPUtils.SNMP_PROP_DELIMITER + "4"));
+ }
+
+ private TestRunner getTestRunner(final String oid, final String port, final String strategy) {
+ final TestRunner runner = TestRunners.newTestRunner(GetSNMP.class);
+ runner.setProperty(GetSNMP.OID, oid);
+ runner.setProperty(GetSNMP.AGENT_HOST, "127.0.0.1");
+ runner.setProperty(GetSNMP.AGENT_PORT, port);
+ runner.setProperty(GetSNMP.SNMP_COMMUNITY, "public");
+ runner.setProperty(GetSNMP.SNMP_VERSION, "SNMPv1");
+ runner.setProperty(GetSNMP.SNMP_STRATEGY, strategy);
+ runner.setProperty(GetSNMP.SNMP_SECURITY_LEVEL, "noAuthNoPriv");
+ return runner;
+ }
+}
diff --git a/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/test/java/org/apache/nifi/snmp/processors/SNMPUtilsTest.java b/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/test/java/org/apache/nifi/snmp/processors/SNMPUtilsTest.java
deleted file mode 100644
index e7386b2..0000000
--- a/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/test/java/org/apache/nifi/snmp/processors/SNMPUtilsTest.java
+++ /dev/null
@@ -1,134 +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.processors;
-
-import static org.junit.Assert.assertEquals;
-
-import java.io.IOException;
-import java.util.concurrent.atomic.AtomicLong;
-
-import org.apache.nifi.flowfile.FlowFile;
-import org.apache.nifi.processor.ProcessSession;
-import org.apache.nifi.util.MockProcessSession;
-import org.apache.nifi.util.SharedSessionState;
-import org.junit.Test;
-import org.snmp4j.CommunityTarget;
-import org.snmp4j.PDU;
-import org.snmp4j.Snmp;
-import org.snmp4j.UserTarget;
-import org.snmp4j.mp.SnmpConstants;
-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;
-
-/**
- * Test class for {@link SNMPUtils}.
- */
-public class SNMPUtilsTest {
-
- /**
- * Test for updating attributes of flow files with {@link PDU}
- */
- @Test
- public void validateUpdateFlowFileAttributes() {
- GetSNMP processor = new GetSNMP();
- ProcessSession processSession = new MockProcessSession(new SharedSessionState(processor, new AtomicLong()),
- processor);
- FlowFile sourceFlowFile = processSession.create();
-
- PDU pdu = new PDU();
- pdu.setErrorIndex(0);
- pdu.setErrorStatus(0);
- pdu.setType(4);
-
- FlowFile f2 = SNMPUtils.updateFlowFileAttributesWithPduProperties(pdu, sourceFlowFile,
- processSession);
-
- assertEquals("0", f2.getAttributes().get(SNMPUtils.SNMP_PROP_PREFIX + "errorIndex"));
- assertEquals("0", f2.getAttributes().get(SNMPUtils.SNMP_PROP_PREFIX + "errorStatus"));
- assertEquals("4", f2.getAttributes().get(SNMPUtils.SNMP_PROP_PREFIX + "type"));
- }
-
- /**
- * Method to create an instance of SNMP
- * @return instance of SNMP
- * @throws IOException IO Exception
- */
- protected static Snmp createSnmp() throws IOException {
- DefaultUdpTransportMapping transportMapping = new DefaultUdpTransportMapping();
- transportMapping.listen();
- return new Snmp(transportMapping);
- }
-
- /**
- * Method to create community target
- * @param community community name
- * @param address address
- * @param version SNMP version
- * @return community target
- */
- protected static CommunityTarget createCommTarget(String community, String address, int version) {
- 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;
- }
-
- /**
- * Method to create a user target
- * @param address address
- * @param securityLevel security level
- * @param securityName security name
- * @return user target
- */
- private static UserTarget createUserTarget(String address, int securityLevel, String securityName) {
- UserTarget target = new UserTarget();
- target.setVersion(SnmpConstants.version3);
- target.setSecurityLevel(securityLevel);
- target.setSecurityName(new OctetString(securityName));
- target.setAddress(new UdpAddress(address));
- target.setRetries(0);
- target.setTimeout(500);
- return target;
- }
-
- /**
- * Method to prepare user target and to add id in the User Based Security Model of the given SNMP instance
- * @param snmp SNMP instance
- * @param address address
- * @param securityLevel security level
- * @param securityName security name
- * @param auth authentication protocol
- * @param priv private protocol
- * @param authPwd authentication password
- * @param privPwd private password
- * @return user target
- */
- protected static UserTarget prepareUser(Snmp snmp, String address, int securityLevel, String securityName, OID auth, OID priv, String authPwd, String privPwd) {
- snmp.getUSM().removeAllUsers();
- OctetString aPwd = authPwd != null ? new OctetString(authPwd) : null;
- 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);
- }
-
-}
diff --git a/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/test/java/org/apache/nifi/snmp/processors/SetSNMPTest.java b/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/test/java/org/apache/nifi/snmp/processors/SetSNMPTest.java
new file mode 100644
index 0000000..7e626be
--- /dev/null
+++ b/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/test/java/org/apache/nifi/snmp/processors/SetSNMPTest.java
@@ -0,0 +1,88 @@
+/*
+ * 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.snmp.testagents.TestSNMPV1Agent;
+import org.apache.nifi.snmp.utils.SNMPUtils;
+import org.apache.nifi.util.MockFlowFile;
+import org.apache.nifi.util.TestRunner;
+import org.apache.nifi.util.TestRunners;
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.snmp4j.agent.mo.DefaultMOFactory;
+import org.snmp4j.agent.mo.MOAccessImpl;
+import org.snmp4j.smi.OID;
+import org.snmp4j.smi.OctetString;
+
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.Map;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+
+public class SetSNMPTest {
+
+ private static TestSNMPV1Agent snmpV1Agent;
+ private static final OID TEST_OID = new OID("1.3.6.1.4.1.32437.1.5.1.4.2.0");
+ private static final String TEST_OID_VALUE = "TestOID";
+ private static final String LOCALHOST = "127.0.0.1";
+ private static final String VALID_OID_FF_ATTRIBUTE = "snmp$1.3.6.1.4.1.32437.1.5.1.4.2.0$4";
+ private static final String INVALID_OID_FF_ATTRIBUTE = "snmp$1.3.6.1.4.1.32437.1.5.1.4.213.0$4";
+
+ @BeforeClass
+ public static void setUp() throws IOException {
+ snmpV1Agent = new TestSNMPV1Agent("127.0.0.1");
+ snmpV1Agent.start();
+ snmpV1Agent.registerManagedObjects(
+ DefaultMOFactory.getInstance().createScalar(new OID(TEST_OID), MOAccessImpl.ACCESS_READ_WRITE, new OctetString(TEST_OID_VALUE))
+ );
+ }
+
+ @AfterClass
+ public static void tearDown() {
+ snmpV1Agent.stop();
+ }
+
+ @Test
+ public void testSnmpV1Set() {
+ final TestRunner runner = getTestRunner(LOCALHOST, String.valueOf(snmpV1Agent.getPort()), VALID_OID_FF_ATTRIBUTE, true);
+ runner.run();
+ final MockFlowFile successFF = runner.getFlowFilesForRelationship(SetSNMP.REL_SUCCESS).get(0);
+ assertNotNull(successFF);
+ assertEquals(TEST_OID_VALUE, successFF.getAttribute(SNMPUtils.SNMP_PROP_PREFIX + TEST_OID.toString() + SNMPUtils.SNMP_PROP_DELIMITER + "4"));
+ }
+
+ private TestRunner getTestRunner(final String host, final String port, final String oid, final boolean withAttributes) {
+ final SetSNMP processor = new SetSNMP();
+ final TestRunner runner = TestRunners.newTestRunner(processor);
+ final MockFlowFile ff = new MockFlowFile(123);
+ if (withAttributes) {
+ final Map<String, String> attributes = ff.getAttributes();
+ final Map<String, String> newAttributes = new HashMap<>(attributes);
+ newAttributes.put(oid, TEST_OID_VALUE);
+ ff.putAttributes(newAttributes);
+ }
+ runner.enqueue(ff);
+ runner.setProperty(GetSNMP.AGENT_HOST, host);
+ runner.setProperty(GetSNMP.AGENT_PORT, port);
+ runner.setProperty(GetSNMP.SNMP_COMMUNITY, "public");
+ runner.setProperty(GetSNMP.SNMP_VERSION, "SNMPv1");
+ return runner;
+ }
+}
diff --git a/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/test/java/org/apache/nifi/snmp/testagents/TestAgent.java b/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/test/java/org/apache/nifi/snmp/testagents/TestAgent.java
new file mode 100644
index 0000000..02e4cc9
--- /dev/null
+++ b/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/test/java/org/apache/nifi/snmp/testagents/TestAgent.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.testagents;
+
+import org.apache.nifi.remote.io.socket.NetworkUtils;
+import org.snmp4j.TransportMapping;
+import org.snmp4j.agent.BaseAgent;
+import org.snmp4j.agent.CommandProcessor;
+import org.snmp4j.agent.DuplicateRegistrationException;
+import org.snmp4j.agent.MOGroup;
+import org.snmp4j.agent.ManagedObject;
+import org.snmp4j.agent.mo.snmp.RowStatus;
+import org.snmp4j.agent.mo.snmp.SnmpCommunityMIB;
+import org.snmp4j.agent.mo.snmp.SnmpNotificationMIB;
+import org.snmp4j.agent.mo.snmp.SnmpTargetMIB;
+import org.snmp4j.agent.mo.snmp.StorageType;
+import org.snmp4j.security.USM;
+import org.snmp4j.smi.Address;
+import org.snmp4j.smi.GenericAddress;
+import org.snmp4j.smi.Integer32;
+import org.snmp4j.smi.OctetString;
+import org.snmp4j.smi.Variable;
+import org.snmp4j.transport.TransportMappings;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.Arrays;
+
+public abstract class TestAgent extends BaseAgent {
+
+ protected static final String BOOT_COUNTER_NAME_TEMPLATE = "target/bootCounter%s_%s.agent";
+ protected static final String CONFIG_NAME_TEMPLATE = "target/conf%s_%s.agent";
+ protected final String host;
+ protected final int port;
+
+ public TestAgent(final File bootCounterFile, final File configFile, final CommandProcessor commandProcessor, final String host) {
+ super(bootCounterFile, configFile, commandProcessor);
+ port = NetworkUtils.availablePort();
+ this.host = host + "/" + port;
+ }
+
+ @Override
+ protected void initTransportMappings() {
+ transportMappings = new TransportMapping[1];
+ final Address transportAddress = GenericAddress.parse(host);
+ final TransportMapping<? extends Address> transportMapping = TransportMappings.getInstance().createTransportMapping(transportAddress);
+ transportMappings[0] = transportMapping;
+ }
+
+ public void start() throws IOException {
+ init();
+ addShutdownHook();
+ getServer().addContext(new OctetString("public"));
+ finishInit();
+ run();
+ sendColdStartNotification();
+ }
+
+ @Override
+ protected void registerManagedObjects() {
+ }
+
+ public void registerManagedObject(ManagedObject mo) {
+ try {
+ server.register(mo, null);
+ } catch (DuplicateRegistrationException ex) {
+ throw new RuntimeException(ex);
+ }
+ }
+
+ public void registerManagedObjects(final ManagedObject... managedObjects) {
+ Arrays.stream(managedObjects).forEach(this::registerManagedObject);
+ }
+
+ @Override
+ protected void unregisterManagedObjects() {
+ }
+
+ protected void unregisterManagedObject(final MOGroup moGroup) {
+ moGroup.unregisterMOs(server, getContext(moGroup));
+ }
+
+ @Override
+ protected void addUsmUser(final USM usm) {
+ }
+
+ @Override
+ protected void addNotificationTargets(final SnmpTargetMIB targetMIB, final SnmpNotificationMIB notificationMIB) {
+ }
+
+ @Override
+ protected void addCommunities(final SnmpCommunityMIB communityMIB) {
+ final Variable[] com2sec = new Variable[]{
+ new OctetString("public"), // community name
+ new OctetString("cpublic"), // security name
+ this.getAgent().getContextEngineID(), // local engine ID
+ new OctetString("public"), // default context name
+ new OctetString(), // transport tag
+ new Integer32(StorageType.nonVolatile), // storage type
+ new Integer32(RowStatus.active) // row status
+ };
+ final SnmpCommunityMIB.SnmpCommunityEntryRow row = communityMIB.getSnmpCommunityEntry().createRow(new OctetString("public2public")
+ .toSubIndex(true), com2sec);
+ communityMIB.getSnmpCommunityEntry().addRow(row);
+ }
+
+ public int getPort() {
+ return port;
+ }
+}
diff --git a/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/test/java/org/apache/nifi/snmp/testagents/TestSNMPV1Agent.java b/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/test/java/org/apache/nifi/snmp/testagents/TestSNMPV1Agent.java
new file mode 100644
index 0000000..3c5182a
--- /dev/null
+++ b/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/test/java/org/apache/nifi/snmp/testagents/TestSNMPV1Agent.java
@@ -0,0 +1,73 @@
+/*
+ * 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.testagents;
+
+import org.snmp4j.agent.CommandProcessor;
+import org.snmp4j.agent.mo.snmp.StorageType;
+import org.snmp4j.agent.mo.snmp.VacmMIB;
+import org.snmp4j.agent.security.MutableVACM;
+import org.snmp4j.mp.MPv3;
+import org.snmp4j.security.SecurityLevel;
+import org.snmp4j.security.SecurityModel;
+import org.snmp4j.smi.OID;
+import org.snmp4j.smi.OctetString;
+
+import java.io.File;
+import java.util.UUID;
+
+public class TestSNMPV1Agent extends TestAgent {
+
+ public TestSNMPV1Agent(final String host) {
+ super(new File(String.format(BOOT_COUNTER_NAME_TEMPLATE, 1, UUID.randomUUID())), new File(String.format(CONFIG_NAME_TEMPLATE, 1, UUID.randomUUID())),
+ new CommandProcessor(new OctetString(MPv3.createLocalEngineID())), host);
+ }
+
+ @Override
+ protected void addViews(final VacmMIB vacmMIB) {
+ vacmMIB.addGroup(SecurityModel.SECURITY_MODEL_SNMPv1,
+ new OctetString("cpublic"),
+ new OctetString("v1v2group"),
+ StorageType.nonVolatile);
+
+ vacmMIB.addAccess(new OctetString("v1v2group"),
+ new OctetString("public"),
+ SecurityModel.SECURITY_MODEL_ANY,
+ SecurityLevel.NOAUTH_NOPRIV,
+ MutableVACM.VACM_MATCH_EXACT,
+ new OctetString("fullReadView"),
+ new OctetString("fullWriteView"),
+ new OctetString("fullNotifyView"),
+ StorageType.nonVolatile);
+
+ vacmMIB.addViewTreeFamily(new OctetString("fullReadView"),
+ new OID("1.3"),
+ new OctetString(),
+ VacmMIB.vacmViewIncluded,
+ StorageType.nonVolatile);
+ vacmMIB.addViewTreeFamily(new OctetString("fullWriteView"),
+ new OID("1.3"),
+ new OctetString(),
+ VacmMIB.vacmViewIncluded,
+ StorageType.nonVolatile);
+ vacmMIB.addViewTreeFamily(new OctetString("fullNotifyView"),
+ new OID("1.3"),
+ new OctetString(),
+ VacmMIB.vacmViewIncluded,
+ StorageType.nonVolatile);
+ }
+
+}
diff --git a/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/test/java/org/apache/nifi/snmp/testagents/TestSNMPV2cAgent.java b/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/test/java/org/apache/nifi/snmp/testagents/TestSNMPV2cAgent.java
new file mode 100644
index 0000000..c330379
--- /dev/null
+++ b/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/test/java/org/apache/nifi/snmp/testagents/TestSNMPV2cAgent.java
@@ -0,0 +1,96 @@
+/*
+ * 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.testagents;
+
+import org.snmp4j.agent.CommandProcessor;
+import org.snmp4j.agent.mo.snmp.RowStatus;
+import org.snmp4j.agent.mo.snmp.SnmpCommunityMIB;
+import org.snmp4j.agent.mo.snmp.StorageType;
+import org.snmp4j.agent.mo.snmp.VacmMIB;
+import org.snmp4j.agent.security.MutableVACM;
+import org.snmp4j.mp.MPv3;
+import org.snmp4j.security.SecurityLevel;
+import org.snmp4j.security.SecurityModel;
+import org.snmp4j.smi.Integer32;
+import org.snmp4j.smi.OID;
+import org.snmp4j.smi.OctetString;
+import org.snmp4j.smi.Variable;
+
+import java.io.File;
+import java.util.UUID;
+
+public class TestSNMPV2cAgent extends TestAgent {
+
+ public TestSNMPV2cAgent(final String host) {
+ super(new File(String.format(BOOT_COUNTER_NAME_TEMPLATE, 2, UUID.randomUUID())), new File(String.format(CONFIG_NAME_TEMPLATE, 2, UUID.randomUUID())),
+ new CommandProcessor(new OctetString(MPv3.createLocalEngineID())), host);
+ }
+
+ @Override
+ protected void addViews(final VacmMIB vacmMIB) {
+ vacmMIB.addGroup(SecurityModel.SECURITY_MODEL_SNMPv2c,
+ new OctetString("cpublic"),
+ new OctetString("v1v2group"),
+ StorageType.nonVolatile);
+
+ vacmMIB.addAccess(new OctetString("v1v2group"),
+ new OctetString("public"),
+ SecurityModel.SECURITY_MODEL_ANY,
+ SecurityLevel.NOAUTH_NOPRIV,
+ MutableVACM.VACM_MATCH_EXACT,
+ new OctetString("fullReadView"),
+ new OctetString("fullWriteView"),
+ new OctetString("fullNotifyView"),
+ StorageType.nonVolatile);
+
+ vacmMIB.addViewTreeFamily(new OctetString("fullReadView"),
+ new OID("1.3"),
+ new OctetString(),
+ VacmMIB.vacmViewIncluded,
+ StorageType.nonVolatile);
+ vacmMIB.addViewTreeFamily(new OctetString("fullWriteView"),
+ new OID("1.3"),
+ new OctetString(),
+ VacmMIB.vacmViewIncluded,
+ StorageType.nonVolatile);
+ vacmMIB.addViewTreeFamily(new OctetString("fullNotifyView"),
+ new OID("1.3"),
+ new OctetString(),
+ VacmMIB.vacmViewIncluded,
+ StorageType.nonVolatile);
+ }
+
+ @Override
+ protected void addCommunities(final SnmpCommunityMIB communityMIB) {
+ final Variable[] com2sec = new Variable[]{
+ new OctetString("public"), // community name
+ new OctetString("cpublic"), // security name
+ this.getAgent().getContextEngineID(), // local engine ID
+ new OctetString("public"), // default context name
+ new OctetString(), // transport tag
+ new Integer32(StorageType.nonVolatile), // storage type
+ new Integer32(RowStatus.active) // row status
+ };
+ final SnmpCommunityMIB.SnmpCommunityEntryRow row = communityMIB.getSnmpCommunityEntry().createRow(new OctetString("public2public")
+ .toSubIndex(true), com2sec);
+ communityMIB.getSnmpCommunityEntry().addRow(row);
+ }
+
+ public int getPort() {
+ return port;
+ }
+}
diff --git a/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/test/java/org/apache/nifi/snmp/testagents/TestSNMPV3Agent.java b/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/test/java/org/apache/nifi/snmp/testagents/TestSNMPV3Agent.java
new file mode 100644
index 0000000..71ba109
--- /dev/null
+++ b/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/test/java/org/apache/nifi/snmp/testagents/TestSNMPV3Agent.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.testagents;
+
+import org.snmp4j.agent.CommandProcessor;
+import org.snmp4j.agent.mo.snmp.StorageType;
+import org.snmp4j.agent.mo.snmp.VacmMIB;
+import org.snmp4j.agent.security.MutableVACM;
+import org.snmp4j.mp.MPv3;
+import org.snmp4j.security.AuthMD5;
+import org.snmp4j.security.AuthSHA;
+import org.snmp4j.security.PrivAES128;
+import org.snmp4j.security.PrivDES;
+import org.snmp4j.security.SecurityLevel;
+import org.snmp4j.security.SecurityModel;
+import org.snmp4j.security.USM;
+import org.snmp4j.security.UsmUser;
+import org.snmp4j.smi.OID;
+import org.snmp4j.smi.OctetString;
+
+import java.io.File;
+import java.util.UUID;
+
+public class TestSNMPV3Agent extends TestAgent {
+
+ public TestSNMPV3Agent(final String host) {
+ super(new File(String.format(BOOT_COUNTER_NAME_TEMPLATE, 1, UUID.randomUUID())), new File(String.format(CONFIG_NAME_TEMPLATE, 1, UUID.randomUUID())),
+ new CommandProcessor(new OctetString(MPv3.createLocalEngineID())), host);
+ }
+
+ @Override
+ protected void addUsmUser(final USM usm) {
+ UsmUser user = new UsmUser(new OctetString("SHA"),
+ AuthSHA.ID,
+ new OctetString("SHAAuthPassword"),
+ null,
+ null);
+ usm.addUser(user.getSecurityName(), usm.getLocalEngineID(), user);
+ user = new UsmUser(new OctetString("SHADES"),
+ AuthSHA.ID,
+ new OctetString("SHADESAuthPassword"),
+ PrivDES.ID,
+ new OctetString("SHADESPrivPassword"));
+ usm.addUser(user.getSecurityName(), usm.getLocalEngineID(), user);
+ user = new UsmUser(new OctetString("MD5DES"),
+ AuthMD5.ID,
+ new OctetString("MD5DESAuthPassword"),
+ PrivDES.ID,
+ new OctetString("MD5DESPrivPassword"));
+ usm.addUser(user.getSecurityName(), usm.getLocalEngineID(), user);
+ user = new UsmUser(new OctetString("SHAAES128"),
+ AuthSHA.ID,
+ new OctetString("SHAAES128AuthPassword"),
+ PrivAES128.ID,
+ new OctetString("SHAAES128PrivPassword"));
+ usm.addUser(user.getSecurityName(), usm.getLocalEngineID(), user);
+ }
+
+ @Override
+ protected void addViews(final VacmMIB vacmMIB) {
+ vacmMIB.addGroup(SecurityModel.SECURITY_MODEL_USM,
+ new OctetString("SHA"),
+ new OctetString("v3-auth-no-priv-group"),
+ StorageType.nonVolatile);
+ vacmMIB.addGroup(SecurityModel.SECURITY_MODEL_USM,
+ new OctetString("SHADES"),
+ new OctetString("v3group"),
+ StorageType.nonVolatile);
+ vacmMIB.addGroup(SecurityModel.SECURITY_MODEL_USM,
+ new OctetString("MD5DES"),
+ new OctetString("v3group"),
+ StorageType.nonVolatile);
+ vacmMIB.addGroup(SecurityModel.SECURITY_MODEL_USM,
+ new OctetString("SHAAES128"),
+ new OctetString("v3group"),
+ StorageType.nonVolatile);
+ vacmMIB.addAccess(new OctetString("v3group"), new OctetString(),
+ SecurityModel.SECURITY_MODEL_USM,
+ SecurityLevel.AUTH_PRIV,
+ MutableVACM.VACM_MATCH_EXACT,
+ new OctetString("fullReadView"),
+ new OctetString("fullWriteView"),
+ new OctetString("fullNotifyView"),
+ StorageType.nonVolatile);
+ vacmMIB.addAccess(new OctetString("v3-auth-no-priv-group"), new OctetString(),
+ SecurityModel.SECURITY_MODEL_USM,
+ SecurityLevel.AUTH_NOPRIV,
+ MutableVACM.VACM_MATCH_EXACT,
+ new OctetString("fullReadView"),
+ new OctetString("fullWriteView"),
+ new OctetString("fullNotifyView"),
+ StorageType.nonVolatile);
+ vacmMIB.addViewTreeFamily(new OctetString("fullReadView"), new OID("1.3"),
+ new OctetString(), VacmMIB.vacmViewIncluded,
+ StorageType.nonVolatile);
+ vacmMIB.addViewTreeFamily(new OctetString("fullWriteView"), new OID("1.3"),
+ new OctetString(), VacmMIB.vacmViewIncluded,
+ StorageType.nonVolatile);
+ vacmMIB.addViewTreeFamily(new OctetString("fullNotifyView"), new OID("1.3"),
+ new OctetString(), VacmMIB.vacmViewIncluded,
+ StorageType.nonVolatile);
+ }
+}
diff --git a/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/test/java/org/apache/nifi/snmp/processors/SNMPTestUtil.java b/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/test/java/org/apache/nifi/snmp/utils/SNMPUtilsTest.java
similarity index 50%
rename from nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/test/java/org/apache/nifi/snmp/processors/SNMPTestUtil.java
rename to nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/test/java/org/apache/nifi/snmp/utils/SNMPUtilsTest.java
index e2850a1..87d7a76 100644
--- a/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/test/java/org/apache/nifi/snmp/processors/SNMPTestUtil.java
+++ b/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/test/java/org/apache/nifi/snmp/utils/SNMPUtilsTest.java
@@ -14,31 +14,34 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.apache.nifi.snmp.processors;
+package org.apache.nifi.snmp.utils;
-import java.io.IOException;
-import java.net.ServerSocket;
+import org.junit.Test;
+import org.snmp4j.PDU;
-public class SNMPTestUtil {
+import java.util.Map;
+
+import static org.junit.Assert.assertEquals;
+
+/**
+ * Test class for {@link SNMPUtils}.
+ */
+public class SNMPUtilsTest {
/**
- * Will determine an available port.
+ * Test for updating attributes of flow files with {@link PDU}
*/
- public static synchronized int availablePort() {
- ServerSocket s = null;
- try {
- s = new ServerSocket(0);
- s.setReuseAddress(true);
- return s.getLocalPort();
- } catch (Exception e) {
- throw new IllegalStateException("Failed to discover available port.", e);
- } finally {
- try {
- s.close();
- } catch (IOException e) {
- // ignore
- }
- }
- }
+ @Test
+ public void validateUpdateFlowFileAttributes() {
+ final PDU pdu = new PDU();
+ pdu.setErrorIndex(0);
+ pdu.setErrorStatus(0);
+ pdu.setType(4);
+
+ final Map<String, String> attributeMap = SNMPUtils.getPduAttributeMap(pdu);
+ assertEquals("0", attributeMap.get(SNMPUtils.SNMP_PROP_PREFIX + "errorIndex"));
+ assertEquals("0", attributeMap.get(SNMPUtils.SNMP_PROP_PREFIX + "errorStatus"));
+ assertEquals("4", attributeMap.get(SNMPUtils.SNMP_PROP_PREFIX + "type"));
+ }
}
diff --git a/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/test/resources/log4j.properties b/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/test/resources/log4j.properties
deleted file mode 100644
index 8c502ec..0000000
--- a/nifi-nar-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/test/resources/log4j.properties
+++ /dev/null
@@ -1,20 +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.
-log4j.rootLogger=INFO, CONSOLE
-
-log4j.appender.CONSOLE=org.apache.log4j.ConsoleAppender
-
-log4j.appender.CONSOLE.layout=org.apache.log4j.PatternLayout
-log4j.appender.CONSOLE.layout.ConversionPattern=%-4r [%t] %-5p %c %x \u2013 %m%n
\ No newline at end of file