mirror of
https://github.com/apache/nifi.git
synced 2025-02-06 01:58:32 +00:00
NIFI-3328: SendTrapSNMP and ListenTrapSNMP processors added.
This commit is contained in:
parent
dfd8adfd8e
commit
bd7536b257
@ -51,6 +51,12 @@ language governing permissions and limitations under the License. -->
|
||||
<version>1.16.0-SNAPSHOT</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.fasterxml.jackson.core</groupId>
|
||||
<artifactId>jackson-databind</artifactId>
|
||||
<version>2.12.3</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
@ -61,7 +67,7 @@ language governing permissions and limitations under the License. -->
|
||||
<configuration>
|
||||
<excludes>
|
||||
<!-- test data -->
|
||||
<exclude>src/test/resources/testdata/*</exclude>
|
||||
<exclude>src/test/resources/*</exclude>
|
||||
</excludes>
|
||||
</configuration>
|
||||
</plugin>
|
||||
|
@ -18,10 +18,11 @@ package org.apache.nifi.snmp.configuration;
|
||||
|
||||
public class SNMPConfiguration {
|
||||
|
||||
private final String agentHost;
|
||||
private final String agentPort;
|
||||
private final int managerPort;
|
||||
private final String targetHost;
|
||||
private final String targetPort;
|
||||
private final int retries;
|
||||
private final int timeout;
|
||||
private final long timeoutInMs;
|
||||
private final int version;
|
||||
private final String authProtocol;
|
||||
private final String authPassphrase;
|
||||
@ -31,10 +32,11 @@ public class SNMPConfiguration {
|
||||
private final String securityLevel;
|
||||
private final String communityString;
|
||||
|
||||
SNMPConfiguration(final String agentHost,
|
||||
final String agentPort,
|
||||
SNMPConfiguration(final int managerPort,
|
||||
final String targetHost,
|
||||
final String targetPort,
|
||||
final int retries,
|
||||
final int timeout,
|
||||
final long timeoutInMs,
|
||||
final int version,
|
||||
final String authProtocol,
|
||||
final String authPassphrase,
|
||||
@ -43,10 +45,11 @@ public class SNMPConfiguration {
|
||||
final String securityName,
|
||||
final String securityLevel,
|
||||
final String communityString) {
|
||||
this.agentHost = agentHost;
|
||||
this.agentPort = agentPort;
|
||||
this.managerPort = managerPort;
|
||||
this.targetHost = targetHost;
|
||||
this.targetPort = targetPort;
|
||||
this.retries = retries;
|
||||
this.timeout = timeout;
|
||||
this.timeoutInMs = timeoutInMs;
|
||||
this.version = version;
|
||||
this.authProtocol = authProtocol;
|
||||
this.authPassphrase = authPassphrase;
|
||||
@ -57,20 +60,24 @@ public class SNMPConfiguration {
|
||||
this.communityString = communityString;
|
||||
}
|
||||
|
||||
public String getAgentHost() {
|
||||
return agentHost;
|
||||
public int getManagerPort() {
|
||||
return managerPort;
|
||||
}
|
||||
|
||||
public String getAgentPort() {
|
||||
return agentPort;
|
||||
public String getTargetHost() {
|
||||
return targetHost;
|
||||
}
|
||||
|
||||
public String getTargetPort() {
|
||||
return targetPort;
|
||||
}
|
||||
|
||||
public int getRetries() {
|
||||
return retries;
|
||||
}
|
||||
|
||||
public int getTimeout() {
|
||||
return timeout;
|
||||
public long getTimeoutInMs() {
|
||||
return timeoutInMs;
|
||||
}
|
||||
|
||||
public int getVersion() {
|
||||
@ -104,4 +111,95 @@ public class SNMPConfiguration {
|
||||
public String getCommunityString() {
|
||||
return communityString;
|
||||
}
|
||||
|
||||
public static Builder builder() {
|
||||
return new Builder();
|
||||
}
|
||||
|
||||
public static class Builder {
|
||||
|
||||
private int managerPort;
|
||||
private String targetHost;
|
||||
private String targetPort;
|
||||
private int retries;
|
||||
private long timeoutInMs = 500L;
|
||||
private int version;
|
||||
private String authProtocol;
|
||||
private String authPassphrase;
|
||||
private String privacyProtocol;
|
||||
private String privacyPassphrase;
|
||||
private String securityName;
|
||||
private String securityLevel;
|
||||
private String communityString;
|
||||
|
||||
public Builder setManagerPort(final int managerPort) {
|
||||
this.managerPort = managerPort;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder setTargetHost(final String targetHost) {
|
||||
this.targetHost = targetHost;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder setTargetPort(final String targetPort) {
|
||||
this.targetPort = targetPort;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder setRetries(final int retries) {
|
||||
this.retries = retries;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder setTimeoutInMs(final long timeoutInMs) {
|
||||
this.timeoutInMs = timeoutInMs;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder setVersion(final int version) {
|
||||
this.version = version;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder setAuthProtocol(final String authProtocol) {
|
||||
this.authProtocol = authProtocol;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder setAuthPassphrase(final String authPassphrase) {
|
||||
this.authPassphrase = authPassphrase;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder setPrivacyProtocol(final String privacyProtocol) {
|
||||
this.privacyProtocol = privacyProtocol;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder setPrivacyPassphrase(final String privacyPassphrase) {
|
||||
this.privacyPassphrase = privacyPassphrase;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder setSecurityName(final String securityName) {
|
||||
this.securityName = securityName;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder setSecurityLevel(final String securityLevel) {
|
||||
this.securityLevel = securityLevel;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder setCommunityString(String communityString) {
|
||||
this.communityString = communityString;
|
||||
return this;
|
||||
}
|
||||
|
||||
public SNMPConfiguration build() {
|
||||
return new SNMPConfiguration(managerPort, targetHost, targetPort, retries, timeoutInMs, version, authProtocol,
|
||||
authPassphrase, privacyProtocol, privacyPassphrase, securityName, securityLevel, communityString);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,100 +0,0 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.nifi.snmp.configuration;
|
||||
|
||||
public class SNMPConfigurationBuilder {
|
||||
private String agentHost;
|
||||
private String agentPort;
|
||||
private int retries;
|
||||
private int timeout;
|
||||
private int version;
|
||||
private String authProtocol;
|
||||
private String authPassphrase;
|
||||
private String privacyProtocol;
|
||||
private String privacyPassphrase;
|
||||
private String securityName;
|
||||
private String securityLevel;
|
||||
private String communityString;
|
||||
|
||||
public SNMPConfigurationBuilder setAgentHost(final String agentHost) {
|
||||
this.agentHost = agentHost;
|
||||
return this;
|
||||
}
|
||||
|
||||
public SNMPConfigurationBuilder setAgentPort(final String agentPort) {
|
||||
this.agentPort = agentPort;
|
||||
return this;
|
||||
}
|
||||
|
||||
public SNMPConfigurationBuilder setRetries(final int retries) {
|
||||
this.retries = retries;
|
||||
return this;
|
||||
}
|
||||
|
||||
public SNMPConfigurationBuilder setTimeout(final int timeout) {
|
||||
this.timeout = timeout;
|
||||
return this;
|
||||
}
|
||||
|
||||
public SNMPConfigurationBuilder setVersion(final int version) {
|
||||
this.version = version;
|
||||
return this;
|
||||
}
|
||||
|
||||
public SNMPConfigurationBuilder setAuthProtocol(final String authProtocol) {
|
||||
this.authProtocol = authProtocol;
|
||||
return this;
|
||||
}
|
||||
|
||||
public SNMPConfigurationBuilder setAuthPassphrase(final String authPassphrase) {
|
||||
this.authPassphrase = authPassphrase;
|
||||
return this;
|
||||
}
|
||||
|
||||
public SNMPConfigurationBuilder setPrivacyProtocol(final String privacyProtocol) {
|
||||
this.privacyProtocol = privacyProtocol;
|
||||
return this;
|
||||
}
|
||||
|
||||
public SNMPConfigurationBuilder setPrivacyPassphrase(final String privacyPassphrase) {
|
||||
this.privacyPassphrase = privacyPassphrase;
|
||||
return this;
|
||||
}
|
||||
|
||||
public SNMPConfigurationBuilder setSecurityName(final String securityName) {
|
||||
this.securityName = securityName;
|
||||
return this;
|
||||
}
|
||||
|
||||
public SNMPConfigurationBuilder setSecurityLevel(final String securityLevel) {
|
||||
this.securityLevel = securityLevel;
|
||||
return this;
|
||||
}
|
||||
|
||||
public SNMPConfigurationBuilder setCommunityString(final String communityString) {
|
||||
this.communityString = communityString;
|
||||
return this;
|
||||
}
|
||||
|
||||
public SNMPConfiguration build() {
|
||||
final boolean isValid = agentHost != null && agentPort != null;
|
||||
if (!isValid) {
|
||||
throw new IllegalStateException("Required properties are not set.");
|
||||
}
|
||||
return new SNMPConfiguration(agentHost, agentPort, retries, timeout, version, authProtocol, authPassphrase, privacyProtocol, privacyPassphrase, securityName, securityLevel, communityString);
|
||||
}
|
||||
}
|
@ -0,0 +1,117 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.nifi.snmp.configuration;
|
||||
|
||||
import org.apache.nifi.util.StringUtils;
|
||||
|
||||
public class V1TrapConfiguration {
|
||||
|
||||
private final String enterpriseOid;
|
||||
private final String agentAddress;
|
||||
private final String genericTrapType;
|
||||
private final String specificTrapType;
|
||||
|
||||
private V1TrapConfiguration(final V1TrapConfiguration.Builder builder) {
|
||||
this.enterpriseOid = builder.enterpriseOid;
|
||||
this.agentAddress = builder.agentAddress;
|
||||
this.genericTrapType = builder.genericTrapType;
|
||||
this.specificTrapType = builder.specificTrapType;
|
||||
}
|
||||
|
||||
public String getEnterpriseOid() {
|
||||
return enterpriseOid;
|
||||
}
|
||||
|
||||
public String getAgentAddress() {
|
||||
return agentAddress;
|
||||
}
|
||||
|
||||
public int getGenericTrapType() {
|
||||
return Integer.parseInt(genericTrapType);
|
||||
}
|
||||
|
||||
public Integer getSpecificTrapType() {
|
||||
if (StringUtils.isNotEmpty(specificTrapType)) {
|
||||
return Integer.parseInt(specificTrapType);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static V1TrapConfiguration.Builder builder() {
|
||||
return new V1TrapConfiguration.Builder();
|
||||
}
|
||||
|
||||
public static final class Builder {
|
||||
String enterpriseOid;
|
||||
String agentAddress;
|
||||
String genericTrapType;
|
||||
String specificTrapType;
|
||||
|
||||
public Builder enterpriseOid(String enterpriseOid) {
|
||||
this.enterpriseOid = enterpriseOid;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder agentAddress(String agentAddress) {
|
||||
this.agentAddress = agentAddress;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder genericTrapType(String genericTrapType) {
|
||||
this.genericTrapType = genericTrapType;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder specificTrapType(String specificTrapType) {
|
||||
this.specificTrapType = specificTrapType;
|
||||
return this;
|
||||
}
|
||||
|
||||
public V1TrapConfiguration build() {
|
||||
if (StringUtils.isEmpty(enterpriseOid)) {
|
||||
throw new IllegalArgumentException("Enterprise OID must be specified.");
|
||||
}
|
||||
if (StringUtils.isEmpty(agentAddress)) {
|
||||
throw new IllegalArgumentException("Agent address must be specified.");
|
||||
}
|
||||
|
||||
final int parsedGenericTrapType;
|
||||
try {
|
||||
parsedGenericTrapType = Integer.parseInt(genericTrapType);
|
||||
if (parsedGenericTrapType < 0 || parsedGenericTrapType > 6) {
|
||||
throw new IllegalArgumentException("Generic Trap Type must be between 0 and 6.");
|
||||
}
|
||||
} catch (NumberFormatException e) {
|
||||
throw new IllegalArgumentException("Generic Trap Type is not a number.");
|
||||
}
|
||||
|
||||
if (parsedGenericTrapType == 6) {
|
||||
try {
|
||||
final int parsedSpecificTrapType = Integer.parseInt(specificTrapType);
|
||||
if (parsedSpecificTrapType < 0) {
|
||||
throw new IllegalArgumentException("Specific Trap Type must be between 0 and 2147483647.");
|
||||
}
|
||||
} catch (NumberFormatException e) {
|
||||
throw new IllegalArgumentException("Generic Trap Type is [6 - Enterprise Specific] but Specific Trap Type is not provided or not a number.");
|
||||
}
|
||||
} else if (StringUtils.isNotEmpty(specificTrapType)) {
|
||||
throw new IllegalArgumentException("Invalid argument: Generic Trap Type is not [6 - Enterprise Specific] but Specific Trap Type is provided.");
|
||||
}
|
||||
return new V1TrapConfiguration(this);
|
||||
}
|
||||
}
|
||||
}
|
@ -14,12 +14,20 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.nifi.snmp.exception;
|
||||
package org.apache.nifi.snmp.configuration;
|
||||
|
||||
public class CreateSNMPClientException extends SNMPException {
|
||||
public class V2TrapConfiguration {
|
||||
|
||||
public CreateSNMPClientException(final String errorMessage) {
|
||||
super(errorMessage);
|
||||
private final String trapOidValue;
|
||||
|
||||
public V2TrapConfiguration(final String trapOidValue) {
|
||||
if (trapOidValue.isEmpty()) {
|
||||
throw new IllegalArgumentException("Trap OID Value must be specified.");
|
||||
}
|
||||
this.trapOidValue = trapOidValue;
|
||||
}
|
||||
|
||||
public String getTrapOidValue() {
|
||||
return trapOidValue;
|
||||
}
|
||||
}
|
@ -1,25 +1,21 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.nifi.snmp.exception;
|
||||
|
||||
public class CloseSNMPClientException extends SNMPException {
|
||||
|
||||
public CloseSNMPClientException(final String errorMessage) {
|
||||
super(errorMessage);
|
||||
}
|
||||
|
||||
}
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.nifi.snmp.dto;
|
||||
|
||||
public enum ErrorStatus {
|
||||
FAILURE, SUCCESS
|
||||
}
|
@ -1,34 +1,37 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.nifi.snmp.operations;
|
||||
|
||||
import org.apache.nifi.flowfile.FlowFile;
|
||||
import org.apache.nifi.snmp.dto.SNMPSingleResponse;
|
||||
import org.apache.nifi.snmp.dto.SNMPTreeResponse;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
public interface SNMPRequestHandler {
|
||||
|
||||
SNMPSingleResponse get(final String oid) throws IOException;
|
||||
|
||||
SNMPTreeResponse walk(final String oid);
|
||||
|
||||
SNMPSingleResponse set(final FlowFile flowfile) throws IOException;
|
||||
|
||||
void close();
|
||||
}
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.nifi.snmp.dto;
|
||||
|
||||
public class SNMPResponseStatus {
|
||||
|
||||
private final String errorMessage;
|
||||
private final ErrorStatus errorStatus;
|
||||
|
||||
|
||||
public SNMPResponseStatus(String errorMessage, ErrorStatus errorStatus) {
|
||||
this.errorMessage = errorMessage;
|
||||
this.errorStatus = errorStatus;
|
||||
}
|
||||
|
||||
public String getErrorMessage() {
|
||||
return errorMessage;
|
||||
}
|
||||
|
||||
public ErrorStatus getErrorStatus() {
|
||||
return errorStatus;
|
||||
}
|
||||
}
|
@ -38,7 +38,6 @@ public class SNMPSingleResponse {
|
||||
return responsePdu.getErrorStatus() == PDU.noError;
|
||||
}
|
||||
|
||||
|
||||
public Map<String, String> getAttributes() {
|
||||
return SNMPUtils.getPduAttributeMap(responsePdu);
|
||||
}
|
||||
@ -65,4 +64,5 @@ public class SNMPSingleResponse {
|
||||
public boolean isReportPdu() {
|
||||
return responsePdu.getType() == PDU.REPORT;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -26,6 +26,7 @@ import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class SNMPTreeResponse {
|
||||
@ -56,4 +57,11 @@ public class SNMPTreeResponse {
|
||||
.filter(TreeEvent::isError)
|
||||
.forEach(event -> logger.error("Error occured in SNMP walk event: {}", event.getErrorMessage()));
|
||||
}
|
||||
|
||||
public boolean isError() {
|
||||
final Optional<TreeEvent> first = events.stream()
|
||||
.filter(TreeEvent::isError)
|
||||
.findFirst();
|
||||
return first.isPresent();
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,58 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.nifi.snmp.dto;
|
||||
|
||||
public class UserDetails {
|
||||
|
||||
private String securityName;
|
||||
private String authProtocol;
|
||||
private String authPassphrase;
|
||||
private String privProtocol;
|
||||
private String privPassphrase;
|
||||
|
||||
public UserDetails() {
|
||||
}
|
||||
|
||||
public UserDetails(final String securityName, final String authProtocol, final String authPassphrase,
|
||||
final String privProtocol, final String privPassphrase) {
|
||||
this.securityName = securityName;
|
||||
this.authProtocol = authProtocol;
|
||||
this.authPassphrase = authPassphrase;
|
||||
this.privProtocol = privProtocol;
|
||||
this.privPassphrase = privPassphrase;
|
||||
}
|
||||
|
||||
public String getSecurityName() {
|
||||
return securityName;
|
||||
}
|
||||
|
||||
public String getAuthProtocol() {
|
||||
return authProtocol;
|
||||
}
|
||||
|
||||
public String getAuthPassphrase() {
|
||||
return authPassphrase;
|
||||
}
|
||||
|
||||
public String getPrivProtocol() {
|
||||
return privProtocol;
|
||||
}
|
||||
|
||||
public String getPrivPassphrase() {
|
||||
return privPassphrase;
|
||||
}
|
||||
}
|
@ -22,4 +22,8 @@ public class SNMPException extends RuntimeException {
|
||||
super(errorMessage);
|
||||
}
|
||||
|
||||
public SNMPException(final Exception exception) {
|
||||
super(exception);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1,91 +0,0 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.nifi.snmp.factory;
|
||||
|
||||
import org.apache.nifi.snmp.configuration.SNMPConfiguration;
|
||||
import org.apache.nifi.snmp.exception.CreateSNMPClientException;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.snmp4j.CommunityTarget;
|
||||
import org.snmp4j.Snmp;
|
||||
import org.snmp4j.Target;
|
||||
import org.snmp4j.UserTarget;
|
||||
import org.snmp4j.security.SecurityLevel;
|
||||
import org.snmp4j.smi.OctetString;
|
||||
import org.snmp4j.smi.UdpAddress;
|
||||
import org.snmp4j.transport.DefaultUdpTransportMapping;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Optional;
|
||||
|
||||
public abstract class AbstractSNMPFactory {
|
||||
|
||||
private static final Logger logger = LoggerFactory.getLogger(AbstractSNMPFactory.class);
|
||||
|
||||
protected AbstractSNMPFactory() {
|
||||
// hide implicit constructor
|
||||
}
|
||||
|
||||
protected static Snmp createSnmpClient() {
|
||||
final Snmp snmp;
|
||||
try {
|
||||
snmp = new Snmp(new DefaultUdpTransportMapping());
|
||||
snmp.listen();
|
||||
return snmp;
|
||||
} catch (IOException e) {
|
||||
final String errorMessage = "Creating SNMP client failed.";
|
||||
logger.error(errorMessage, e);
|
||||
throw new CreateSNMPClientException(errorMessage);
|
||||
}
|
||||
}
|
||||
|
||||
protected static Target createUserTarget(final SNMPConfiguration configuration) {
|
||||
final UserTarget userTarget = new UserTarget();
|
||||
setupTargetBasicProperties(userTarget, configuration);
|
||||
|
||||
final int securityLevel = SecurityLevel.valueOf(configuration.getSecurityLevel()).getSnmpValue();
|
||||
userTarget.setSecurityLevel(securityLevel);
|
||||
|
||||
final String securityName = configuration.getSecurityName();
|
||||
Optional.ofNullable(securityName).map(OctetString::new).ifPresent(userTarget::setSecurityName);
|
||||
|
||||
return userTarget;
|
||||
}
|
||||
|
||||
protected static Target createCommunityTarget(final SNMPConfiguration configuration) {
|
||||
final Target communityTarget = new CommunityTarget();
|
||||
setupTargetBasicProperties(communityTarget, configuration);
|
||||
final String community = configuration.getCommunityString();
|
||||
|
||||
Optional.ofNullable(community).map(OctetString::new).ifPresent(communityTarget::setSecurityName);
|
||||
|
||||
return communityTarget;
|
||||
}
|
||||
|
||||
private static void setupTargetBasicProperties(final Target target, final SNMPConfiguration configuration) {
|
||||
final int snmpVersion = configuration.getVersion();
|
||||
final String host = configuration.getAgentHost();
|
||||
final String port = configuration.getAgentPort();
|
||||
final int retries = configuration.getRetries();
|
||||
final int timeout = configuration.getTimeout();
|
||||
|
||||
target.setVersion(snmpVersion);
|
||||
target.setAddress(new UdpAddress(host + "/" + port));
|
||||
target.setRetries(retries);
|
||||
target.setTimeout(timeout);
|
||||
}
|
||||
}
|
@ -1,70 +0,0 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.nifi.snmp.factory;
|
||||
|
||||
import org.apache.nifi.snmp.configuration.SNMPConfiguration;
|
||||
import org.apache.nifi.snmp.exception.InvalidSnmpVersionException;
|
||||
import org.snmp4j.Snmp;
|
||||
import org.snmp4j.Target;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
public class CompositeSNMPFactory implements SNMPFactory {
|
||||
|
||||
private static final String INVALID_SNMP_VERSION = "SNMP version is not supported.";
|
||||
private static final List<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();
|
||||
}
|
||||
}
|
@ -1,76 +0,0 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.nifi.snmp.factory;
|
||||
|
||||
import org.apache.nifi.snmp.configuration.SNMPConfiguration;
|
||||
import org.apache.nifi.snmp.utils.SNMPUtils;
|
||||
import org.snmp4j.Snmp;
|
||||
import org.snmp4j.Target;
|
||||
import org.snmp4j.mp.MPv3;
|
||||
import org.snmp4j.mp.SnmpConstants;
|
||||
import org.snmp4j.security.SecurityModels;
|
||||
import org.snmp4j.security.SecurityProtocols;
|
||||
import org.snmp4j.security.USM;
|
||||
import org.snmp4j.security.UsmUser;
|
||||
import org.snmp4j.smi.OID;
|
||||
import org.snmp4j.smi.OctetString;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
public class V3SNMPFactory extends AbstractSNMPFactory implements SNMPFactory {
|
||||
|
||||
@Override
|
||||
public boolean supports(final int version) {
|
||||
return SnmpConstants.version3 == version;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Snmp createSnmpManagerInstance(final SNMPConfiguration configuration) {
|
||||
final Snmp snmp = createSnmpClient();
|
||||
|
||||
// If there's a USM instance associated with the MPv3 bound to this Snmp instance (like an agent running
|
||||
// on the same host) it is not null.
|
||||
if (snmp.getUSM() == null) {
|
||||
final OctetString localEngineId = new OctetString(MPv3.createLocalEngineID());
|
||||
final USM usm = new USM(SecurityProtocols.getInstance(), localEngineId, 0);
|
||||
SecurityModels.getInstance().addSecurityModel(usm);
|
||||
}
|
||||
|
||||
final String username = configuration.getSecurityName();
|
||||
final OID authProtocol = Optional.ofNullable(configuration.getAuthProtocol())
|
||||
.map(SNMPUtils::getAuth).orElse(null);
|
||||
final OID privacyProtocol = Optional.ofNullable(configuration.getPrivacyProtocol())
|
||||
.map(SNMPUtils::getPriv).orElse(null);
|
||||
final String authPassword = configuration.getAuthPassphrase();
|
||||
final String privacyPassword = configuration.getPrivacyPassphrase();
|
||||
final OctetString authPasswordOctet = authPassword != null ? new OctetString(authPassword) : null;
|
||||
final OctetString privacyPasswordOctet = privacyPassword != null ? new OctetString(privacyPassword) : null;
|
||||
|
||||
// Add user information.
|
||||
snmp.getUSM().addUser(
|
||||
new OctetString(username),
|
||||
new UsmUser(new OctetString(username), authProtocol, authPasswordOctet,
|
||||
privacyProtocol, privacyPasswordOctet));
|
||||
|
||||
return snmp;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Target createTargetInstance(final SNMPConfiguration configuration) {
|
||||
return createUserTarget(configuration);
|
||||
}
|
||||
}
|
@ -0,0 +1,50 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.nifi.snmp.factory.core;
|
||||
|
||||
import org.apache.nifi.snmp.configuration.SNMPConfiguration;
|
||||
import org.apache.nifi.snmp.operations.SNMPResourceHandler;
|
||||
import org.snmp4j.Snmp;
|
||||
import org.snmp4j.Target;
|
||||
import org.snmp4j.smi.UdpAddress;
|
||||
|
||||
public interface SNMPContext {
|
||||
|
||||
default SNMPResourceHandler createSNMPResourceHandler(final SNMPConfiguration snmpConfiguration) {
|
||||
return new SNMPResourceHandler(
|
||||
createSnmpManagerInstance(snmpConfiguration),
|
||||
createTargetInstance(snmpConfiguration)
|
||||
);
|
||||
}
|
||||
|
||||
default void setupTargetBasicProperties(final Target target, final SNMPConfiguration configuration) {
|
||||
final int snmpVersion = configuration.getVersion();
|
||||
final String host = configuration.getTargetHost();
|
||||
final String port = configuration.getTargetPort();
|
||||
final int retries = configuration.getRetries();
|
||||
final long timeout = configuration.getTimeoutInMs();
|
||||
|
||||
target.setVersion(snmpVersion);
|
||||
target.setAddress(new UdpAddress(host + "/" + port));
|
||||
target.setRetries(retries);
|
||||
target.setTimeout(timeout);
|
||||
}
|
||||
|
||||
Snmp createSnmpManagerInstance(final SNMPConfiguration configuration);
|
||||
|
||||
Target createTargetInstance(final SNMPConfiguration configuration);
|
||||
}
|
@ -0,0 +1,48 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.nifi.snmp.factory.core;
|
||||
|
||||
import org.apache.nifi.snmp.exception.InvalidSnmpVersionException;
|
||||
import org.snmp4j.mp.SnmpConstants;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
|
||||
public class SNMPFactoryProvider {
|
||||
|
||||
private SNMPFactoryProvider() {
|
||||
// not to instantiate
|
||||
}
|
||||
|
||||
private static final String INVALID_SNMP_VERSION = "SNMP version is not supported: %s";
|
||||
private static final Map<Integer, SNMPContext> FACTORIES;
|
||||
|
||||
static {
|
||||
final Map<Integer, SNMPContext> factories = new HashMap<>();
|
||||
factories.put(SnmpConstants.version1, new V1V2cSNMPFactory());
|
||||
factories.put(SnmpConstants.version2c, new V1V2cSNMPFactory());
|
||||
factories.put(SnmpConstants.version3, new V3SNMPFactory());
|
||||
FACTORIES = Collections.unmodifiableMap(factories);
|
||||
}
|
||||
|
||||
public static SNMPContext getFactory(final int version) {
|
||||
return Optional.ofNullable(FACTORIES.get(version))
|
||||
.orElseThrow(() -> new InvalidSnmpVersionException(String.format(INVALID_SNMP_VERSION, version)));
|
||||
}
|
||||
}
|
@ -14,27 +14,29 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.nifi.snmp.factory;
|
||||
package org.apache.nifi.snmp.factory.core;
|
||||
|
||||
import org.apache.nifi.processor.exception.ProcessException;
|
||||
import org.apache.nifi.snmp.configuration.SNMPConfiguration;
|
||||
import org.snmp4j.Snmp;
|
||||
import org.snmp4j.Target;
|
||||
import org.snmp4j.mp.SnmpConstants;
|
||||
import org.snmp4j.smi.UdpAddress;
|
||||
import org.snmp4j.transport.DefaultUdpTransportMapping;
|
||||
|
||||
public class V2cSNMPFactory extends AbstractSNMPFactory implements SNMPFactory {
|
||||
import java.io.IOException;
|
||||
|
||||
@Override
|
||||
public boolean supports(final int version) {
|
||||
return SnmpConstants.version2c == version;
|
||||
}
|
||||
public class SNMPManagerFactory {
|
||||
|
||||
private static final String LOCALHOST = "127.0.0.1";
|
||||
|
||||
@Override
|
||||
public Snmp createSnmpManagerInstance(final SNMPConfiguration configuration) {
|
||||
return createSnmpClient();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Target createTargetInstance(final SNMPConfiguration configuration) {
|
||||
return createCommunityTarget(configuration);
|
||||
final String managerAddress = LOCALHOST + "/" + configuration.getManagerPort();
|
||||
final Snmp snmpManager;
|
||||
try {
|
||||
snmpManager = new Snmp(new DefaultUdpTransportMapping(new UdpAddress(managerAddress)));
|
||||
snmpManager.listen();
|
||||
} catch (IOException e) {
|
||||
throw new ProcessException(e);
|
||||
}
|
||||
return snmpManager;
|
||||
}
|
||||
}
|
@ -14,27 +14,25 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.nifi.snmp.factory;
|
||||
package org.apache.nifi.snmp.factory.core;
|
||||
|
||||
import org.apache.nifi.snmp.configuration.SNMPConfiguration;
|
||||
import org.snmp4j.Snmp;
|
||||
import org.snmp4j.CommunityTarget;
|
||||
import org.snmp4j.Target;
|
||||
import org.snmp4j.mp.SnmpConstants;
|
||||
import org.snmp4j.smi.OctetString;
|
||||
|
||||
public class V1SNMPFactory extends AbstractSNMPFactory implements SNMPFactory {
|
||||
import java.util.Optional;
|
||||
|
||||
@Override
|
||||
public boolean supports(final int version) {
|
||||
return SnmpConstants.version1 == version;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Snmp createSnmpManagerInstance(final SNMPConfiguration configuration) {
|
||||
return createSnmpClient();
|
||||
}
|
||||
public class V1V2cSNMPFactory extends SNMPManagerFactory implements SNMPContext {
|
||||
|
||||
@Override
|
||||
public Target createTargetInstance(final SNMPConfiguration configuration) {
|
||||
return createCommunityTarget(configuration);
|
||||
final Target communityTarget = new CommunityTarget();
|
||||
setupTargetBasicProperties(communityTarget, configuration);
|
||||
final String community = configuration.getCommunityString();
|
||||
|
||||
Optional.ofNullable(community).map(OctetString::new).ifPresent(communityTarget::setSecurityName);
|
||||
|
||||
return communityTarget;
|
||||
}
|
||||
}
|
@ -0,0 +1,77 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.nifi.snmp.factory.core;
|
||||
|
||||
import org.apache.nifi.snmp.configuration.SNMPConfiguration;
|
||||
import org.apache.nifi.snmp.utils.SNMPUtils;
|
||||
import org.snmp4j.Snmp;
|
||||
import org.snmp4j.Target;
|
||||
import org.snmp4j.UserTarget;
|
||||
import org.snmp4j.mp.MPv3;
|
||||
import org.snmp4j.security.SecurityLevel;
|
||||
import org.snmp4j.security.SecurityModels;
|
||||
import org.snmp4j.security.SecurityProtocols;
|
||||
import org.snmp4j.security.USM;
|
||||
import org.snmp4j.security.UsmUser;
|
||||
import org.snmp4j.smi.OID;
|
||||
import org.snmp4j.smi.OctetString;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
public class V3SNMPFactory extends SNMPManagerFactory implements SNMPContext {
|
||||
|
||||
@Override
|
||||
public Snmp createSnmpManagerInstance(final SNMPConfiguration configuration) {
|
||||
final Snmp snmpManager = super.createSnmpManagerInstance(configuration);
|
||||
|
||||
// Create USM.
|
||||
final OctetString localEngineId = new OctetString(MPv3.createLocalEngineID());
|
||||
final USM usm = new USM(SecurityProtocols.getInstance(), localEngineId, 0);
|
||||
SecurityModels.getInstance().addSecurityModel(usm);
|
||||
|
||||
Optional.ofNullable(configuration.getSecurityName())
|
||||
.map(OctetString::new)
|
||||
.ifPresent(securityName -> {
|
||||
OID authProtocol = Optional.ofNullable(configuration.getAuthProtocol())
|
||||
.map(SNMPUtils::getAuth).orElse(null);
|
||||
OctetString authPassphrase = Optional.ofNullable(configuration.getAuthPassphrase())
|
||||
.map(OctetString::new).orElse(null);
|
||||
OID privacyProtocol = Optional.ofNullable(configuration.getPrivacyProtocol())
|
||||
.map(SNMPUtils::getPriv).orElse(null);
|
||||
OctetString privacyPassphrase = Optional.ofNullable(configuration.getPrivacyPassphrase())
|
||||
.map(OctetString::new).orElse(null);
|
||||
snmpManager.getUSM().addUser(securityName, new UsmUser(securityName, authProtocol, authPassphrase,
|
||||
privacyProtocol, privacyPassphrase));
|
||||
});
|
||||
|
||||
return snmpManager;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Target createTargetInstance(final SNMPConfiguration configuration) {
|
||||
final UserTarget userTarget = new UserTarget();
|
||||
setupTargetBasicProperties(userTarget, configuration);
|
||||
|
||||
final int securityLevel = SecurityLevel.valueOf(configuration.getSecurityLevel()).getSnmpValue();
|
||||
userTarget.setSecurityLevel(securityLevel);
|
||||
|
||||
final String securityName = configuration.getSecurityName();
|
||||
Optional.ofNullable(securityName).map(OctetString::new).ifPresent(userTarget::setSecurityName);
|
||||
|
||||
return userTarget;
|
||||
}
|
||||
}
|
@ -0,0 +1,58 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.nifi.snmp.factory.trap;
|
||||
|
||||
import org.apache.nifi.snmp.configuration.V1TrapConfiguration;
|
||||
import org.snmp4j.PDU;
|
||||
import org.snmp4j.PDUv1;
|
||||
import org.snmp4j.Target;
|
||||
import org.snmp4j.smi.IpAddress;
|
||||
import org.snmp4j.smi.OID;
|
||||
import org.snmp4j.util.DefaultPDUFactory;
|
||||
import org.snmp4j.util.PDUFactory;
|
||||
|
||||
import java.time.Duration;
|
||||
import java.time.Instant;
|
||||
import java.util.Optional;
|
||||
|
||||
/**
|
||||
* Factory class to create SNMPv1-Trap-PDU for SNMPv1.
|
||||
*/
|
||||
public class V1TrapPDUFactory {
|
||||
|
||||
private static final PDUFactory v1PduFactory = new DefaultPDUFactory(PDU.V1TRAP);
|
||||
|
||||
final Target target;
|
||||
final Instant startTime;
|
||||
|
||||
public V1TrapPDUFactory(final Target target, final Instant startTime) {
|
||||
this.target = target;
|
||||
this.startTime = startTime;
|
||||
}
|
||||
|
||||
public PDU get(final V1TrapConfiguration v1TrapConfiguration) {
|
||||
final PDUv1 pdu = (PDUv1) v1PduFactory.createPDU(target);
|
||||
Optional.ofNullable(v1TrapConfiguration.getEnterpriseOid()).map(OID::new).ifPresent(pdu::setEnterprise);
|
||||
Optional.ofNullable(v1TrapConfiguration.getAgentAddress()).map(IpAddress::new).ifPresent(pdu::setAgentAddress);
|
||||
pdu.setGenericTrap(v1TrapConfiguration.getGenericTrapType());
|
||||
Optional.ofNullable(v1TrapConfiguration.getSpecificTrapType()).ifPresent(pdu::setSpecificTrap);
|
||||
final long elapsedMillis = Duration.between(startTime, Instant.now()).toMillis();
|
||||
pdu.setTimestamp(elapsedMillis);
|
||||
return pdu;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,54 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.nifi.snmp.factory.trap;
|
||||
|
||||
import org.apache.nifi.snmp.configuration.V2TrapConfiguration;
|
||||
import org.snmp4j.PDU;
|
||||
import org.snmp4j.Target;
|
||||
import org.snmp4j.mp.SnmpConstants;
|
||||
import org.snmp4j.smi.OctetString;
|
||||
import org.snmp4j.smi.TimeTicks;
|
||||
import org.snmp4j.smi.VariableBinding;
|
||||
import org.snmp4j.util.DefaultPDUFactory;
|
||||
import org.snmp4j.util.PDUFactory;
|
||||
|
||||
import java.time.Duration;
|
||||
import java.time.Instant;
|
||||
|
||||
/**
|
||||
* Factory class to create SNMPv2-Trap-PDU for SNMPv2c and SNMPv3.
|
||||
*/
|
||||
public class V2TrapPDUFactory {
|
||||
private static final PDUFactory v2PduFactory = new DefaultPDUFactory(PDU.TRAP);
|
||||
|
||||
final Target target;
|
||||
final Instant startTime;
|
||||
|
||||
public V2TrapPDUFactory(final Target target, final Instant startTime) {
|
||||
this.target = target;
|
||||
this.startTime = startTime;
|
||||
}
|
||||
|
||||
public PDU get(final V2TrapConfiguration v2TrapConfiguration) {
|
||||
final PDU pdu = v2PduFactory.createPDU(target);
|
||||
pdu.add(new VariableBinding(SnmpConstants.snmpTrapOID, new OctetString(v2TrapConfiguration.getTrapOidValue())));
|
||||
final long elapsedMillis = Duration.between(startTime, Instant.now()).toMillis();
|
||||
pdu.add(new VariableBinding(SnmpConstants.sysUpTime, new TimeTicks(elapsedMillis)));
|
||||
return pdu;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,150 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.nifi.snmp.operations;
|
||||
|
||||
import org.apache.nifi.snmp.dto.SNMPSingleResponse;
|
||||
import org.apache.nifi.snmp.dto.SNMPTreeResponse;
|
||||
import org.apache.nifi.snmp.exception.RequestTimeoutException;
|
||||
import org.apache.nifi.snmp.exception.SNMPWalkException;
|
||||
import org.apache.nifi.snmp.utils.SNMPUtils;
|
||||
import org.snmp4j.PDU;
|
||||
import org.snmp4j.Snmp;
|
||||
import org.snmp4j.Target;
|
||||
import org.snmp4j.event.ResponseEvent;
|
||||
import org.snmp4j.smi.OID;
|
||||
import org.snmp4j.smi.VariableBinding;
|
||||
import org.snmp4j.util.DefaultPDUFactory;
|
||||
import org.snmp4j.util.PDUFactory;
|
||||
import org.snmp4j.util.TreeEvent;
|
||||
import org.snmp4j.util.TreeUtils;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
|
||||
import static org.apache.nifi.snmp.operations.SNMPResourceHandler.REQUEST_TIMEOUT_EXCEPTION_TEMPLATE;
|
||||
|
||||
public class GetSNMPHandler {
|
||||
|
||||
private static final PDUFactory getPduFactory = new DefaultPDUFactory(PDU.GET);
|
||||
|
||||
protected static final String EMPTY_SUBTREE_EXCEPTION_MESSAGE = "Agent is not available, the %s OID not found or user not found. " +
|
||||
"Please, check if (1) the agent is available, (2) the processor's SNMP version matches the agent version, " +
|
||||
"(3) the OID is correct, (4) The user is valid.";
|
||||
|
||||
protected static final String SNMP_ERROR_EXCEPTION_MESSAGE = "Agent is not available, OID not found or user not found. " +
|
||||
"Please, check if (1) the agent is available, (2) the processor's SNMP version matches the agent version, " +
|
||||
"(3) the OID is correct, (4) The user is valid.";
|
||||
|
||||
protected static final String LEAF_ELEMENT_EXCEPTION_MESSAGE = "OID not found or it is a single leaf element. The leaf element " +
|
||||
"associated with this %s OID does not contain child OIDs. Please check if the OID exists in the agent " +
|
||||
"MIB or specify a parent OID with at least one child element";
|
||||
|
||||
private final SNMPResourceHandler snmpResourceHandler;
|
||||
private TreeUtils treeUtils;
|
||||
|
||||
public GetSNMPHandler(final SNMPResourceHandler snmpResourceHandler) {
|
||||
this.snmpResourceHandler = snmpResourceHandler;
|
||||
this.treeUtils = new TreeUtils(snmpResourceHandler.getSnmpManager(), getPduFactory);
|
||||
}
|
||||
|
||||
public SNMPSingleResponse get(final String oid) throws IOException {
|
||||
final Target target = snmpResourceHandler.getTarget();
|
||||
final Snmp snmpManager = snmpResourceHandler.getSnmpManager();
|
||||
|
||||
final PDU pdu = getPduFactory.createPDU(target);
|
||||
pdu.add(new VariableBinding(new OID(oid)));
|
||||
|
||||
final PDU responsePdu = getResponsePdu(target, snmpManager, pdu);
|
||||
return new SNMPSingleResponse(target, responsePdu);
|
||||
}
|
||||
|
||||
public Optional<SNMPSingleResponse> get(final Map<String, String> flowFileAttributes) throws IOException {
|
||||
final Target target = snmpResourceHandler.getTarget();
|
||||
final Snmp snmpManager = snmpResourceHandler.getSnmpManager();
|
||||
|
||||
final PDU pdu = getPduFactory.createPDU(target);
|
||||
VariableBinding[] variableBindings = SNMPUtils.addGetVariables(flowFileAttributes);
|
||||
if (variableBindings.length == 0) {
|
||||
return Optional.empty();
|
||||
}
|
||||
pdu.addAll(variableBindings);
|
||||
|
||||
final PDU responsePdu = getResponsePdu(target, snmpManager, pdu);
|
||||
return Optional.of(new SNMPSingleResponse(target, responsePdu));
|
||||
}
|
||||
|
||||
public SNMPTreeResponse walk(final String oid) {
|
||||
final Target target = snmpResourceHandler.getTarget();
|
||||
final List<TreeEvent> subtree = treeUtils.getSubtree(target, new OID(oid));
|
||||
|
||||
evaluateSubtreeErrors(oid, subtree);
|
||||
|
||||
return new SNMPTreeResponse(target, subtree);
|
||||
}
|
||||
|
||||
public Optional<SNMPTreeResponse> walk(final Map<String, String> flowFileAttributes) {
|
||||
final Target target = snmpResourceHandler.getTarget();
|
||||
final List<TreeEvent> subtree;
|
||||
|
||||
final OID[] oids = SNMPUtils.addWalkVariables(flowFileAttributes);
|
||||
if (oids.length == 0) {
|
||||
return Optional.empty();
|
||||
}
|
||||
subtree = treeUtils.walk(target, oids);
|
||||
|
||||
evaluateSubtreeErrors(Arrays.toString(oids), subtree);
|
||||
|
||||
return Optional.of(new SNMPTreeResponse(target, subtree));
|
||||
}
|
||||
|
||||
private PDU getResponsePdu(Target target, Snmp snmpManager, PDU pdu) throws IOException {
|
||||
final ResponseEvent response = snmpManager.get(pdu, target);
|
||||
final PDU responsePdu = response.getResponse();
|
||||
if (responsePdu == null) {
|
||||
throw new RequestTimeoutException(String.format(REQUEST_TIMEOUT_EXCEPTION_TEMPLATE, "read"));
|
||||
}
|
||||
return responsePdu;
|
||||
}
|
||||
|
||||
private void evaluateSubtreeErrors(String oid, List<TreeEvent> subtree) {
|
||||
if (subtree.isEmpty()) {
|
||||
throw new SNMPWalkException(String.format(EMPTY_SUBTREE_EXCEPTION_MESSAGE, oid));
|
||||
}
|
||||
if (isSnmpError(subtree)) {
|
||||
throw new SNMPWalkException(SNMP_ERROR_EXCEPTION_MESSAGE);
|
||||
}
|
||||
if (isLeafElement(subtree)) {
|
||||
throw new SNMPWalkException(String.format(LEAF_ELEMENT_EXCEPTION_MESSAGE, oid));
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isSnmpError(final List<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;
|
||||
}
|
||||
|
||||
// Visible for testing
|
||||
void setTreeUtils(final TreeUtils treeUtils) {
|
||||
this.treeUtils = treeUtils;
|
||||
}
|
||||
}
|
@ -1,38 +0,0 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.nifi.snmp.operations;
|
||||
|
||||
import org.apache.nifi.snmp.configuration.SNMPConfiguration;
|
||||
import org.apache.nifi.snmp.factory.CompositeSNMPFactory;
|
||||
import org.apache.nifi.snmp.factory.SNMPFactory;
|
||||
import org.snmp4j.Snmp;
|
||||
import org.snmp4j.Target;
|
||||
|
||||
public final class SNMPRequestHandlerFactory {
|
||||
|
||||
public static SNMPRequestHandler createStandardRequestHandler(final SNMPConfiguration configuration) {
|
||||
final SNMPFactory snmpFactory = new CompositeSNMPFactory();
|
||||
final Snmp snmpClient = snmpFactory.createSnmpManagerInstance(configuration);
|
||||
final Target target = snmpFactory.createTargetInstance(configuration);
|
||||
return new StandardSNMPRequestHandler(snmpClient, target);
|
||||
}
|
||||
|
||||
private SNMPRequestHandlerFactory() {
|
||||
// This should not be instantiated.
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,70 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.nifi.snmp.operations;
|
||||
|
||||
import org.apache.nifi.processor.exception.ProcessException;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.snmp4j.Snmp;
|
||||
import org.snmp4j.Target;
|
||||
import org.snmp4j.security.SecurityModels;
|
||||
import org.snmp4j.smi.Integer32;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
public class SNMPResourceHandler {
|
||||
|
||||
public static final String INVALID_FLOWFILE_EXCEPTION_MESSAGE = "Could not read the variable bindings from the " +
|
||||
"flowfile. Please, add the OIDs to set in separate properties. E.g. Property name: snmp$1.3.6.1.2.1.1.1.0 " +
|
||||
"Value: Example value. ";
|
||||
|
||||
public static final String REQUEST_TIMEOUT_EXCEPTION_TEMPLATE = "Request timed out. Please check if (1). the " +
|
||||
"agent host and port is correctly set, (2). the agent is running, (3). the agent SNMP version corresponds" +
|
||||
" with the processor's one, (4) the community string is correct and has %1$s access, (5) In case of SNMPv3" +
|
||||
" check if the user credentials are valid and the user in a group with %1$s access.";
|
||||
|
||||
private final Logger logger = LoggerFactory.getLogger(this.getClass());
|
||||
private final Snmp snmpManager;
|
||||
private final Target target;
|
||||
|
||||
public SNMPResourceHandler(final Snmp snmpManager, final Target target) {
|
||||
this.snmpManager = snmpManager;
|
||||
this.target = target;
|
||||
}
|
||||
|
||||
public Snmp getSnmpManager() {
|
||||
return snmpManager;
|
||||
}
|
||||
|
||||
public Target getTarget() {
|
||||
return target;
|
||||
}
|
||||
|
||||
public void close() {
|
||||
try {
|
||||
if (snmpManager.getUSM() != null) {
|
||||
snmpManager.getUSM().removeAllUsers();
|
||||
SecurityModels.getInstance().removeSecurityModel(new Integer32(snmpManager.getUSM().getID()));
|
||||
}
|
||||
snmpManager.close();
|
||||
} catch (IOException e) {
|
||||
final String errorMessage = "Could not close SNMP manager.";
|
||||
logger.error(errorMessage, e);
|
||||
throw new ProcessException(errorMessage);
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,77 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.nifi.snmp.operations;
|
||||
|
||||
import org.apache.nifi.flowfile.FlowFile;
|
||||
import org.apache.nifi.logging.ComponentLog;
|
||||
import org.apache.nifi.processor.ProcessSession;
|
||||
import org.apache.nifi.processor.ProcessSessionFactory;
|
||||
import org.apache.nifi.snmp.utils.SNMPUtils;
|
||||
import org.snmp4j.CommandResponder;
|
||||
import org.snmp4j.CommandResponderEvent;
|
||||
import org.snmp4j.PDU;
|
||||
import org.snmp4j.PDUv1;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import static org.apache.nifi.snmp.processors.ListenTrapSNMP.REL_FAILURE;
|
||||
import static org.apache.nifi.snmp.processors.ListenTrapSNMP.REL_SUCCESS;
|
||||
|
||||
public class SNMPTrapReceiver implements CommandResponder {
|
||||
|
||||
private final ProcessSessionFactory processSessionFactory;
|
||||
private final ComponentLog logger;
|
||||
|
||||
public SNMPTrapReceiver(final ProcessSessionFactory processSessionFactory, final ComponentLog logger) {
|
||||
this.processSessionFactory = processSessionFactory;
|
||||
this.logger = logger;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void processPdu(final CommandResponderEvent event) {
|
||||
final PDU pdu = event.getPDU();
|
||||
if (isValidTrapPdu(pdu)) {
|
||||
final ProcessSession processSession = processSessionFactory.createSession();
|
||||
final FlowFile flowFile = createFlowFile(processSession, pdu);
|
||||
processSession.getProvenanceReporter().create(flowFile, event.getPeerAddress() + "/" + pdu.getRequestID());
|
||||
if (pdu.getErrorStatus() == PDU.noError) {
|
||||
processSession.transfer(flowFile, REL_SUCCESS);
|
||||
} else {
|
||||
processSession.transfer(flowFile, REL_FAILURE);
|
||||
}
|
||||
processSession.commitAsync();
|
||||
} else {
|
||||
logger.error("Request timed out or parameters are incorrect.");
|
||||
}
|
||||
}
|
||||
|
||||
private FlowFile createFlowFile(final ProcessSession processSession, final PDU pdu) {
|
||||
FlowFile flowFile = processSession.create();
|
||||
final Map<String, String> attributes;
|
||||
if (pdu instanceof PDUv1) {
|
||||
attributes = SNMPUtils.getV1TrapPduAttributeMap((PDUv1) pdu);
|
||||
} else {
|
||||
attributes = SNMPUtils.getPduAttributeMap(pdu);
|
||||
}
|
||||
flowFile = processSession.putAllAttributes(flowFile, attributes);
|
||||
return flowFile;
|
||||
}
|
||||
|
||||
private boolean isValidTrapPdu(final PDU pdu) {
|
||||
return pdu != null && (pdu.getType() == PDU.V1TRAP || pdu.getType() == PDU.TRAP);
|
||||
}
|
||||
}
|
@ -0,0 +1,124 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.nifi.snmp.operations;
|
||||
|
||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
import com.fasterxml.jackson.core.type.TypeReference;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import org.apache.nifi.logging.ComponentLog;
|
||||
import org.apache.nifi.processor.ProcessSessionFactory;
|
||||
import org.apache.nifi.processor.exception.ProcessException;
|
||||
import org.apache.nifi.snmp.configuration.SNMPConfiguration;
|
||||
import org.apache.nifi.snmp.dto.UserDetails;
|
||||
import org.apache.nifi.snmp.factory.core.SNMPManagerFactory;
|
||||
import org.apache.nifi.snmp.utils.SNMPUtils;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.snmp4j.Snmp;
|
||||
import org.snmp4j.mp.MPv3;
|
||||
import org.snmp4j.mp.SnmpConstants;
|
||||
import org.snmp4j.security.SecurityModels;
|
||||
import org.snmp4j.security.SecurityProtocols;
|
||||
import org.snmp4j.security.USM;
|
||||
import org.snmp4j.security.UsmUser;
|
||||
import org.snmp4j.smi.Integer32;
|
||||
import org.snmp4j.smi.OctetString;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
import java.util.Scanner;
|
||||
|
||||
public class SNMPTrapReceiverHandler {
|
||||
|
||||
private static final Logger logger = LoggerFactory.getLogger(SNMPTrapReceiverHandler.class);
|
||||
|
||||
private final SNMPConfiguration configuration;
|
||||
private final String usmUsersFilePath;
|
||||
private Snmp snmpManager;
|
||||
private boolean isStarted;
|
||||
|
||||
public SNMPTrapReceiverHandler(final SNMPConfiguration configuration, final String usmUsersFilePath) {
|
||||
this.configuration = configuration;
|
||||
this.usmUsersFilePath = usmUsersFilePath;
|
||||
snmpManager = new SNMPManagerFactory().createSnmpManagerInstance(configuration);
|
||||
}
|
||||
|
||||
public void createTrapReceiver(final ProcessSessionFactory processSessionFactory, final ComponentLog logger) {
|
||||
addUsmUsers();
|
||||
SNMPTrapReceiver trapReceiver = new SNMPTrapReceiver(processSessionFactory, logger);
|
||||
snmpManager.addCommandResponder(trapReceiver);
|
||||
isStarted = true;
|
||||
}
|
||||
|
||||
public boolean isStarted() {
|
||||
return isStarted;
|
||||
}
|
||||
|
||||
public void close() {
|
||||
try {
|
||||
if (snmpManager.getUSM() != null) {
|
||||
snmpManager.getUSM().removeAllUsers();
|
||||
SecurityModels.getInstance().removeSecurityModel(new Integer32(snmpManager.getUSM().getID()));
|
||||
}
|
||||
snmpManager.close();
|
||||
isStarted = false;
|
||||
} catch (IOException e) {
|
||||
final String errorMessage = "Could not close SNMP manager.";
|
||||
logger.error(errorMessage, e);
|
||||
throw new ProcessException(errorMessage);
|
||||
}
|
||||
}
|
||||
|
||||
private void addUsmUsers() {
|
||||
if (configuration.getVersion() == SnmpConstants.version3) {
|
||||
USM usm = new USM(SecurityProtocols.getInstance(), new OctetString(MPv3.createLocalEngineID()), 0);
|
||||
SecurityModels.getInstance().addSecurityModel(usm);
|
||||
|
||||
try (Scanner scanner = new Scanner(new File(usmUsersFilePath))) {
|
||||
final String content = scanner.useDelimiter("\\Z").next();
|
||||
final ObjectMapper mapper = new ObjectMapper();
|
||||
final List<UserDetails> userDetails = mapper.readValue(content, new TypeReference<List<UserDetails>>() {
|
||||
});
|
||||
userDetails.stream()
|
||||
.map(this::convertToUsmUser)
|
||||
.forEach(user -> snmpManager.getUSM().addUser(user));
|
||||
|
||||
} catch (FileNotFoundException e) {
|
||||
throw new ProcessException("USM user file not found, please check the file path and file permissions.", e);
|
||||
} catch (JsonProcessingException e) {
|
||||
throw new ProcessException("Could not parse USM user file, please check the processor details for examples.", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private UsmUser convertToUsmUser(final UserDetails user) {
|
||||
return new UsmUser(
|
||||
new OctetString(user.getSecurityName()),
|
||||
SNMPUtils.getAuth(user.getAuthProtocol()),
|
||||
new OctetString(user.getAuthPassphrase()),
|
||||
SNMPUtils.getPriv(user.getPrivProtocol()),
|
||||
new OctetString(user.getPrivPassphrase())
|
||||
);
|
||||
}
|
||||
|
||||
// Visible for testing.
|
||||
void setSnmpManager(final Snmp snmpManager) {
|
||||
this.snmpManager = snmpManager;
|
||||
}
|
||||
}
|
@ -0,0 +1,75 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.nifi.snmp.operations;
|
||||
|
||||
import org.apache.nifi.logging.ComponentLog;
|
||||
import org.apache.nifi.snmp.configuration.V1TrapConfiguration;
|
||||
import org.apache.nifi.snmp.configuration.V2TrapConfiguration;
|
||||
import org.apache.nifi.snmp.factory.trap.V1TrapPDUFactory;
|
||||
import org.apache.nifi.snmp.factory.trap.V2TrapPDUFactory;
|
||||
import org.apache.nifi.snmp.utils.SNMPUtils;
|
||||
import org.snmp4j.PDU;
|
||||
import org.snmp4j.Snmp;
|
||||
import org.snmp4j.Target;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.time.Instant;
|
||||
import java.util.Map;
|
||||
|
||||
public class SendTrapSNMPHandler {
|
||||
private final SNMPResourceHandler snmpResourceHandler;
|
||||
private final ComponentLog logger;
|
||||
private final V1TrapPDUFactory v1TrapPDUFactory;
|
||||
private final V2TrapPDUFactory v2TrapPDUFactory;
|
||||
|
||||
public SendTrapSNMPHandler(final SNMPResourceHandler snmpResourceHandler, final Instant startTime, final ComponentLog logger) {
|
||||
this.snmpResourceHandler = snmpResourceHandler;
|
||||
this.logger = logger;
|
||||
v1TrapPDUFactory = createV1TrapPduFactory(startTime);
|
||||
v2TrapPDUFactory = createV2TrapPduFactory(startTime);
|
||||
}
|
||||
|
||||
public void sendTrap(final Map<String, String> flowFileAttributes, final V1TrapConfiguration trapConfiguration) throws IOException {
|
||||
final PDU pdu = v1TrapPDUFactory.get(trapConfiguration);
|
||||
sendTrap(flowFileAttributes, pdu);
|
||||
}
|
||||
|
||||
public void sendTrap(final Map<String, String> flowFileAttributes, final V2TrapConfiguration trapConfiguration) throws IOException {
|
||||
final PDU pdu = v2TrapPDUFactory.get(trapConfiguration);
|
||||
sendTrap(flowFileAttributes, pdu);
|
||||
}
|
||||
|
||||
private void sendTrap(Map<String, String> flowFileAttributes, PDU pdu) throws IOException {
|
||||
final Target target = snmpResourceHandler.getTarget();
|
||||
final Snmp snmpManager = snmpResourceHandler.getSnmpManager();
|
||||
|
||||
final boolean isAnyVariableAdded = SNMPUtils.addVariables(pdu, flowFileAttributes);
|
||||
if (!isAnyVariableAdded) {
|
||||
logger.debug("No optional SNMP specific variables found in flowfile.");
|
||||
}
|
||||
|
||||
snmpManager.send(pdu, target);
|
||||
}
|
||||
|
||||
V1TrapPDUFactory createV1TrapPduFactory(final Instant startTime) {
|
||||
return new V1TrapPDUFactory(snmpResourceHandler.getTarget(), startTime);
|
||||
}
|
||||
|
||||
V2TrapPDUFactory createV2TrapPduFactory(final Instant startTime) {
|
||||
return new V2TrapPDUFactory(snmpResourceHandler.getTarget(), startTime);
|
||||
}
|
||||
}
|
@ -0,0 +1,66 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.nifi.snmp.operations;
|
||||
|
||||
import org.apache.nifi.snmp.dto.SNMPSingleResponse;
|
||||
import org.apache.nifi.snmp.exception.RequestTimeoutException;
|
||||
import org.apache.nifi.snmp.utils.SNMPUtils;
|
||||
import org.snmp4j.PDU;
|
||||
import org.snmp4j.Snmp;
|
||||
import org.snmp4j.Target;
|
||||
import org.snmp4j.event.ResponseEvent;
|
||||
import org.snmp4j.util.DefaultPDUFactory;
|
||||
import org.snmp4j.util.PDUFactory;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
|
||||
import static org.apache.nifi.snmp.operations.SNMPResourceHandler.REQUEST_TIMEOUT_EXCEPTION_TEMPLATE;
|
||||
|
||||
public class SetSNMPHandler {
|
||||
private static PDUFactory setPduFactory = new DefaultPDUFactory(PDU.SET);
|
||||
|
||||
private final SNMPResourceHandler snmpResourceHandler;
|
||||
|
||||
public SetSNMPHandler(final SNMPResourceHandler snmpResourceHandler) {
|
||||
this.snmpResourceHandler = snmpResourceHandler;
|
||||
}
|
||||
|
||||
public Optional<SNMPSingleResponse> set(final Map<String, String> flowFileAttributes) throws IOException {
|
||||
Target target = snmpResourceHandler.getTarget();
|
||||
Snmp snmpManager = snmpResourceHandler.getSnmpManager();
|
||||
|
||||
final PDU pdu = setPduFactory.createPDU(target);
|
||||
final boolean isAnySnmpVariableInFlowFile = SNMPUtils.addVariables(pdu, flowFileAttributes);
|
||||
if (isAnySnmpVariableInFlowFile) {
|
||||
final ResponseEvent response = snmpManager.set(pdu, target);
|
||||
final PDU responsePdu = response.getResponse();
|
||||
if (responsePdu == null) {
|
||||
throw new RequestTimeoutException(String.format(REQUEST_TIMEOUT_EXCEPTION_TEMPLATE, "write"));
|
||||
}
|
||||
return Optional.of(new SNMPSingleResponse(target, responsePdu));
|
||||
} else {
|
||||
return Optional.empty();
|
||||
}
|
||||
}
|
||||
|
||||
// visible for testing
|
||||
static void setSetPduFactory(final PDUFactory setPduFactory) {
|
||||
SetSNMPHandler.setPduFactory = setPduFactory;
|
||||
}
|
||||
}
|
@ -1,148 +0,0 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.nifi.snmp.operations;
|
||||
|
||||
import org.apache.nifi.flowfile.FlowFile;
|
||||
import org.apache.nifi.snmp.dto.SNMPSingleResponse;
|
||||
import org.apache.nifi.snmp.dto.SNMPTreeResponse;
|
||||
import org.apache.nifi.snmp.exception.CloseSNMPClientException;
|
||||
import org.apache.nifi.snmp.exception.InvalidFlowFileException;
|
||||
import org.apache.nifi.snmp.exception.RequestTimeoutException;
|
||||
import org.apache.nifi.snmp.exception.SNMPWalkException;
|
||||
import org.apache.nifi.snmp.utils.SNMPUtils;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.snmp4j.PDU;
|
||||
import org.snmp4j.Snmp;
|
||||
import org.snmp4j.Target;
|
||||
import org.snmp4j.event.ResponseEvent;
|
||||
import org.snmp4j.security.SecurityModels;
|
||||
import org.snmp4j.smi.Integer32;
|
||||
import org.snmp4j.smi.OID;
|
||||
import org.snmp4j.smi.VariableBinding;
|
||||
import org.snmp4j.util.DefaultPDUFactory;
|
||||
import org.snmp4j.util.PDUFactory;
|
||||
import org.snmp4j.util.TreeEvent;
|
||||
import org.snmp4j.util.TreeUtils;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
|
||||
final class StandardSNMPRequestHandler implements SNMPRequestHandler {
|
||||
|
||||
private static final Logger logger = LoggerFactory.getLogger(StandardSNMPRequestHandler.class);
|
||||
private static final PDUFactory getPduFactory = new DefaultPDUFactory(PDU.GET);
|
||||
private static final PDUFactory setPduFactory = new DefaultPDUFactory(PDU.SET);
|
||||
private final Snmp snmpManager;
|
||||
private final Target target;
|
||||
|
||||
StandardSNMPRequestHandler(final Snmp snmpManager, final Target target) {
|
||||
this.snmpManager = snmpManager;
|
||||
this.target = target;
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct the PDU to perform the SNMP Get request and returns
|
||||
* the result in order to create the flow file.
|
||||
*
|
||||
* @return {@link ResponseEvent}
|
||||
*/
|
||||
public SNMPSingleResponse get(final String oid) throws IOException {
|
||||
final PDU pdu = getPduFactory.createPDU(target);
|
||||
pdu.add(new VariableBinding(new OID(oid)));
|
||||
final ResponseEvent response = snmpManager.get(pdu, target);
|
||||
final PDU responsePdu = response.getResponse();
|
||||
if (responsePdu == null) {
|
||||
throw new RequestTimeoutException("Request timed out. Please check if (1). the agent host and port is correctly set, " +
|
||||
"(2). the agent is running, (3). the agent SNMP version corresponds with the processor's one, (4) the " +
|
||||
"community string is correct and has read access, (5) In case of SNMPv3 check if the user credentials " +
|
||||
"are valid and the user in a group with read access.");
|
||||
}
|
||||
return new SNMPSingleResponse(target, responsePdu);
|
||||
}
|
||||
|
||||
/**
|
||||
* Perform a SNMP walk and returns the list of {@link TreeEvent}
|
||||
*
|
||||
* @return the list of {@link TreeEvent}
|
||||
*/
|
||||
public SNMPTreeResponse walk(final String oid) {
|
||||
final TreeUtils treeUtils = new TreeUtils(snmpManager, getPduFactory);
|
||||
final List<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);
|
||||
}
|
||||
}
|
||||
}
|
@ -19,7 +19,6 @@ package org.apache.nifi.snmp.processors;
|
||||
import org.apache.nifi.annotation.behavior.RequiresInstanceClassLoading;
|
||||
import org.apache.nifi.annotation.lifecycle.OnScheduled;
|
||||
import org.apache.nifi.annotation.lifecycle.OnStopped;
|
||||
import org.apache.nifi.components.AllowableValue;
|
||||
import org.apache.nifi.components.PropertyDescriptor;
|
||||
import org.apache.nifi.flowfile.FlowFile;
|
||||
import org.apache.nifi.processor.AbstractProcessor;
|
||||
@ -27,21 +26,20 @@ import org.apache.nifi.processor.ProcessContext;
|
||||
import org.apache.nifi.processor.ProcessSession;
|
||||
import org.apache.nifi.processor.Relationship;
|
||||
import org.apache.nifi.processor.util.StandardValidators;
|
||||
import org.apache.nifi.reporting.InitializationException;
|
||||
import org.apache.nifi.snmp.configuration.SNMPConfiguration;
|
||||
import org.apache.nifi.snmp.configuration.SNMPConfigurationBuilder;
|
||||
import org.apache.nifi.snmp.dto.ErrorStatus;
|
||||
import org.apache.nifi.snmp.dto.SNMPResponseStatus;
|
||||
import org.apache.nifi.snmp.dto.SNMPSingleResponse;
|
||||
import org.apache.nifi.snmp.dto.SNMPValue;
|
||||
import org.apache.nifi.snmp.exception.SNMPException;
|
||||
import org.apache.nifi.snmp.factory.core.SNMPFactoryProvider;
|
||||
import org.apache.nifi.snmp.logging.SLF4JLogFactory;
|
||||
import org.apache.nifi.snmp.operations.SNMPRequestHandler;
|
||||
import org.apache.nifi.snmp.operations.SNMPRequestHandlerFactory;
|
||||
import org.apache.nifi.snmp.operations.SNMPResourceHandler;
|
||||
import org.apache.nifi.snmp.processors.properties.BasicProperties;
|
||||
import org.apache.nifi.snmp.processors.properties.V3SecurityProperties;
|
||||
import org.apache.nifi.snmp.utils.SNMPUtils;
|
||||
import org.snmp4j.log.LogFactory;
|
||||
import org.snmp4j.mp.SnmpConstants;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
|
||||
/**
|
||||
@ -55,49 +53,7 @@ abstract class AbstractSNMPProcessor extends AbstractProcessor {
|
||||
LogFactory.setLogFactory(new SLF4JLogFactory());
|
||||
}
|
||||
|
||||
private static final String SHA_2_ALGORITHM = "Provides authentication based on the HMAC-SHA-2 algorithm.";
|
||||
private static final String NO_SUCH_OBJECT = "noSuchObject";
|
||||
// SNMP versions
|
||||
public static final AllowableValue SNMP_V1 = new AllowableValue("SNMPv1", "v1", "SNMP version 1");
|
||||
public static final AllowableValue SNMP_V2C = new AllowableValue("SNMPv2c", "v2c", "SNMP version 2c");
|
||||
public static final AllowableValue SNMP_V3 = new AllowableValue("SNMPv3", "v3", "SNMP version 3 with improved security");
|
||||
|
||||
// SNMPv3 security levels
|
||||
public static final AllowableValue NO_AUTH_NO_PRIV = new AllowableValue("noAuthNoPriv", "noAuthNoPriv",
|
||||
"No authentication or encryption.");
|
||||
public static final AllowableValue AUTH_NO_PRIV = new AllowableValue("authNoPriv", "authNoPriv",
|
||||
"Authentication without encryption.");
|
||||
public static final AllowableValue AUTH_PRIV = new AllowableValue("authPriv", "authPriv",
|
||||
"Authentication and encryption.");
|
||||
|
||||
// SNMPv3 authentication protocols
|
||||
public static final AllowableValue MD5 = new AllowableValue("MD5", "MD5",
|
||||
"Provides authentication based on the HMAC-MD5 algorithm.");
|
||||
public static final AllowableValue SHA = new AllowableValue("SHA", "SHA",
|
||||
"Provides authentication based on the HMAC-SHA algorithm.");
|
||||
public static final AllowableValue HMAC128SHA224 = new AllowableValue("HMAC128SHA224", "SHA224",
|
||||
SHA_2_ALGORITHM);
|
||||
public static final AllowableValue HMAC192SHA256 = new AllowableValue("HMAC192SHA256", "SHA256",
|
||||
SHA_2_ALGORITHM);
|
||||
public static final AllowableValue HMAC256SHA384 = new AllowableValue("HMAC256SHA384", "SHA384",
|
||||
SHA_2_ALGORITHM);
|
||||
public static final AllowableValue HMAC384SHA512 = new AllowableValue("HMAC384SHA512", "SHA512",
|
||||
SHA_2_ALGORITHM);
|
||||
|
||||
// SNMPv3 encryption
|
||||
public static final AllowableValue DES = new AllowableValue("DES", "DES",
|
||||
"Symmetric-key algorithm for the encryption of digital data. DES has been considered insecure" +
|
||||
"because of the feasilibity of brute-force attacks. We recommend using the AES encryption protocol.");
|
||||
public static final AllowableValue DES3 = new AllowableValue("3DES", "3DES",
|
||||
"Symmetric-key block cipher, which applies the DES cipher algorithm three times to each data block." +
|
||||
" 3DES has been considered insecure has been deprecated by NIST in 2017. We recommend using the AES encryption protocol.");
|
||||
|
||||
private static final String AES_DESCRIPTION = "AES is a symmetric algorithm which uses the same 128, 192, or 256 bit" +
|
||||
" key for both encryption and decryption (the security of an AES system increases exponentially with key length).";
|
||||
|
||||
public static final AllowableValue AES128 = new AllowableValue("AES128", "AES128", AES_DESCRIPTION);
|
||||
public static final AllowableValue AES192 = new AllowableValue("AES192", "AES192", AES_DESCRIPTION);
|
||||
public static final AllowableValue AES256 = new AllowableValue("AES256", "AES256", AES_DESCRIPTION);
|
||||
|
||||
public static final PropertyDescriptor AGENT_HOST = new PropertyDescriptor.Builder()
|
||||
.name("snmp-hostname")
|
||||
@ -117,136 +73,31 @@ abstract class AbstractSNMPProcessor extends AbstractProcessor {
|
||||
.addValidator(StandardValidators.PORT_VALIDATOR)
|
||||
.build();
|
||||
|
||||
public static final PropertyDescriptor SNMP_VERSION = new PropertyDescriptor.Builder()
|
||||
.name("snmp-version")
|
||||
.displayName("SNMP Version")
|
||||
.description("Three significant versions of SNMP have been developed and deployed. " +
|
||||
"SNMPv1 is the original version of the protocol. More recent versions, " +
|
||||
"SNMPv2c and SNMPv3, feature improvements in performance, flexibility and security.")
|
||||
.required(true)
|
||||
.allowableValues(SNMP_V1, SNMP_V2C, SNMP_V3)
|
||||
.defaultValue(SNMP_V1.getValue())
|
||||
.build();
|
||||
|
||||
public static final PropertyDescriptor SNMP_COMMUNITY = new PropertyDescriptor.Builder()
|
||||
.name("snmp-community")
|
||||
.displayName("SNMP Community")
|
||||
.description("SNMPv1 and SNMPv2 use communities to establish trust between managers and agents." +
|
||||
" Most agents support three community names, one each for read-only, read-write and trap." +
|
||||
" These three community strings control different types of activities. The read-only community" +
|
||||
" applies to get requests. The read-write community string applies to set requests. The trap" +
|
||||
" community string applies to receipt of traps.")
|
||||
.required(true)
|
||||
.sensitive(true)
|
||||
.defaultValue("public")
|
||||
.addValidator(StandardValidators.NON_EMPTY_VALIDATOR)
|
||||
.dependsOn(SNMP_VERSION, SNMP_V1, SNMP_V2C)
|
||||
.build();
|
||||
|
||||
public static final PropertyDescriptor SNMP_SECURITY_LEVEL = new PropertyDescriptor.Builder()
|
||||
.name("snmp-security-level")
|
||||
.displayName("SNMP Security Level")
|
||||
.description("SNMP version 3 provides extra security with User Based Security Model (USM). The three levels of security is " +
|
||||
"1. Communication without authentication and encryption (NoAuthNoPriv). " +
|
||||
"2. Communication with authentication and without encryption (AuthNoPriv). " +
|
||||
"3. Communication with authentication and encryption (AuthPriv).")
|
||||
.required(true)
|
||||
.allowableValues(NO_AUTH_NO_PRIV, AUTH_NO_PRIV, AUTH_PRIV)
|
||||
.defaultValue(NO_AUTH_NO_PRIV.getValue())
|
||||
.dependsOn(SNMP_VERSION, SNMP_V3)
|
||||
.build();
|
||||
|
||||
public static final PropertyDescriptor SNMP_SECURITY_NAME = new PropertyDescriptor.Builder()
|
||||
.name("snmp-security-name")
|
||||
.displayName("SNMP Security Name")
|
||||
.description("User name used for SNMP v3 Authentication.")
|
||||
.required(true)
|
||||
.addValidator(StandardValidators.NON_EMPTY_VALIDATOR)
|
||||
.dependsOn(SNMP_VERSION, SNMP_V3)
|
||||
.build();
|
||||
|
||||
public static final PropertyDescriptor SNMP_AUTH_PROTOCOL = new PropertyDescriptor.Builder()
|
||||
.name("snmp-authentication-protocol")
|
||||
.displayName("SNMP Authentication Protocol")
|
||||
.description("Hash based authentication protocol for secure authentication.")
|
||||
.required(true)
|
||||
.allowableValues(MD5, SHA, HMAC128SHA224, HMAC192SHA256, HMAC256SHA384, HMAC384SHA512)
|
||||
.dependsOn(SNMP_SECURITY_LEVEL, AUTH_NO_PRIV, AUTH_PRIV)
|
||||
.build();
|
||||
|
||||
public static final PropertyDescriptor SNMP_AUTH_PASSWORD = new PropertyDescriptor.Builder()
|
||||
.name("snmp-authentication-passphrase")
|
||||
.displayName("SNMP Authentication Passphrase")
|
||||
.description("Passphrase used for SNMP authentication protocol.")
|
||||
.required(true)
|
||||
.addValidator(StandardValidators.NON_EMPTY_VALIDATOR)
|
||||
.sensitive(true)
|
||||
.dependsOn(SNMP_SECURITY_LEVEL, AUTH_NO_PRIV, AUTH_PRIV)
|
||||
.build();
|
||||
|
||||
public static final PropertyDescriptor SNMP_PRIVACY_PROTOCOL = new PropertyDescriptor.Builder()
|
||||
.name("snmp-private-protocol")
|
||||
.displayName("SNMP Privacy Protocol")
|
||||
.description("Privacy allows for encryption of SNMP v3 messages to ensure confidentiality of data.")
|
||||
.required(true)
|
||||
.allowableValues(DES, DES3, AES128, AES192, AES256)
|
||||
.dependsOn(SNMP_SECURITY_LEVEL, AUTH_PRIV)
|
||||
.build();
|
||||
|
||||
public static final PropertyDescriptor SNMP_PRIVACY_PASSWORD = new PropertyDescriptor.Builder()
|
||||
.name("snmp-private-protocol-passphrase")
|
||||
.displayName("SNMP Privacy Passphrase")
|
||||
.description("Passphrase used for SNMP privacy protocol.")
|
||||
.required(true)
|
||||
.addValidator(StandardValidators.NON_EMPTY_VALIDATOR)
|
||||
.sensitive(true)
|
||||
.dependsOn(SNMP_SECURITY_LEVEL, AUTH_PRIV)
|
||||
.build();
|
||||
|
||||
public static final PropertyDescriptor SNMP_RETRIES = new PropertyDescriptor.Builder()
|
||||
.name("snmp-retries")
|
||||
.displayName("Number of Retries")
|
||||
.description("Set the number of retries when requesting the SNMP Agent.")
|
||||
.required(false)
|
||||
.defaultValue("0")
|
||||
.addValidator(StandardValidators.NON_NEGATIVE_INTEGER_VALIDATOR)
|
||||
.build();
|
||||
|
||||
public static final PropertyDescriptor SNMP_TIMEOUT = new PropertyDescriptor.Builder()
|
||||
.name("snmp-timeout")
|
||||
.displayName("Timeout (ms)")
|
||||
.description("Set the timeout (in milliseconds) when requesting the SNMP Agent.")
|
||||
.required(false)
|
||||
.defaultValue("5000")
|
||||
.addValidator(StandardValidators.NON_NEGATIVE_INTEGER_VALIDATOR)
|
||||
.build();
|
||||
|
||||
|
||||
protected volatile SNMPRequestHandler snmpRequestHandler;
|
||||
protected volatile SNMPResourceHandler snmpResourceHandler;
|
||||
|
||||
@OnScheduled
|
||||
public void initSnmpManager(final ProcessContext context) throws InitializationException {
|
||||
final int version = SNMPUtils.getVersion(context.getProperty(SNMP_VERSION).getValue());
|
||||
public void initSnmpManager(final ProcessContext context) {
|
||||
final int version = SNMPUtils.getVersion(context.getProperty(BasicProperties.SNMP_VERSION).getValue());
|
||||
final SNMPConfiguration configuration;
|
||||
try {
|
||||
configuration = new SNMPConfigurationBuilder()
|
||||
.setAgentHost(context.getProperty(AGENT_HOST).getValue())
|
||||
.setAgentPort(context.getProperty(AGENT_PORT).toString())
|
||||
.setRetries(context.getProperty(SNMP_RETRIES).asInteger())
|
||||
.setTimeout(context.getProperty(SNMP_TIMEOUT).asInteger())
|
||||
.setVersion(version)
|
||||
.setAuthProtocol(context.getProperty(SNMP_AUTH_PROTOCOL).getValue())
|
||||
.setAuthPassphrase(context.getProperty(SNMP_AUTH_PASSWORD).getValue())
|
||||
.setPrivacyProtocol(context.getProperty(SNMP_PRIVACY_PROTOCOL).getValue())
|
||||
.setPrivacyPassphrase(context.getProperty(SNMP_PRIVACY_PASSWORD).getValue())
|
||||
.setSecurityName(context.getProperty(SNMP_SECURITY_NAME).getValue())
|
||||
.setSecurityLevel(context.getProperty(SNMP_SECURITY_LEVEL).getValue())
|
||||
.setCommunityString(context.getProperty(SNMP_COMMUNITY).getValue())
|
||||
.build();
|
||||
} catch (IllegalStateException e) {
|
||||
throw new InitializationException(e);
|
||||
}
|
||||
snmpRequestHandler = SNMPRequestHandlerFactory.createStandardRequestHandler(configuration);
|
||||
final String targetHost = getTargetHost(context);
|
||||
final String targetPort = getTargetPort(context);
|
||||
|
||||
configuration = SNMPConfiguration.builder()
|
||||
.setTargetHost(targetHost)
|
||||
.setTargetPort(targetPort)
|
||||
.setRetries(context.getProperty(BasicProperties.SNMP_RETRIES).asInteger())
|
||||
.setTimeoutInMs(context.getProperty(BasicProperties.SNMP_TIMEOUT).asInteger())
|
||||
.setVersion(version)
|
||||
.setAuthProtocol(context.getProperty(V3SecurityProperties.SNMP_AUTH_PROTOCOL).getValue())
|
||||
.setAuthPassphrase(context.getProperty(V3SecurityProperties.SNMP_AUTH_PASSWORD).getValue())
|
||||
.setPrivacyProtocol(context.getProperty(V3SecurityProperties.SNMP_PRIVACY_PROTOCOL).getValue())
|
||||
.setPrivacyPassphrase(context.getProperty(V3SecurityProperties.SNMP_PRIVACY_PASSWORD).getValue())
|
||||
.setSecurityName(context.getProperty(V3SecurityProperties.SNMP_SECURITY_NAME).getValue())
|
||||
.setSecurityLevel(context.getProperty(V3SecurityProperties.SNMP_SECURITY_LEVEL).getValue())
|
||||
.setCommunityString(context.getProperty(BasicProperties.SNMP_COMMUNITY).getValue())
|
||||
.build();
|
||||
|
||||
snmpResourceHandler = SNMPFactoryProvider.getFactory(version).createSNMPResourceHandler(configuration);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -254,61 +105,61 @@ abstract class AbstractSNMPProcessor extends AbstractProcessor {
|
||||
*/
|
||||
@OnStopped
|
||||
public void close() {
|
||||
if (snmpRequestHandler != null) {
|
||||
snmpRequestHandler.close();
|
||||
snmpRequestHandler = null;
|
||||
if (snmpResourceHandler != null) {
|
||||
snmpResourceHandler.close();
|
||||
snmpResourceHandler = null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Method to add attribute in flow file
|
||||
*
|
||||
* @param key attribute key
|
||||
* @param value attribute value
|
||||
* @param flowFile flow file to update
|
||||
* @param processSession session
|
||||
* @return updated flow file
|
||||
*/
|
||||
protected FlowFile addAttribute(final String key, final String value, FlowFile flowFile, final ProcessSession processSession) {
|
||||
final Map<String, String> attributes = new HashMap<>();
|
||||
attributes.put(key, value);
|
||||
flowFile = processSession.putAllAttributes(flowFile, attributes);
|
||||
return flowFile;
|
||||
protected void handleResponse(final ProcessContext context, final ProcessSession processSession, final FlowFile flowFile, final SNMPSingleResponse response,
|
||||
final Relationship success, final Relationship failure, final String provenanceAddress) {
|
||||
final SNMPResponseStatus snmpResponseStatus = processResponse(response);
|
||||
processSession.putAllAttributes(flowFile, response.getAttributes());
|
||||
if (snmpResponseStatus.getErrorStatus() == ErrorStatus.FAILURE) {
|
||||
getLogger().error("SNMP request failed, response error: " + snmpResponseStatus.getErrorMessage());
|
||||
processSession.getProvenanceReporter().modifyAttributes(flowFile, response.getTargetAddress() + provenanceAddress);
|
||||
processSession.transfer(flowFile, failure);
|
||||
context.yield();
|
||||
} else {
|
||||
processSession.getProvenanceReporter().modifyAttributes(flowFile, response.getTargetAddress() + provenanceAddress);
|
||||
processSession.transfer(flowFile, success);
|
||||
}
|
||||
}
|
||||
|
||||
protected void processResponse(final ProcessSession processSession, FlowFile flowFile, final SNMPSingleResponse response,
|
||||
final String provenanceAddress, final Relationship success) {
|
||||
protected SNMPResponseStatus processResponse(final SNMPSingleResponse response) {
|
||||
if (response.isValid()) {
|
||||
if (response.isReportPdu()) {
|
||||
final String oid = response.getVariableBindings().get(0).getOid();
|
||||
final Optional<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));
|
||||
return new SNMPResponseStatus(String.format("Report-PDU returned, but no error message found. " +
|
||||
"Please, check the OID %s in an online OID repository.", oid), ErrorStatus.FAILURE);
|
||||
}
|
||||
throw new SNMPException("SNMPRequest failed, Report-PDU returned. " + reportPduErrorMessage.get());
|
||||
return new SNMPResponseStatus("Report-PDU returned. " + reportPduErrorMessage.get(), ErrorStatus.FAILURE);
|
||||
}
|
||||
checkV2cV3VariableBindings(response);
|
||||
flowFile = processSession.putAllAttributes(flowFile, response.getAttributes());
|
||||
processSession.transfer(flowFile, success);
|
||||
processSession.getProvenanceReporter().receive(flowFile, provenanceAddress);
|
||||
return checkV2cV3VariableBindings(response);
|
||||
} else {
|
||||
final String error = response.getErrorStatusText();
|
||||
throw new SNMPException("SNMP request failed, response error: " + error);
|
||||
final String errorMessage = response.getErrorStatusText();
|
||||
return new SNMPResponseStatus(errorMessage, ErrorStatus.FAILURE);
|
||||
}
|
||||
}
|
||||
|
||||
private void checkV2cV3VariableBindings(SNMPSingleResponse response) {
|
||||
if (response.getVersion() != SnmpConstants.version1) {
|
||||
private SNMPResponseStatus checkV2cV3VariableBindings(SNMPSingleResponse response) {
|
||||
if (response.getVersion() == SnmpConstants.version2c || response.getVersion() == SnmpConstants.version3) {
|
||||
final Optional<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.");
|
||||
return new SNMPResponseStatus("OID not found.", ErrorStatus.FAILURE);
|
||||
}
|
||||
} else {
|
||||
throw new SNMPException("Empty SNMP response: no variable binding found.");
|
||||
return new SNMPResponseStatus("Empty SNMP response: no variable binding found.", ErrorStatus.FAILURE);
|
||||
}
|
||||
}
|
||||
return new SNMPResponseStatus("Successful SNMP Response", ErrorStatus.SUCCESS);
|
||||
}
|
||||
|
||||
protected abstract String getTargetHost(ProcessContext processContext);
|
||||
|
||||
protected abstract String getTargetPort(ProcessContext processContext);
|
||||
}
|
||||
|
@ -22,6 +22,7 @@ import org.apache.nifi.annotation.behavior.WritesAttribute;
|
||||
import org.apache.nifi.annotation.behavior.WritesAttributes;
|
||||
import org.apache.nifi.annotation.documentation.CapabilityDescription;
|
||||
import org.apache.nifi.annotation.documentation.Tags;
|
||||
import org.apache.nifi.annotation.lifecycle.OnScheduled;
|
||||
import org.apache.nifi.components.AllowableValue;
|
||||
import org.apache.nifi.components.PropertyDescriptor;
|
||||
import org.apache.nifi.flowfile.FlowFile;
|
||||
@ -31,8 +32,10 @@ import org.apache.nifi.processor.Relationship;
|
||||
import org.apache.nifi.processor.util.StandardValidators;
|
||||
import org.apache.nifi.snmp.dto.SNMPSingleResponse;
|
||||
import org.apache.nifi.snmp.dto.SNMPTreeResponse;
|
||||
import org.apache.nifi.snmp.exception.SNMPException;
|
||||
import org.apache.nifi.snmp.exception.SNMPWalkException;
|
||||
import org.apache.nifi.snmp.operations.GetSNMPHandler;
|
||||
import org.apache.nifi.snmp.processors.properties.BasicProperties;
|
||||
import org.apache.nifi.snmp.processors.properties.V3SecurityProperties;
|
||||
import org.apache.nifi.snmp.utils.SNMPUtils;
|
||||
import org.apache.nifi.snmp.validators.OIDValidator;
|
||||
|
||||
@ -41,16 +44,20 @@ import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* Retrieving data from configured SNMP agent which, upon each invocation of
|
||||
* {@link #onTrigger(ProcessContext, ProcessSession)} method, will construct a
|
||||
* {@link FlowFile} containing in its properties the information retrieved.
|
||||
* Performs an SNMP Get operation based on processor or incoming FlowFile attributes.
|
||||
* Upon each invocation of {@link #onTrigger(ProcessContext, ProcessSession)}
|
||||
* method, in case of a valid incoming FlowFile, it will inspect the attributes of
|
||||
* the FlowFile and look for attributes with name formatted as "snmp$OID" to set the
|
||||
* attribute value to this OID.
|
||||
* The output {@link FlowFile} won't have any content.
|
||||
*/
|
||||
@Tags({"snmp", "get", "oid", "walk"})
|
||||
@InputRequirement(Requirement.INPUT_FORBIDDEN)
|
||||
@InputRequirement(Requirement.INPUT_ALLOWED)
|
||||
@CapabilityDescription("Retrieves information from SNMP Agent with SNMP Get request and outputs a FlowFile with information" +
|
||||
" in attributes and without any content")
|
||||
@WritesAttributes({
|
||||
@ -74,11 +81,12 @@ public class GetSNMP extends AbstractSNMPProcessor {
|
||||
"A manager-to-agent request to retrieve the value of multiple variables. Snmp WALK also traverses all subnodes " +
|
||||
"under the specified OID.");
|
||||
|
||||
// OID to request (if walk, it is the root ID of the request).
|
||||
public static final PropertyDescriptor OID = new PropertyDescriptor.Builder()
|
||||
.name("snmp-oid")
|
||||
.displayName("OID")
|
||||
.description("Each OID (object identifier) identifies a variable that can be read or set via SNMP.")
|
||||
.description("Each OID (object identifier) identifies a variable that can be read or set via SNMP." +
|
||||
" This value is not taken into account for an input flowfile and will be omitted. Can be set to empty" +
|
||||
"string when the OIDs are provided through flowfile.")
|
||||
.required(true)
|
||||
.addValidator(new OIDValidator())
|
||||
.build();
|
||||
@ -95,7 +103,8 @@ public class GetSNMP extends AbstractSNMPProcessor {
|
||||
public static final PropertyDescriptor TEXTUAL_OID = new PropertyDescriptor.Builder()
|
||||
.name("snmp-textual-oid")
|
||||
.displayName("Textual OID")
|
||||
.description("The textual OID to request.")
|
||||
.description("The textual form of the numeric OID to request. This property is user defined, not processed and appended to " +
|
||||
"the outgoing flowfile.")
|
||||
.required(false)
|
||||
.addValidator(StandardValidators.NON_BLANK_VALIDATOR)
|
||||
.defaultValue(null)
|
||||
@ -114,16 +123,16 @@ public class GetSNMP extends AbstractSNMPProcessor {
|
||||
protected static final List<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,
|
||||
BasicProperties.SNMP_VERSION,
|
||||
BasicProperties.SNMP_COMMUNITY,
|
||||
V3SecurityProperties.SNMP_SECURITY_LEVEL,
|
||||
V3SecurityProperties.SNMP_SECURITY_NAME,
|
||||
V3SecurityProperties.SNMP_AUTH_PROTOCOL,
|
||||
V3SecurityProperties.SNMP_AUTH_PASSWORD,
|
||||
V3SecurityProperties.SNMP_PRIVACY_PROTOCOL,
|
||||
V3SecurityProperties.SNMP_PRIVACY_PASSWORD,
|
||||
BasicProperties.SNMP_RETRIES,
|
||||
BasicProperties.SNMP_TIMEOUT,
|
||||
OID,
|
||||
TEXTUAL_OID,
|
||||
SNMP_STRATEGY
|
||||
@ -134,54 +143,100 @@ public class GetSNMP extends AbstractSNMPProcessor {
|
||||
REL_FAILURE
|
||||
)));
|
||||
|
||||
private volatile GetSNMPHandler snmpHandler;
|
||||
|
||||
@OnScheduled
|
||||
public void init(final ProcessContext context) {
|
||||
initSnmpManager(context);
|
||||
snmpHandler = new GetSNMPHandler(snmpResourceHandler);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTrigger(final ProcessContext context, final ProcessSession processSession) {
|
||||
final SNMPStrategy snmpStrategy = SNMPStrategy.valueOf(context.getProperty(SNMP_STRATEGY).getValue());
|
||||
final String oid = context.getProperty(OID).getValue();
|
||||
final FlowFile flowfile = processSession.get();
|
||||
|
||||
if (SNMPStrategy.GET == snmpStrategy) {
|
||||
performSnmpGet(context, processSession, oid);
|
||||
performSnmpGet(context, processSession, oid, flowfile);
|
||||
} else if (SNMPStrategy.WALK == snmpStrategy) {
|
||||
performSnmpWalk(context, processSession, oid);
|
||||
performSnmpWalk(context, processSession, oid, flowfile);
|
||||
}
|
||||
}
|
||||
|
||||
private void performSnmpWalk(final ProcessContext context, final ProcessSession processSession, final String oid) {
|
||||
void performSnmpWalk(final ProcessContext context, final ProcessSession processSession, final String oid,
|
||||
final FlowFile flowFile) {
|
||||
try {
|
||||
final SNMPTreeResponse response = snmpRequestHandler.walk(oid);
|
||||
response.logErrors(getLogger());
|
||||
FlowFile flowFile = createFlowFileWithTreeEventProperties(response, processSession);
|
||||
processSession.getProvenanceReporter().receive(flowFile, response.getTargetAddress() + "/" + oid);
|
||||
processSession.transfer(flowFile, REL_SUCCESS);
|
||||
if (flowFile != null) {
|
||||
performSnmpWalkWithFlowFile(processSession, flowFile);
|
||||
} else {
|
||||
performSnmpWalkWithoutFlowFile(processSession, oid);
|
||||
}
|
||||
} catch (SNMPWalkException e) {
|
||||
getLogger().error(e.getMessage());
|
||||
context.yield();
|
||||
processSession.rollback();
|
||||
}
|
||||
}
|
||||
|
||||
private void performSnmpGet(final ProcessContext context, final ProcessSession processSession, final String oid) {
|
||||
final SNMPSingleResponse response;
|
||||
private void performSnmpWalkWithFlowFile(ProcessSession processSession, FlowFile flowFile) {
|
||||
final Optional<SNMPTreeResponse> optionalResponse = snmpHandler.walk(flowFile.getAttributes());
|
||||
if (optionalResponse.isPresent()) {
|
||||
final SNMPTreeResponse response = optionalResponse.get();
|
||||
response.logErrors(getLogger());
|
||||
processSession.putAllAttributes(flowFile, response.getAttributes());
|
||||
processSession.getProvenanceReporter().modifyAttributes(flowFile, response.getTargetAddress() + "/walk");
|
||||
processSession.transfer(flowFile, response.isError() ? REL_FAILURE : REL_SUCCESS);
|
||||
} else {
|
||||
getLogger().warn("No SNMP specific attributes found in flowfile.");
|
||||
processSession.getProvenanceReporter().receive(flowFile, "/walk");
|
||||
processSession.transfer(flowFile, REL_FAILURE);
|
||||
}
|
||||
}
|
||||
|
||||
private void performSnmpWalkWithoutFlowFile(ProcessSession processSession, String oid) {
|
||||
final SNMPTreeResponse response = snmpHandler.walk(oid);
|
||||
response.logErrors(getLogger());
|
||||
final FlowFile outgoingFlowFile = processSession.create();
|
||||
processSession.putAllAttributes(outgoingFlowFile, response.getAttributes());
|
||||
processSession.getProvenanceReporter().create(outgoingFlowFile, response.getTargetAddress() + "/walk");
|
||||
processSession.transfer(outgoingFlowFile, REL_SUCCESS);
|
||||
}
|
||||
|
||||
void performSnmpGet(final ProcessContext context, final ProcessSession processSession, final String oid,
|
||||
final FlowFile flowFile) {
|
||||
final String textualOidKey = SNMPUtils.SNMP_PROP_PREFIX + "textualOid";
|
||||
final Map<String, String> textualOidMap = Collections.singletonMap(textualOidKey, context.getProperty(TEXTUAL_OID).getValue());
|
||||
try {
|
||||
response = snmpRequestHandler.get(oid);
|
||||
final FlowFile flowFile = processSession.create();
|
||||
addAttribute(SNMPUtils.SNMP_PROP_PREFIX + "textualOid", context.getProperty(TEXTUAL_OID).getValue(), flowFile, processSession);
|
||||
final String provenanceAddress = response.getTargetAddress() + "/" + oid;
|
||||
processResponse(processSession, flowFile, response, provenanceAddress, REL_SUCCESS);
|
||||
} catch (SNMPException e) {
|
||||
getLogger().error(e.getMessage());
|
||||
context.yield();
|
||||
processSession.rollback();
|
||||
if (flowFile != null) {
|
||||
performSnmpGetWithFlowFile(context, processSession, flowFile, textualOidMap);
|
||||
} else {
|
||||
performSnmpGetWithoutFlowFile(context, processSession, oid, textualOidMap);
|
||||
}
|
||||
} catch (IOException e) {
|
||||
getLogger().error("Failed to send request to the agent. Check if the agent supports the used version.");
|
||||
getLogger().error("Failed to send request to the agent. Check if the agent supports the used version.", e);
|
||||
context.yield();
|
||||
processSession.rollback();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<PropertyDescriptor> getSupportedPropertyDescriptors() {
|
||||
return PROPERTY_DESCRIPTORS;
|
||||
private void performSnmpGetWithoutFlowFile(ProcessContext context, ProcessSession processSession, String oid, Map<String, String> textualOidMap) throws IOException {
|
||||
final SNMPSingleResponse response = snmpHandler.get(oid);
|
||||
final FlowFile outgoingFlowFile = processSession.create();
|
||||
processSession.putAllAttributes(outgoingFlowFile, textualOidMap);
|
||||
processSession.getProvenanceReporter().receive(outgoingFlowFile, response.getTargetAddress() + "/get");
|
||||
handleResponse(context, processSession, outgoingFlowFile, response, REL_SUCCESS, REL_FAILURE, "/get");
|
||||
}
|
||||
|
||||
private void performSnmpGetWithFlowFile(ProcessContext context, ProcessSession processSession, FlowFile flowFile, Map<String, String> textualOidMap) throws IOException {
|
||||
final Optional<SNMPSingleResponse> optionalResponse = snmpHandler.get(flowFile.getAttributes());
|
||||
if (optionalResponse.isPresent()) {
|
||||
final SNMPSingleResponse response = optionalResponse.get();
|
||||
processSession.putAllAttributes(flowFile, textualOidMap);
|
||||
handleResponse(context, processSession, flowFile, response, REL_SUCCESS, REL_FAILURE, "/get");
|
||||
} else {
|
||||
getLogger().warn("No SNMP specific attributes found in flowfile.");
|
||||
processSession.transfer(flowFile, REL_FAILURE);
|
||||
context.yield();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -189,10 +244,18 @@ public class GetSNMP extends AbstractSNMPProcessor {
|
||||
return RELATIONSHIPS;
|
||||
}
|
||||
|
||||
private FlowFile createFlowFileWithTreeEventProperties(final SNMPTreeResponse response, final ProcessSession processSession) {
|
||||
FlowFile flowFile = processSession.create();
|
||||
flowFile = processSession.putAllAttributes(flowFile, response.getAttributes());
|
||||
return flowFile;
|
||||
@Override
|
||||
protected List<PropertyDescriptor> getSupportedPropertyDescriptors() {
|
||||
return PROPERTY_DESCRIPTORS;
|
||||
}
|
||||
|
||||
protected String getTargetHost(ProcessContext processContext) {
|
||||
return processContext.getProperty(AGENT_HOST).getValue();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getTargetPort(ProcessContext processContext) {
|
||||
return processContext.getProperty(AGENT_PORT).getValue();
|
||||
}
|
||||
|
||||
private enum SNMPStrategy {
|
||||
|
@ -0,0 +1,143 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.nifi.snmp.processors;
|
||||
|
||||
import org.apache.nifi.annotation.behavior.InputRequirement;
|
||||
import org.apache.nifi.annotation.behavior.RequiresInstanceClassLoading;
|
||||
import org.apache.nifi.annotation.behavior.WritesAttribute;
|
||||
import org.apache.nifi.annotation.documentation.CapabilityDescription;
|
||||
import org.apache.nifi.annotation.documentation.Tags;
|
||||
import org.apache.nifi.annotation.lifecycle.OnScheduled;
|
||||
import org.apache.nifi.annotation.lifecycle.OnStopped;
|
||||
import org.apache.nifi.components.PropertyDescriptor;
|
||||
import org.apache.nifi.flowfile.FlowFile;
|
||||
import org.apache.nifi.processor.AbstractSessionFactoryProcessor;
|
||||
import org.apache.nifi.processor.ProcessContext;
|
||||
import org.apache.nifi.processor.ProcessSessionFactory;
|
||||
import org.apache.nifi.processor.Relationship;
|
||||
import org.apache.nifi.processor.util.StandardValidators;
|
||||
import org.apache.nifi.snmp.configuration.SNMPConfiguration;
|
||||
import org.apache.nifi.snmp.operations.SNMPTrapReceiverHandler;
|
||||
import org.apache.nifi.snmp.processors.properties.BasicProperties;
|
||||
import org.apache.nifi.snmp.processors.properties.V3SecurityProperties;
|
||||
import org.apache.nifi.snmp.utils.SNMPUtils;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* Receiving data from a configured SNMP agent which, upon each invocation of
|
||||
* {@link #onTrigger(ProcessContext, ProcessSessionFactory)} method, will construct a
|
||||
* {@link FlowFile} containing in its properties the information retrieved.
|
||||
* The output {@link FlowFile} won't have any content.
|
||||
*/
|
||||
@Tags({"snmp", "listen", "trap"})
|
||||
@InputRequirement(InputRequirement.Requirement.INPUT_FORBIDDEN)
|
||||
@CapabilityDescription("Receives information from SNMP Agent and outputs a FlowFile with information in attributes and without any content")
|
||||
@WritesAttribute(attribute = SNMPUtils.SNMP_PROP_PREFIX + "*", description = "Attributes retrieved from the SNMP response. It may include:"
|
||||
+ " snmp$errorIndex, snmp$errorStatus, snmp$errorStatusText, snmp$nonRepeaters, snmp$requestID, snmp$type, snmp$variableBindings")
|
||||
@RequiresInstanceClassLoading
|
||||
public class ListenTrapSNMP extends AbstractSessionFactoryProcessor {
|
||||
|
||||
public static final PropertyDescriptor SNMP_MANAGER_PORT = new PropertyDescriptor.Builder()
|
||||
.name("snmp-manager-port")
|
||||
.displayName("SNMP Manager Port")
|
||||
.description("The port where the SNMP Manager listens to the incoming traps.")
|
||||
.required(true)
|
||||
.defaultValue("0")
|
||||
.addValidator(StandardValidators.PORT_VALIDATOR)
|
||||
.build();
|
||||
|
||||
public static final PropertyDescriptor SNMP_USM_USERS_FILE_PATH = new PropertyDescriptor.Builder()
|
||||
.name("snmp-usm-users-file-path")
|
||||
.displayName("SNMP Users File Path")
|
||||
.description("The path of the json file containing the user credentials for SNMPv3. Check Usage for more details.")
|
||||
.required(true)
|
||||
.defaultValue("")
|
||||
.dependsOn(BasicProperties.SNMP_VERSION, BasicProperties.SNMP_V3)
|
||||
.addValidator(StandardValidators.NON_EMPTY_VALIDATOR)
|
||||
.build();
|
||||
|
||||
public static final Relationship REL_SUCCESS = new Relationship.Builder()
|
||||
.name("success")
|
||||
.description("All FlowFiles that are received from the SNMP agent are routed to this relationship")
|
||||
.build();
|
||||
|
||||
public static final Relationship REL_FAILURE = new Relationship.Builder()
|
||||
.name("failure")
|
||||
.description("All FlowFiles that cannot received from the SNMP agent are routed to this relationship")
|
||||
.build();
|
||||
|
||||
protected static final List<PropertyDescriptor> PROPERTY_DESCRIPTORS = Collections.unmodifiableList(Arrays.asList(
|
||||
SNMP_MANAGER_PORT,
|
||||
BasicProperties.SNMP_VERSION,
|
||||
BasicProperties.SNMP_COMMUNITY,
|
||||
V3SecurityProperties.SNMP_SECURITY_LEVEL,
|
||||
SNMP_USM_USERS_FILE_PATH
|
||||
));
|
||||
|
||||
private static final Set<Relationship> RELATIONSHIPS = Collections.unmodifiableSet(new HashSet<>(Arrays.asList(
|
||||
REL_SUCCESS,
|
||||
REL_FAILURE
|
||||
)));
|
||||
|
||||
private volatile SNMPTrapReceiverHandler snmpTrapReceiverHandler;
|
||||
|
||||
@OnScheduled
|
||||
public void initSnmpManager(ProcessContext context) {
|
||||
final int version = SNMPUtils.getVersion(context.getProperty(BasicProperties.SNMP_VERSION).getValue());
|
||||
final int managerPort = context.getProperty(SNMP_MANAGER_PORT).asInteger();
|
||||
final String usmUsersFilePath = context.getProperty(SNMP_USM_USERS_FILE_PATH).getValue();
|
||||
SNMPConfiguration configuration;
|
||||
|
||||
configuration = SNMPConfiguration.builder()
|
||||
.setManagerPort(managerPort)
|
||||
.setVersion(version)
|
||||
.setSecurityLevel(context.getProperty(V3SecurityProperties.SNMP_SECURITY_LEVEL).getValue())
|
||||
.setCommunityString(context.getProperty(BasicProperties.SNMP_COMMUNITY).getValue())
|
||||
.build();
|
||||
|
||||
snmpTrapReceiverHandler = new SNMPTrapReceiverHandler(configuration, usmUsersFilePath);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTrigger(final ProcessContext context, final ProcessSessionFactory processSessionFactory) {
|
||||
if (!snmpTrapReceiverHandler.isStarted()) {
|
||||
snmpTrapReceiverHandler.createTrapReceiver(processSessionFactory, getLogger());
|
||||
}
|
||||
}
|
||||
|
||||
@OnStopped
|
||||
public void close() {
|
||||
if (snmpTrapReceiverHandler != null) {
|
||||
snmpTrapReceiverHandler.close();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<Relationship> getRelationships() {
|
||||
return RELATIONSHIPS;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<PropertyDescriptor> getSupportedPropertyDescriptors() {
|
||||
return PROPERTY_DESCRIPTORS;
|
||||
}
|
||||
}
|
@ -0,0 +1,170 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.nifi.snmp.processors;
|
||||
|
||||
import org.apache.nifi.annotation.behavior.InputRequirement;
|
||||
import org.apache.nifi.annotation.behavior.InputRequirement.Requirement;
|
||||
import org.apache.nifi.annotation.documentation.CapabilityDescription;
|
||||
import org.apache.nifi.annotation.documentation.Tags;
|
||||
import org.apache.nifi.annotation.lifecycle.OnScheduled;
|
||||
import org.apache.nifi.components.PropertyDescriptor;
|
||||
import org.apache.nifi.flowfile.FlowFile;
|
||||
import org.apache.nifi.processor.ProcessContext;
|
||||
import org.apache.nifi.processor.ProcessSession;
|
||||
import org.apache.nifi.processor.Relationship;
|
||||
import org.apache.nifi.processor.util.StandardValidators;
|
||||
import org.apache.nifi.snmp.configuration.V1TrapConfiguration;
|
||||
import org.apache.nifi.snmp.configuration.V2TrapConfiguration;
|
||||
import org.apache.nifi.snmp.operations.SendTrapSNMPHandler;
|
||||
import org.apache.nifi.snmp.processors.properties.BasicProperties;
|
||||
import org.apache.nifi.snmp.processors.properties.V1TrapProperties;
|
||||
import org.apache.nifi.snmp.processors.properties.V2TrapProperties;
|
||||
import org.apache.nifi.snmp.processors.properties.V3SecurityProperties;
|
||||
import org.apache.nifi.snmp.utils.SNMPUtils;
|
||||
import org.snmp4j.mp.SnmpConstants;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.time.Instant;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* Sends data to an SNMP manager which, upon each invocation of
|
||||
* {@link #onTrigger(ProcessContext, ProcessSession)} method, will construct a
|
||||
* {@link FlowFile} containing in its properties the information retrieved.
|
||||
* The output {@link FlowFile} won't have any content.
|
||||
*/
|
||||
@Tags({"snmp", "send", "trap"})
|
||||
@InputRequirement(Requirement.INPUT_ALLOWED)
|
||||
@CapabilityDescription("Sends information to SNMP Manager.")
|
||||
public class SendTrapSNMP extends AbstractSNMPProcessor {
|
||||
|
||||
public static final PropertyDescriptor SNMP_MANAGER_HOST = new PropertyDescriptor.Builder()
|
||||
.name("snmp-trap-manager-host")
|
||||
.displayName("SNMP Manager Host")
|
||||
.description("The host where the SNMP Manager sends the trap.")
|
||||
.required(true)
|
||||
.defaultValue("localhost")
|
||||
.addValidator(StandardValidators.NON_EMPTY_VALIDATOR)
|
||||
.build();
|
||||
|
||||
public static final PropertyDescriptor SNMP_MANAGER_PORT = new PropertyDescriptor.Builder()
|
||||
.name("snmp-trap-manager-port")
|
||||
.displayName("SNMP Manager Port")
|
||||
.description("The port where the SNMP Manager listens to the incoming traps.")
|
||||
.required(true)
|
||||
.defaultValue("0")
|
||||
.addValidator(StandardValidators.PORT_VALIDATOR)
|
||||
.build();
|
||||
|
||||
public static final Relationship REL_SUCCESS = new Relationship.Builder()
|
||||
.name("success")
|
||||
.description("All FlowFiles that have been successfully used to perform SNMP Set are routed to this relationship")
|
||||
.build();
|
||||
|
||||
public static final Relationship REL_FAILURE = new Relationship.Builder()
|
||||
.name("failure")
|
||||
.description("All FlowFiles that cannot received from the SNMP agent are routed to this relationship")
|
||||
.build();
|
||||
|
||||
protected static final List<PropertyDescriptor> PROPERTY_DESCRIPTORS = Collections.unmodifiableList(Arrays.asList(
|
||||
SNMP_MANAGER_HOST,
|
||||
SNMP_MANAGER_PORT,
|
||||
BasicProperties.SNMP_VERSION,
|
||||
BasicProperties.SNMP_COMMUNITY,
|
||||
V3SecurityProperties.SNMP_SECURITY_LEVEL,
|
||||
V3SecurityProperties.SNMP_SECURITY_NAME,
|
||||
V3SecurityProperties.SNMP_AUTH_PROTOCOL,
|
||||
V3SecurityProperties.SNMP_AUTH_PASSWORD,
|
||||
V3SecurityProperties.SNMP_PRIVACY_PROTOCOL,
|
||||
V3SecurityProperties.SNMP_PRIVACY_PASSWORD,
|
||||
BasicProperties.SNMP_RETRIES,
|
||||
BasicProperties.SNMP_TIMEOUT,
|
||||
V1TrapProperties.ENTERPRISE_OID,
|
||||
V1TrapProperties.AGENT_ADDRESS,
|
||||
V1TrapProperties.GENERIC_TRAP_TYPE,
|
||||
V1TrapProperties.SPECIFIC_TRAP_TYPE,
|
||||
V2TrapProperties.TRAP_OID_VALUE
|
||||
));
|
||||
|
||||
private static final Set<Relationship> RELATIONSHIPS = Collections.unmodifiableSet(new HashSet<>(Arrays.asList(
|
||||
REL_SUCCESS, REL_FAILURE
|
||||
)));
|
||||
|
||||
private volatile SendTrapSNMPHandler snmpHandler;
|
||||
|
||||
@OnScheduled
|
||||
public void init(ProcessContext context) {
|
||||
Instant startTime = Instant.now();
|
||||
initSnmpManager(context);
|
||||
snmpHandler = new SendTrapSNMPHandler(snmpResourceHandler, startTime, getLogger());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTrigger(final ProcessContext context, final ProcessSession processSession) {
|
||||
final FlowFile flowFile = processSession.get();
|
||||
if (flowFile != null) {
|
||||
try {
|
||||
final int snmpVersion = SNMPUtils.getVersion(context.getProperty(BasicProperties.SNMP_VERSION).getValue());
|
||||
if (SnmpConstants.version1 == snmpVersion) {
|
||||
V1TrapConfiguration v1TrapConfiguration = V1TrapConfiguration.builder()
|
||||
.enterpriseOid(context.getProperty(V1TrapProperties.ENTERPRISE_OID).evaluateAttributeExpressions(flowFile).getValue())
|
||||
.agentAddress(context.getProperty(V1TrapProperties.AGENT_ADDRESS).evaluateAttributeExpressions(flowFile).getValue())
|
||||
.genericTrapType(context.getProperty(V1TrapProperties.GENERIC_TRAP_TYPE).evaluateAttributeExpressions(flowFile).getValue())
|
||||
.specificTrapType(context.getProperty(V1TrapProperties.SPECIFIC_TRAP_TYPE).evaluateAttributeExpressions(flowFile).getValue())
|
||||
.build();
|
||||
snmpHandler.sendTrap(flowFile.getAttributes(), v1TrapConfiguration);
|
||||
} else {
|
||||
V2TrapConfiguration v2TrapConfiguration = new V2TrapConfiguration(
|
||||
context.getProperty(V2TrapProperties.TRAP_OID_VALUE).evaluateAttributeExpressions(flowFile).getValue()
|
||||
);
|
||||
snmpHandler.sendTrap(flowFile.getAttributes(), v2TrapConfiguration);
|
||||
}
|
||||
processSession.transfer(flowFile, REL_SUCCESS);
|
||||
} catch (IOException e) {
|
||||
getLogger().error("Failed to send request to the agent. Check if the agent supports the used version.", e);
|
||||
processSession.transfer(processSession.penalize(flowFile), REL_FAILURE);
|
||||
} catch (IllegalArgumentException e) {
|
||||
getLogger().error("Invalid trap configuration.", e);
|
||||
processSession.transfer(processSession.penalize(flowFile), REL_FAILURE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<Relationship> getRelationships() {
|
||||
return RELATIONSHIPS;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<PropertyDescriptor> getSupportedPropertyDescriptors() {
|
||||
return PROPERTY_DESCRIPTORS;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getTargetHost(ProcessContext processContext) {
|
||||
return processContext.getProperty(SNMP_MANAGER_HOST).getValue();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getTargetPort(ProcessContext processContext) {
|
||||
return processContext.getProperty(SNMP_MANAGER_PORT).getValue();
|
||||
}
|
||||
}
|
@ -22,13 +22,16 @@ import org.apache.nifi.annotation.behavior.WritesAttribute;
|
||||
import org.apache.nifi.annotation.behavior.WritesAttributes;
|
||||
import org.apache.nifi.annotation.documentation.CapabilityDescription;
|
||||
import org.apache.nifi.annotation.documentation.Tags;
|
||||
import org.apache.nifi.annotation.lifecycle.OnScheduled;
|
||||
import org.apache.nifi.components.PropertyDescriptor;
|
||||
import org.apache.nifi.flowfile.FlowFile;
|
||||
import org.apache.nifi.processor.ProcessContext;
|
||||
import org.apache.nifi.processor.ProcessSession;
|
||||
import org.apache.nifi.processor.Relationship;
|
||||
import org.apache.nifi.snmp.dto.SNMPSingleResponse;
|
||||
import org.apache.nifi.snmp.exception.SNMPException;
|
||||
import org.apache.nifi.snmp.operations.SetSNMPHandler;
|
||||
import org.apache.nifi.snmp.processors.properties.BasicProperties;
|
||||
import org.apache.nifi.snmp.processors.properties.V3SecurityProperties;
|
||||
import org.apache.nifi.snmp.utils.SNMPUtils;
|
||||
|
||||
import java.io.IOException;
|
||||
@ -36,19 +39,21 @@ import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* Performs a SNMP Set operation based on attributes of incoming FlowFile.
|
||||
* Performs an SNMP Set operation based on attributes of incoming FlowFile.
|
||||
* Upon each invocation of {@link #onTrigger(ProcessContext, ProcessSession)}
|
||||
* method, it will inspect attributes of FlowFile and look for attributes with
|
||||
* name formatted as "snmp$OID" to set the attribute value to this OID.
|
||||
* The output {@link FlowFile} won't have any content.
|
||||
*/
|
||||
@Tags({"snmp", "set", "oid"})
|
||||
@InputRequirement(Requirement.INPUT_REQUIRED)
|
||||
@CapabilityDescription("Based on incoming FlowFile attributes, the processor will execute SNMP Set requests." +
|
||||
" When finding attributes with the name snmp$<OID>, the processor will attempt to set the value of" +
|
||||
" the attribute to the corresponding OID given in the attribute name")
|
||||
" the attribute to the corresponding OID given in the attribute name.")
|
||||
@WritesAttributes({
|
||||
@WritesAttribute(attribute = SNMPUtils.SNMP_PROP_PREFIX + "<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."),
|
||||
@ -74,16 +79,16 @@ public class SetSNMP extends AbstractSNMPProcessor {
|
||||
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
|
||||
BasicProperties.SNMP_VERSION,
|
||||
BasicProperties.SNMP_COMMUNITY,
|
||||
V3SecurityProperties.SNMP_SECURITY_LEVEL,
|
||||
V3SecurityProperties.SNMP_SECURITY_NAME,
|
||||
V3SecurityProperties.SNMP_AUTH_PROTOCOL,
|
||||
V3SecurityProperties.SNMP_AUTH_PASSWORD,
|
||||
V3SecurityProperties.SNMP_PRIVACY_PROTOCOL,
|
||||
V3SecurityProperties.SNMP_PRIVACY_PASSWORD,
|
||||
BasicProperties.SNMP_RETRIES,
|
||||
BasicProperties.SNMP_TIMEOUT
|
||||
));
|
||||
|
||||
private static final Set<Relationship> RELATIONSHIPS = Collections.unmodifiableSet(new HashSet<>(Arrays.asList(
|
||||
@ -91,19 +96,34 @@ public class SetSNMP extends AbstractSNMPProcessor {
|
||||
REL_FAILURE
|
||||
)));
|
||||
|
||||
private volatile SetSNMPHandler snmpHandler;
|
||||
|
||||
@OnScheduled
|
||||
public void init(final ProcessContext context) {
|
||||
initSnmpManager(context);
|
||||
snmpHandler = new SetSNMPHandler(snmpResourceHandler);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTrigger(final ProcessContext context, final ProcessSession processSession) {
|
||||
final FlowFile flowFile = processSession.get();
|
||||
if (flowFile != null) {
|
||||
try {
|
||||
final SNMPSingleResponse response = snmpRequestHandler.set(flowFile);
|
||||
processResponse(processSession, flowFile, response, response.getTargetAddress(), REL_SUCCESS);
|
||||
} catch (SNMPException e) {
|
||||
getLogger().error(e.getMessage());
|
||||
processError(context, processSession, flowFile);
|
||||
final Optional<SNMPSingleResponse> optionalResponse = snmpHandler.set(flowFile.getAttributes());
|
||||
if (optionalResponse.isPresent()) {
|
||||
processSession.remove(flowFile);
|
||||
final FlowFile outgoingFlowFile = processSession.create();
|
||||
final SNMPSingleResponse response = optionalResponse.get();
|
||||
processSession.getProvenanceReporter().receive(outgoingFlowFile, "/set");
|
||||
handleResponse(context, processSession, outgoingFlowFile, response, REL_SUCCESS, REL_FAILURE, "/set");
|
||||
} else {
|
||||
getLogger().warn("No SNMP specific attributes found in flowfile.");
|
||||
processSession.transfer(flowFile, REL_FAILURE);
|
||||
}
|
||||
} catch (IOException e) {
|
||||
getLogger().error("Failed to send request to the agent. Check if the agent supports the used version.");
|
||||
processError(context, processSession, flowFile);
|
||||
processSession.transfer(processSession.penalize(flowFile), REL_FAILURE);
|
||||
context.yield();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -118,9 +138,13 @@ public class SetSNMP extends AbstractSNMPProcessor {
|
||||
return RELATIONSHIPS;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getTargetHost(ProcessContext processContext) {
|
||||
return processContext.getProperty(AGENT_HOST).getValue();
|
||||
}
|
||||
|
||||
private void processError(final ProcessContext context, final ProcessSession processSession, final FlowFile flowFile) {
|
||||
processSession.transfer(processSession.penalize(flowFile), REL_FAILURE);
|
||||
context.yield();
|
||||
@Override
|
||||
protected String getTargetPort(ProcessContext processContext) {
|
||||
return processContext.getProperty(AGENT_PORT).getValue();
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,77 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.nifi.snmp.processors.properties;
|
||||
|
||||
import org.apache.nifi.components.AllowableValue;
|
||||
import org.apache.nifi.components.PropertyDescriptor;
|
||||
import org.apache.nifi.processor.util.StandardValidators;
|
||||
|
||||
public class BasicProperties {
|
||||
|
||||
private BasicProperties() {
|
||||
// Utility class, not needed to instantiate.
|
||||
}
|
||||
|
||||
public static final AllowableValue SNMP_V1 = new AllowableValue("SNMPv1", "v1", "SNMP version 1");
|
||||
public static final AllowableValue SNMP_V2C = new AllowableValue("SNMPv2c", "v2c", "SNMP version 2c");
|
||||
public static final AllowableValue SNMP_V3 = new AllowableValue("SNMPv3", "v3", "SNMP version 3 with improved security");
|
||||
|
||||
|
||||
public static final PropertyDescriptor SNMP_VERSION = new PropertyDescriptor.Builder()
|
||||
.name("snmp-version")
|
||||
.displayName("SNMP Version")
|
||||
.description("Three significant versions of SNMP have been developed and deployed. " +
|
||||
"SNMPv1 is the original version of the protocol. More recent versions, " +
|
||||
"SNMPv2c and SNMPv3, feature improvements in performance, flexibility and security.")
|
||||
.required(true)
|
||||
.allowableValues(SNMP_V1, SNMP_V2C, SNMP_V3)
|
||||
.defaultValue(SNMP_V1.getValue())
|
||||
.build();
|
||||
|
||||
public static final PropertyDescriptor SNMP_COMMUNITY = new PropertyDescriptor.Builder()
|
||||
.name("snmp-community")
|
||||
.displayName("SNMP Community")
|
||||
.description("SNMPv1 and SNMPv2 use communities to establish trust between managers and agents." +
|
||||
" Most agents support three community names, one each for read-only, read-write and trap." +
|
||||
" These three community strings control different types of activities. The read-only community" +
|
||||
" applies to get requests. The read-write community string applies to set requests. The trap" +
|
||||
" community string applies to receipt of traps.")
|
||||
.required(true)
|
||||
.sensitive(true)
|
||||
.defaultValue("public")
|
||||
.addValidator(StandardValidators.NON_EMPTY_VALIDATOR)
|
||||
.dependsOn(SNMP_VERSION, SNMP_V1, SNMP_V2C)
|
||||
.build();
|
||||
|
||||
public static final PropertyDescriptor SNMP_RETRIES = new PropertyDescriptor.Builder()
|
||||
.name("snmp-retries")
|
||||
.displayName("Number of Retries")
|
||||
.description("Set the number of retries when requesting the SNMP Agent.")
|
||||
.required(false)
|
||||
.defaultValue("0")
|
||||
.addValidator(StandardValidators.NON_NEGATIVE_INTEGER_VALIDATOR)
|
||||
.build();
|
||||
|
||||
public static final PropertyDescriptor SNMP_TIMEOUT = new PropertyDescriptor.Builder()
|
||||
.name("snmp-timeout")
|
||||
.displayName("Timeout (ms)")
|
||||
.description("Set the timeout in ms when requesting the SNMP Agent.")
|
||||
.required(false)
|
||||
.defaultValue("5000")
|
||||
.addValidator(StandardValidators.POSITIVE_INTEGER_VALIDATOR)
|
||||
.build();
|
||||
}
|
@ -0,0 +1,80 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.nifi.snmp.processors.properties;
|
||||
|
||||
import org.apache.nifi.components.AllowableValue;
|
||||
import org.apache.nifi.components.PropertyDescriptor;
|
||||
import org.apache.nifi.expression.ExpressionLanguageScope;
|
||||
import org.apache.nifi.processor.util.StandardValidators;
|
||||
|
||||
import static org.apache.nifi.snmp.processors.properties.BasicProperties.SNMP_V1;
|
||||
import static org.apache.nifi.snmp.processors.properties.BasicProperties.SNMP_VERSION;
|
||||
|
||||
|
||||
public class V1TrapProperties {
|
||||
|
||||
private V1TrapProperties() {
|
||||
// Utility class, not needed to instantiate.
|
||||
}
|
||||
|
||||
private static final AllowableValue GENERIC_TRAP_TYPE_ENTERPRISE_SPECIFIC = new AllowableValue("6", "Enterprise Specific",
|
||||
"An enterpriseSpecific trap signifies that a particular enterprise-specific trap has occurred which " +
|
||||
"can be defined in the Specific Trap Type field.");
|
||||
|
||||
public static final PropertyDescriptor ENTERPRISE_OID = new PropertyDescriptor.Builder()
|
||||
.name("snmp-trap-enterprise-oid")
|
||||
.displayName("Enterprise OID")
|
||||
.description("Enterprise is the vendor identification (OID) for the network management sub-system that generated the trap.")
|
||||
.required(true)
|
||||
.addValidator(StandardValidators.NON_EMPTY_VALIDATOR)
|
||||
.dependsOn(SNMP_VERSION, SNMP_V1)
|
||||
.expressionLanguageSupported(ExpressionLanguageScope.FLOWFILE_ATTRIBUTES)
|
||||
.build();
|
||||
|
||||
public static final PropertyDescriptor AGENT_ADDRESS = new PropertyDescriptor.Builder()
|
||||
.name("snmp-trap-agent-address")
|
||||
.displayName("SNMP Trap Agent Address")
|
||||
.description("The address where the SNMP Manager sends the trap.")
|
||||
.required(true)
|
||||
.defaultValue("0")
|
||||
.addValidator(StandardValidators.NON_EMPTY_VALIDATOR)
|
||||
.dependsOn(SNMP_VERSION, SNMP_V1)
|
||||
.expressionLanguageSupported(ExpressionLanguageScope.FLOWFILE_ATTRIBUTES)
|
||||
.build();
|
||||
|
||||
public static final PropertyDescriptor GENERIC_TRAP_TYPE = new PropertyDescriptor.Builder()
|
||||
.name("snmp-trap-generic-type")
|
||||
.displayName("Generic Trap Type")
|
||||
.description("Generic trap type is an integer in the range of 0 to 6. See processor usage for details.")
|
||||
.required(false)
|
||||
.addValidator(StandardValidators.createLongValidator(0, 6, true))
|
||||
.dependsOn(SNMP_VERSION, SNMP_V1)
|
||||
.expressionLanguageSupported(ExpressionLanguageScope.FLOWFILE_ATTRIBUTES)
|
||||
.build();
|
||||
|
||||
public static final PropertyDescriptor SPECIFIC_TRAP_TYPE = new PropertyDescriptor.Builder()
|
||||
.name("snmp-trap-specific-type")
|
||||
.displayName("Specific Trap Type")
|
||||
.description("Specific trap type is a number that further specifies the nature of the event that generated " +
|
||||
"the trap in the case of traps of generic type 6 (enterpriseSpecific). The interpretation of this " +
|
||||
"code is vendor-specific.")
|
||||
.required(true)
|
||||
.addValidator(StandardValidators.POSITIVE_INTEGER_VALIDATOR)
|
||||
.dependsOn(SNMP_VERSION, SNMP_V1)
|
||||
.expressionLanguageSupported(ExpressionLanguageScope.FLOWFILE_ATTRIBUTES)
|
||||
.build();
|
||||
}
|
@ -0,0 +1,42 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.nifi.snmp.processors.properties;
|
||||
|
||||
import org.apache.nifi.components.PropertyDescriptor;
|
||||
import org.apache.nifi.expression.ExpressionLanguageScope;
|
||||
import org.apache.nifi.processor.util.StandardValidators;
|
||||
|
||||
import static org.apache.nifi.snmp.processors.properties.BasicProperties.SNMP_V2C;
|
||||
import static org.apache.nifi.snmp.processors.properties.BasicProperties.SNMP_V3;
|
||||
import static org.apache.nifi.snmp.processors.properties.BasicProperties.SNMP_VERSION;
|
||||
|
||||
public class V2TrapProperties {
|
||||
|
||||
private V2TrapProperties() {
|
||||
// Utility class, not needed to instantiate.
|
||||
}
|
||||
|
||||
public static final PropertyDescriptor TRAP_OID_VALUE = new PropertyDescriptor.Builder()
|
||||
.name("snmp-trap-oid-value")
|
||||
.displayName("Trap OID Value")
|
||||
.description("The value of the trap OID.")
|
||||
.required(true)
|
||||
.addValidator(StandardValidators.NON_EMPTY_VALIDATOR)
|
||||
.dependsOn(SNMP_VERSION, SNMP_V2C, SNMP_V3)
|
||||
.expressionLanguageSupported(ExpressionLanguageScope.FLOWFILE_ATTRIBUTES)
|
||||
.build();
|
||||
}
|
@ -0,0 +1,130 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.nifi.snmp.processors.properties;
|
||||
|
||||
import org.apache.nifi.components.AllowableValue;
|
||||
import org.apache.nifi.components.PropertyDescriptor;
|
||||
import org.apache.nifi.processor.util.StandardValidators;
|
||||
import org.snmp4j.security.SecurityLevel;
|
||||
|
||||
import static org.apache.nifi.snmp.processors.properties.BasicProperties.SNMP_V3;
|
||||
import static org.apache.nifi.snmp.processors.properties.BasicProperties.SNMP_VERSION;
|
||||
|
||||
public class V3SecurityProperties {
|
||||
|
||||
private V3SecurityProperties() {
|
||||
// Utility class, not needed to instantiate.
|
||||
}
|
||||
|
||||
private static final String SHA_2_ALGORITHM = "Provides authentication based on the HMAC-SHA-2 algorithm.";
|
||||
private static final String AES_DESCRIPTION = "AES is a symmetric algorithm which uses the same 128, 192, or 256 bit" +
|
||||
" key for both encryption and decryption (the security of an AES system increases exponentially with key length).";
|
||||
|
||||
// SNMPv3 security levels
|
||||
public static final AllowableValue NO_AUTH_NO_PRIV = new AllowableValue(SecurityLevel.noAuthNoPriv.name(), SecurityLevel.noAuthNoPriv.name(),
|
||||
"No authentication or encryption.");
|
||||
public static final AllowableValue AUTH_NO_PRIV = new AllowableValue(SecurityLevel.authNoPriv.name(), SecurityLevel.authNoPriv.name(),
|
||||
"Authentication without encryption.");
|
||||
public static final AllowableValue AUTH_PRIV = new AllowableValue(SecurityLevel.authPriv.name(), SecurityLevel.authPriv.name(),
|
||||
"Authentication and encryption.");
|
||||
|
||||
// SNMPv3 authentication protocols
|
||||
public static final AllowableValue MD5 = new AllowableValue("MD5", "MD5",
|
||||
"Provides authentication based on the HMAC-MD5 algorithm.");
|
||||
public static final AllowableValue SHA = new AllowableValue("SHA", "SHA",
|
||||
"Provides authentication based on the HMAC-SHA algorithm.");
|
||||
public static final AllowableValue HMAC128SHA224 = new AllowableValue("HMAC128SHA224", "SHA224",
|
||||
SHA_2_ALGORITHM);
|
||||
public static final AllowableValue HMAC192SHA256 = new AllowableValue("HMAC192SHA256", "SHA256",
|
||||
SHA_2_ALGORITHM);
|
||||
public static final AllowableValue HMAC256SHA384 = new AllowableValue("HMAC256SHA384", "SHA384",
|
||||
SHA_2_ALGORITHM);
|
||||
public static final AllowableValue HMAC384SHA512 = new AllowableValue("HMAC384SHA512", "SHA512",
|
||||
SHA_2_ALGORITHM);
|
||||
|
||||
// SNMPv3 encryption
|
||||
public static final AllowableValue DES = new AllowableValue("DES", "DES",
|
||||
"Symmetric-key algorithm for the encryption of digital data. DES has been considered insecure" +
|
||||
"because of the feasilibity of brute-force attacks. We recommend using the AES encryption protocol.");
|
||||
public static final AllowableValue DES3 = new AllowableValue("3DES", "3DES",
|
||||
"Symmetric-key block cipher, which applies the DES cipher algorithm three times to each data block." +
|
||||
" 3DES has been considered insecure has been deprecated by NIST in 2017. We recommend using the AES encryption protocol.");
|
||||
|
||||
public static final AllowableValue AES128 = new AllowableValue("AES128", "AES128", AES_DESCRIPTION);
|
||||
public static final AllowableValue AES192 = new AllowableValue("AES192", "AES192", AES_DESCRIPTION);
|
||||
public static final AllowableValue AES256 = new AllowableValue("AES256", "AES256", AES_DESCRIPTION);
|
||||
|
||||
public static final PropertyDescriptor SNMP_SECURITY_LEVEL = new PropertyDescriptor.Builder()
|
||||
.name("snmp-security-level")
|
||||
.displayName("SNMP Security Level")
|
||||
.description("SNMP version 3 provides extra security with User Based Security Model (USM). The three levels of security is " +
|
||||
"1. Communication without authentication and encryption (NoAuthNoPriv). " +
|
||||
"2. Communication with authentication and without encryption (AuthNoPriv). " +
|
||||
"3. Communication with authentication and encryption (AuthPriv).")
|
||||
.required(true)
|
||||
.allowableValues(NO_AUTH_NO_PRIV, AUTH_NO_PRIV, AUTH_PRIV)
|
||||
.defaultValue(NO_AUTH_NO_PRIV.getValue())
|
||||
.dependsOn(SNMP_VERSION, SNMP_V3)
|
||||
.build();
|
||||
|
||||
public static final PropertyDescriptor SNMP_SECURITY_NAME = new PropertyDescriptor.Builder()
|
||||
.name("snmp-security-name")
|
||||
.displayName("SNMP Security Name")
|
||||
.description("User name used for SNMP v3 Authentication.")
|
||||
.required(true)
|
||||
.addValidator(StandardValidators.NON_EMPTY_VALIDATOR)
|
||||
.dependsOn(SNMP_VERSION, SNMP_V3)
|
||||
.build();
|
||||
|
||||
public static final PropertyDescriptor SNMP_AUTH_PROTOCOL = new PropertyDescriptor.Builder()
|
||||
.name("snmp-authentication-protocol")
|
||||
.displayName("SNMP Authentication Protocol")
|
||||
.description("Hash based authentication protocol for secure authentication.")
|
||||
.required(true)
|
||||
.allowableValues(MD5, SHA, HMAC128SHA224, HMAC192SHA256, HMAC256SHA384, HMAC384SHA512)
|
||||
.dependsOn(SNMP_SECURITY_LEVEL, AUTH_NO_PRIV, AUTH_PRIV)
|
||||
.build();
|
||||
|
||||
public static final PropertyDescriptor SNMP_AUTH_PASSWORD = new PropertyDescriptor.Builder()
|
||||
.name("snmp-authentication-passphrase")
|
||||
.displayName("SNMP Authentication Passphrase")
|
||||
.description("Passphrase used for SNMP authentication protocol.")
|
||||
.required(true)
|
||||
.addValidator(StandardValidators.NON_EMPTY_VALIDATOR)
|
||||
.sensitive(true)
|
||||
.dependsOn(SNMP_SECURITY_LEVEL, AUTH_NO_PRIV, AUTH_PRIV)
|
||||
.build();
|
||||
|
||||
public static final PropertyDescriptor SNMP_PRIVACY_PROTOCOL = new PropertyDescriptor.Builder()
|
||||
.name("snmp-private-protocol")
|
||||
.displayName("SNMP Privacy Protocol")
|
||||
.description("Privacy allows for encryption of SNMP v3 messages to ensure confidentiality of data.")
|
||||
.required(true)
|
||||
.allowableValues(DES, DES3, AES128, AES192, AES256)
|
||||
.dependsOn(SNMP_SECURITY_LEVEL, AUTH_PRIV)
|
||||
.build();
|
||||
|
||||
public static final PropertyDescriptor SNMP_PRIVACY_PASSWORD = new PropertyDescriptor.Builder()
|
||||
.name("snmp-private-protocol-passphrase")
|
||||
.displayName("SNMP Privacy Passphrase")
|
||||
.description("Passphrase used for SNMP privacy protocol.")
|
||||
.required(true)
|
||||
.addValidator(StandardValidators.NON_EMPTY_VALIDATOR)
|
||||
.sensitive(true)
|
||||
.dependsOn(SNMP_SECURITY_LEVEL, AUTH_PRIV)
|
||||
.build();
|
||||
}
|
@ -16,13 +16,13 @@
|
||||
*/
|
||||
package org.apache.nifi.snmp.utils;
|
||||
|
||||
import org.apache.nifi.flowfile.FlowFile;
|
||||
import org.apache.nifi.snmp.exception.InvalidAuthProtocolException;
|
||||
import org.apache.nifi.snmp.exception.InvalidPrivProtocolException;
|
||||
import org.apache.nifi.snmp.exception.InvalidSnmpVersionException;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.snmp4j.PDU;
|
||||
import org.snmp4j.PDUv1;
|
||||
import org.snmp4j.mp.SnmpConstants;
|
||||
import org.snmp4j.security.AuthHMAC128SHA224;
|
||||
import org.snmp4j.security.AuthHMAC192SHA256;
|
||||
@ -44,6 +44,7 @@ import org.snmp4j.smi.OctetString;
|
||||
import org.snmp4j.smi.Variable;
|
||||
import org.snmp4j.smi.VariableBinding;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
@ -67,8 +68,8 @@ public final class SNMPUtils {
|
||||
|
||||
private static final Map<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 static final Map<String, Integer> VERSION_MAP;
|
||||
|
||||
private SNMPUtils() {
|
||||
// hide implicit constructor
|
||||
@ -132,12 +133,18 @@ public final class SNMPUtils {
|
||||
return attributes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method to construct {@link FlowFile} attributes from a vector of {@link VariableBinding}
|
||||
*
|
||||
* @param variableBindings list of {@link VariableBinding}
|
||||
* @return the attributes map
|
||||
*/
|
||||
public static Map<String, String> getV1TrapPduAttributeMap(final PDUv1 v1TrapPdu) {
|
||||
final Map<String, String> trapAttributes = getPduAttributeMap(v1TrapPdu);
|
||||
|
||||
trapAttributes.computeIfAbsent(SNMP_PROP_PREFIX + "enterprise", v -> String.valueOf(v1TrapPdu.getEnterprise()));
|
||||
trapAttributes.computeIfAbsent(SNMP_PROP_PREFIX + "agentAddress", v -> String.valueOf(v1TrapPdu.getAgentAddress()));
|
||||
trapAttributes.computeIfAbsent(SNMP_PROP_PREFIX + "genericTrapType", v -> String.valueOf(v1TrapPdu.getGenericTrap()));
|
||||
trapAttributes.computeIfAbsent(SNMP_PROP_PREFIX + "specificTrapType", v -> String.valueOf(v1TrapPdu.getSpecificTrap()));
|
||||
trapAttributes.computeIfAbsent(SNMP_PROP_PREFIX + "timestamp", v -> String.valueOf(v1TrapPdu.getTimestamp()));
|
||||
|
||||
return trapAttributes;
|
||||
}
|
||||
|
||||
public static Map<String, String> createWalkOidValuesMap(final List<VariableBinding> variableBindings) {
|
||||
final Map<String, String> attributes = new HashMap<>();
|
||||
variableBindings.forEach(vb -> addAttributeFromVariable(vb, attributes));
|
||||
@ -159,46 +166,72 @@ public final class SNMPUtils {
|
||||
throw new InvalidAuthProtocolException("Invalid authentication protocol provided.");
|
||||
}
|
||||
|
||||
public static int getVersion(final String snmpVersion) {
|
||||
return Optional.ofNullable(VERSION_MAP.get(snmpVersion))
|
||||
.orElseThrow(() -> new InvalidSnmpVersionException("Invalid SNMP version provided."));
|
||||
}
|
||||
|
||||
/**
|
||||
* Method to construct {@link VariableBinding} based on {@link FlowFile}
|
||||
* attributes in order to update the {@link PDU} that is going to be sent to
|
||||
* the SNMP Agent.
|
||||
*
|
||||
* @param pdu {@link PDU} to be sent
|
||||
* @param attributes {@link FlowFile} attributes
|
||||
* @return true if at least one {@link VariableBinding} has been created, false otherwise
|
||||
*/
|
||||
public static boolean addVariables(final PDU pdu, final Map<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;
|
||||
try {
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (ArrayIndexOutOfBoundsException e) {
|
||||
return false;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public static VariableBinding[] addGetVariables(final Map<String, String> attributes) {
|
||||
List<VariableBinding> variableBindings = new ArrayList<>();
|
||||
try {
|
||||
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];
|
||||
if (SNMPUtils.OID_PATTERN.matcher(snmpPropName).matches()) {
|
||||
variableBindings.add(new VariableBinding(new OID(snmpPropName)));
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (ArrayIndexOutOfBoundsException e) {
|
||||
return new VariableBinding[0];
|
||||
}
|
||||
return variableBindings.toArray(new VariableBinding[0]);
|
||||
}
|
||||
|
||||
public static OID[] addWalkVariables(final Map<String, String> attributes) {
|
||||
List<OID> oids = new ArrayList<>();
|
||||
try {
|
||||
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];
|
||||
if (SNMPUtils.OID_PATTERN.matcher(snmpPropName).matches()) {
|
||||
oids.add(new OID(snmpPropName));
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (ArrayIndexOutOfBoundsException e) {
|
||||
return new OID[0];
|
||||
}
|
||||
return oids.toArray(new OID[0]);
|
||||
}
|
||||
|
||||
private static void addAttributeFromVariable(final VariableBinding variableBinding, final Map<String, String> attributes) {
|
||||
attributes.put(SNMP_PROP_PREFIX + variableBinding.getOid() + SNMP_PROP_DELIMITER + variableBinding.getVariable().getSyntax(), variableBinding.getVariable().toString());
|
||||
}
|
||||
@ -231,4 +264,9 @@ public final class SNMPUtils {
|
||||
}
|
||||
return errorMessage.map(s -> oid + ": " + s);
|
||||
}
|
||||
|
||||
public static int getVersion(final String snmpVersion) {
|
||||
return Optional.ofNullable(VERSION_MAP.get(snmpVersion))
|
||||
.orElseThrow(() -> new InvalidSnmpVersionException("Invalid SNMP version provided."));
|
||||
}
|
||||
}
|
||||
|
@ -14,3 +14,5 @@
|
||||
# limitations under the License.
|
||||
org.apache.nifi.snmp.processors.GetSNMP
|
||||
org.apache.nifi.snmp.processors.SetSNMP
|
||||
org.apache.nifi.snmp.processors.SendTrapSNMP
|
||||
org.apache.nifi.snmp.processors.ListenTrapSNMP
|
||||
|
@ -23,12 +23,19 @@
|
||||
<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
|
||||
This processor polls a SNMP agent to get information for a given OID or OIDs (Strategy = GET) or for all the sub-tree
|
||||
associated to a given OID or OIDs
|
||||
(Strategy = WALK). This processors supports SNMPv1, SNMPv2c and SNMPv3. The component is based on <a
|
||||
href="http://www.snmp4j.org/">SNMP4J</a>.
|
||||
</p>
|
||||
<p>
|
||||
The processor can compile the SNMP Get PDU from the attributes of an input flowfile (multiple OIDs can be specified)
|
||||
or from a single OID specified in the processor property. In the former case, the processor will only consider the
|
||||
OIDs specified in the flowfile.
|
||||
The processor is looking for attributes prefixed with <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. The flowfile attribute
|
||||
value can be empty (it will be later filled with the retrieved value and written into the outgoing flowfile).
|
||||
|
||||
When the processor is triggered, it sends the SNMP request and gets the information associated to request OID(s).
|
||||
Once response is received
|
||||
from the SNMP agent, a FlowFile is constructed. The FlowFile content is empty, all the information is written in the
|
||||
|
@ -0,0 +1,54 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<!--
|
||||
Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
contributor license agreements. See the NOTICE file distributed with
|
||||
this work for additional information regarding copyright ownership.
|
||||
The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
(the "License"); you may not use this file except in compliance with
|
||||
the License. You may obtain a copy of the License at
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
<head>
|
||||
<meta charset="utf-8"/>
|
||||
<title>ListenTrapSNMP</title>
|
||||
<link rel="stylesheet" href="../../../../../css/component-usage.css" type="text/css"/>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<h2>Summary</h2>
|
||||
<p>
|
||||
This processor listens to SNMP traps and creates a flowfile from the trap PDU.
|
||||
The versions SNMPv1, SNMPv2c and SNMPv3 are supproted. The component is based on <a href="http://www.snmp4j.org/">SNMP4J</a>.
|
||||
</p>
|
||||
<p>
|
||||
In case of SNMPv3, users can be specified in a json file. E.g.:
|
||||
<pre>
|
||||
<code>
|
||||
[
|
||||
{
|
||||
"securityName":"user1",
|
||||
"authProtocol":"MD5",
|
||||
"authPassphrase":"abc12345",
|
||||
"privProtocol":"DES",
|
||||
"privPassphrase":"abc12345"
|
||||
},
|
||||
{
|
||||
"securityName":"newUser2",
|
||||
"authProtocol":"MD5",
|
||||
"authPassphrase":"abc12345",
|
||||
"privProtocol":"AES256",
|
||||
"privPassphrase":"abc12345"
|
||||
}
|
||||
]
|
||||
|
||||
</code>
|
||||
</pre>
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
@ -0,0 +1,45 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<!--
|
||||
Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
contributor license agreements. See the NOTICE file distributed with
|
||||
this work for additional information regarding copyright ownership.
|
||||
The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
(the "License"); you may not use this file except in compliance with
|
||||
the License. You may obtain a copy of the License at
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
<head>
|
||||
<meta charset="utf-8"/>
|
||||
<title>SendTrapSNMP</title>
|
||||
<link rel="stylesheet" href="../../../../../css/component-usage.css" type="text/css"/>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<h2>Summary</h2>
|
||||
<p>
|
||||
This processor generates and transmits SNMP Traps to the specified SNMP manager. Attributes can be given
|
||||
as processor properties, either predefined or dynamically using Expression Language from flowfiles.
|
||||
Flowfile properties with snmp prefix (e.g. snmp$1.2.3.4.5 - OID) value can be used to define additional PDU variables.
|
||||
</p>
|
||||
<p>
|
||||
The allowable Generic Trap Types are:
|
||||
<ol start="0">
|
||||
<li>Cold Start</li>
|
||||
<li>Warm Start</li>
|
||||
<li>Link Down</li>
|
||||
<li>Link Up</li>
|
||||
<li>Authentication Failure</li>
|
||||
<li>EGP Neighbor Loss</li>
|
||||
<li>Enterprise Specific</li>
|
||||
</ol>
|
||||
|
||||
Specific trap type can set in case of Enterprise Specific generic trap type is chosen.
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
@ -0,0 +1,75 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.nifi.snmp.configuration;
|
||||
|
||||
import org.apache.nifi.remote.io.socket.NetworkUtils;
|
||||
import org.junit.Test;
|
||||
import org.snmp4j.mp.SnmpConstants;
|
||||
|
||||
import static org.apache.nifi.snmp.helper.configurations.SNMPConfigurationFactory.COMMUNITY_STRING;
|
||||
import static org.apache.nifi.snmp.helper.configurations.SNMPConfigurationFactory.DEFAULT_HOST;
|
||||
import static org.apache.nifi.snmp.helper.configurations.SNMPV3ConfigurationFactory.AUTH_PASSPHRASE;
|
||||
import static org.apache.nifi.snmp.helper.configurations.SNMPV3ConfigurationFactory.AUTH_PROTOCOL;
|
||||
import static org.apache.nifi.snmp.helper.configurations.SNMPV3ConfigurationFactory.PRIV_PASSPHRASE;
|
||||
import static org.apache.nifi.snmp.helper.configurations.SNMPV3ConfigurationFactory.PRIV_PROTOCOL;
|
||||
import static org.apache.nifi.snmp.helper.configurations.SNMPV3ConfigurationFactory.SECURITY_LEVEL;
|
||||
import static org.apache.nifi.snmp.helper.configurations.SNMPV3ConfigurationFactory.SECURITY_NAME;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
public class SNMPConfigurationTest {
|
||||
|
||||
private static final int MANAGER_PORT = NetworkUtils.availablePort();
|
||||
private static final String TARGET_PORT = "55556";
|
||||
private static final int RETRIES = 3;
|
||||
private static final int VERSION = SnmpConstants.version3;
|
||||
private static final int TIMEOUT_IN_MS = 3000;
|
||||
|
||||
@Test
|
||||
public void testMembersAreSetCorrectly() {
|
||||
final SNMPConfiguration snmpConfiguration = SNMPConfiguration.builder()
|
||||
.setManagerPort(MANAGER_PORT)
|
||||
.setTargetHost(DEFAULT_HOST)
|
||||
.setTargetPort(TARGET_PORT)
|
||||
.setRetries(RETRIES)
|
||||
.setTimeoutInMs(TIMEOUT_IN_MS)
|
||||
.setVersion(VERSION)
|
||||
.setCommunityString(COMMUNITY_STRING)
|
||||
.setSecurityLevel(SECURITY_LEVEL)
|
||||
.setSecurityName(SECURITY_NAME)
|
||||
.setAuthProtocol(AUTH_PROTOCOL)
|
||||
.setAuthPassphrase(AUTH_PASSPHRASE)
|
||||
.setPrivacyProtocol(PRIV_PROTOCOL)
|
||||
.setPrivacyPassphrase(PRIV_PASSPHRASE)
|
||||
.build();
|
||||
|
||||
assertEquals(MANAGER_PORT, snmpConfiguration.getManagerPort());
|
||||
assertEquals(DEFAULT_HOST, snmpConfiguration.getTargetHost());
|
||||
assertEquals(TARGET_PORT, snmpConfiguration.getTargetPort());
|
||||
assertEquals(RETRIES, snmpConfiguration.getRetries());
|
||||
assertEquals(TIMEOUT_IN_MS, snmpConfiguration.getTimeoutInMs());
|
||||
assertEquals(VERSION, snmpConfiguration.getVersion());
|
||||
assertEquals(COMMUNITY_STRING, snmpConfiguration.getCommunityString());
|
||||
assertEquals(SECURITY_LEVEL, snmpConfiguration.getSecurityLevel());
|
||||
assertEquals(SECURITY_NAME, snmpConfiguration.getSecurityName());
|
||||
assertEquals(AUTH_PROTOCOL, snmpConfiguration.getAuthProtocol());
|
||||
assertEquals(AUTH_PASSPHRASE, snmpConfiguration.getAuthPassphrase());
|
||||
assertEquals(PRIV_PROTOCOL, snmpConfiguration.getPrivacyProtocol());
|
||||
assertEquals(PRIV_PASSPHRASE, snmpConfiguration.getPrivacyPassphrase());
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,141 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.nifi.snmp.configuration;
|
||||
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.rules.ExpectedException;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertThrows;
|
||||
|
||||
public class V1TrapConfigurationTest {
|
||||
|
||||
private static final String AGENT_ADDRESS = "127.0.0.1";
|
||||
private static final String ENTERPRISE_OID = "1.3.6.1.4.1.8072.2.3.0.1";
|
||||
private static final int GENERIC_TRAP_TYPE = 6;
|
||||
private static final Integer SPECIFIC_TRAP_TYPE = 2;
|
||||
|
||||
@Rule
|
||||
public ExpectedException exceptionRule = ExpectedException.none();
|
||||
|
||||
@Test
|
||||
public void testMembersAreSetCorrectly() {
|
||||
final V1TrapConfiguration v1TrapConfiguration = V1TrapConfiguration.builder()
|
||||
.enterpriseOid(ENTERPRISE_OID)
|
||||
.agentAddress(AGENT_ADDRESS)
|
||||
.genericTrapType(String.valueOf(GENERIC_TRAP_TYPE))
|
||||
.specificTrapType(String.valueOf(SPECIFIC_TRAP_TYPE))
|
||||
.build();
|
||||
|
||||
assertEquals(ENTERPRISE_OID, v1TrapConfiguration.getEnterpriseOid());
|
||||
assertEquals(AGENT_ADDRESS, v1TrapConfiguration.getAgentAddress());
|
||||
assertEquals(GENERIC_TRAP_TYPE, v1TrapConfiguration.getGenericTrapType());
|
||||
assertEquals(SPECIFIC_TRAP_TYPE, v1TrapConfiguration.getSpecificTrapType());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRequireNonNullEnterpriseOid() {
|
||||
exceptionRule.expect(IllegalArgumentException.class);
|
||||
exceptionRule.expectMessage("Enterprise OID must be specified.");
|
||||
V1TrapConfiguration.builder()
|
||||
.agentAddress(AGENT_ADDRESS)
|
||||
.genericTrapType(String.valueOf(GENERIC_TRAP_TYPE))
|
||||
.specificTrapType(String.valueOf(SPECIFIC_TRAP_TYPE))
|
||||
.build();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRequireNonNullAgentAddress() {
|
||||
exceptionRule.expect(IllegalArgumentException.class);
|
||||
exceptionRule.expectMessage("Agent address must be specified.");
|
||||
V1TrapConfiguration.builder()
|
||||
.enterpriseOid(ENTERPRISE_OID)
|
||||
.genericTrapType(String.valueOf(GENERIC_TRAP_TYPE))
|
||||
.specificTrapType(String.valueOf(SPECIFIC_TRAP_TYPE))
|
||||
.build();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGenericTypeIsNegative() {
|
||||
final IllegalArgumentException exception = assertThrows(IllegalArgumentException.class, () -> V1TrapConfiguration.builder()
|
||||
.agentAddress(AGENT_ADDRESS)
|
||||
.enterpriseOid(ENTERPRISE_OID)
|
||||
.genericTrapType("-1")
|
||||
.build()
|
||||
);
|
||||
assertEquals("Generic Trap Type must be between 0 and 6.", exception.getMessage());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGenericTypeIsGreaterThan6() {
|
||||
final IllegalArgumentException exception = assertThrows(IllegalArgumentException.class, () -> V1TrapConfiguration.builder()
|
||||
.agentAddress(AGENT_ADDRESS)
|
||||
.enterpriseOid(ENTERPRISE_OID)
|
||||
.genericTrapType("7")
|
||||
.build()
|
||||
);
|
||||
assertEquals("Generic Trap Type must be between 0 and 6.", exception.getMessage());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGenericTypeIsNotANumber() {
|
||||
final IllegalArgumentException exception = assertThrows(IllegalArgumentException.class, () -> V1TrapConfiguration.builder()
|
||||
.agentAddress(AGENT_ADDRESS)
|
||||
.enterpriseOid(ENTERPRISE_OID)
|
||||
.genericTrapType("invalid")
|
||||
.build()
|
||||
);
|
||||
assertEquals("Generic Trap Type is not a number.", exception.getMessage());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSpecificTrapTypeIsNegative() {
|
||||
final IllegalArgumentException exception = assertThrows(IllegalArgumentException.class, () -> V1TrapConfiguration.builder()
|
||||
.agentAddress(AGENT_ADDRESS)
|
||||
.enterpriseOid(ENTERPRISE_OID)
|
||||
.genericTrapType(String.valueOf(GENERIC_TRAP_TYPE))
|
||||
.specificTrapType("-1")
|
||||
.build()
|
||||
);
|
||||
assertEquals("Specific Trap Type must be between 0 and 2147483647.", exception.getMessage());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGenericTrapTypeIsEnterpriseSpecificButSpecificTrapTypeIsNotSet() {
|
||||
final IllegalArgumentException exception = assertThrows(IllegalArgumentException.class, () -> V1TrapConfiguration.builder()
|
||||
.agentAddress(AGENT_ADDRESS)
|
||||
.enterpriseOid(ENTERPRISE_OID)
|
||||
.genericTrapType(String.valueOf(GENERIC_TRAP_TYPE))
|
||||
.build()
|
||||
);
|
||||
assertEquals("Generic Trap Type is [6 - Enterprise Specific] but Specific Trap Type is not provided or not a number.", exception.getMessage());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGenericTrapTypeIsNotEnterpriseSpecificButSpecificTrapTypeIsSet() {
|
||||
final IllegalArgumentException exception = assertThrows(IllegalArgumentException.class, () -> V1TrapConfiguration.builder()
|
||||
.agentAddress(AGENT_ADDRESS)
|
||||
.enterpriseOid(ENTERPRISE_OID)
|
||||
.genericTrapType("5")
|
||||
.specificTrapType("123")
|
||||
.build()
|
||||
);
|
||||
assertEquals("Invalid argument: Generic Trap Type is not [6 - Enterprise Specific] but Specific Trap Type is provided.", exception.getMessage());
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,165 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.nifi.snmp.dto;
|
||||
|
||||
import org.apache.nifi.util.LogMessage;
|
||||
import org.apache.nifi.util.MockComponentLog;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
import org.mockito.Mock;
|
||||
import org.snmp4j.CommunityTarget;
|
||||
import org.snmp4j.Target;
|
||||
import org.snmp4j.smi.OID;
|
||||
import org.snmp4j.smi.OctetString;
|
||||
import org.snmp4j.smi.UdpAddress;
|
||||
import org.snmp4j.smi.VariableBinding;
|
||||
import org.snmp4j.util.TreeEvent;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
public class SNMPTreeResponseTest {
|
||||
|
||||
private static final String SNMP_SEPARATOR = "$";
|
||||
private static final String SNMP_PREFIX = "snmp" + SNMP_SEPARATOR;
|
||||
private static final String VB_SYNTAX = "4";
|
||||
|
||||
private static final String OID_1 = "1.3.6.1.4.1.32437.1.5.1.4.2.0";
|
||||
private static final String OID_2 = "1.3.6.1.4.1.32437.1.5.1.4.3.0";
|
||||
private static final String OID_3 = "1.3.6.1.4.1.32437.1.5.1.4.4.0";
|
||||
private static final String OID_1_VALUE = "OID_1_VALUE";
|
||||
private static final String OID_2_VALUE = "OID_2_VALUE";
|
||||
private static final String OID_3_VALUE = "OID_3_VALUE";
|
||||
|
||||
private static final String TARGET_ADDRESS = "127.0.0.1/50555";
|
||||
|
||||
private static VariableBinding[] vbs1;
|
||||
private static VariableBinding[] vbs2;
|
||||
private static VariableBinding[] vbs3;
|
||||
private static Map<String, String> vbMap;
|
||||
@Mock
|
||||
private static Target target;
|
||||
|
||||
@BeforeClass
|
||||
public static void setUp() {
|
||||
vbMap = new HashMap<>();
|
||||
vbMap.put(SNMP_PREFIX + OID_1 + SNMP_SEPARATOR + VB_SYNTAX, OID_1_VALUE);
|
||||
vbMap.put(SNMP_PREFIX + OID_2 + SNMP_SEPARATOR + VB_SYNTAX, OID_2_VALUE);
|
||||
vbMap.put(SNMP_PREFIX + OID_3 + SNMP_SEPARATOR + VB_SYNTAX, OID_3_VALUE);
|
||||
|
||||
target = new CommunityTarget();
|
||||
target.setAddress(new UdpAddress(TARGET_ADDRESS));
|
||||
|
||||
vbs1 = new VariableBinding[]{
|
||||
new VariableBinding(new OID(OID_1), new OctetString(OID_1_VALUE)),
|
||||
};
|
||||
vbs2 = new VariableBinding[]{
|
||||
new VariableBinding(new OID(OID_2), new OctetString(OID_2_VALUE)),
|
||||
};
|
||||
vbs3 = new VariableBinding[]{
|
||||
new VariableBinding(new OID(OID_3), new OctetString(OID_3_VALUE))
|
||||
};
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetAttributes() {
|
||||
final TreeEvent treeEvent1 = mock(TreeEvent.class);
|
||||
when(treeEvent1.getVariableBindings()).thenReturn(vbs1);
|
||||
final TreeEvent treeEvent2 = mock(TreeEvent.class);
|
||||
when(treeEvent2.getVariableBindings()).thenReturn(vbs2);
|
||||
final TreeEvent treeEvent3 = mock(TreeEvent.class);
|
||||
when(treeEvent3.getVariableBindings()).thenReturn(vbs3);
|
||||
|
||||
final List<TreeEvent> treeEvents = new ArrayList<>();
|
||||
Collections.addAll(treeEvents, treeEvent1, treeEvent2, treeEvent3);
|
||||
|
||||
final SNMPTreeResponse snmpTreeResponse = new SNMPTreeResponse(target, treeEvents);
|
||||
final Map<String, String> attributes = snmpTreeResponse.getAttributes();
|
||||
|
||||
assertEquals(3, attributes.size());
|
||||
assertEquals(vbMap, attributes);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetAttributesFlattensEmptyVariableBindingArrays() {
|
||||
final TreeEvent emptyTreeEvent = mock(TreeEvent.class);
|
||||
when(emptyTreeEvent.getVariableBindings()).thenReturn(new VariableBinding[0]);
|
||||
final TreeEvent normalTreeEvent = mock(TreeEvent.class);
|
||||
when(normalTreeEvent.getVariableBindings()).thenReturn(vbs1);
|
||||
|
||||
final List<TreeEvent> treeEvents = new ArrayList<>();
|
||||
Collections.addAll(treeEvents, emptyTreeEvent, normalTreeEvent);
|
||||
|
||||
final SNMPTreeResponse snmpTreeResponse = new SNMPTreeResponse(target, treeEvents);
|
||||
final Map<String, String> attributes = snmpTreeResponse.getAttributes();
|
||||
|
||||
assertEquals(1, attributes.size());
|
||||
assertEquals(OID_1_VALUE, attributes.get(SNMP_PREFIX + OID_1 + SNMP_SEPARATOR + VB_SYNTAX));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetAttributesFiltersNullVariableBindings() {
|
||||
final TreeEvent nullTreeEvent = mock(TreeEvent.class);
|
||||
when(nullTreeEvent.getVariableBindings()).thenReturn(null);
|
||||
final TreeEvent normalTreeEvent = mock(TreeEvent.class);
|
||||
when(normalTreeEvent.getVariableBindings()).thenReturn(vbs1);
|
||||
|
||||
final List<TreeEvent> treeEvents = new ArrayList<>();
|
||||
Collections.addAll(treeEvents, nullTreeEvent, normalTreeEvent);
|
||||
|
||||
final SNMPTreeResponse snmpTreeResponse = new SNMPTreeResponse(target, treeEvents);
|
||||
final Map<String, String> attributes = snmpTreeResponse.getAttributes();
|
||||
|
||||
assertEquals(1, attributes.size());
|
||||
assertEquals(OID_1_VALUE, attributes.get(SNMP_PREFIX + OID_1 + SNMP_SEPARATOR + VB_SYNTAX));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetTargetAddress() {
|
||||
final TreeEvent treeEvent = mock(TreeEvent.class);
|
||||
final List<TreeEvent> treeEvents = new ArrayList<>();
|
||||
treeEvents.add(treeEvent);
|
||||
final SNMPTreeResponse snmpTreeResponse = new SNMPTreeResponse(target, treeEvents);
|
||||
final String actualTargetAddress = snmpTreeResponse.getTargetAddress();
|
||||
|
||||
assertEquals(TARGET_ADDRESS, actualTargetAddress);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testLogErrors() {
|
||||
final MockComponentLog logger = new MockComponentLog("id1", new Object());
|
||||
|
||||
|
||||
final List<TreeEvent> treeEvents = new ArrayList<>();
|
||||
final TreeEvent treeEvent = mock(TreeEvent.class);
|
||||
when(treeEvent.isError()).thenReturn(true);
|
||||
when(treeEvent.getErrorMessage()).thenReturn("ERROR MESSAGE");
|
||||
treeEvents.add(treeEvent);
|
||||
final SNMPTreeResponse snmpTreeResponse = new SNMPTreeResponse(target, treeEvents);
|
||||
snmpTreeResponse.logErrors(logger);
|
||||
|
||||
final List<LogMessage> errorMessages = logger.getErrorMessages();
|
||||
System.out.println("asd");
|
||||
}
|
||||
}
|
@ -1,68 +0,0 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.nifi.snmp.factory;
|
||||
|
||||
import org.apache.nifi.snmp.configuration.SNMPConfiguration;
|
||||
import org.apache.nifi.snmp.configuration.SNMPConfigurationBuilder;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.snmp4j.Snmp;
|
||||
import org.snmp4j.mp.SnmpConstants;
|
||||
import org.snmp4j.security.UsmUser;
|
||||
import org.snmp4j.smi.OID;
|
||||
import org.snmp4j.smi.OctetString;
|
||||
|
||||
import static org.hamcrest.CoreMatchers.equalTo;
|
||||
import static org.hamcrest.CoreMatchers.is;
|
||||
import static org.hamcrest.MatcherAssert.assertThat;
|
||||
|
||||
public class SNMPClientFactoryTest {
|
||||
|
||||
private final SNMPConfigurationBuilder configurationBuilder = new SNMPConfigurationBuilder()
|
||||
.setAgentHost("127.0.0.1")
|
||||
.setAgentPort("12345")
|
||||
.setRetries(1)
|
||||
.setTimeout(1000)
|
||||
.setSecurityLevel("noAuthNoPriv")
|
||||
.setSecurityName("userName")
|
||||
.setAuthProtocol("SHA")
|
||||
.setAuthPassphrase("authPassword")
|
||||
.setPrivacyProtocol("DES")
|
||||
.setPrivacyPassphrase("privacyPassword")
|
||||
.setCommunityString("public");
|
||||
|
||||
@Test
|
||||
public void testSnmpV3ClientWithoutCorrespondingAgentDoesNotHaveUSM() {
|
||||
final SNMPConfiguration configuration = configurationBuilder
|
||||
.setVersion(SnmpConstants.version3)
|
||||
.build();
|
||||
|
||||
|
||||
final SNMPFactory snmpFactory = new CompositeSNMPFactory();
|
||||
final Snmp snmpManager = snmpFactory.createSnmpManagerInstance(configuration);
|
||||
final UsmUser user = snmpManager.getUSM().getUserTable().getUser(new OctetString("userName")).getUsmUser();
|
||||
|
||||
final OID usmHMACSHAAuthProtocol = new OID("1.3.6.1.6.3.10.1.1.3");
|
||||
final OID usmDESPrivProtocol = new OID("1.3.6.1.6.3.10.1.2.2");
|
||||
|
||||
assertThat("userName", is(equalTo(user.getSecurityName().toString())));
|
||||
assertThat(usmHMACSHAAuthProtocol, is(equalTo(user.getAuthenticationProtocol())));
|
||||
assertThat("authPassword", is(equalTo(user.getAuthenticationPassphrase().toString())));
|
||||
assertThat(usmDESPrivProtocol, is(equalTo(user.getPrivacyProtocol())));
|
||||
assertThat("privacyPassword", is(equalTo(user.getPrivacyPassphrase().toString())));
|
||||
assertThat(3, is(equalTo(user.getSecurityModel())));
|
||||
}
|
||||
}
|
@ -0,0 +1,47 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.nifi.snmp.factory.core;
|
||||
|
||||
import org.apache.nifi.snmp.configuration.SNMPConfiguration;
|
||||
import org.junit.Test;
|
||||
import org.snmp4j.Snmp;
|
||||
import org.snmp4j.Target;
|
||||
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.spy;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
public class SNMPContextTest {
|
||||
|
||||
@Test
|
||||
public void testCreateSNMPContext() {
|
||||
final SNMPContext snmpContext = spy(SNMPContext.class);
|
||||
final Snmp mockSnmpManager = mock(Snmp.class);
|
||||
final Target mockTarget = mock(Target.class);
|
||||
final SNMPConfiguration snmpConfiguration = mock(SNMPConfiguration.class);
|
||||
|
||||
when(snmpContext.createSnmpManagerInstance(snmpConfiguration)).thenReturn(mockSnmpManager);
|
||||
when(snmpContext.createTargetInstance(snmpConfiguration)).thenReturn(mockTarget);
|
||||
|
||||
snmpContext.createSNMPResourceHandler(snmpConfiguration);
|
||||
|
||||
verify(snmpContext).createSnmpManagerInstance(snmpConfiguration);
|
||||
verify(snmpContext).createTargetInstance(snmpConfiguration);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,37 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.nifi.snmp.factory.core;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.snmp4j.mp.SnmpConstants;
|
||||
|
||||
import static org.hamcrest.MatcherAssert.assertThat;
|
||||
import static org.hamcrest.core.IsInstanceOf.instanceOf;
|
||||
|
||||
public class SNMPFactoryProviderTest {
|
||||
|
||||
@Test
|
||||
public void testCreateFactoryByVersion() {
|
||||
final SNMPContext snmpV1V2cFactoryFromVersion1 = SNMPFactoryProvider.getFactory(SnmpConstants.version1);
|
||||
final SNMPContext snmpV1V2cFactoryFromVersion2c = SNMPFactoryProvider.getFactory(SnmpConstants.version2c);
|
||||
final SNMPContext snmpV3Factory = SNMPFactoryProvider.getFactory(SnmpConstants.version3);
|
||||
assertThat(snmpV1V2cFactoryFromVersion1, instanceOf(V1V2cSNMPFactory.class));
|
||||
assertThat(snmpV1V2cFactoryFromVersion2c, instanceOf(V1V2cSNMPFactory.class));
|
||||
assertThat(snmpV3Factory, instanceOf(V3SNMPFactory.class));
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,90 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.nifi.snmp.factory.core;
|
||||
|
||||
import org.apache.nifi.remote.io.socket.NetworkUtils;
|
||||
import org.apache.nifi.snmp.configuration.SNMPConfiguration;
|
||||
import org.apache.nifi.util.StringUtils;
|
||||
import org.junit.Test;
|
||||
import org.snmp4j.CommunityTarget;
|
||||
import org.snmp4j.Snmp;
|
||||
import org.snmp4j.Target;
|
||||
import org.snmp4j.security.SecurityLevel;
|
||||
|
||||
import static org.apache.nifi.snmp.helper.configurations.SNMPConfigurationFactory.DEFAULT_HOST;
|
||||
import static org.hamcrest.MatcherAssert.assertThat;
|
||||
import static org.hamcrest.core.IsInstanceOf.instanceOf;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.mockito.Mockito.spy;
|
||||
import static org.mockito.Mockito.verify;
|
||||
|
||||
public class V1V2cSNMPFactoryTest {
|
||||
|
||||
private static final int RETRIES = 3;
|
||||
|
||||
@Test
|
||||
public void testFactoryCreatesV1V2Configuration() {
|
||||
final V1V2cSNMPFactory snmpFactory = new V1V2cSNMPFactory();
|
||||
final int managerPort = NetworkUtils.availablePort();
|
||||
final String targetPort = String.valueOf(NetworkUtils.availablePort());
|
||||
final SNMPConfiguration snmpConfiguration = getSnmpConfiguration(managerPort, targetPort);
|
||||
|
||||
final Target target = snmpFactory.createTargetInstance(snmpConfiguration);
|
||||
|
||||
assertThat(target, instanceOf(CommunityTarget.class));
|
||||
assertEquals(DEFAULT_HOST + "/" + targetPort, target.getAddress().toString());
|
||||
assertEquals(RETRIES, target.getRetries());
|
||||
assertEquals(1, target.getSecurityLevel());
|
||||
assertEquals(StringUtils.EMPTY, target.getSecurityName().toString());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFactoryCreatesSnmpManager() {
|
||||
final V1V2cSNMPFactory snmpFactory = new V1V2cSNMPFactory();
|
||||
final int managerPort = NetworkUtils.availablePort();
|
||||
final String targetPort = String.valueOf(NetworkUtils.availablePort());
|
||||
final SNMPConfiguration snmpConfiguration = getSnmpConfiguration(managerPort, targetPort);
|
||||
|
||||
final Snmp snmpManager = snmpFactory.createSnmpManagerInstance(snmpConfiguration);
|
||||
|
||||
final String address = snmpManager.getMessageDispatcher().getTransportMappings().iterator().next().getListenAddress().toString();
|
||||
assertEquals(DEFAULT_HOST + "/" + managerPort, address);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFactoryCreatesResourceHandler() {
|
||||
final V1V2cSNMPFactory snmpFactory = spy(V1V2cSNMPFactory.class);
|
||||
final int managerPort = NetworkUtils.availablePort();
|
||||
final String targetPort = String.valueOf(NetworkUtils.availablePort());
|
||||
final SNMPConfiguration snmpConfiguration = getSnmpConfiguration(managerPort, targetPort);
|
||||
|
||||
snmpFactory.createSNMPResourceHandler(snmpConfiguration);
|
||||
|
||||
verify(snmpFactory).createTargetInstance(snmpConfiguration);
|
||||
verify(snmpFactory).createSnmpManagerInstance(snmpConfiguration);
|
||||
}
|
||||
|
||||
private SNMPConfiguration getSnmpConfiguration(int managerPort, String targetPort) {
|
||||
return new SNMPConfiguration.Builder()
|
||||
.setRetries(RETRIES)
|
||||
.setManagerPort(managerPort)
|
||||
.setTargetHost(DEFAULT_HOST)
|
||||
.setTargetPort(targetPort)
|
||||
.setSecurityLevel(SecurityLevel.noAuthNoPriv.name())
|
||||
.build();
|
||||
}
|
||||
}
|
@ -0,0 +1,107 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.nifi.snmp.factory.core;
|
||||
|
||||
import org.apache.nifi.remote.io.socket.NetworkUtils;
|
||||
import org.apache.nifi.snmp.configuration.SNMPConfiguration;
|
||||
import org.junit.Test;
|
||||
import org.snmp4j.Snmp;
|
||||
import org.snmp4j.Target;
|
||||
import org.snmp4j.UserTarget;
|
||||
import org.snmp4j.security.SecurityLevel;
|
||||
import org.snmp4j.security.SecurityModels;
|
||||
import org.snmp4j.security.USM;
|
||||
import org.snmp4j.smi.Integer32;
|
||||
import org.snmp4j.smi.OctetString;
|
||||
|
||||
import static org.apache.nifi.snmp.helper.configurations.SNMPConfigurationFactory.DEFAULT_HOST;
|
||||
import static org.apache.nifi.snmp.helper.configurations.SNMPV3ConfigurationFactory.AUTH_PASSPHRASE;
|
||||
import static org.apache.nifi.snmp.helper.configurations.SNMPV3ConfigurationFactory.AUTH_PROTOCOL;
|
||||
import static org.apache.nifi.snmp.helper.configurations.SNMPV3ConfigurationFactory.PRIV_PASSPHRASE;
|
||||
import static org.apache.nifi.snmp.helper.configurations.SNMPV3ConfigurationFactory.PRIV_PROTOCOL;
|
||||
import static org.apache.nifi.snmp.helper.configurations.SNMPV3ConfigurationFactory.SECURITY_NAME;
|
||||
import static org.hamcrest.MatcherAssert.assertThat;
|
||||
import static org.hamcrest.core.IsInstanceOf.instanceOf;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.mockito.Mockito.spy;
|
||||
import static org.mockito.Mockito.verify;
|
||||
|
||||
public class V3SNMPFactoryTest {
|
||||
|
||||
private static final int RETRIES = 3;
|
||||
private static final int EXPECTED_SECURITY_LEVEL = 3;
|
||||
|
||||
@Test
|
||||
public void testFactoryCreatesTarget() {
|
||||
final V3SNMPFactory snmpFactory = new V3SNMPFactory();
|
||||
final int managerPort = NetworkUtils.availablePort();
|
||||
final String targetPort = String.valueOf(NetworkUtils.availablePort());
|
||||
final SNMPConfiguration snmpConfiguration = getSnmpConfiguration(managerPort, targetPort);
|
||||
|
||||
final Target target = snmpFactory.createTargetInstance(snmpConfiguration);
|
||||
|
||||
assertThat(target, instanceOf(UserTarget.class));
|
||||
assertEquals(DEFAULT_HOST + "/" + targetPort, target.getAddress().toString());
|
||||
assertEquals(RETRIES, target.getRetries());
|
||||
assertEquals(EXPECTED_SECURITY_LEVEL, target.getSecurityLevel());
|
||||
assertEquals(SECURITY_NAME, target.getSecurityName().toString());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFactoryCreatesSnmpManager() {
|
||||
final V3SNMPFactory snmpFactory = new V3SNMPFactory();
|
||||
final int managerPort = NetworkUtils.availablePort();
|
||||
final String targetPort = String.valueOf(NetworkUtils.availablePort());
|
||||
final SNMPConfiguration snmpConfiguration = getSnmpConfiguration(managerPort, targetPort);
|
||||
|
||||
final Snmp snmpManager = snmpFactory.createSnmpManagerInstance(snmpConfiguration);
|
||||
|
||||
final String address = snmpManager.getMessageDispatcher().getTransportMappings().iterator().next().getListenAddress().toString();
|
||||
USM usm = (USM) SecurityModels.getInstance().getSecurityModel(new Integer32(3));
|
||||
assertEquals(DEFAULT_HOST + "/" + managerPort, address);
|
||||
assertTrue(usm.hasUser(null, new OctetString("SHAAES128")));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFactoryCreatesResourceHandler() {
|
||||
final V3SNMPFactory snmpFactory = spy(V3SNMPFactory.class);
|
||||
final int managerPort = NetworkUtils.availablePort();
|
||||
final String targetPort = String.valueOf(NetworkUtils.availablePort());
|
||||
final SNMPConfiguration snmpConfiguration = getSnmpConfiguration(managerPort, targetPort);
|
||||
snmpFactory.createSNMPResourceHandler(snmpConfiguration);
|
||||
|
||||
verify(snmpFactory).createTargetInstance(snmpConfiguration);
|
||||
verify(snmpFactory).createSnmpManagerInstance(snmpConfiguration);
|
||||
}
|
||||
|
||||
private SNMPConfiguration getSnmpConfiguration(int managerPort, String targetPort) {
|
||||
return new SNMPConfiguration.Builder()
|
||||
.setRetries(RETRIES)
|
||||
.setManagerPort(managerPort)
|
||||
.setTargetHost(DEFAULT_HOST)
|
||||
.setTargetPort(targetPort)
|
||||
.setSecurityLevel(SecurityLevel.authPriv.name())
|
||||
.setSecurityName(SECURITY_NAME)
|
||||
.setAuthProtocol(AUTH_PROTOCOL)
|
||||
.setAuthPassphrase(AUTH_PASSPHRASE)
|
||||
.setPrivacyProtocol(PRIV_PROTOCOL)
|
||||
.setPrivacyPassphrase(PRIV_PASSPHRASE)
|
||||
.build();
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,59 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.nifi.snmp.factory.trap;
|
||||
|
||||
import org.apache.nifi.snmp.configuration.V1TrapConfiguration;
|
||||
import org.junit.Test;
|
||||
import org.snmp4j.PDU;
|
||||
import org.snmp4j.PDUv1;
|
||||
import org.snmp4j.Target;
|
||||
|
||||
import java.time.Instant;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.mockito.Mockito.mock;
|
||||
|
||||
public class V1TrapPDUFactoryTest {
|
||||
|
||||
private static final String AGENT_ADDRESS = "127.0.0.1";
|
||||
private static final String ENTERPRISE_OID = "1.3.6.1.4.1.8072.2.3.0.1";
|
||||
private static final int GENERIC_TRAP_TYPE = 6;
|
||||
private static final int SPECIFIC_TRAP_TYPE = 2;
|
||||
|
||||
@Test
|
||||
public void testCreateV1TrapPdu() {
|
||||
final Target mockTarget = mock(Target.class);
|
||||
final V1TrapConfiguration v1TrapConfiguration = V1TrapConfiguration.builder()
|
||||
.enterpriseOid(ENTERPRISE_OID)
|
||||
.agentAddress(AGENT_ADDRESS)
|
||||
.genericTrapType(String.valueOf(GENERIC_TRAP_TYPE))
|
||||
.specificTrapType(String.valueOf(SPECIFIC_TRAP_TYPE))
|
||||
.build();
|
||||
|
||||
final V1TrapPDUFactory v1TrapPduFactory = new V1TrapPDUFactory(mockTarget, Instant.now());
|
||||
final PDU pdu = v1TrapPduFactory.get(v1TrapConfiguration);
|
||||
|
||||
assertEquals(PDU.V1TRAP, pdu.getType());
|
||||
|
||||
final PDUv1 pduV1 = (PDUv1) pdu;
|
||||
|
||||
assertEquals(ENTERPRISE_OID, pduV1.getEnterprise().toString());
|
||||
assertEquals(AGENT_ADDRESS, pduV1.getAgentAddress().toString());
|
||||
assertEquals(GENERIC_TRAP_TYPE, pduV1.getGenericTrap());
|
||||
assertEquals(SPECIFIC_TRAP_TYPE, pduV1.getSpecificTrap());
|
||||
}
|
||||
}
|
@ -0,0 +1,58 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.nifi.snmp.factory.trap;
|
||||
|
||||
import org.apache.nifi.snmp.configuration.V2TrapConfiguration;
|
||||
import org.junit.Test;
|
||||
import org.snmp4j.PDU;
|
||||
import org.snmp4j.Target;
|
||||
import org.snmp4j.mp.SnmpConstants;
|
||||
import org.snmp4j.smi.VariableBinding;
|
||||
|
||||
import java.time.Instant;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
import java.util.Vector;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.mockito.Mockito.mock;
|
||||
|
||||
public class V2TrapPDUFactoryTest {
|
||||
|
||||
private static final String TRAP_OID = "1.3.6.1.4.1.8072.2.3.0.1";
|
||||
|
||||
@Test
|
||||
public void testCreateV2TrapPdu() {
|
||||
final Target mockTarget = mock(Target.class);
|
||||
final V2TrapConfiguration v2TrapConfiguration = new V2TrapConfiguration(TRAP_OID);
|
||||
final V2TrapPDUFactory v2TrapPduFactory = new V2TrapPDUFactory(mockTarget, Instant.now());
|
||||
|
||||
final PDU pdu = v2TrapPduFactory.get(v2TrapConfiguration);
|
||||
|
||||
final Vector<? extends VariableBinding> variableBindings = pdu.getVariableBindings();
|
||||
|
||||
Set<String> expected = new HashSet<>(Arrays.asList(SnmpConstants.snmpTrapOID.toString(), TRAP_OID));
|
||||
Set<String> actual = variableBindings.stream()
|
||||
.flatMap(c -> Stream.of(c.getOid().toString(), c.getVariable().toString()))
|
||||
.collect(Collectors.toSet());
|
||||
assertTrue(actual.containsAll(expected));
|
||||
}
|
||||
|
||||
}
|
@ -1,68 +0,0 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.nifi.snmp.helper;
|
||||
|
||||
import org.snmp4j.CommunityTarget;
|
||||
import org.snmp4j.Snmp;
|
||||
import org.snmp4j.UserTarget;
|
||||
import org.snmp4j.security.UsmUser;
|
||||
import org.snmp4j.smi.OID;
|
||||
import org.snmp4j.smi.OctetString;
|
||||
import org.snmp4j.smi.UdpAddress;
|
||||
import org.snmp4j.transport.DefaultUdpTransportMapping;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
public class SNMPTestUtils {
|
||||
|
||||
public static Snmp createSnmpClient() throws IOException {
|
||||
final DefaultUdpTransportMapping transportMapping = new DefaultUdpTransportMapping();
|
||||
transportMapping.listen();
|
||||
return new Snmp(transportMapping);
|
||||
}
|
||||
|
||||
public static CommunityTarget createCommTarget(final String community, final String address, final int version) {
|
||||
final CommunityTarget target = new CommunityTarget();
|
||||
target.setVersion(version);
|
||||
target.setCommunity(new OctetString(community));
|
||||
target.setAddress(new UdpAddress(address));
|
||||
target.setRetries(0);
|
||||
target.setTimeout(500);
|
||||
return target;
|
||||
}
|
||||
|
||||
public static UserTarget createUserTarget(final String address, final int securityLevel, final String securityName, final int version) {
|
||||
final UserTarget target = new UserTarget();
|
||||
target.setVersion(version);
|
||||
target.setSecurityLevel(securityLevel);
|
||||
target.setSecurityName(new OctetString(securityName));
|
||||
target.setAddress(new UdpAddress(address));
|
||||
target.setRetries(0);
|
||||
target.setTimeout(500);
|
||||
return target;
|
||||
}
|
||||
|
||||
public static UserTarget prepareUser(final Snmp snmp, final int version, final String address, final int securityLevel, final String securityName,
|
||||
final OID auth, final OID priv, final String authPwd, final String privPwd) {
|
||||
snmp.getUSM().removeAllUsers();
|
||||
final OctetString aPwd = authPwd != null ? new OctetString(authPwd) : null;
|
||||
final OctetString pPwd = privPwd != null ? new OctetString(privPwd) : null;
|
||||
snmp.getUSM().addUser(new OctetString(securityName), new UsmUser(new OctetString(securityName), auth, aPwd, priv, pPwd));
|
||||
return createUserTarget(address, securityLevel, securityName, version);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,46 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.nifi.snmp.helper;
|
||||
|
||||
import org.apache.nifi.snmp.configuration.V1TrapConfiguration;
|
||||
import org.apache.nifi.snmp.configuration.V2TrapConfiguration;
|
||||
import org.snmp4j.PDUv1;
|
||||
|
||||
public class TrapConfigurationFactory {
|
||||
|
||||
// v1 specific
|
||||
private static final String ENTERPRISE_OID = "1.3.5.7.11";
|
||||
private static final String AGENT_ADDRESS = "1.2.3.4";
|
||||
private static final String GENERIC_TRAP_TYPE = String.valueOf(PDUv1.ENTERPRISE_SPECIFIC);
|
||||
private static final String SPECIFIC_TRAP_TYPE = "2";
|
||||
|
||||
// v2c/v3 specific
|
||||
private static final String TRAP_OID_VALUE = "testTrapOidValue";
|
||||
|
||||
public static V1TrapConfiguration getV1TrapConfiguration() {
|
||||
return V1TrapConfiguration.builder()
|
||||
.enterpriseOid(ENTERPRISE_OID)
|
||||
.agentAddress(AGENT_ADDRESS)
|
||||
.genericTrapType(GENERIC_TRAP_TYPE)
|
||||
.specificTrapType(SPECIFIC_TRAP_TYPE)
|
||||
.build();
|
||||
}
|
||||
|
||||
public static V2TrapConfiguration getV2TrapConfiguration() {
|
||||
return new V2TrapConfiguration(TRAP_OID_VALUE);
|
||||
}
|
||||
}
|
@ -14,17 +14,19 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.nifi.snmp.factory;
|
||||
package org.apache.nifi.snmp.helper.configurations;
|
||||
|
||||
import org.apache.nifi.snmp.configuration.SNMPConfiguration;
|
||||
import org.snmp4j.Snmp;
|
||||
import org.snmp4j.Target;
|
||||
|
||||
public interface SNMPFactory {
|
||||
public interface SNMPConfigurationFactory {
|
||||
|
||||
boolean supports(final int version);
|
||||
String DEFAULT_HOST = "127.0.0.1";
|
||||
String COMMUNITY_STRING = "public";
|
||||
|
||||
Snmp createSnmpManagerInstance(final SNMPConfiguration configuration);
|
||||
SNMPConfiguration createSnmpGetSetConfiguration(int agentPort);
|
||||
|
||||
SNMPConfiguration createSnmpGetSetConfigWithCustomHost(final String host, final int agentPort);
|
||||
|
||||
SNMPConfiguration createSnmpListenTrapConfig(final int managerPort);
|
||||
|
||||
Target createTargetInstance(final SNMPConfiguration configuration);
|
||||
}
|
@ -0,0 +1,57 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.nifi.snmp.helper.configurations;
|
||||
|
||||
import org.apache.nifi.snmp.configuration.SNMPConfiguration;
|
||||
|
||||
public class SNMPV1V2cConfigurationFactory implements SNMPConfigurationFactory {
|
||||
|
||||
private int snmpVersion;
|
||||
|
||||
public SNMPV1V2cConfigurationFactory(int snmpVersion) {
|
||||
this.snmpVersion = snmpVersion;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SNMPConfiguration createSnmpGetSetConfiguration(final int agentPort) {
|
||||
return SNMPConfiguration.builder()
|
||||
.setTargetHost(DEFAULT_HOST)
|
||||
.setTargetPort(String.valueOf(agentPort))
|
||||
.setCommunityString(COMMUNITY_STRING)
|
||||
.setVersion(snmpVersion)
|
||||
.build();
|
||||
}
|
||||
|
||||
@Override
|
||||
public SNMPConfiguration createSnmpGetSetConfigWithCustomHost(final String host, final int agentPort) {
|
||||
return SNMPConfiguration.builder()
|
||||
.setTargetHost(host)
|
||||
.setTargetPort(String.valueOf(agentPort))
|
||||
.setCommunityString(COMMUNITY_STRING)
|
||||
.setVersion(snmpVersion)
|
||||
.build();
|
||||
}
|
||||
|
||||
@Override
|
||||
public SNMPConfiguration createSnmpListenTrapConfig(final int managerPort) {
|
||||
return SNMPConfiguration.builder()
|
||||
.setManagerPort(managerPort)
|
||||
.setCommunityString(COMMUNITY_STRING)
|
||||
.setVersion(snmpVersion)
|
||||
.build();
|
||||
}
|
||||
}
|
@ -0,0 +1,71 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.nifi.snmp.helper.configurations;
|
||||
|
||||
import org.apache.nifi.snmp.configuration.SNMPConfiguration;
|
||||
import org.snmp4j.mp.SnmpConstants;
|
||||
|
||||
public class SNMPV3ConfigurationFactory implements SNMPConfigurationFactory {
|
||||
|
||||
// V3 security (users are set in test agents)
|
||||
public static final String SECURITY_LEVEL = "authPriv";
|
||||
public static final String SECURITY_NAME = "SHAAES128";
|
||||
public static final String AUTH_PROTOCOL = "SHA";
|
||||
public static final String AUTH_PASSPHRASE = "SHAAES128AuthPassphrase";
|
||||
public static final String PRIV_PROTOCOL = "AES128";
|
||||
public static final String PRIV_PASSPHRASE = "SHAAES128PrivPassphrase";
|
||||
|
||||
@Override
|
||||
public SNMPConfiguration createSnmpGetSetConfiguration(final int agentPort) {
|
||||
return SNMPConfiguration.builder()
|
||||
.setTargetHost(DEFAULT_HOST)
|
||||
.setTargetPort(String.valueOf(agentPort))
|
||||
.setCommunityString(COMMUNITY_STRING)
|
||||
.setVersion(SnmpConstants.version3)
|
||||
.setSecurityLevel(SECURITY_LEVEL)
|
||||
.setSecurityName(SECURITY_NAME)
|
||||
.setAuthProtocol(AUTH_PROTOCOL)
|
||||
.setAuthPassphrase(AUTH_PASSPHRASE)
|
||||
.setPrivacyProtocol(PRIV_PROTOCOL)
|
||||
.setPrivacyPassphrase(PRIV_PASSPHRASE)
|
||||
.build();
|
||||
}
|
||||
|
||||
@Override
|
||||
public SNMPConfiguration createSnmpGetSetConfigWithCustomHost(final String host, final int agentPort) {
|
||||
return SNMPConfiguration.builder()
|
||||
.setTargetHost(host)
|
||||
.setTargetPort(String.valueOf(agentPort))
|
||||
.setCommunityString(COMMUNITY_STRING)
|
||||
.setVersion(SnmpConstants.version3)
|
||||
.setSecurityLevel(SECURITY_LEVEL)
|
||||
.setSecurityName(SECURITY_NAME)
|
||||
.setAuthProtocol(AUTH_PROTOCOL)
|
||||
.setAuthPassphrase(AUTH_PASSPHRASE)
|
||||
.setPrivacyProtocol(PRIV_PROTOCOL)
|
||||
.setPrivacyPassphrase(PRIV_PASSPHRASE)
|
||||
.build();
|
||||
}
|
||||
|
||||
@Override
|
||||
public SNMPConfiguration createSnmpListenTrapConfig(final int managerPort) {
|
||||
return SNMPConfiguration.builder()
|
||||
.setManagerPort(managerPort)
|
||||
.setVersion(SnmpConstants.version3)
|
||||
.build();
|
||||
}
|
||||
}
|
@ -0,0 +1,58 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.nifi.snmp.helper.testrunners;
|
||||
|
||||
import org.apache.nifi.snmp.exception.InvalidSnmpVersionException;
|
||||
import org.apache.nifi.util.MockFlowFile;
|
||||
import org.apache.nifi.util.TestRunner;
|
||||
import org.snmp4j.mp.SnmpConstants;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import static org.apache.nifi.snmp.utils.SNMPUtils.SNMP_PROP_PREFIX;
|
||||
|
||||
public interface SNMPTestRunnerFactory {
|
||||
|
||||
TestRunner createSnmpGetTestRunner(final int agentPort, final String oid, final String strategy);
|
||||
|
||||
TestRunner createSnmpSetTestRunner(final int agentPort, final String oid, final String oidValue);
|
||||
|
||||
TestRunner createSnmpSendTrapTestRunner(final int managerPort, final String oid, final String oidValue);
|
||||
|
||||
TestRunner createSnmpListenTrapTestRunner(final int managerPort);
|
||||
|
||||
default MockFlowFile getFlowFile(String oid, String oidValue) {
|
||||
final MockFlowFile flowFile = new MockFlowFile(1L);
|
||||
final Map<String, String> attributes = new HashMap<>();
|
||||
attributes.put(SNMP_PROP_PREFIX + oid, oidValue);
|
||||
flowFile.putAttributes(attributes);
|
||||
return flowFile;
|
||||
}
|
||||
|
||||
default String getVersionName(final int version) {
|
||||
if (version == SnmpConstants.version1) {
|
||||
return "SNMPv1";
|
||||
} else if (version == SnmpConstants.version2c) {
|
||||
return "SNMPv2c";
|
||||
} else if (version == SnmpConstants.version3) {
|
||||
return "SNMPv3";
|
||||
} else {
|
||||
throw new InvalidSnmpVersionException("Invalid SNMP version");
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,93 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.nifi.snmp.helper.testrunners;
|
||||
|
||||
import org.apache.nifi.snmp.configuration.SNMPConfiguration;
|
||||
import org.apache.nifi.snmp.configuration.V1TrapConfiguration;
|
||||
import org.apache.nifi.snmp.helper.TrapConfigurationFactory;
|
||||
import org.apache.nifi.snmp.helper.configurations.SNMPConfigurationFactory;
|
||||
import org.apache.nifi.snmp.helper.configurations.SNMPV1V2cConfigurationFactory;
|
||||
import org.apache.nifi.snmp.processors.GetSNMP;
|
||||
import org.apache.nifi.snmp.processors.ListenTrapSNMP;
|
||||
import org.apache.nifi.snmp.processors.SendTrapSNMP;
|
||||
import org.apache.nifi.snmp.processors.SetSNMP;
|
||||
import org.apache.nifi.snmp.processors.properties.BasicProperties;
|
||||
import org.apache.nifi.snmp.processors.properties.V1TrapProperties;
|
||||
import org.apache.nifi.util.MockFlowFile;
|
||||
import org.apache.nifi.util.TestRunner;
|
||||
import org.apache.nifi.util.TestRunners;
|
||||
import org.snmp4j.mp.SnmpConstants;
|
||||
|
||||
public class SNMPV1TestRunnerFactory implements SNMPTestRunnerFactory {
|
||||
|
||||
|
||||
private static final SNMPConfigurationFactory snmpV1V2ConfigurationFactory = new SNMPV1V2cConfigurationFactory(SnmpConstants.version1);
|
||||
|
||||
@Override
|
||||
public TestRunner createSnmpGetTestRunner(final int agentPort, final String oid, final String strategy) {
|
||||
final TestRunner runner = TestRunners.newTestRunner(GetSNMP.class);
|
||||
final SNMPConfiguration snmpConfiguration = snmpV1V2ConfigurationFactory.createSnmpGetSetConfiguration(agentPort);
|
||||
runner.setProperty(GetSNMP.AGENT_HOST, snmpConfiguration.getTargetHost());
|
||||
runner.setProperty(GetSNMP.AGENT_PORT, snmpConfiguration.getTargetPort());
|
||||
runner.setProperty(BasicProperties.SNMP_COMMUNITY, snmpConfiguration.getCommunityString());
|
||||
runner.setProperty(BasicProperties.SNMP_VERSION, getVersionName(snmpConfiguration.getVersion()));
|
||||
runner.setProperty(GetSNMP.SNMP_STRATEGY, strategy);
|
||||
runner.setProperty(GetSNMP.OID, oid);
|
||||
return runner;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TestRunner createSnmpSetTestRunner(final int agentPort, final String oid, final String oidValue) {
|
||||
final TestRunner runner = TestRunners.newTestRunner(SetSNMP.class);
|
||||
final SNMPConfiguration snmpConfiguration = snmpV1V2ConfigurationFactory.createSnmpGetSetConfiguration(agentPort);
|
||||
runner.setProperty(SetSNMP.AGENT_HOST, snmpConfiguration.getTargetHost());
|
||||
runner.setProperty(SetSNMP.AGENT_PORT, snmpConfiguration.getTargetPort());
|
||||
runner.setProperty(BasicProperties.SNMP_COMMUNITY, snmpConfiguration.getCommunityString());
|
||||
runner.setProperty(BasicProperties.SNMP_VERSION, getVersionName(snmpConfiguration.getVersion()));
|
||||
final MockFlowFile flowFile = getFlowFile(oid, oidValue);
|
||||
runner.enqueue(flowFile);
|
||||
return runner;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TestRunner createSnmpSendTrapTestRunner(final int managerPort, final String oid, final String oidValue) {
|
||||
final TestRunner runner = TestRunners.newTestRunner(SendTrapSNMP.class);
|
||||
final SNMPConfiguration snmpConfiguration = snmpV1V2ConfigurationFactory.createSnmpGetSetConfiguration(managerPort);
|
||||
final V1TrapConfiguration trapConfiguration = TrapConfigurationFactory.getV1TrapConfiguration();
|
||||
runner.setProperty(SendTrapSNMP.SNMP_MANAGER_HOST, snmpConfiguration.getTargetHost());
|
||||
runner.setProperty(SendTrapSNMP.SNMP_MANAGER_PORT, snmpConfiguration.getTargetPort());
|
||||
runner.setProperty(BasicProperties.SNMP_COMMUNITY, snmpConfiguration.getCommunityString());
|
||||
runner.setProperty(BasicProperties.SNMP_VERSION, getVersionName(snmpConfiguration.getVersion()));
|
||||
runner.setProperty(V1TrapProperties.ENTERPRISE_OID, trapConfiguration.getEnterpriseOid());
|
||||
runner.setProperty(V1TrapProperties.AGENT_ADDRESS, trapConfiguration.getAgentAddress());
|
||||
runner.setProperty(V1TrapProperties.GENERIC_TRAP_TYPE, String.valueOf(trapConfiguration.getGenericTrapType()));
|
||||
runner.setProperty(V1TrapProperties.SPECIFIC_TRAP_TYPE, String.valueOf(trapConfiguration.getSpecificTrapType()));
|
||||
final MockFlowFile flowFile = getFlowFile(oid, oidValue);
|
||||
runner.enqueue(flowFile);
|
||||
return runner;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TestRunner createSnmpListenTrapTestRunner(final int managerPort) {
|
||||
final TestRunner runner = TestRunners.newTestRunner(ListenTrapSNMP.class);
|
||||
final SNMPConfiguration snmpConfiguration = snmpV1V2ConfigurationFactory.createSnmpListenTrapConfig(managerPort);
|
||||
runner.setProperty(ListenTrapSNMP.SNMP_MANAGER_PORT, String.valueOf(snmpConfiguration.getManagerPort()));
|
||||
runner.setProperty(BasicProperties.SNMP_COMMUNITY, snmpConfiguration.getCommunityString());
|
||||
runner.setProperty(BasicProperties.SNMP_VERSION, getVersionName(snmpConfiguration.getVersion()));
|
||||
return runner;
|
||||
}
|
||||
}
|
@ -0,0 +1,89 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.nifi.snmp.helper.testrunners;
|
||||
|
||||
import org.apache.nifi.snmp.configuration.SNMPConfiguration;
|
||||
import org.apache.nifi.snmp.configuration.V2TrapConfiguration;
|
||||
import org.apache.nifi.snmp.helper.TrapConfigurationFactory;
|
||||
import org.apache.nifi.snmp.helper.configurations.SNMPConfigurationFactory;
|
||||
import org.apache.nifi.snmp.helper.configurations.SNMPV1V2cConfigurationFactory;
|
||||
import org.apache.nifi.snmp.processors.GetSNMP;
|
||||
import org.apache.nifi.snmp.processors.ListenTrapSNMP;
|
||||
import org.apache.nifi.snmp.processors.SendTrapSNMP;
|
||||
import org.apache.nifi.snmp.processors.SetSNMP;
|
||||
import org.apache.nifi.snmp.processors.properties.BasicProperties;
|
||||
import org.apache.nifi.snmp.processors.properties.V2TrapProperties;
|
||||
import org.apache.nifi.util.MockFlowFile;
|
||||
import org.apache.nifi.util.TestRunner;
|
||||
import org.apache.nifi.util.TestRunners;
|
||||
import org.snmp4j.mp.SnmpConstants;
|
||||
|
||||
public class SNMPV2cTestRunnerFactory implements SNMPTestRunnerFactory {
|
||||
|
||||
private static final SNMPConfigurationFactory snmpV2cConfigurationFactory = new SNMPV1V2cConfigurationFactory(SnmpConstants.version2c);
|
||||
|
||||
@Override
|
||||
public TestRunner createSnmpGetTestRunner(int agentPort, String oid, String strategy) {
|
||||
final TestRunner runner = TestRunners.newTestRunner(GetSNMP.class);
|
||||
final SNMPConfiguration snmpConfiguration = snmpV2cConfigurationFactory.createSnmpGetSetConfiguration(agentPort);
|
||||
runner.setProperty(GetSNMP.OID, oid);
|
||||
runner.setProperty(GetSNMP.AGENT_HOST, snmpConfiguration.getTargetHost());
|
||||
runner.setProperty(GetSNMP.AGENT_PORT, snmpConfiguration.getTargetPort());
|
||||
runner.setProperty(BasicProperties.SNMP_COMMUNITY, snmpConfiguration.getCommunityString());
|
||||
runner.setProperty(BasicProperties.SNMP_VERSION, getVersionName(snmpConfiguration.getVersion()));
|
||||
runner.setProperty(GetSNMP.SNMP_STRATEGY, strategy);
|
||||
return runner;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TestRunner createSnmpSetTestRunner(int agentPort, String oid, String oidValue) {
|
||||
final TestRunner runner = TestRunners.newTestRunner(SetSNMP.class);
|
||||
final SNMPConfiguration snmpConfiguration = snmpV2cConfigurationFactory.createSnmpGetSetConfiguration(agentPort);
|
||||
runner.setProperty(SetSNMP.AGENT_HOST, snmpConfiguration.getTargetHost());
|
||||
runner.setProperty(SetSNMP.AGENT_PORT, snmpConfiguration.getTargetPort());
|
||||
runner.setProperty(BasicProperties.SNMP_COMMUNITY, snmpConfiguration.getCommunityString());
|
||||
runner.setProperty(BasicProperties.SNMP_VERSION, getVersionName(snmpConfiguration.getVersion()));
|
||||
final MockFlowFile flowFile = getFlowFile(oid, oidValue);
|
||||
runner.enqueue(flowFile);
|
||||
return runner;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TestRunner createSnmpSendTrapTestRunner(int managerPort, final String oid, final String oidValue) {
|
||||
final TestRunner runner = TestRunners.newTestRunner(SendTrapSNMP.class);
|
||||
final SNMPConfiguration snmpConfiguration = snmpV2cConfigurationFactory.createSnmpGetSetConfiguration(managerPort);
|
||||
final V2TrapConfiguration trapConfiguration = TrapConfigurationFactory.getV2TrapConfiguration();
|
||||
runner.setProperty(SendTrapSNMP.SNMP_MANAGER_HOST, snmpConfiguration.getTargetHost());
|
||||
runner.setProperty(SendTrapSNMP.SNMP_MANAGER_PORT, snmpConfiguration.getTargetPort());
|
||||
runner.setProperty(BasicProperties.SNMP_COMMUNITY, snmpConfiguration.getCommunityString());
|
||||
runner.setProperty(BasicProperties.SNMP_VERSION, getVersionName(snmpConfiguration.getVersion()));
|
||||
runner.setProperty(V2TrapProperties.TRAP_OID_VALUE, trapConfiguration.getTrapOidValue());
|
||||
final MockFlowFile flowFile = getFlowFile(oid, oidValue);
|
||||
runner.enqueue(flowFile);
|
||||
return runner;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TestRunner createSnmpListenTrapTestRunner(int managerPort) {
|
||||
final TestRunner runner = TestRunners.newTestRunner(ListenTrapSNMP.class);
|
||||
final SNMPConfiguration snmpConfiguration = snmpV2cConfigurationFactory.createSnmpListenTrapConfig(managerPort);
|
||||
runner.setProperty(ListenTrapSNMP.SNMP_MANAGER_PORT, String.valueOf(snmpConfiguration.getManagerPort()));
|
||||
runner.setProperty(BasicProperties.SNMP_COMMUNITY, snmpConfiguration.getCommunityString());
|
||||
runner.setProperty(BasicProperties.SNMP_VERSION, getVersionName(snmpConfiguration.getVersion()));
|
||||
return runner;
|
||||
}
|
||||
}
|
@ -0,0 +1,112 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.nifi.snmp.helper.testrunners;
|
||||
|
||||
import org.apache.nifi.snmp.configuration.SNMPConfiguration;
|
||||
import org.apache.nifi.snmp.configuration.V2TrapConfiguration;
|
||||
import org.apache.nifi.snmp.helper.TrapConfigurationFactory;
|
||||
import org.apache.nifi.snmp.helper.configurations.SNMPConfigurationFactory;
|
||||
import org.apache.nifi.snmp.helper.configurations.SNMPV3ConfigurationFactory;
|
||||
import org.apache.nifi.snmp.processors.GetSNMP;
|
||||
import org.apache.nifi.snmp.processors.ListenTrapSNMP;
|
||||
import org.apache.nifi.snmp.processors.SendTrapSNMP;
|
||||
import org.apache.nifi.snmp.processors.SetSNMP;
|
||||
import org.apache.nifi.snmp.processors.properties.BasicProperties;
|
||||
import org.apache.nifi.snmp.processors.properties.V2TrapProperties;
|
||||
import org.apache.nifi.snmp.processors.properties.V3SecurityProperties;
|
||||
import org.apache.nifi.util.MockFlowFile;
|
||||
import org.apache.nifi.util.TestRunner;
|
||||
import org.apache.nifi.util.TestRunners;
|
||||
|
||||
public class SNMPV3TestRunnerFactory implements SNMPTestRunnerFactory {
|
||||
|
||||
private static final String USM_USERS_FILE_PATH = "src/test/resources/usm.json";
|
||||
private static final SNMPConfigurationFactory snmpV3ConfigurationFactory = new SNMPV3ConfigurationFactory();
|
||||
|
||||
@Override
|
||||
public TestRunner createSnmpGetTestRunner(int agentPort, String oid, String strategy) {
|
||||
final TestRunner runner = TestRunners.newTestRunner(GetSNMP.class);
|
||||
final SNMPConfiguration snmpConfiguration = snmpV3ConfigurationFactory.createSnmpGetSetConfiguration(agentPort);
|
||||
runner.setProperty(GetSNMP.OID, oid);
|
||||
runner.setProperty(GetSNMP.SNMP_STRATEGY, strategy);
|
||||
runner.setProperty(GetSNMP.AGENT_HOST, snmpConfiguration.getTargetHost());
|
||||
runner.setProperty(GetSNMP.AGENT_PORT, snmpConfiguration.getTargetPort());
|
||||
runner.setProperty(BasicProperties.SNMP_COMMUNITY, snmpConfiguration.getCommunityString());
|
||||
runner.setProperty(BasicProperties.SNMP_VERSION, getVersionName(snmpConfiguration.getVersion()));
|
||||
runner.setProperty(V3SecurityProperties.SNMP_SECURITY_LEVEL, snmpConfiguration.getSecurityLevel());
|
||||
runner.setProperty(V3SecurityProperties.SNMP_SECURITY_NAME, snmpConfiguration.getSecurityName());
|
||||
runner.setProperty(V3SecurityProperties.SNMP_AUTH_PROTOCOL, snmpConfiguration.getAuthProtocol());
|
||||
runner.setProperty(V3SecurityProperties.SNMP_AUTH_PASSWORD, snmpConfiguration.getAuthPassphrase());
|
||||
runner.setProperty(V3SecurityProperties.SNMP_PRIVACY_PROTOCOL, snmpConfiguration.getPrivacyProtocol());
|
||||
runner.setProperty(V3SecurityProperties.SNMP_PRIVACY_PASSWORD, snmpConfiguration.getPrivacyPassphrase());
|
||||
return runner;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TestRunner createSnmpSetTestRunner(int agentPort, String oid, String oidValue) {
|
||||
final TestRunner runner = TestRunners.newTestRunner(SetSNMP.class);
|
||||
final SNMPConfiguration snmpConfiguration = snmpV3ConfigurationFactory.createSnmpGetSetConfiguration(agentPort);
|
||||
runner.setProperty(SetSNMP.AGENT_HOST, snmpConfiguration.getTargetHost());
|
||||
runner.setProperty(SetSNMP.AGENT_PORT, snmpConfiguration.getTargetPort());
|
||||
runner.setProperty(BasicProperties.SNMP_COMMUNITY, snmpConfiguration.getCommunityString());
|
||||
runner.setProperty(BasicProperties.SNMP_VERSION, getVersionName(snmpConfiguration.getVersion()));
|
||||
runner.setProperty(V3SecurityProperties.SNMP_SECURITY_LEVEL, snmpConfiguration.getSecurityLevel());
|
||||
runner.setProperty(V3SecurityProperties.SNMP_SECURITY_NAME, snmpConfiguration.getSecurityName());
|
||||
runner.setProperty(V3SecurityProperties.SNMP_AUTH_PROTOCOL, snmpConfiguration.getAuthProtocol());
|
||||
runner.setProperty(V3SecurityProperties.SNMP_AUTH_PASSWORD, snmpConfiguration.getAuthPassphrase());
|
||||
runner.setProperty(V3SecurityProperties.SNMP_PRIVACY_PROTOCOL, snmpConfiguration.getPrivacyProtocol());
|
||||
runner.setProperty(V3SecurityProperties.SNMP_PRIVACY_PASSWORD, snmpConfiguration.getPrivacyPassphrase());
|
||||
final MockFlowFile flowFile = getFlowFile(oid, oidValue);
|
||||
runner.enqueue(flowFile);
|
||||
return runner;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TestRunner createSnmpSendTrapTestRunner(int managerPort, final String oid, final String oidValue) {
|
||||
final TestRunner runner = TestRunners.newTestRunner(SendTrapSNMP.class);
|
||||
final SNMPConfiguration snmpConfiguration = snmpV3ConfigurationFactory.createSnmpGetSetConfiguration(managerPort);
|
||||
final V2TrapConfiguration trapConfiguration = TrapConfigurationFactory.getV2TrapConfiguration();
|
||||
runner.setProperty(SendTrapSNMP.SNMP_MANAGER_HOST, snmpConfiguration.getTargetHost());
|
||||
runner.setProperty(SendTrapSNMP.SNMP_MANAGER_PORT, snmpConfiguration.getTargetPort());
|
||||
runner.setProperty(BasicProperties.SNMP_COMMUNITY, snmpConfiguration.getCommunityString());
|
||||
runner.setProperty(BasicProperties.SNMP_VERSION, getVersionName(snmpConfiguration.getVersion()));
|
||||
runner.setProperty(V2TrapProperties.TRAP_OID_VALUE, trapConfiguration.getTrapOidValue());
|
||||
|
||||
runner.setProperty(V3SecurityProperties.SNMP_SECURITY_LEVEL, snmpConfiguration.getSecurityLevel());
|
||||
runner.setProperty(V3SecurityProperties.SNMP_SECURITY_NAME, snmpConfiguration.getSecurityName());
|
||||
runner.setProperty(V3SecurityProperties.SNMP_AUTH_PROTOCOL, snmpConfiguration.getAuthProtocol());
|
||||
runner.setProperty(V3SecurityProperties.SNMP_AUTH_PASSWORD, snmpConfiguration.getAuthPassphrase());
|
||||
runner.setProperty(V3SecurityProperties.SNMP_PRIVACY_PROTOCOL, snmpConfiguration.getPrivacyProtocol());
|
||||
runner.setProperty(V3SecurityProperties.SNMP_PRIVACY_PASSWORD, snmpConfiguration.getPrivacyPassphrase());
|
||||
|
||||
final MockFlowFile flowFile = getFlowFile(oid, oidValue);
|
||||
runner.enqueue(flowFile);
|
||||
|
||||
return runner;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TestRunner createSnmpListenTrapTestRunner(int managerPort) {
|
||||
final TestRunner runner = TestRunners.newTestRunner(ListenTrapSNMP.class);
|
||||
final SNMPConfiguration snmpConfiguration = snmpV3ConfigurationFactory.createSnmpListenTrapConfig(managerPort);
|
||||
runner.setProperty(ListenTrapSNMP.SNMP_MANAGER_PORT, String.valueOf(snmpConfiguration.getManagerPort()));
|
||||
runner.setProperty(BasicProperties.SNMP_VERSION, getVersionName(snmpConfiguration.getVersion()));
|
||||
runner.setProperty(ListenTrapSNMP.SNMP_USM_USERS_FILE_PATH, USM_USERS_FILE_PATH);
|
||||
|
||||
return runner;
|
||||
}
|
||||
}
|
@ -0,0 +1,271 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.nifi.snmp.operations;
|
||||
|
||||
import org.apache.nifi.snmp.dto.SNMPSingleResponse;
|
||||
import org.apache.nifi.snmp.dto.SNMPTreeResponse;
|
||||
import org.apache.nifi.snmp.exception.RequestTimeoutException;
|
||||
import org.apache.nifi.snmp.exception.SNMPWalkException;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.mockito.ArgumentCaptor;
|
||||
import org.mockito.Mockito;
|
||||
import org.snmp4j.PDU;
|
||||
import org.snmp4j.Snmp;
|
||||
import org.snmp4j.Target;
|
||||
import org.snmp4j.event.ResponseEvent;
|
||||
import org.snmp4j.smi.OID;
|
||||
import org.snmp4j.smi.OctetString;
|
||||
import org.snmp4j.smi.VariableBinding;
|
||||
import org.snmp4j.util.TreeEvent;
|
||||
import org.snmp4j.util.TreeUtils;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
|
||||
import static org.apache.nifi.snmp.operations.GetSNMPHandler.EMPTY_SUBTREE_EXCEPTION_MESSAGE;
|
||||
import static org.apache.nifi.snmp.operations.GetSNMPHandler.LEAF_ELEMENT_EXCEPTION_MESSAGE;
|
||||
import static org.apache.nifi.snmp.operations.GetSNMPHandler.SNMP_ERROR_EXCEPTION_MESSAGE;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
public class GetSNMPHandlerTest {
|
||||
|
||||
private static final String OID = "1.3.6.1.4.1.343";
|
||||
|
||||
private Target mockTarget;
|
||||
private Snmp mockSnmpManager;
|
||||
private SNMPResourceHandler snmpResourceHandler;
|
||||
|
||||
@Before
|
||||
public void init() {
|
||||
mockTarget = mock(Target.class);
|
||||
mockSnmpManager = mock(Snmp.class);
|
||||
snmpResourceHandler = new SNMPResourceHandler(mockSnmpManager, mockTarget);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetSnmpWithEmptyFlowFile() throws IOException {
|
||||
final ResponseEvent mockResponseEvent = mock(ResponseEvent.class);
|
||||
final PDU mockPdu = mock(PDU.class);
|
||||
when(mockResponseEvent.getResponse()).thenReturn(mockPdu);
|
||||
when(mockSnmpManager.get(any(PDU.class), any(Target.class))).thenReturn(mockResponseEvent);
|
||||
|
||||
final GetSNMPHandler getSNMPHandler = new GetSNMPHandler(snmpResourceHandler);
|
||||
getSNMPHandler.get(OID);
|
||||
|
||||
ArgumentCaptor<PDU> captor = ArgumentCaptor.forClass(PDU.class);
|
||||
Mockito.verify(mockSnmpManager).get(captor.capture(), any(Target.class));
|
||||
|
||||
final PDU pdu = captor.getValue();
|
||||
assertEquals(1, pdu.getVariableBindings().size());
|
||||
assertEquals(OID, pdu.getVariableBindings().get(0).getOid().toString());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetSnmpWithInvalidFlowFile() throws IOException {
|
||||
final Map<String, String> invalidFlowFileAttributes = new HashMap<>();
|
||||
invalidFlowFileAttributes.put("invalid", "flowfile attribute");
|
||||
|
||||
final ResponseEvent mockResponseEvent = mock(ResponseEvent.class);
|
||||
final PDU mockPdu = mock(PDU.class);
|
||||
when(mockResponseEvent.getResponse()).thenReturn(mockPdu);
|
||||
when(mockSnmpManager.get(any(PDU.class), any(Target.class))).thenReturn(mockResponseEvent);
|
||||
|
||||
final GetSNMPHandler getSNMPHandler = new GetSNMPHandler(snmpResourceHandler);
|
||||
final Optional<SNMPSingleResponse> optionalResponse = getSNMPHandler.get(invalidFlowFileAttributes);
|
||||
|
||||
assertFalse(optionalResponse.isPresent());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetSnmpWithValidFlowFile() throws IOException {
|
||||
final String flowFileOid = "1.3.6.1.2.1.1.1.0";
|
||||
final Map<String, String> flowFileAttributes = new HashMap<>();
|
||||
flowFileAttributes.put("snmp$" + flowFileOid, "OID value");
|
||||
|
||||
final ResponseEvent mockResponseEvent = mock(ResponseEvent.class);
|
||||
final PDU mockPdu = mock(PDU.class);
|
||||
when(mockResponseEvent.getResponse()).thenReturn(mockPdu);
|
||||
when(mockSnmpManager.get(any(PDU.class), any(Target.class))).thenReturn(mockResponseEvent);
|
||||
|
||||
final GetSNMPHandler getSNMPHandler = new GetSNMPHandler(snmpResourceHandler);
|
||||
getSNMPHandler.get(flowFileAttributes);
|
||||
|
||||
ArgumentCaptor<PDU> captor = ArgumentCaptor.forClass(PDU.class);
|
||||
Mockito.verify(mockSnmpManager).get(captor.capture(), any(Target.class));
|
||||
|
||||
final PDU pdu = captor.getValue();
|
||||
assertEquals(1, pdu.getVariableBindings().size());
|
||||
assertEquals(flowFileOid, pdu.getVariableBindings().get(0).getOid().toString());
|
||||
assertEquals("Null", pdu.getVariableBindings().get(0).getVariable().toString());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetSnmpWhenTimeout() throws IOException {
|
||||
final ResponseEvent mockResponseEvent = mock(ResponseEvent.class);
|
||||
when(mockResponseEvent.getResponse()).thenReturn(null);
|
||||
when(mockSnmpManager.get(any(PDU.class), any(Target.class))).thenReturn(mockResponseEvent);
|
||||
|
||||
final GetSNMPHandler getSNMPHandler = new GetSNMPHandler(snmpResourceHandler);
|
||||
|
||||
final RequestTimeoutException requestTimeoutException = Assert.assertThrows(
|
||||
RequestTimeoutException.class,
|
||||
() -> getSNMPHandler.get(OID)
|
||||
);
|
||||
|
||||
assertEquals(String.format(SNMPResourceHandler.REQUEST_TIMEOUT_EXCEPTION_TEMPLATE, "read"),
|
||||
requestTimeoutException.getMessage());
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Test
|
||||
public void testWalkSnmpWithEmptyFlowFile() {
|
||||
final TreeUtils mockTreeUtils = mock(TreeUtils.class);
|
||||
final TreeEvent mockTreeEvent = mock(TreeEvent.class);
|
||||
final List<TreeEvent> mockSubtree = (List<TreeEvent>) mock(List.class);
|
||||
|
||||
final VariableBinding[] variableBindings = new VariableBinding[1];
|
||||
variableBindings[0] = new VariableBinding(new OID(OID), new OctetString("OID value"));
|
||||
when(mockTreeEvent.getVariableBindings()).thenReturn(variableBindings);
|
||||
when(mockSubtree.get(0)).thenReturn(mockTreeEvent);
|
||||
when(mockTreeUtils.getSubtree(mockTarget, new OID(OID))).thenReturn(mockSubtree);
|
||||
|
||||
final GetSNMPHandler getSNMPHandler = new GetSNMPHandler(snmpResourceHandler);
|
||||
getSNMPHandler.setTreeUtils(mockTreeUtils);
|
||||
getSNMPHandler.walk(OID);
|
||||
|
||||
ArgumentCaptor<OID> captor = ArgumentCaptor.forClass(OID.class);
|
||||
Mockito.verify(mockTreeUtils).getSubtree(any(Target.class), captor.capture());
|
||||
|
||||
assertEquals(OID, captor.getValue().toString());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testWalkSnmpWithInvalidFlowFile() {
|
||||
final Map<String, String> invalidFlowFileAttributes = new HashMap<>();
|
||||
invalidFlowFileAttributes.put("invalid", "flowfile attribute");
|
||||
|
||||
final GetSNMPHandler getSNMPHandler = new GetSNMPHandler(snmpResourceHandler);
|
||||
final Optional<SNMPTreeResponse> optionalResponse = getSNMPHandler.walk(invalidFlowFileAttributes);
|
||||
|
||||
assertFalse(optionalResponse.isPresent());
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Test
|
||||
public void testWalkSnmpWithValidFlowFile() {
|
||||
final String flowFileOid = "1.3.6.1.2.1.1.1.0";
|
||||
final Map<String, String> flowFileAttributes = new HashMap<>();
|
||||
flowFileAttributes.put("snmp$" + flowFileOid, "OID value");
|
||||
|
||||
final TreeUtils mockTreeUtils = mock(TreeUtils.class);
|
||||
final TreeEvent mockTreeEvent = mock(TreeEvent.class);
|
||||
final List<TreeEvent> mockSubtree = (List<TreeEvent>) mock(List.class);
|
||||
|
||||
final VariableBinding[] variableBindings = new VariableBinding[1];
|
||||
variableBindings[0] = new VariableBinding(new OID(OID), new OctetString("OID value"));
|
||||
when(mockTreeEvent.getVariableBindings()).thenReturn(variableBindings);
|
||||
when(mockSubtree.get(0)).thenReturn(mockTreeEvent);
|
||||
when(mockSubtree.isEmpty()).thenReturn(false);
|
||||
when(mockTreeUtils.walk(any(Target.class), any(OID[].class))).thenReturn(mockSubtree);
|
||||
|
||||
final GetSNMPHandler getSNMPHandler = new GetSNMPHandler(snmpResourceHandler);
|
||||
getSNMPHandler.setTreeUtils(mockTreeUtils);
|
||||
getSNMPHandler.walk(flowFileAttributes);
|
||||
|
||||
ArgumentCaptor<OID[]> captor = ArgumentCaptor.forClass(OID[].class);
|
||||
Mockito.verify(mockTreeUtils).walk(any(Target.class), captor.capture());
|
||||
|
||||
assertEquals(flowFileOid, captor.getValue()[0].toString());
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Test
|
||||
public void testWalkSnmpWithEmptySubtreeThrowsException() {
|
||||
final TreeUtils mockTreeUtils = mock(TreeUtils.class);
|
||||
final List<TreeEvent> mockSubtree = (List<TreeEvent>) mock(List.class);
|
||||
|
||||
when(mockSubtree.isEmpty()).thenReturn(true);
|
||||
when(mockTreeUtils.getSubtree(any(Target.class), any(org.snmp4j.smi.OID.class))).thenReturn(mockSubtree);
|
||||
|
||||
final GetSNMPHandler getSNMPHandler = new GetSNMPHandler(snmpResourceHandler);
|
||||
getSNMPHandler.setTreeUtils(mockTreeUtils);
|
||||
|
||||
final SNMPWalkException snmpWalkException = Assert.assertThrows(
|
||||
SNMPWalkException.class,
|
||||
() -> getSNMPHandler.walk(OID)
|
||||
);
|
||||
|
||||
assertEquals(String.format(EMPTY_SUBTREE_EXCEPTION_MESSAGE, OID), snmpWalkException.getMessage());
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Test
|
||||
public void testWalkSnmpWithSubtreeErrorThrowsException() {
|
||||
final TreeUtils mockTreeUtils = mock(TreeUtils.class);
|
||||
final TreeEvent mockTreeEvent = mock(TreeEvent.class);
|
||||
final List<TreeEvent> mockSubtree = (List<TreeEvent>) mock(List.class);
|
||||
|
||||
when(mockSubtree.get(0)).thenReturn(mockTreeEvent);
|
||||
when(mockSubtree.isEmpty()).thenReturn(false);
|
||||
when(mockSubtree.size()).thenReturn(1);
|
||||
when(mockTreeUtils.getSubtree(any(Target.class), any(org.snmp4j.smi.OID.class))).thenReturn(mockSubtree);
|
||||
|
||||
final GetSNMPHandler getSNMPHandler = new GetSNMPHandler(snmpResourceHandler);
|
||||
getSNMPHandler.setTreeUtils(mockTreeUtils);
|
||||
|
||||
final SNMPWalkException snmpWalkException = Assert.assertThrows(
|
||||
SNMPWalkException.class,
|
||||
() -> getSNMPHandler.walk(OID)
|
||||
);
|
||||
|
||||
assertEquals(SNMP_ERROR_EXCEPTION_MESSAGE, snmpWalkException.getMessage());
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Test
|
||||
public void testWalkSnmpWithLeafElementSubtreeThrowsException() {
|
||||
final TreeUtils mockTreeUtils = mock(TreeUtils.class);
|
||||
final TreeEvent mockTreeEvent = mock(TreeEvent.class);
|
||||
final List<TreeEvent> mockSubtree = (List<TreeEvent>) mock(List.class);
|
||||
|
||||
final VariableBinding[] variableBindings = new VariableBinding[0];
|
||||
when(mockTreeEvent.getVariableBindings()).thenReturn(variableBindings);
|
||||
when(mockSubtree.get(0)).thenReturn(mockTreeEvent);
|
||||
when(mockSubtree.isEmpty()).thenReturn(false);
|
||||
when(mockSubtree.size()).thenReturn(1);
|
||||
when(mockTreeUtils.getSubtree(any(Target.class), any(org.snmp4j.smi.OID.class))).thenReturn(mockSubtree);
|
||||
|
||||
final GetSNMPHandler getSNMPHandler = new GetSNMPHandler(snmpResourceHandler);
|
||||
getSNMPHandler.setTreeUtils(mockTreeUtils);
|
||||
|
||||
final SNMPWalkException snmpWalkException = Assert.assertThrows(
|
||||
SNMPWalkException.class,
|
||||
() -> getSNMPHandler.walk(OID)
|
||||
);
|
||||
|
||||
assertEquals(String.format(LEAF_ELEMENT_EXCEPTION_MESSAGE, OID), snmpWalkException.getMessage());
|
||||
}
|
||||
}
|
@ -16,45 +16,67 @@
|
||||
*/
|
||||
package org.apache.nifi.snmp.operations;
|
||||
|
||||
import org.apache.nifi.snmp.configuration.SNMPConfiguration;
|
||||
import org.apache.nifi.snmp.dto.SNMPSingleResponse;
|
||||
import org.apache.nifi.snmp.dto.SNMPTreeResponse;
|
||||
import org.apache.nifi.snmp.helper.SNMPTestUtils;
|
||||
import org.apache.nifi.snmp.dto.SNMPValue;
|
||||
import org.apache.nifi.snmp.exception.RequestTimeoutException;
|
||||
import org.apache.nifi.snmp.factory.core.SNMPFactoryProvider;
|
||||
import org.apache.nifi.snmp.helper.configurations.SNMPConfigurationFactory;
|
||||
import org.apache.nifi.snmp.helper.configurations.SNMPV1V2cConfigurationFactory;
|
||||
import org.apache.nifi.snmp.helper.configurations.SNMPV3ConfigurationFactory;
|
||||
import org.apache.nifi.snmp.testagents.TestAgent;
|
||||
import org.apache.nifi.util.MockFlowFile;
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.snmp4j.CommunityTarget;
|
||||
import org.snmp4j.Snmp;
|
||||
import org.apache.nifi.snmp.testagents.TestSNMPV1Agent;
|
||||
import org.apache.nifi.snmp.testagents.TestSNMPV2cAgent;
|
||||
import org.apache.nifi.snmp.testagents.TestSNMPV3Agent;
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.junit.runners.Parameterized;
|
||||
import org.snmp4j.agent.mo.DefaultMOFactory;
|
||||
import org.snmp4j.agent.mo.MOAccessImpl;
|
||||
import org.snmp4j.mp.SnmpConstants;
|
||||
import org.snmp4j.smi.OID;
|
||||
import org.snmp4j.smi.OctetString;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.fail;
|
||||
|
||||
public abstract class SNMPRequestTest {
|
||||
@RunWith(Parameterized.class)
|
||||
public class SNMPRequestTest {
|
||||
|
||||
protected static final String LOCALHOST = "127.0.0.1";
|
||||
protected static final String INVALID_HOST = "127.0.0.2";
|
||||
protected static final String READ_ONLY_OID_1 = "1.3.6.1.4.1.32437.1.5.1.4.2.0";
|
||||
protected static final String READ_ONLY_OID_2 = "1.3.6.1.4.1.32437.1.5.1.4.3.0";
|
||||
protected static final String WRITE_ONLY_OID = "1.3.6.1.4.1.32437.1.5.1.4.4.0";
|
||||
protected static final String READ_ONLY_OID_VALUE_1 = "TestOID1";
|
||||
protected static final String READ_ONLY_OID_VALUE_2 = "TestOID2";
|
||||
protected static final String WRITE_ONLY_OID_VALUE = "writeOnlyOID";
|
||||
protected static final String SNMP_PROP_DELIMITER = "$";
|
||||
protected static final String SNMP_PROP_PREFIX = "snmp" + SNMP_PROP_DELIMITER;
|
||||
protected static final String NOT_WRITABLE = "Not writable";
|
||||
protected static final String NO_ACCESS = "No access";
|
||||
protected static final String SUCCESS = "Success";
|
||||
protected static final String EXPECTED_OID_VALUE = "testValue";
|
||||
private static final String LOCALHOST = "127.0.0.1";
|
||||
private static final String INVALID_HOST = "127.0.0.2";
|
||||
private static final String READ_ONLY_OID_1 = "1.3.6.1.4.1.32437.1.5.1.4.2.0";
|
||||
private static final String READ_ONLY_OID_2 = "1.3.6.1.4.1.32437.1.5.1.4.3.0";
|
||||
private static final String WRITE_ONLY_OID = "1.3.6.1.4.1.32437.1.5.1.4.4.0";
|
||||
private static final String WALK_OID = "1.3.6.1.4.1.32437";
|
||||
private static final String INVALID_OID = "1.3.6.1.4.1.32437.0";
|
||||
private static final String READ_ONLY_OID_VALUE_1 = "TestOID1";
|
||||
private static final String READ_ONLY_OID_VALUE_2 = "TestOID2";
|
||||
private static final String WRITE_ONLY_OID_VALUE = "writeOnlyOID";
|
||||
private static final String SNMP_PROP_DELIMITER = "$";
|
||||
private static final String SNMP_PROP_PREFIX = "snmp" + SNMP_PROP_DELIMITER;
|
||||
private static final String NOT_WRITABLE = "Not writable";
|
||||
private static final String NO_ACCESS = "No access";
|
||||
private static final String SUCCESS = "Success";
|
||||
private static final String NO_SUCH_OBJECT = "noSuchObject";
|
||||
private static final String UNABLE_TO_CREATE_OBJECT = "Unable to create object";
|
||||
private static final String TEST_OID_VALUE = "testValue";
|
||||
private static final String NO_SUCH_NAME = "No such name";
|
||||
protected static final Map<String, String> WALK_OID_MAP;
|
||||
|
||||
static {
|
||||
@ -64,53 +86,217 @@ public abstract class SNMPRequestTest {
|
||||
WALK_OID_MAP = Collections.unmodifiableMap(oidMap);
|
||||
}
|
||||
|
||||
protected final TestAgent agent = getAgentInstance();
|
||||
private static final SNMPConfigurationFactory snmpV1ConfigurationFactory = new SNMPV1V2cConfigurationFactory(SnmpConstants.version1);
|
||||
private static final SNMPConfigurationFactory snmpv2cConfigurationFactory = new SNMPV1V2cConfigurationFactory(SnmpConstants.version2c);
|
||||
private static final SNMPConfigurationFactory snmpv3ConfigurationFactory = new SNMPV3ConfigurationFactory();
|
||||
|
||||
protected abstract TestAgent getAgentInstance();
|
||||
private static final TestAgent v1TestAgent = new TestSNMPV1Agent(LOCALHOST);
|
||||
private static final TestAgent v2cTestAgent = new TestSNMPV2cAgent(LOCALHOST);
|
||||
private static final TestAgent v3TestAgent = new TestSNMPV3Agent(LOCALHOST);
|
||||
|
||||
@BeforeEach
|
||||
private SNMPResourceHandler snmpResourceHandler;
|
||||
|
||||
static {
|
||||
registerManagedObjects(v1TestAgent);
|
||||
registerManagedObjects(v2cTestAgent);
|
||||
registerManagedObjects(v3TestAgent);
|
||||
}
|
||||
|
||||
@Before
|
||||
public void initAgent() throws IOException {
|
||||
agent.start();
|
||||
agent.registerManagedObjects(
|
||||
DefaultMOFactory.getInstance().createScalar(new OID(READ_ONLY_OID_1), MOAccessImpl.ACCESS_READ_ONLY, new OctetString(READ_ONLY_OID_VALUE_1)),
|
||||
DefaultMOFactory.getInstance().createScalar(new OID(READ_ONLY_OID_2), MOAccessImpl.ACCESS_READ_ONLY, new OctetString(READ_ONLY_OID_VALUE_2)),
|
||||
DefaultMOFactory.getInstance().createScalar(new OID(WRITE_ONLY_OID), MOAccessImpl.ACCESS_WRITE_ONLY, new OctetString(WRITE_ONLY_OID_VALUE))
|
||||
);
|
||||
}
|
||||
|
||||
@AfterEach
|
||||
@After
|
||||
public void tearDown() {
|
||||
agent.stop();
|
||||
agent.unregister();
|
||||
snmpResourceHandler.close();
|
||||
}
|
||||
|
||||
protected SNMPTreeResponse getTreeEvents(final int port, final int version) throws IOException {
|
||||
final Snmp snmp = SNMPTestUtils.createSnmpClient();
|
||||
final CommunityTarget target = SNMPTestUtils.createCommTarget("public", LOCALHOST + "/" + port, version);
|
||||
final StandardSNMPRequestHandler standardSnmpRequestHandler = new StandardSNMPRequestHandler(snmp, target);
|
||||
return standardSnmpRequestHandler.walk("1.3.6.1.4.1.32437");
|
||||
@Parameterized.Parameters
|
||||
public static Collection<Object[]> data() {
|
||||
return Arrays.asList(new Object[][]{
|
||||
{SnmpConstants.version1, snmpV1ConfigurationFactory, v1TestAgent, NO_SUCH_NAME, NO_SUCH_NAME, NO_SUCH_NAME, NO_SUCH_NAME},
|
||||
{SnmpConstants.version2c, snmpv2cConfigurationFactory, v2cTestAgent, NOT_WRITABLE, NO_ACCESS, NO_SUCH_OBJECT, UNABLE_TO_CREATE_OBJECT},
|
||||
{SnmpConstants.version3, snmpv3ConfigurationFactory, v3TestAgent, NOT_WRITABLE, NO_ACCESS, NO_SUCH_OBJECT, UNABLE_TO_CREATE_OBJECT}
|
||||
});
|
||||
}
|
||||
|
||||
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);
|
||||
private final int version;
|
||||
private final SNMPConfigurationFactory snmpConfigurationFactory;
|
||||
private final TestAgent agent;
|
||||
private final String cannotSetReadOnlyOidStatusMessage;
|
||||
private final String cannotModifyOidStatusMessage;
|
||||
private final String getInvalidOidStatusMessage;
|
||||
private final String setInvalidOidStatusMessage;
|
||||
|
||||
public SNMPRequestTest(final int version, final SNMPConfigurationFactory snmpConfigurationFactory, final TestAgent agent,
|
||||
final String cannotSetReadOnlyOidStatusMessage, final String cannotModifyOidStatusMessage,
|
||||
final String getInvalidOidStatusMessage, final String setInvalidOidStatusMessage) {
|
||||
this.version = version;
|
||||
this.snmpConfigurationFactory = snmpConfigurationFactory;
|
||||
this.agent = agent;
|
||||
this.cannotSetReadOnlyOidStatusMessage = cannotSetReadOnlyOidStatusMessage;
|
||||
this.cannotModifyOidStatusMessage = cannotModifyOidStatusMessage;
|
||||
this.getInvalidOidStatusMessage = getInvalidOidStatusMessage;
|
||||
this.setInvalidOidStatusMessage = setInvalidOidStatusMessage;
|
||||
}
|
||||
|
||||
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);
|
||||
@Test
|
||||
public void testSuccessfulSnmpGet() throws IOException {
|
||||
final SNMPConfiguration snmpConfiguration = snmpConfigurationFactory.createSnmpGetSetConfiguration(agent.getPort());
|
||||
snmpResourceHandler = SNMPFactoryProvider.getFactory(version).createSNMPResourceHandler(snmpConfiguration);
|
||||
final GetSNMPHandler getSNMPHandler = new GetSNMPHandler(snmpResourceHandler);
|
||||
final SNMPSingleResponse response = getSNMPHandler.get(READ_ONLY_OID_1);
|
||||
assertEquals(READ_ONLY_OID_VALUE_1, response.getVariableBindings().get(0).getVariable());
|
||||
assertEquals(SUCCESS, response.getErrorStatusText());
|
||||
|
||||
final MockFlowFile flowFile = new MockFlowFile(1L);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSuccessfulSnmpGetWithFlowFileInput() throws IOException {
|
||||
final SNMPConfiguration snmpConfiguration = snmpConfigurationFactory.createSnmpGetSetConfiguration(agent.getPort());
|
||||
snmpResourceHandler = SNMPFactoryProvider.getFactory(version).createSNMPResourceHandler(snmpConfiguration);
|
||||
final GetSNMPHandler getSNMPHandler = new GetSNMPHandler(snmpResourceHandler);
|
||||
final Optional<SNMPSingleResponse> optionalResponse = getSNMPHandler.get(getFlowFileAttributesForSnmpGet(READ_ONLY_OID_1, READ_ONLY_OID_2));
|
||||
if (optionalResponse.isPresent()) {
|
||||
final SNMPSingleResponse response = optionalResponse.get();
|
||||
Set<String> expectedVariables = new HashSet<>(Arrays.asList(READ_ONLY_OID_VALUE_1, READ_ONLY_OID_VALUE_2));
|
||||
Set<String> actualVariables = response.getVariableBindings().stream().map(SNMPValue::getVariable).collect(Collectors.toSet());
|
||||
assertEquals(expectedVariables, actualVariables);
|
||||
assertEquals(SUCCESS, response.getErrorStatusText());
|
||||
} else {
|
||||
fail("Response is not present.");
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSuccessfulSnmpWalk() {
|
||||
final SNMPConfiguration snmpConfiguration = snmpConfigurationFactory.createSnmpGetSetConfiguration(agent.getPort());
|
||||
snmpResourceHandler = SNMPFactoryProvider.getFactory(version).createSNMPResourceHandler(snmpConfiguration);
|
||||
final GetSNMPHandler getSNMPHandler = new GetSNMPHandler(snmpResourceHandler);
|
||||
final SNMPTreeResponse response = getSNMPHandler.walk(WALK_OID);
|
||||
|
||||
assertSubTreeContainsOids(response);
|
||||
}
|
||||
|
||||
@Test(expected = RequestTimeoutException.class)
|
||||
public void testSnmpGetTimeoutReturnsNull() throws IOException {
|
||||
final SNMPConfiguration snmpConfiguration = snmpConfigurationFactory.createSnmpGetSetConfigWithCustomHost(INVALID_HOST, agent.getPort());
|
||||
snmpResourceHandler = SNMPFactoryProvider.getFactory(version).createSNMPResourceHandler(snmpConfiguration);
|
||||
|
||||
final GetSNMPHandler getSNMPHandler = new GetSNMPHandler(snmpResourceHandler);
|
||||
getSNMPHandler.get(READ_ONLY_OID_1);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSnmpGetInvalidOidWithFlowFileInput() throws IOException {
|
||||
final SNMPConfiguration snmpConfiguration = snmpConfigurationFactory.createSnmpGetSetConfiguration(agent.getPort());
|
||||
snmpResourceHandler = SNMPFactoryProvider.getFactory(version).createSNMPResourceHandler(snmpConfiguration);
|
||||
final GetSNMPHandler getSNMPHandler = new GetSNMPHandler(snmpResourceHandler);
|
||||
final Optional<SNMPSingleResponse> optionalResponse = getSNMPHandler.get(getFlowFileAttributesForSnmpGet(INVALID_OID, READ_ONLY_OID_2));
|
||||
if (optionalResponse.isPresent()) {
|
||||
final SNMPSingleResponse response = optionalResponse.get();
|
||||
if (version == SnmpConstants.version1) {
|
||||
assertEquals("Null", response.getVariableBindings().get(1).getVariable());
|
||||
assertEquals(READ_ONLY_OID_VALUE_2, response.getVariableBindings().get(0).getVariable());
|
||||
assertEquals(NO_SUCH_NAME, response.getErrorStatusText());
|
||||
} else {
|
||||
assertEquals(NO_SUCH_OBJECT, response.getVariableBindings().get(1).getVariable());
|
||||
assertEquals(READ_ONLY_OID_VALUE_2, response.getVariableBindings().get(0).getVariable());
|
||||
assertEquals(SUCCESS, response.getErrorStatusText());
|
||||
}
|
||||
} else {
|
||||
fail("Response is not present.");
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSuccessfulSnmpSet() throws IOException {
|
||||
final Map<String, String> flowFileAttributes = getFlowFileAttributes(WRITE_ONLY_OID);
|
||||
|
||||
final SNMPConfiguration snmpConfiguration = snmpConfigurationFactory.createSnmpGetSetConfiguration(agent.getPort());
|
||||
snmpResourceHandler = SNMPFactoryProvider.getFactory(version).createSNMPResourceHandler(snmpConfiguration);
|
||||
final SetSNMPHandler setSNMPHandler = new SetSNMPHandler(snmpResourceHandler);
|
||||
final Optional<SNMPSingleResponse> optionalResponse = setSNMPHandler.set(flowFileAttributes);
|
||||
if (optionalResponse.isPresent()) {
|
||||
final SNMPSingleResponse response = optionalResponse.get();
|
||||
assertEquals(TEST_OID_VALUE, response.getVariableBindings().get(0).getVariable());
|
||||
assertEquals(SUCCESS, response.getErrorStatusText());
|
||||
} else {
|
||||
fail("Response is not present.");
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCannotSetReadOnlyObject() throws IOException {
|
||||
final Map<String, String> flowFileAttributes = getFlowFileAttributes(READ_ONLY_OID_1);
|
||||
|
||||
final SNMPConfiguration snmpConfiguration = snmpConfigurationFactory.createSnmpGetSetConfiguration(agent.getPort());
|
||||
snmpResourceHandler = SNMPFactoryProvider.getFactory(version).createSNMPResourceHandler(snmpConfiguration);
|
||||
final SetSNMPHandler setSNMPHandler = new SetSNMPHandler(snmpResourceHandler);
|
||||
final Optional<SNMPSingleResponse> optionalResponse = setSNMPHandler.set(flowFileAttributes);
|
||||
if (optionalResponse.isPresent()) {
|
||||
final SNMPSingleResponse response = optionalResponse.get();
|
||||
assertEquals(cannotSetReadOnlyOidStatusMessage, response.getErrorStatusText());
|
||||
} else {
|
||||
fail("Response is not present.");
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCannotGetWriteOnlyObject() throws IOException {
|
||||
final SNMPConfiguration snmpConfiguration = snmpConfigurationFactory.createSnmpGetSetConfiguration(agent.getPort());
|
||||
snmpResourceHandler = SNMPFactoryProvider.getFactory(version).createSNMPResourceHandler(snmpConfiguration);
|
||||
final GetSNMPHandler getSNMPHandler = new GetSNMPHandler(snmpResourceHandler);
|
||||
final SNMPSingleResponse response = getSNMPHandler.get(WRITE_ONLY_OID);
|
||||
|
||||
assertEquals(cannotModifyOidStatusMessage, response.getErrorStatusText());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCannotGetInvalidOid() throws IOException {
|
||||
final SNMPConfiguration snmpConfiguration = snmpConfigurationFactory.createSnmpGetSetConfiguration(agent.getPort());
|
||||
snmpResourceHandler = SNMPFactoryProvider.getFactory(version).createSNMPResourceHandler(snmpConfiguration);
|
||||
final GetSNMPHandler getSNMPHandler = new GetSNMPHandler(snmpResourceHandler);
|
||||
final SNMPSingleResponse response = getSNMPHandler.get(INVALID_OID);
|
||||
if (version == SnmpConstants.version1) {
|
||||
assertEquals(getInvalidOidStatusMessage, response.getErrorStatusText());
|
||||
} else {
|
||||
assertEquals(getInvalidOidStatusMessage, response.getVariableBindings().get(0).getVariable());
|
||||
assertEquals(SUCCESS, response.getErrorStatusText());
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCannotSetInvalidOid() throws IOException {
|
||||
final Map<String, String> flowFileAttributes = getFlowFileAttributes(INVALID_OID);
|
||||
final SNMPConfiguration snmpConfiguration = snmpConfigurationFactory.createSnmpGetSetConfiguration(agent.getPort());
|
||||
snmpResourceHandler = SNMPFactoryProvider.getFactory(version).createSNMPResourceHandler(snmpConfiguration);
|
||||
final SetSNMPHandler setSNMPHandler = new SetSNMPHandler(snmpResourceHandler);
|
||||
final Optional<SNMPSingleResponse> optionalResponse = setSNMPHandler.set(flowFileAttributes);
|
||||
if (optionalResponse.isPresent()) {
|
||||
final SNMPSingleResponse response = optionalResponse.get();
|
||||
assertEquals(setInvalidOidStatusMessage, response.getErrorStatusText());
|
||||
} else {
|
||||
fail("Response is not present.");
|
||||
}
|
||||
}
|
||||
|
||||
private Map<String, String> getFlowFileAttributes(String oid) {
|
||||
final Map<String, String> attributes = new HashMap<>();
|
||||
attributes.put(SNMP_PROP_PREFIX + oid, expectedOid);
|
||||
flowFile.putAttributes(attributes);
|
||||
|
||||
return standardSnmpRequestHandler.set(flowFile);
|
||||
attributes.put(SNMP_PROP_PREFIX + oid, TEST_OID_VALUE);
|
||||
return attributes;
|
||||
}
|
||||
|
||||
protected void assertSubTreeContainsOids(SNMPTreeResponse response) {
|
||||
private Map<String, String> getFlowFileAttributesForSnmpGet(String... oids) {
|
||||
final Map<String, String> attributes = new HashMap<>();
|
||||
Arrays.stream(oids).forEach(oid -> attributes.put(SNMP_PROP_PREFIX + oid, null));
|
||||
return attributes;
|
||||
}
|
||||
|
||||
private void assertSubTreeContainsOids(SNMPTreeResponse response) {
|
||||
final Map<String, String> attributes = response.getAttributes();
|
||||
attributes.entrySet().forEach(this::checkEntryContainsSubString);
|
||||
}
|
||||
@ -124,7 +310,15 @@ public abstract class SNMPRequestTest {
|
||||
}
|
||||
});
|
||||
if (!isMatch.get()) {
|
||||
fail("Expected OID did not found in subtree.");
|
||||
fail("Expected OID is not found in subtree.");
|
||||
}
|
||||
}
|
||||
|
||||
private static void registerManagedObjects(final TestAgent agent) {
|
||||
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))
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,146 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.nifi.snmp.operations;
|
||||
|
||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
import com.fasterxml.jackson.core.type.TypeReference;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import org.apache.nifi.processor.ProcessSessionFactory;
|
||||
import org.apache.nifi.remote.io.socket.NetworkUtils;
|
||||
import org.apache.nifi.snmp.configuration.SNMPConfiguration;
|
||||
import org.apache.nifi.snmp.dto.UserDetails;
|
||||
import org.apache.nifi.snmp.utils.SNMPUtils;
|
||||
import org.apache.nifi.util.MockComponentLog;
|
||||
import org.junit.Test;
|
||||
import org.snmp4j.Snmp;
|
||||
import org.snmp4j.mp.SnmpConstants;
|
||||
import org.snmp4j.security.USM;
|
||||
import org.snmp4j.security.UsmUser;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Scanner;
|
||||
import java.util.Set;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.Mockito.doAnswer;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
public class SNMPTrapReceiverHandlerTest {
|
||||
|
||||
public static final String USERS_JSON = "src/test/resources/users.json";
|
||||
|
||||
@Test
|
||||
public void testTrapReceiverCreatesCommandResponder() {
|
||||
final SNMPConfiguration snmpConfiguration = mock(SNMPConfiguration.class);
|
||||
final ProcessSessionFactory mockProcessSessionFactory = mock(ProcessSessionFactory.class);
|
||||
final MockComponentLog mockComponentLog = new MockComponentLog("componentId", new Object());
|
||||
final Snmp mockSnmpManager = mock(Snmp.class);
|
||||
when(snmpConfiguration.getManagerPort()).thenReturn(NetworkUtils.availablePort());
|
||||
when(snmpConfiguration.getVersion()).thenReturn(SnmpConstants.version1);
|
||||
|
||||
final SNMPTrapReceiverHandler trapReceiverHandler = new SNMPTrapReceiverHandler(snmpConfiguration, null);
|
||||
trapReceiverHandler.setSnmpManager(mockSnmpManager);
|
||||
trapReceiverHandler.createTrapReceiver(mockProcessSessionFactory, mockComponentLog);
|
||||
|
||||
|
||||
verify(mockSnmpManager).addCommandResponder(any(SNMPTrapReceiver.class));
|
||||
|
||||
assertTrue(trapReceiverHandler.isStarted());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCloseTrapReceiverCleansUpResources() throws IOException {
|
||||
final SNMPConfiguration snmpConfiguration = mock(SNMPConfiguration.class);
|
||||
final ProcessSessionFactory mockProcessSessionFactory = mock(ProcessSessionFactory.class);
|
||||
final MockComponentLog mockComponentLog = new MockComponentLog("componentId", new Object());
|
||||
final USM mockUsm = mock(USM.class);
|
||||
final Snmp mockSnmpManager = mock(Snmp.class);
|
||||
|
||||
when(mockSnmpManager.getUSM()).thenReturn(mockUsm);
|
||||
when(snmpConfiguration.getManagerPort()).thenReturn(NetworkUtils.availablePort());
|
||||
when(snmpConfiguration.getVersion()).thenReturn(SnmpConstants.version1);
|
||||
|
||||
final SNMPTrapReceiverHandler trapReceiverHandler = new SNMPTrapReceiverHandler(snmpConfiguration, null);
|
||||
trapReceiverHandler.setSnmpManager(mockSnmpManager);
|
||||
trapReceiverHandler.createTrapReceiver(mockProcessSessionFactory, mockComponentLog);
|
||||
trapReceiverHandler.close();
|
||||
|
||||
verify(mockUsm).removeAllUsers();
|
||||
verify(mockSnmpManager).close();
|
||||
|
||||
assertFalse(trapReceiverHandler.isStarted());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAddUsmUsers() throws JsonProcessingException, FileNotFoundException {
|
||||
final Set<String> expectedUserAttributes = new HashSet<>();
|
||||
try (Scanner scanner = new Scanner(new File(USERS_JSON))) {
|
||||
final String content = scanner.useDelimiter("\\Z").next();
|
||||
final ObjectMapper mapper = new ObjectMapper();
|
||||
final List<UserDetails> userDetails = mapper.readValue(content, new TypeReference<List<UserDetails>>() {
|
||||
});
|
||||
userDetails
|
||||
.forEach(user -> {
|
||||
expectedUserAttributes.add(user.getSecurityName());
|
||||
expectedUserAttributes.add(SNMPUtils.getAuth(user.getAuthProtocol()).toString());
|
||||
expectedUserAttributes.add(user.getAuthPassphrase());
|
||||
expectedUserAttributes.add(SNMPUtils.getPriv(user.getPrivProtocol()).toString());
|
||||
expectedUserAttributes.add(user.getPrivPassphrase());
|
||||
});
|
||||
}
|
||||
final Set<String> usmAttributes = new HashSet<>();
|
||||
final SNMPConfiguration snmpConfiguration = mock(SNMPConfiguration.class);
|
||||
final ProcessSessionFactory mockProcessSessionFactory = mock(ProcessSessionFactory.class);
|
||||
final MockComponentLog mockComponentLog = new MockComponentLog("componentId", new Object());
|
||||
final Snmp mockSnmpManager = mock(Snmp.class);
|
||||
final USM mockUsm = mock(USM.class);
|
||||
|
||||
when(snmpConfiguration.getManagerPort()).thenReturn(NetworkUtils.availablePort());
|
||||
when(snmpConfiguration.getVersion()).thenReturn(SnmpConstants.version3);
|
||||
doAnswer(invocation -> {
|
||||
UsmUser usmUser = (UsmUser) invocation.getArgument(0);
|
||||
usmAttributes.add(usmUser.getSecurityName().toString());
|
||||
usmAttributes.add(usmUser.getAuthenticationProtocol().toString());
|
||||
usmAttributes.add(usmUser.getAuthenticationPassphrase().toString());
|
||||
usmAttributes.add(usmUser.getPrivacyProtocol().toString());
|
||||
usmAttributes.add(usmUser.getPrivacyPassphrase().toString());
|
||||
return null;
|
||||
}).when(mockUsm).addUser(any(UsmUser.class));
|
||||
when(mockSnmpManager.getUSM()).thenReturn(mockUsm);
|
||||
|
||||
final SNMPTrapReceiverHandler trapReceiverHandler = new SNMPTrapReceiverHandler(snmpConfiguration, USERS_JSON);
|
||||
trapReceiverHandler.setSnmpManager(mockSnmpManager);
|
||||
trapReceiverHandler.createTrapReceiver(mockProcessSessionFactory, mockComponentLog);
|
||||
|
||||
|
||||
verify(mockSnmpManager).addCommandResponder(any(SNMPTrapReceiver.class));
|
||||
|
||||
assertTrue(trapReceiverHandler.isStarted());
|
||||
|
||||
assertEquals(expectedUserAttributes, usmAttributes);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,153 @@
|
||||
/*
|
||||
* 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.processor.ProcessSessionFactory;
|
||||
import org.apache.nifi.snmp.processors.ListenTrapSNMP;
|
||||
import org.apache.nifi.util.LogMessage;
|
||||
import org.apache.nifi.util.MockComponentLog;
|
||||
import org.apache.nifi.util.MockFlowFile;
|
||||
import org.apache.nifi.util.MockProcessSession;
|
||||
import org.apache.nifi.util.SharedSessionState;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.snmp4j.CommandResponderEvent;
|
||||
import org.snmp4j.PDU;
|
||||
import org.snmp4j.PDUv1;
|
||||
import org.snmp4j.smi.OID;
|
||||
import org.snmp4j.smi.VariableBinding;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Vector;
|
||||
import java.util.concurrent.atomic.AtomicLong;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.mockito.Mockito.doReturn;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
public class SNMPTrapReceiverTest {
|
||||
|
||||
private static final Object MOCK_COMPONENT_ID = new Object();
|
||||
|
||||
private ProcessSessionFactory mockProcessSessionFactory;
|
||||
private MockProcessSession mockProcessSession;
|
||||
private MockComponentLog mockComponentLog;
|
||||
private PDU mockPdu;
|
||||
private SNMPTrapReceiver snmpTrapReceiver;
|
||||
|
||||
|
||||
@Before
|
||||
public void init() {
|
||||
mockProcessSessionFactory = mock(ProcessSessionFactory.class);
|
||||
mockComponentLog = new MockComponentLog("componentId", MOCK_COMPONENT_ID);
|
||||
mockPdu = mock(PDU.class);
|
||||
snmpTrapReceiver = new SNMPTrapReceiver(mockProcessSessionFactory, mockComponentLog);
|
||||
final ListenTrapSNMP listenTrapSNMP = new ListenTrapSNMP();
|
||||
mockProcessSession = new MockProcessSession(new SharedSessionState(listenTrapSNMP, new AtomicLong(0L)), listenTrapSNMP);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testReceiveTrapWithNullPduLogsError() {
|
||||
CommandResponderEvent mockEvent = mock(CommandResponderEvent.class);
|
||||
|
||||
snmpTrapReceiver.processPdu(mockEvent);
|
||||
|
||||
final LogMessage logMessage = mockComponentLog.getErrorMessages().get(0);
|
||||
|
||||
assertEquals(String.format("%s Request timed out or parameters are incorrect.", MOCK_COMPONENT_ID), logMessage.getMsg());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testReceiveTrapWithInvalidPduTypeLogsError() {
|
||||
final CommandResponderEvent mockEvent = mock(CommandResponderEvent.class);
|
||||
|
||||
when(mockPdu.getType()).thenReturn(PDU.REPORT);
|
||||
when(mockEvent.getPDU()).thenReturn(mockPdu);
|
||||
snmpTrapReceiver.processPdu(mockEvent);
|
||||
|
||||
final LogMessage logMessage = mockComponentLog.getErrorMessages().get(0);
|
||||
|
||||
assertEquals(String.format("%s Request timed out or parameters are incorrect.", MOCK_COMPONENT_ID), logMessage.getMsg());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testTrapReceiverCreatesTrapPduV1FlowFile() {
|
||||
final CommandResponderEvent mockEvent = mock(CommandResponderEvent.class);
|
||||
final PDUv1 mockV1Pdu = mock(PDUv1.class);
|
||||
|
||||
when(mockV1Pdu.getType()).thenReturn(PDU.V1TRAP);
|
||||
when(mockV1Pdu.getEnterprise()).thenReturn(new OID("1.3.6.1.2.1.1.1.0"));
|
||||
when(mockV1Pdu.getSpecificTrap()).thenReturn(4);
|
||||
final Vector<VariableBinding> vbs = new Vector<>();
|
||||
doReturn(vbs).when(mockV1Pdu).getVariableBindings();
|
||||
when(mockEvent.getPDU()).thenReturn(mockV1Pdu);
|
||||
when(mockProcessSessionFactory.createSession()).thenReturn(mockProcessSession);
|
||||
|
||||
snmpTrapReceiver.processPdu(mockEvent);
|
||||
|
||||
final List<MockFlowFile> flowFiles = mockProcessSession.getFlowFilesForRelationship(ListenTrapSNMP.REL_SUCCESS);
|
||||
final FlowFile flowFile = flowFiles.get(0);
|
||||
|
||||
assertEquals("1.3.6.1.2.1.1.1.0", flowFile.getAttribute("snmp$enterprise"));
|
||||
assertEquals(String.valueOf(4), flowFile.getAttribute("snmp$specificTrapType"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testTrapReceiverCreatesTrapPduV2FlowFile() {
|
||||
final CommandResponderEvent mockEvent = mock(CommandResponderEvent.class);
|
||||
|
||||
when(mockPdu.getType()).thenReturn(PDU.TRAP);
|
||||
when(mockPdu.getErrorIndex()).thenReturn(123);
|
||||
when(mockPdu.getErrorStatusText()).thenReturn("test error status text");
|
||||
final Vector<VariableBinding> vbs = new Vector<>();
|
||||
doReturn(vbs).when(mockPdu).getVariableBindings();
|
||||
when(mockEvent.getPDU()).thenReturn(mockPdu);
|
||||
when(mockProcessSessionFactory.createSession()).thenReturn(mockProcessSession);
|
||||
|
||||
snmpTrapReceiver.processPdu(mockEvent);
|
||||
|
||||
final List<MockFlowFile> flowFiles = mockProcessSession.getFlowFilesForRelationship(ListenTrapSNMP.REL_SUCCESS);
|
||||
final FlowFile flowFile = flowFiles.get(0);
|
||||
|
||||
assertEquals(String.valueOf(123), flowFile.getAttribute("snmp$errorIndex"));
|
||||
assertEquals("test error status text", flowFile.getAttribute("snmp$errorStatusText"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testReceiveTrapWithErrorGetsTransferredToFailure() {
|
||||
final CommandResponderEvent mockEvent = mock(CommandResponderEvent.class);
|
||||
|
||||
when(mockPdu.getType()).thenReturn(PDU.TRAP);
|
||||
when(mockPdu.getErrorStatus()).thenReturn(PDU.badValue);
|
||||
final Vector<VariableBinding> vbs = new Vector<>();
|
||||
doReturn(vbs).when(mockPdu).getVariableBindings();
|
||||
when(mockEvent.getPDU()).thenReturn(mockPdu);
|
||||
when(mockProcessSessionFactory.createSession()).thenReturn(mockProcessSession);
|
||||
|
||||
snmpTrapReceiver.processPdu(mockEvent);
|
||||
|
||||
final List<MockFlowFile> flowFiles = mockProcessSession.getFlowFilesForRelationship(ListenTrapSNMP.REL_FAILURE);
|
||||
|
||||
assertFalse(flowFiles.isEmpty());
|
||||
final FlowFile flowFile = flowFiles.get(0);
|
||||
|
||||
assertEquals(String.valueOf(PDU.badValue), flowFile.getAttribute("snmp$errorStatus"));
|
||||
}
|
||||
}
|
@ -1,86 +0,0 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.nifi.snmp.operations;
|
||||
|
||||
import org.apache.nifi.snmp.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.jupiter.api.Test;
|
||||
import org.snmp4j.MessageException;
|
||||
import org.snmp4j.mp.SnmpConstants;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||
|
||||
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
|
||||
public void testSnmpGetTimeoutReturnsNull() {
|
||||
assertThrows(RequestTimeoutException.class, () -> getResponseEvent(INVALID_HOST, agent.getPort(), SnmpConstants.version1, READ_ONLY_OID_1));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSnmpGetWithInvalidTargetThrowsException() {
|
||||
assertThrows(MessageException.class, () -> 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());
|
||||
}
|
||||
}
|
@ -1,86 +0,0 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.nifi.snmp.operations;
|
||||
|
||||
import org.apache.nifi.snmp.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.jupiter.api.Test;
|
||||
import org.snmp4j.MessageException;
|
||||
import org.snmp4j.mp.SnmpConstants;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||
|
||||
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
|
||||
public void testSnmpGetTimeoutReturnsNull() {
|
||||
assertThrows(RequestTimeoutException.class, () -> getResponseEvent(INVALID_HOST, agent.getPort(), SnmpConstants.version2c, READ_ONLY_OID_1));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSnmpGetWithInvalidTargetThrowsException() {
|
||||
assertThrows(MessageException.class, () -> 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());
|
||||
}
|
||||
}
|
@ -1,135 +0,0 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.nifi.snmp.operations;
|
||||
|
||||
import org.apache.nifi.snmp.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.jupiter.api.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.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||
|
||||
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
|
||||
public void testSnmpGetTimeoutReturnsNull() throws IOException {
|
||||
final StandardSNMPRequestHandler standardSnmpRequestHandler = getSnmpV3Getter(INVALID_HOST, SnmpConstants.version3,
|
||||
"SHA", "SHAAuthPassword");
|
||||
assertThrows(RequestTimeoutException.class, () -> standardSnmpRequestHandler.get(READ_ONLY_OID_1));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSnmpGetWithInvalidTargetThrowsException() throws IOException {
|
||||
final StandardSNMPRequestHandler standardSnmpRequestHandler = getSnmpV3Getter(LOCALHOST, -1, "SHA", "SHAAuthPassword");
|
||||
assertThrows(MessageException.class, () -> 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);
|
||||
}
|
||||
}
|
@ -0,0 +1,109 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.nifi.snmp.operations;
|
||||
|
||||
import org.apache.nifi.snmp.configuration.V1TrapConfiguration;
|
||||
import org.apache.nifi.snmp.configuration.V2TrapConfiguration;
|
||||
import org.apache.nifi.snmp.factory.trap.V1TrapPDUFactory;
|
||||
import org.apache.nifi.snmp.factory.trap.V2TrapPDUFactory;
|
||||
import org.apache.nifi.util.MockComponentLog;
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.snmp4j.PDU;
|
||||
import org.snmp4j.Snmp;
|
||||
import org.snmp4j.Target;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.time.Instant;
|
||||
import java.util.Collections;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
public class SendTrapSNMPHandlerTest {
|
||||
|
||||
private Target mockTarget;
|
||||
private Snmp mockSnmpManager;
|
||||
private PDU mockPdu;
|
||||
private MockComponentLog mockComponentLog;
|
||||
private V1TrapConfiguration mockV1TrapConfiguration;
|
||||
private V2TrapConfiguration mockV2TrapConfiguration;
|
||||
private SNMPResourceHandler snmpResourceHandler;
|
||||
private SendTrapSNMPHandler sendTrapSNMPHandler;
|
||||
|
||||
@Before
|
||||
public void init() {
|
||||
mockTarget = mock(Target.class);
|
||||
mockSnmpManager = mock(Snmp.class);
|
||||
mockPdu = mock(PDU.class);
|
||||
mockComponentLog = new MockComponentLog("id", new Object());
|
||||
mockV1TrapConfiguration = mock(V1TrapConfiguration.class);
|
||||
mockV2TrapConfiguration = mock(V2TrapConfiguration.class);
|
||||
V1TrapPDUFactory mockV1TrapPDUFactory = mock(V1TrapPDUFactory.class);
|
||||
when(mockV1TrapPDUFactory.get(mockV1TrapConfiguration)).thenReturn(mockPdu);
|
||||
V2TrapPDUFactory mockV2TrapPDUFactory = mock(V2TrapPDUFactory.class);
|
||||
when(mockV2TrapPDUFactory.get(mockV2TrapConfiguration)).thenReturn(mockPdu);
|
||||
|
||||
snmpResourceHandler = new SNMPResourceHandler(mockSnmpManager, mockTarget);
|
||||
|
||||
sendTrapSNMPHandler = new SendTrapSNMPHandler(snmpResourceHandler, Instant.now(), mockComponentLog) {
|
||||
@Override
|
||||
V1TrapPDUFactory createV1TrapPduFactory(final Instant startTime) {
|
||||
return mockV1TrapPDUFactory;
|
||||
}
|
||||
|
||||
@Override
|
||||
V2TrapPDUFactory createV2TrapPduFactory(final Instant startTime) {
|
||||
return mockV2TrapPDUFactory;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@After
|
||||
public void tearDown() {
|
||||
snmpResourceHandler.close();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSendV1TrapWithValidFlowfile() throws IOException {
|
||||
final String flowFileOid = "1.3.6.1.2.1.1.1.0";
|
||||
sendTrapSNMPHandler.sendTrap(Collections.singletonMap("snmp$" + flowFileOid, "OID value"), mockV1TrapConfiguration);
|
||||
|
||||
verify(mockSnmpManager).send(mockPdu, mockTarget);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSendV2TrapWithValidFlowfile() throws IOException {
|
||||
final String flowFileOid = "1.3.6.1.2.1.1.1.0";
|
||||
sendTrapSNMPHandler.sendTrap(Collections.singletonMap("snmp$" + flowFileOid, "OID value"), mockV2TrapConfiguration);
|
||||
|
||||
verify(mockSnmpManager).send(mockPdu, mockTarget);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSendV1TrapWithFlowfileWithoutOptionalSnmpAttributes() throws IOException {
|
||||
sendTrapSNMPHandler.sendTrap(Collections.singletonMap("invalid key", "invalid value"), mockV1TrapConfiguration);
|
||||
|
||||
verify(mockSnmpManager).send(mockPdu, mockTarget);
|
||||
|
||||
final String expectedDebugLog = "{} No optional SNMP specific variables found in flowfile.";
|
||||
assertEquals(expectedDebugLog, mockComponentLog.getDebugMessages().get(0).getMsg());
|
||||
}
|
||||
}
|
@ -0,0 +1,119 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.nifi.snmp.operations;
|
||||
|
||||
import org.apache.nifi.snmp.dto.SNMPSingleResponse;
|
||||
import org.apache.nifi.snmp.exception.RequestTimeoutException;
|
||||
import org.junit.After;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.snmp4j.PDU;
|
||||
import org.snmp4j.Snmp;
|
||||
import org.snmp4j.Target;
|
||||
import org.snmp4j.event.ResponseEvent;
|
||||
import org.snmp4j.util.DefaultPDUFactory;
|
||||
import org.snmp4j.util.PDUFactory;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
|
||||
import static org.apache.nifi.snmp.operations.SNMPResourceHandler.REQUEST_TIMEOUT_EXCEPTION_TEMPLATE;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
public class SetSNMPHandlerTest {
|
||||
|
||||
private static final PDUFactory defaultSetPduFactory = new DefaultPDUFactory(PDU.SET);
|
||||
|
||||
private Target mockTarget;
|
||||
private Snmp mockSnmpManager;
|
||||
private PDU mockPdu;
|
||||
private PDU mockResponsePdu;
|
||||
private ResponseEvent mockResponseEvent;
|
||||
|
||||
private SetSNMPHandler setSNMPHandler;
|
||||
|
||||
@Before
|
||||
public void init() {
|
||||
mockTarget = mock(Target.class);
|
||||
mockSnmpManager = mock(Snmp.class);
|
||||
PDUFactory mockPduFactory = mock(PDUFactory.class);
|
||||
mockPdu = mock(PDU.class);
|
||||
mockResponsePdu = mock(PDU.class);
|
||||
mockResponseEvent = mock(ResponseEvent.class);
|
||||
|
||||
when(mockPduFactory.createPDU(mockTarget)).thenReturn(mockPdu);
|
||||
|
||||
SNMPResourceHandler snmpResourceHandler = new SNMPResourceHandler(mockSnmpManager, mockTarget);
|
||||
setSNMPHandler = new SetSNMPHandler(snmpResourceHandler);
|
||||
SetSNMPHandler.setSetPduFactory(mockPduFactory);
|
||||
}
|
||||
|
||||
@After
|
||||
public void tearDown() {
|
||||
SetSNMPHandler.setSetPduFactory(defaultSetPduFactory);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSetSnmpValidResponse() throws IOException {
|
||||
final String flowFileOid = "1.3.6.1.2.1.1.1.0";
|
||||
final Map<String, String> flowFileAttributes = new HashMap<>();
|
||||
flowFileAttributes.put("snmp$" + flowFileOid, "OID value");
|
||||
|
||||
when(mockResponseEvent.getResponse()).thenReturn(mockResponsePdu);
|
||||
when(mockSnmpManager.set(any(PDU.class), any(Target.class))).thenReturn(mockResponseEvent);
|
||||
|
||||
setSNMPHandler.set(flowFileAttributes);
|
||||
|
||||
verify(mockSnmpManager).set(mockPdu, mockTarget);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSetSnmpTimeoutThrowsException() throws IOException {
|
||||
final String flowFileOid = "1.3.6.1.2.1.1.1.0";
|
||||
final Map<String, String> flowFileAttributes = new HashMap<>();
|
||||
flowFileAttributes.put("snmp$" + flowFileOid, "OID value");
|
||||
|
||||
when(mockSnmpManager.set(any(PDU.class), any(Target.class))).thenReturn(mockResponseEvent);
|
||||
|
||||
final RequestTimeoutException requestTimeoutException = Assert.assertThrows(
|
||||
RequestTimeoutException.class,
|
||||
() -> setSNMPHandler.set(flowFileAttributes)
|
||||
);
|
||||
|
||||
assertEquals(String.format(REQUEST_TIMEOUT_EXCEPTION_TEMPLATE, "write"), requestTimeoutException.getMessage());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSetSnmpWithInvalidPduThrowsException() throws IOException {
|
||||
final Map<String, String> flowFileAttributes = new HashMap<>();
|
||||
flowFileAttributes.put("invalid key", "invalid value");
|
||||
|
||||
when(mockSnmpManager.set(any(PDU.class), any(Target.class))).thenReturn(mockResponseEvent);
|
||||
|
||||
final Optional<SNMPSingleResponse> optionalResponse = setSNMPHandler.set(flowFileAttributes);
|
||||
|
||||
assertFalse(optionalResponse.isPresent());
|
||||
}
|
||||
}
|
@ -0,0 +1,162 @@
|
||||
/*
|
||||
* 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.remote.io.socket.NetworkUtils;
|
||||
import org.apache.nifi.snmp.dto.SNMPSingleResponse;
|
||||
import org.apache.nifi.snmp.dto.SNMPValue;
|
||||
import org.apache.nifi.snmp.helper.testrunners.SNMPV1TestRunnerFactory;
|
||||
import org.apache.nifi.util.MockFlowFile;
|
||||
import org.apache.nifi.util.MockProcessContext;
|
||||
import org.apache.nifi.util.MockProcessSession;
|
||||
import org.apache.nifi.util.SharedSessionState;
|
||||
import org.apache.nifi.util.TestRunner;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.snmp4j.mp.SnmpConstants;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.atomic.AtomicLong;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
public class AbstractSNMPProcessorTest {
|
||||
|
||||
private static final String TEST_OID = "1.3.6.1.4.1.32437.1.5.1.4.2.0";
|
||||
private static final String UNSUPPORTED_SECURITY_LEVEL = "1.3.6.1.6.3.15.1.1.1";
|
||||
|
||||
private GetSNMP getSNMP;
|
||||
private MockProcessContext mockProcessContext;
|
||||
private MockProcessSession mockProcessSession;
|
||||
private MockFlowFile mockFlowFile;
|
||||
private SNMPSingleResponse mockResponse;
|
||||
private TestRunner getTestRunner;
|
||||
|
||||
@Before
|
||||
public void init() {
|
||||
getTestRunner = new SNMPV1TestRunnerFactory().createSnmpGetTestRunner(NetworkUtils.availablePort(), TEST_OID, "GET");
|
||||
getSNMP = (GetSNMP) getTestRunner.getProcessor();
|
||||
mockProcessContext = new MockProcessContext(getSNMP);
|
||||
mockProcessSession = new MockProcessSession(new SharedSessionState(getSNMP, new AtomicLong(0L)), getSNMP);
|
||||
mockFlowFile = mockProcessSession.create();
|
||||
mockResponse = mock(SNMPSingleResponse.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testProcessResponseWithInvalidResponseThrowsException() {
|
||||
final String errorStatus = "Test error status text";
|
||||
when(mockResponse.getErrorStatusText()).thenReturn(errorStatus);
|
||||
|
||||
|
||||
getSNMP.handleResponse(mockProcessContext, mockProcessSession, mockFlowFile, mockResponse, GetSNMP.REL_SUCCESS, GetSNMP.REL_FAILURE, "provenanceAddress");
|
||||
|
||||
final String actualLogMessage = getTestRunner.getLogger().getErrorMessages().get(0).getMsg();
|
||||
final String expectedLogMessage = String.format("SNMP request failed, response error: %s", errorStatus);
|
||||
assertTrue(actualLogMessage.contains(expectedLogMessage));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testProcessResponseWithNoSuchObjectThrowsException() {
|
||||
when(mockResponse.isValid()).thenReturn(true);
|
||||
when(mockResponse.getVersion()).thenReturn(SnmpConstants.version2c);
|
||||
|
||||
List<SNMPValue> vbs = Collections.singletonList(new SNMPValue(TEST_OID, "noSuchObject"));
|
||||
when(mockResponse.getVariableBindings()).thenReturn(vbs);
|
||||
|
||||
|
||||
getSNMP.handleResponse(mockProcessContext, mockProcessSession, mockFlowFile, mockResponse, GetSNMP.REL_SUCCESS, GetSNMP.REL_FAILURE, "provenanceAddress");
|
||||
|
||||
|
||||
final String actualLogMessage = getTestRunner.getLogger().getErrorMessages().get(0).getMsg();
|
||||
final String expectedLogMessage = "SNMP request failed, response error: OID not found.";
|
||||
assertTrue(actualLogMessage.contains(expectedLogMessage));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testValidProcessResponseWithoutVariableBindingThrowsException() {
|
||||
when(mockResponse.isValid()).thenReturn(true);
|
||||
when(mockResponse.getVersion()).thenReturn(SnmpConstants.version2c);
|
||||
|
||||
when(mockResponse.getVariableBindings()).thenReturn(Collections.emptyList());
|
||||
|
||||
getSNMP.handleResponse(mockProcessContext, mockProcessSession, mockFlowFile, mockResponse, GetSNMP.REL_SUCCESS, GetSNMP.REL_FAILURE, "provenanceAddress");
|
||||
|
||||
|
||||
final String actualLogMessage = getTestRunner.getLogger().getErrorMessages().get(0).getMsg();
|
||||
final String expectedLogMessage = "Empty SNMP response: no variable binding found.";
|
||||
assertTrue(actualLogMessage.contains(expectedLogMessage));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testValidProcessResponse() {
|
||||
when(mockResponse.isValid()).thenReturn(true);
|
||||
when(mockResponse.getVersion()).thenReturn(SnmpConstants.version2c);
|
||||
|
||||
final List<SNMPValue> vbs = Collections.singletonList(new SNMPValue(TEST_OID, "testOIDValue"));
|
||||
when(mockResponse.getVariableBindings()).thenReturn(vbs);
|
||||
|
||||
final Map<String, String> attributes = Collections.singletonMap(TEST_OID, "testOIDValue");
|
||||
when(mockResponse.getAttributes()).thenReturn(attributes);
|
||||
|
||||
getSNMP.handleResponse(mockProcessContext, mockProcessSession, mockFlowFile, mockResponse, GetSNMP.REL_SUCCESS, GetSNMP.REL_FAILURE, "provenanceAddress");
|
||||
final List<MockFlowFile> flowFilesForRelationship = mockProcessSession.getFlowFilesForRelationship(GetSNMP.REL_SUCCESS);
|
||||
|
||||
assertEquals("testOIDValue", flowFilesForRelationship.get(0).getAttribute(TEST_OID));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testProcessResponseWithReportPduWithoutErrorMessage() {
|
||||
when(mockResponse.isValid()).thenReturn(true);
|
||||
when(mockResponse.isReportPdu()).thenReturn(true);
|
||||
|
||||
final List<SNMPValue> vbs = Collections.singletonList(new SNMPValue(TEST_OID, "testOIDValue"));
|
||||
when(mockResponse.getVariableBindings()).thenReturn(vbs);
|
||||
|
||||
|
||||
getSNMP.handleResponse(mockProcessContext, mockProcessSession, mockFlowFile, mockResponse, GetSNMP.REL_SUCCESS, GetSNMP.REL_FAILURE, "provenanceAddress");
|
||||
|
||||
|
||||
final String actualLogMessage = getTestRunner.getLogger().getErrorMessages().get(0).getMsg();
|
||||
final String expectedLogMessage = String.format("SNMP request failed, response error: Report-PDU returned, but no error message found. " +
|
||||
"Please, check the OID %s in an online OID repository.", TEST_OID);
|
||||
|
||||
assertTrue(actualLogMessage.contains(expectedLogMessage));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testProcessResponseWithReportPdu() {
|
||||
when(mockResponse.isValid()).thenReturn(true);
|
||||
when(mockResponse.isReportPdu()).thenReturn(true);
|
||||
|
||||
final List<SNMPValue> vbs = Collections.singletonList(new SNMPValue(UNSUPPORTED_SECURITY_LEVEL, "testOIDValue"));
|
||||
when(mockResponse.getVariableBindings()).thenReturn(vbs);
|
||||
|
||||
|
||||
getSNMP.handleResponse(mockProcessContext, mockProcessSession, mockFlowFile, mockResponse, GetSNMP.REL_SUCCESS, GetSNMP.REL_FAILURE, "provenanceAddress");
|
||||
|
||||
|
||||
final String actualLogMessage = getTestRunner.getLogger().getErrorMessages().get(0).getMsg();
|
||||
final String expectedLogMessage = String.format("SNMP request failed, response error: Report-PDU returned. %s: usmStatsUnsupportedSecLevels", UNSUPPORTED_SECURITY_LEVEL);
|
||||
|
||||
assertTrue(actualLogMessage.contains(expectedLogMessage));
|
||||
}
|
||||
}
|
@ -0,0 +1,154 @@
|
||||
/*
|
||||
* 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.commons.lang3.StringUtils;
|
||||
import org.apache.nifi.snmp.helper.testrunners.SNMPTestRunnerFactory;
|
||||
import org.apache.nifi.snmp.helper.testrunners.SNMPV1TestRunnerFactory;
|
||||
import org.apache.nifi.snmp.helper.testrunners.SNMPV2cTestRunnerFactory;
|
||||
import org.apache.nifi.snmp.helper.testrunners.SNMPV3TestRunnerFactory;
|
||||
import org.apache.nifi.snmp.testagents.TestAgent;
|
||||
import org.apache.nifi.snmp.testagents.TestSNMPV1Agent;
|
||||
import org.apache.nifi.snmp.testagents.TestSNMPV2cAgent;
|
||||
import org.apache.nifi.snmp.testagents.TestSNMPV3Agent;
|
||||
import org.apache.nifi.snmp.utils.SNMPUtils;
|
||||
import org.apache.nifi.util.MockFlowFile;
|
||||
import org.apache.nifi.util.TestRunner;
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.junit.runners.Parameterized;
|
||||
import org.snmp4j.agent.mo.DefaultMOFactory;
|
||||
import org.snmp4j.agent.mo.MOAccessImpl;
|
||||
import org.snmp4j.smi.OID;
|
||||
import org.snmp4j.smi.OctetString;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
|
||||
@RunWith(Parameterized.class)
|
||||
public class GetSNMPIntegrationTest {
|
||||
|
||||
private static final String LOCALHOST = "127.0.0.1";
|
||||
private static final String READ_ONLY_OID_1 = "1.3.6.1.4.1.32437.1.5.1.4.2.0";
|
||||
private static final String READ_ONLY_OID_2 = "1.3.6.1.4.1.32437.1.5.1.4.3.0";
|
||||
private static final String NOT_FOUND_OID = "1.3.4.1.2.1.343";
|
||||
private static final String WALK_OID = "1.3.6.1.4.1.32437";
|
||||
private static final String READ_ONLY_OID_VALUE_1 = "TestOID1";
|
||||
private static final String READ_ONLY_OID_VALUE_2 = "TestOID2";
|
||||
private static final String GET = "GET";
|
||||
private static final String WALK = "WALK";
|
||||
|
||||
private static final SNMPTestRunnerFactory v1TestRunnerFactory = new SNMPV1TestRunnerFactory();
|
||||
private static final SNMPTestRunnerFactory v2cTestRunnerFactory = new SNMPV2cTestRunnerFactory();
|
||||
private static final SNMPTestRunnerFactory v3TestRunnerFactory = new SNMPV3TestRunnerFactory();
|
||||
|
||||
private static final TestAgent v1TestAgent = new TestSNMPV1Agent(LOCALHOST);
|
||||
private static final TestAgent v2cTestAgent = new TestSNMPV2cAgent(LOCALHOST);
|
||||
private static final TestAgent v3TestAgent = new TestSNMPV3Agent(LOCALHOST);
|
||||
|
||||
static {
|
||||
registerManagedObjects(v1TestAgent);
|
||||
registerManagedObjects(v2cTestAgent);
|
||||
registerManagedObjects(v3TestAgent);
|
||||
}
|
||||
|
||||
@Parameterized.Parameters
|
||||
public static Collection<Object[]> data() {
|
||||
return Arrays.asList(new Object[][]{
|
||||
{v1TestAgent, v1TestRunnerFactory},
|
||||
{v2cTestAgent, v2cTestRunnerFactory},
|
||||
{v3TestAgent, v3TestRunnerFactory}
|
||||
});
|
||||
}
|
||||
|
||||
private final TestAgent testAgent;
|
||||
private final SNMPTestRunnerFactory testRunnerFactory;
|
||||
|
||||
public GetSNMPIntegrationTest(final TestAgent testAgent, final SNMPTestRunnerFactory testRunnerFactory) {
|
||||
this.testAgent = testAgent;
|
||||
this.testRunnerFactory = testRunnerFactory;
|
||||
}
|
||||
|
||||
@Before
|
||||
public void setUp() throws IOException {
|
||||
testAgent.start();
|
||||
}
|
||||
|
||||
@After
|
||||
public void tearDown() {
|
||||
testAgent.stop();
|
||||
testAgent.unregister();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSnmpGet() {
|
||||
|
||||
final TestRunner runner = testRunnerFactory.createSnmpGetTestRunner(testAgent.getPort(), READ_ONLY_OID_1, GET);
|
||||
runner.run();
|
||||
final MockFlowFile successFF = runner.getFlowFilesForRelationship(GetSNMP.REL_SUCCESS).get(0);
|
||||
|
||||
assertNotNull(successFF);
|
||||
assertEquals(READ_ONLY_OID_VALUE_1, successFF.getAttribute(SNMPUtils.SNMP_PROP_PREFIX + READ_ONLY_OID_1 + SNMPUtils.SNMP_PROP_DELIMITER + "4"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSnmpWalk() {
|
||||
final TestRunner runner = testRunnerFactory.createSnmpGetTestRunner(testAgent.getPort(), WALK_OID, WALK);
|
||||
runner.run();
|
||||
final MockFlowFile successFF = runner.getFlowFilesForRelationship(GetSNMP.REL_SUCCESS).get(0);
|
||||
assertNotNull(successFF);
|
||||
|
||||
assertEquals(READ_ONLY_OID_VALUE_1, successFF.getAttribute(SNMPUtils.SNMP_PROP_PREFIX + READ_ONLY_OID_1 + SNMPUtils.SNMP_PROP_DELIMITER + "4"));
|
||||
assertEquals(READ_ONLY_OID_VALUE_2, successFF.getAttribute(SNMPUtils.SNMP_PROP_PREFIX + READ_ONLY_OID_2 + SNMPUtils.SNMP_PROP_DELIMITER + "4"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSnmpGetWithEmptyResponse() {
|
||||
final MockFlowFile mockFlowFile = new MockFlowFile(0L);
|
||||
mockFlowFile.putAttributes(Collections.singletonMap("snmp$" + NOT_FOUND_OID, StringUtils.EMPTY));
|
||||
final TestRunner runner = testRunnerFactory.createSnmpGetTestRunner(testAgent.getPort(), NOT_FOUND_OID, GET);
|
||||
runner.enqueue(mockFlowFile);
|
||||
runner.run();
|
||||
|
||||
if (testAgent == v1TestAgent) {
|
||||
final MockFlowFile failureFF = runner.getFlowFilesForRelationship(GetSNMP.REL_FAILURE).get(0);
|
||||
assertNotNull(failureFF);
|
||||
assertEquals(StringUtils.EMPTY, failureFF.getAttribute(SNMPUtils.SNMP_PROP_PREFIX + NOT_FOUND_OID));
|
||||
assertEquals("No such name", failureFF.getAttribute(SNMPUtils.SNMP_PROP_PREFIX + "errorStatusText"));
|
||||
} else {
|
||||
final MockFlowFile failureFF = runner.getFlowFilesForRelationship(GetSNMP.REL_FAILURE).get(0);
|
||||
assertNotNull(failureFF);
|
||||
assertEquals("noSuchObject", failureFF.getAttribute(SNMPUtils.SNMP_PROP_PREFIX + NOT_FOUND_OID + SNMPUtils.SNMP_PROP_DELIMITER + "128"));
|
||||
assertEquals("Success", failureFF.getAttribute(SNMPUtils.SNMP_PROP_PREFIX + "errorStatusText"));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static void registerManagedObjects(final TestAgent agent) {
|
||||
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))
|
||||
);
|
||||
}
|
||||
}
|
@ -16,77 +16,47 @@
|
||||
*/
|
||||
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.remote.io.socket.NetworkUtils;
|
||||
import org.apache.nifi.snmp.helper.testrunners.SNMPV1TestRunnerFactory;
|
||||
import org.apache.nifi.util.MockProcessSession;
|
||||
import org.apache.nifi.util.SharedSessionState;
|
||||
import org.apache.nifi.util.TestRunner;
|
||||
import org.apache.nifi.util.TestRunners;
|
||||
import org.junit.jupiter.api.AfterAll;
|
||||
import org.junit.jupiter.api.BeforeAll;
|
||||
import org.junit.jupiter.api.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.concurrent.atomic.AtomicLong;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.Mockito.doNothing;
|
||||
import static org.mockito.Mockito.spy;
|
||||
import static org.mockito.Mockito.verify;
|
||||
|
||||
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";
|
||||
private static final String OID = "1.3.6.1.4.1.32437.1.5.1.4.2.0";
|
||||
|
||||
@BeforeAll
|
||||
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))
|
||||
);
|
||||
}
|
||||
@Test
|
||||
public void testOnTriggerWithGetStrategyPerformsSnmpGet() {
|
||||
final TestRunner getSnmpTestRunner = new SNMPV1TestRunnerFactory().createSnmpGetTestRunner(NetworkUtils.availablePort(), OID, "GET");
|
||||
final GetSNMP spyGetSNMP = spy((GetSNMP) getSnmpTestRunner.getProcessor());
|
||||
final MockProcessSession mockProcessSession = new MockProcessSession(new SharedSessionState(spyGetSNMP, new AtomicLong(0L)), spyGetSNMP);
|
||||
|
||||
@AfterAll
|
||||
public static void tearDown() {
|
||||
snmpV1Agent.stop();
|
||||
doNothing().when(spyGetSNMP).performSnmpGet(any(), any(), any(), any());
|
||||
|
||||
spyGetSNMP.onTrigger(getSnmpTestRunner.getProcessContext(), mockProcessSession);
|
||||
|
||||
verify(spyGetSNMP).performSnmpGet(any(), any(), any(), any());
|
||||
}
|
||||
|
||||
@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"));
|
||||
}
|
||||
public void testOnTriggerWithWalkStrategyPerformsSnmpWalk() {
|
||||
final TestRunner getSnmpTestRunner = new SNMPV1TestRunnerFactory().createSnmpGetTestRunner(NetworkUtils.availablePort(), OID, "WALK");
|
||||
final GetSNMP spyGetSNMP = spy((GetSNMP) getSnmpTestRunner.getProcessor());
|
||||
final MockProcessSession mockProcessSession = new MockProcessSession(new SharedSessionState(spyGetSNMP, new AtomicLong(0L)), spyGetSNMP);
|
||||
|
||||
@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"));
|
||||
}
|
||||
doNothing().when(spyGetSNMP).performSnmpWalk(any(), any(), any(), any());
|
||||
|
||||
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;
|
||||
spyGetSNMP.onTrigger(getSnmpTestRunner.getProcessContext(), mockProcessSession);
|
||||
|
||||
verify(spyGetSNMP).performSnmpWalk(any(), any(), any(), any());
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,112 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.nifi.snmp.processors;
|
||||
|
||||
import org.apache.nifi.snmp.helper.testrunners.SNMPTestRunnerFactory;
|
||||
import org.apache.nifi.snmp.helper.testrunners.SNMPV1TestRunnerFactory;
|
||||
import org.apache.nifi.snmp.helper.testrunners.SNMPV2cTestRunnerFactory;
|
||||
import org.apache.nifi.snmp.helper.testrunners.SNMPV3TestRunnerFactory;
|
||||
import org.apache.nifi.snmp.testagents.TestAgent;
|
||||
import org.apache.nifi.snmp.testagents.TestSNMPV1Agent;
|
||||
import org.apache.nifi.snmp.testagents.TestSNMPV2cAgent;
|
||||
import org.apache.nifi.snmp.testagents.TestSNMPV3Agent;
|
||||
import org.apache.nifi.snmp.utils.SNMPUtils;
|
||||
import org.apache.nifi.util.MockFlowFile;
|
||||
import org.apache.nifi.util.TestRunner;
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.junit.runners.Parameterized;
|
||||
import org.snmp4j.agent.mo.DefaultMOFactory;
|
||||
import org.snmp4j.agent.mo.MOAccessImpl;
|
||||
import org.snmp4j.smi.OID;
|
||||
import org.snmp4j.smi.OctetString;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
|
||||
@RunWith(Parameterized.class)
|
||||
public class SetSNMPIntegrationTest {
|
||||
|
||||
private static final String LOCALHOST = "127.0.0.1";
|
||||
private static final String TEST_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 SNMPTestRunnerFactory v1TestRunnerFactory = new SNMPV1TestRunnerFactory();
|
||||
private static final SNMPTestRunnerFactory v2cTestRunnerFactory = new SNMPV2cTestRunnerFactory();
|
||||
private static final SNMPTestRunnerFactory v3TestRunnerFactory = new SNMPV3TestRunnerFactory();
|
||||
|
||||
private static final TestAgent v1TestAgent = new TestSNMPV1Agent(LOCALHOST);
|
||||
private static final TestAgent v2cTestAgent = new TestSNMPV2cAgent(LOCALHOST);
|
||||
private static final TestAgent v3TestAgent = new TestSNMPV3Agent(LOCALHOST);
|
||||
|
||||
static {
|
||||
registerManagedObjects(v1TestAgent);
|
||||
registerManagedObjects(v2cTestAgent);
|
||||
registerManagedObjects(v3TestAgent);
|
||||
}
|
||||
|
||||
@Parameterized.Parameters
|
||||
public static Collection<Object[]> data() {
|
||||
return Arrays.asList(new Object[][]{
|
||||
{v1TestAgent, v1TestRunnerFactory},
|
||||
{v2cTestAgent, v2cTestRunnerFactory},
|
||||
{v3TestAgent, v3TestRunnerFactory}
|
||||
});
|
||||
}
|
||||
|
||||
private final TestAgent testAgent;
|
||||
private final SNMPTestRunnerFactory testRunnerFactory;
|
||||
|
||||
public SetSNMPIntegrationTest(final TestAgent testAgent, final SNMPTestRunnerFactory testRunnerFactory) {
|
||||
this.testAgent = testAgent;
|
||||
this.testRunnerFactory = testRunnerFactory;
|
||||
}
|
||||
|
||||
@Before
|
||||
public void setUp() throws IOException {
|
||||
testAgent.start();
|
||||
}
|
||||
|
||||
@After
|
||||
public void tearDown() {
|
||||
testAgent.stop();
|
||||
testAgent.unregister();
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testSnmpSet() {
|
||||
final TestRunner runner = testRunnerFactory.createSnmpSetTestRunner(testAgent.getPort(), TEST_OID, TEST_OID_VALUE);
|
||||
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 + SNMPUtils.SNMP_PROP_DELIMITER + "4"));
|
||||
}
|
||||
|
||||
private static void registerManagedObjects(final TestAgent agent) {
|
||||
agent.registerManagedObjects(
|
||||
DefaultMOFactory.getInstance().createScalar(new OID(TEST_OID), MOAccessImpl.ACCESS_READ_WRITE, new OctetString(TEST_OID_VALUE))
|
||||
);
|
||||
}
|
||||
}
|
@ -1,88 +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 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.jupiter.api.AfterAll;
|
||||
import org.junit.jupiter.api.BeforeAll;
|
||||
import org.junit.jupiter.api.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.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.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";
|
||||
|
||||
@BeforeAll
|
||||
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))
|
||||
);
|
||||
}
|
||||
|
||||
@AfterAll
|
||||
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;
|
||||
}
|
||||
}
|
@ -0,0 +1,108 @@
|
||||
/*
|
||||
* 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.remote.io.socket.NetworkUtils;
|
||||
import org.apache.nifi.snmp.configuration.V1TrapConfiguration;
|
||||
import org.apache.nifi.snmp.configuration.V2TrapConfiguration;
|
||||
import org.apache.nifi.snmp.helper.TrapConfigurationFactory;
|
||||
import org.apache.nifi.snmp.helper.testrunners.SNMPTestRunnerFactory;
|
||||
import org.apache.nifi.snmp.helper.testrunners.SNMPV1TestRunnerFactory;
|
||||
import org.apache.nifi.snmp.helper.testrunners.SNMPV2cTestRunnerFactory;
|
||||
import org.apache.nifi.snmp.utils.SNMPUtils;
|
||||
import org.apache.nifi.util.MockFlowFile;
|
||||
import org.apache.nifi.util.TestRunner;
|
||||
import org.junit.Ignore;
|
||||
import org.junit.Test;
|
||||
import org.snmp4j.mp.SnmpConstants;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
|
||||
public class TrapSNMPIntegrationTest {
|
||||
|
||||
protected static final String SYSTEM_DESCRIPTION_OID = "1.3.6.1.2.1.1.1.0";
|
||||
protected static final String SYSTEM_DESCRIPTION_OID_VALUE = "optionalTrapOidTestValue";
|
||||
|
||||
@Test
|
||||
public void testSendReceiveV1Trap() throws InterruptedException {
|
||||
final int listenPort = NetworkUtils.availablePort();
|
||||
|
||||
final V1TrapConfiguration v1TrapConfiguration = TrapConfigurationFactory.getV1TrapConfiguration();
|
||||
final SNMPTestRunnerFactory v1TestRunnerFactory = new SNMPV1TestRunnerFactory();
|
||||
|
||||
final TestRunner sendTrapTestRunner = v1TestRunnerFactory.createSnmpSendTrapTestRunner(listenPort, SYSTEM_DESCRIPTION_OID, SYSTEM_DESCRIPTION_OID_VALUE);
|
||||
final TestRunner listenTrapTestRunner = v1TestRunnerFactory.createSnmpListenTrapTestRunner(listenPort);
|
||||
|
||||
listenTrapTestRunner.run(1, false);
|
||||
sendTrapTestRunner.run(1);
|
||||
|
||||
Thread.sleep(50);
|
||||
|
||||
final MockFlowFile successFF = listenTrapTestRunner.getFlowFilesForRelationship(GetSNMP.REL_SUCCESS).get(0);
|
||||
|
||||
assertNotNull(successFF);
|
||||
assertEquals("Success", successFF.getAttribute(SNMPUtils.SNMP_PROP_PREFIX + "errorStatusText"));
|
||||
|
||||
assertEquals(v1TrapConfiguration.getEnterpriseOid(), successFF.getAttribute(SNMPUtils.SNMP_PROP_PREFIX + "enterprise"));
|
||||
assertEquals(v1TrapConfiguration.getAgentAddress(), successFF.getAttribute(SNMPUtils.SNMP_PROP_PREFIX + "agentAddress"));
|
||||
assertEquals(String.valueOf(v1TrapConfiguration.getGenericTrapType()), successFF.getAttribute(SNMPUtils.SNMP_PROP_PREFIX + "genericTrapType"));
|
||||
assertEquals(String.valueOf(v1TrapConfiguration.getSpecificTrapType()), successFF.getAttribute(SNMPUtils.SNMP_PROP_PREFIX + "specificTrapType"));
|
||||
|
||||
|
||||
assertEquals(SYSTEM_DESCRIPTION_OID_VALUE, successFF.getAttribute(SNMPUtils.SNMP_PROP_PREFIX + SYSTEM_DESCRIPTION_OID
|
||||
+ SNMPUtils.SNMP_PROP_DELIMITER + "4"));
|
||||
|
||||
listenTrapTestRunner.shutdown();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSendReceiveV2Trap() throws InterruptedException {
|
||||
final int listenPort = NetworkUtils.availablePort();
|
||||
|
||||
final V2TrapConfiguration v2TrapConfiguration = TrapConfigurationFactory.getV2TrapConfiguration();
|
||||
final SNMPTestRunnerFactory v2cTestRunnerFactory = new SNMPV2cTestRunnerFactory();
|
||||
|
||||
final TestRunner sendTrapTestRunner = v2cTestRunnerFactory.createSnmpSendTrapTestRunner(listenPort, SYSTEM_DESCRIPTION_OID, SYSTEM_DESCRIPTION_OID_VALUE);
|
||||
final TestRunner listenTrapTestRunner = v2cTestRunnerFactory.createSnmpListenTrapTestRunner(listenPort);
|
||||
|
||||
listenTrapTestRunner.run(1, false);
|
||||
sendTrapTestRunner.run(1);
|
||||
|
||||
Thread.sleep(50);
|
||||
|
||||
final MockFlowFile successFF = listenTrapTestRunner.getFlowFilesForRelationship(GetSNMP.REL_SUCCESS).get(0);
|
||||
|
||||
assertNotNull(successFF);
|
||||
assertEquals("Success", successFF.getAttribute(SNMPUtils.SNMP_PROP_PREFIX + "errorStatusText"));
|
||||
|
||||
assertEquals(v2TrapConfiguration.getTrapOidValue(), successFF.getAttribute(SNMPUtils.SNMP_PROP_PREFIX + SnmpConstants.snmpTrapOID
|
||||
+ SNMPUtils.SNMP_PROP_DELIMITER + "4"));
|
||||
|
||||
assertEquals(SYSTEM_DESCRIPTION_OID_VALUE, successFF.getAttribute(SNMPUtils.SNMP_PROP_PREFIX + SYSTEM_DESCRIPTION_OID
|
||||
+ SNMPUtils.SNMP_PROP_DELIMITER + "4"));
|
||||
|
||||
listenTrapTestRunner.shutdown();
|
||||
}
|
||||
|
||||
@Ignore("The ListenTrapSNMP and SendTrapSNMP processors use the same SecurityProtocols instance" +
|
||||
" and same USM (the USM is stored in a map by version), hence this case shall be manually tested." +
|
||||
" Check assertByVersion() to see what the trap payload must contain.")
|
||||
@Test
|
||||
public void testReceiveV3Trap() {
|
||||
}
|
||||
}
|
@ -53,6 +53,11 @@ public abstract class TestAgent extends BaseAgent {
|
||||
this.address = String.format("udp:%s/%d", host, port);
|
||||
}
|
||||
|
||||
public void unregister() {
|
||||
unregisterSnmpMIBs();
|
||||
snmpMpdMib.unregisterMOs(server, getContext(snmpMpdMib));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void initTransportMappings() {
|
||||
transportMappings = new TransportMapping[1];
|
||||
|
@ -0,0 +1,16 @@
|
||||
[
|
||||
{
|
||||
"securityName":"user1",
|
||||
"authProtocol":"MD5",
|
||||
"authPassphrase":"abc12345",
|
||||
"privProtocol":"DES",
|
||||
"privPassphrase":"abc12345"
|
||||
},
|
||||
{
|
||||
"securityName":"newUser2",
|
||||
"authProtocol":"MD5",
|
||||
"authPassphrase":"abc12345",
|
||||
"privProtocol":"AES256",
|
||||
"privPassphrase":"abc12345"
|
||||
}
|
||||
]
|
Loading…
x
Reference in New Issue
Block a user