NIFI-10054: Improve SendTrapSNMP error handling

Signed-off-by: Pierre Villard <pierre.villard.fr@gmail.com>

This closes #6081.
This commit is contained in:
Lehel 2022-05-26 18:35:14 +02:00 committed by Pierre Villard
parent 7f93cb4c91
commit 04aa32cd57
No known key found for this signature in database
GPG Key ID: F92A93B30C07C6D5
2 changed files with 49 additions and 2 deletions

View File

@ -25,6 +25,8 @@ 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.TransportIpAddress;
import java.io.IOException;
import java.time.Instant;
@ -62,7 +64,13 @@ public class SendTrapSNMPHandler {
logger.debug("No optional SNMP specific variables found in flowfile.");
}
snmpManager.send(pdu, target);
final ResponseEvent response = snmpManager.send(pdu, target);
if (response == null) {
final int port = ((TransportIpAddress) target.getAddress()).getPort();
throw new IOException(String.format("The sent PDU has not been confirmed, the target port [%d] may be unavailable.", port));
} else if (response.getError() != null) {
throw new IOException("An error occurred while sending trap.", response.getError());
}
}
V1TrapPDUFactory createV1TrapPduFactory(final Instant startTime) {

View File

@ -18,6 +18,7 @@ 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.exception.SNMPException;
import org.apache.nifi.snmp.factory.trap.V1TrapPDUFactory;
import org.apache.nifi.snmp.factory.trap.V2TrapPDUFactory;
import org.apache.nifi.util.MockComponentLog;
@ -27,12 +28,16 @@ import org.junit.Test;
import org.snmp4j.PDU;
import org.snmp4j.Snmp;
import org.snmp4j.Target;
import org.snmp4j.event.ResponseEvent;
import org.snmp4j.smi.TransportIpAddress;
import java.io.IOException;
import java.time.Instant;
import java.util.Collections;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertThrows;
import static org.junit.Assert.assertTrue;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
@ -42,6 +47,7 @@ public class SendTrapSNMPHandlerTest {
private Target mockTarget;
private Snmp mockSnmpManager;
private PDU mockPdu;
private ResponseEvent mockResponseEvent;
private MockComponentLog mockComponentLog;
private V1TrapConfiguration mockV1TrapConfiguration;
private V2TrapConfiguration mockV2TrapConfiguration;
@ -49,10 +55,11 @@ public class SendTrapSNMPHandlerTest {
private SendTrapSNMPHandler sendTrapSNMPHandler;
@Before
public void init() {
public void init() throws IOException {
mockTarget = mock(Target.class);
mockSnmpManager = mock(Snmp.class);
mockPdu = mock(PDU.class);
mockResponseEvent = mock(ResponseEvent.class);
mockComponentLog = new MockComponentLog("id", new Object());
mockV1TrapConfiguration = mock(V1TrapConfiguration.class);
mockV2TrapConfiguration = mock(V2TrapConfiguration.class);
@ -61,6 +68,8 @@ public class SendTrapSNMPHandlerTest {
V2TrapPDUFactory mockV2TrapPDUFactory = mock(V2TrapPDUFactory.class);
when(mockV2TrapPDUFactory.get(mockV2TrapConfiguration)).thenReturn(mockPdu);
when(mockSnmpManager.send(mockPdu, mockTarget)).thenReturn(mockResponseEvent);
snmpResourceHandler = new SNMPResourceHandler(mockSnmpManager, mockTarget);
sendTrapSNMPHandler = new SendTrapSNMPHandler(snmpResourceHandler, Instant.now(), mockComponentLog) {
@ -106,4 +115,34 @@ public class SendTrapSNMPHandlerTest {
final String expectedDebugLog = "{} No optional SNMP specific variables found in flowfile.";
assertEquals(expectedDebugLog, mockComponentLog.getDebugMessages().get(0).getMsg());
}
@Test
public void testSendTrapToInvalidPort() throws IOException {
when(mockSnmpManager.send(mockPdu, mockTarget)).thenReturn(null);
final TransportIpAddress mockAddress = mock(TransportIpAddress.class);
final int port = 55555;
when(mockAddress.getPort()).thenReturn(port);
when(mockTarget.getAddress()).thenReturn(mockAddress);
final String flowFileOid = "1.3.6.1.2.1.1.1.0";
Exception e = assertThrows(IOException.class,
() -> sendTrapSNMPHandler.sendTrap(Collections.singletonMap("snmp$" + flowFileOid, "OID value"), mockV2TrapConfiguration)
);
assertTrue(e.getMessage().contains(String.valueOf(port)));
}
@Test
public void testSendTrapInvalidResponse() throws IOException {
final String trapSnmpError = "Test Trap SNMP Error";
when(mockResponseEvent.getError()).thenReturn(new SNMPException(trapSnmpError));
when(mockSnmpManager.send(mockPdu, mockTarget)).thenReturn(mockResponseEvent);
final String flowFileOid = "1.3.6.1.2.1.1.1.0";
Exception e = assertThrows(IOException.class,
() -> sendTrapSNMPHandler.sendTrap(Collections.singletonMap("snmp$" + flowFileOid, "OID value"), mockV2TrapConfiguration)
);
assertTrue(e.getCause().getMessage().contains(trapSnmpError));
}
}