Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Eliminate warnings in SNMP tests #1

Open
wants to merge 2 commits into
base: 4850-flaky-snmp
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@
import jakarta.enterprise.context.ApplicationScoped;
import jakarta.inject.Inject;
import jakarta.inject.Named;
import jakarta.ws.rs.GET;
import jakarta.ws.rs.POST;
import jakarta.ws.rs.Path;
import jakarta.ws.rs.PathParam;
Expand All @@ -47,8 +46,6 @@
@ApplicationScoped
public class SnmpResource {

public static OID TRAP_OID = new OID("1.2.3.4.5");

@ConfigProperty(name = SnmpRoute.TRAP_V0_PORT)
int trap0Port;

Expand All @@ -66,14 +63,13 @@ public class SnmpResource {
ProducerTemplate producerTemplate;

@Path("/producePDU/{version}")
@GET
@POST
@Produces(MediaType.TEXT_PLAIN)
public Response producePDU(@PathParam("version") int version) {
public Response producePDU(@PathParam("version") int version, String payload) {
String url = String.format("snmp://%s?retries=1&snmpVersion=%d", snmpListenAddress, version);
SnmpMessage pdu = producerTemplate.requestBody(url, version, SnmpMessage.class);

String response = pdu.getSnmpMessage().getVariableBindings().stream()
.filter(vb -> vb.getOid().equals(SnmpConstants.sysDescr))
.map(vb -> vb.getVariable().toString())
.collect(Collectors.joining());

Expand All @@ -85,12 +81,12 @@ public Response producePDU(@PathParam("version") int version) {
@Produces(MediaType.TEXT_PLAIN)
public Response getNext(String payload, @PathParam("version") int version) {
String url = String.format("snmp://%s?type=GET_NEXT&retries=1&protocol=udp&oids=%s&snmpVersion=%d", snmpListenAddress,
SnmpConstants.sysDescr, version);
payload, version);
@SuppressWarnings("unchecked")
List<SnmpMessage> pdu = producerTemplate.requestBody(url, "", List.class);

String response = pdu.stream()
.flatMap(m -> m.getSnmpMessage().getVariableBindings().stream())
.filter(vb -> vb.getOid().equals(SnmpConstants.sysDescr))
.map(vb -> vb.getVariable().toString())
.collect(Collectors.joining(","));

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,16 +59,16 @@ public void configure() {
from("snmp:0.0.0.0:" + trap1Port + "?protocol=udp&type=TRAP&snmpVersion=1")
.process(e -> snmpResults.get("v1_trap").add(e.getIn().getBody(SnmpMessage.class)));

//POLL consumer 2 oidps, snmpVersion=0
//POLL consumer 2 oids, snmpVersion=0
from("snmp://" + snmpListenAddress + "?protocol=udp&snmpVersion=0&type=POLL&oids=" +
SnmpConstants.sysName + "," + SnmpConstants.sysContact)
SnmpConstants.sysLocation + "," + SnmpConstants.sysContact)
.process(e -> snmpResults.get("v0_poll2oids").add(e.getIn().getBody(SnmpMessage.class)));
//POLL consumer 2 oidps, snmpVersion=1
//POLL consumer 2 oids, snmpVersion=1
from("snmp://" + snmpListenAddress + "?protocol=udp&snmpVersion=1&type=POLL&oids=" +
SnmpConstants.sysName + "," + SnmpConstants.sysContact)
SnmpConstants.sysLocation + "," + SnmpConstants.sysContact)
.process(e -> snmpResults.get("v1_poll2oids").add(e.getIn().getBody(SnmpMessage.class)));

//POLL consumer starting with dot snmpVersion=0
// POLL consumer starting with dot snmpVersion=0
from("snmp://" + snmpListenAddress
+ "?protocol=udp&snmpVersion=0&type=POLL&oids=.1.3.6.1.4.1.6527.3.1.2.21.2.1.50")
.process(e -> snmpResults.get("v0_pollStartingDot").add(e.getIn().getBody(SnmpMessage.class)));
Expand All @@ -79,11 +79,11 @@ public void configure() {

//POLL consumer snmpVersion=0
from("snmp://" + snmpListenAddress + "?protocol=udp&snmpVersion=0&type=POLL&oids="
+ SnmpConstants.sysName)
+ SnmpConstants.sysDescr)
.process(e -> snmpResults.get("v0_poll").add(e.getIn().getBody(SnmpMessage.class)));
//POLL consumer snmpVersion=1
from("snmp://" + snmpListenAddress + "?protocol=udp&snmpVersion=1&type=POLL&oids="
+ SnmpConstants.sysName)
+ SnmpConstants.sysDescr)
.process(e -> snmpResults.get("v1_poll").add(e.getIn().getBody(SnmpMessage.class)));
}

Expand All @@ -93,15 +93,15 @@ static class Producers {
@Named("snmpTrapResults")
Map<String, Deque<SnmpMessage>> snmpResults() {
Map<String, Deque<SnmpMessage>> map = new ConcurrentHashMap<>();
map.put("v0_trap", new ConcurrentLinkedDeque());
map.put("v1_trap", new ConcurrentLinkedDeque());
map.put("v0_poll", new ConcurrentLinkedDeque());
map.put("v1_poll", new ConcurrentLinkedDeque());
map.put("v3_poll", new ConcurrentLinkedDeque());
map.put("v0_pollStartingDot", new ConcurrentLinkedDeque());
map.put("v1_pollStartingDot", new ConcurrentLinkedDeque());
map.put("v0_poll2oids", new ConcurrentLinkedDeque());
map.put("v1_poll2oids", new ConcurrentLinkedDeque());
map.put("v0_trap", new ConcurrentLinkedDeque<>());
map.put("v1_trap", new ConcurrentLinkedDeque<>());
map.put("v0_poll", new ConcurrentLinkedDeque<>());
map.put("v1_poll", new ConcurrentLinkedDeque<>());
map.put("v3_poll", new ConcurrentLinkedDeque<>());
map.put("v0_pollStartingDot", new ConcurrentLinkedDeque<>());
map.put("v1_pollStartingDot", new ConcurrentLinkedDeque<>());
map.put("v0_poll2oids", new ConcurrentLinkedDeque<>());
map.put("v1_poll2oids", new ConcurrentLinkedDeque<>());
return map;
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.MethodSource;
import org.snmp4j.mp.SnmpConstants;
import org.snmp4j.smi.OID;

import static org.awaitility.Awaitility.await;

Expand All @@ -40,6 +41,13 @@
@QuarkusTestResource(SnmpTestResource.class)
class SnmpTest {

public static final OID GET_NEXT_OID = new OID(new int[] { 1, 3, 6, 1, 2, 1, 25, 3, 2, 1, 5, 1 });
public static final OID POLL_OID = SnmpConstants.sysDescr;
public static final OID PRODUCE_PDU_OID = SnmpConstants.sysName;
public static final OID TWO_OIDS_A = SnmpConstants.sysLocation;
public static final OID TWO_OIDS_B = SnmpConstants.sysContact;
public static final OID DOT_OID = new OID(new int[] { 1, 3, 6, 1, 4, 1, 6527, 3, 1, 2, 21, 2, 1, 50 });

static Stream<Integer> supportedVersions() {
return Stream.of(0, 1/*, 3 not supported because of https://issues.apache.org/jira/browse/CAMEL-19298 */);
}
Expand Down Expand Up @@ -74,13 +82,14 @@ public void testPoll(int version) throws Exception {

await().atMost(20L, TimeUnit.SECONDS).pollDelay(100, TimeUnit.MILLISECONDS).until(() -> {
String result = RestAssured.given()
.body(SnmpConstants.sysName.toString())
.body(SnmpConstants.sysDescr.toString())
.post("/snmp/results/" + resultsName)
.then()
.statusCode(200)
.extract().body().asString();

return result.startsWith("Response from the test #1,Response from the test #2,Response from the test #3");
return result
.startsWith("My POLL Printer - response #1,My POLL Printer - response #2,My POLL Printer - response #3");
});
}

Expand All @@ -91,36 +100,37 @@ public void testPollStartingDot(int version) throws Exception {

await().atMost(20L, TimeUnit.SECONDS).pollDelay(100, TimeUnit.MILLISECONDS).until(() -> {
String result = RestAssured.given()
.body("1.3.6.1.4.1.6527.3.1.2.21.2.1.50")
.body(DOT_OID.toString())
.post("/snmp/results/" + resultsName)
.then()
.statusCode(200)
.extract().body().asString();

return result.startsWith("Response from the test #1,Response from the test #2,Response from the test #3");
return result.startsWith("My DOT Printer - response #1,My DOT Printer - response #2,My DOT Printer - response #3");
});
}

@ParameterizedTest
@MethodSource("supportedVersions")
public void testProducePDU(int version) {
RestAssured
.get("/snmp/producePDU/" + version)
RestAssured.given()
.body(PRODUCE_PDU_OID.toString())
.post("/snmp/producePDU/" + version)
.then()
.statusCode(200)
.body(Matchers.equalTo("Response from the test #1"));
.body(Matchers.startsWith("My PRODUCE_PDU Printer - response #"));
}

@ParameterizedTest
@MethodSource("supportedVersions")
public void testGetNext(int version) {

RestAssured.given()
.body("TEXT")
.body(GET_NEXT_OID.toString())
.post("/snmp/getNext/" + version)
.then()
.statusCode(200)
.body(Matchers.equalTo("Response from the test #1,Response from the test #2"));
.body(Matchers.equalTo("1,2,My GET_NEXT Printer - response #3"));
}

@ParameterizedTest
Expand All @@ -130,20 +140,22 @@ public void testPollWith2OIDs(int version) throws Exception {

await().atMost(20L, TimeUnit.SECONDS).pollDelay(100, TimeUnit.MILLISECONDS).until(() -> {
String resultOid1 = RestAssured.given()
.body(SnmpConstants.sysName.toString())
.body(TWO_OIDS_A.toString())
.post("/snmp/results/" + resultsName)
.then()
.statusCode(200)
.extract().body().asString();
String resultOid2 = RestAssured.given()
.body(SnmpConstants.sysContact.toString())
.body(TWO_OIDS_B.toString())
.post("/snmp/results/" + resultsName)
.then()
.statusCode(200)
.extract().body().asString();

return resultOid1.startsWith("Response from the test #1,Response from the test #2,Response from the test #3") &&
resultOid2.startsWith("Response from the test #1,Response from the test #2,Response from the test #3");
return resultOid1.startsWith(
"My 2 OIDs A Printer - response #1,My 2 OIDs A Printer - response #2,My 2 OIDs A Printer - response #3") &&
resultOid2.startsWith(
"My 2 OIDs B Printer - response #1,My 2 OIDs B Printer - response #2,My 2 OIDs B Printer - response #3");
});

}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@
import java.io.IOException;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.Vector;
import java.util.concurrent.ConcurrentHashMap;
import java.util.stream.Collectors;
Expand All @@ -33,6 +32,7 @@
import org.snmp4j.MessageException;
import org.snmp4j.PDU;
import org.snmp4j.PDUv1;
import org.snmp4j.ScopedPDU;
import org.snmp4j.Snmp;
import org.snmp4j.mp.SnmpConstants;
import org.snmp4j.mp.StatusInformation;
Expand Down Expand Up @@ -96,38 +96,34 @@ public TestCommandResponder(Snmp commandResponder) {
@Override
public synchronized void processPdu(CommandResponderEvent event) {
PDU pdu = event.getPDU();
Vector<? extends VariableBinding> vbs = Optional.ofNullable(pdu.getVariableBindings()).orElse(new Vector<>(0));
Vector<? extends VariableBinding> vbs;
if (pdu.getVariableBindings() != null) {
vbs = new Vector<>(pdu.getVariableBindings());
} else {
vbs = new Vector<>(0);
}
String key = vbs.stream().sequential().map(vb -> vb.getOid().toString()).collect(Collectors.joining(","));

//differ snmp versions
if (pdu instanceof PDUv1) {
key = "v1" + key;
key = "v1_" + key;
} else if (pdu instanceof ScopedPDU) {
key = "v3_" + key;
} else {
key = "v2_" + key;
}
int numberOfSent = counts.getOrDefault(key, 0);

//if 3 responses were already sent for the OID, do not respond anymore
if (numberOfSent > 3) {
return;
}
//first 2 responses are quick, the third response takes 3000ms (so there is a timeout with default 1500ms) ->
// getNext producer will receive only 2 messages
// poll consumer should receive all of them
if (numberOfSent % 3 == 2) {
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
//nothing
}
}

try {
PDU response = makeResponse(++numberOfSent, SnmpConstants.version1, vbs);
response.setRequestID(pdu.getRequestID());
commandResponder.getMessageDispatcher().returnResponsePdu(
event.getMessageProcessingModel(), event.getSecurityModel(),
event.getSecurityName(), event.getSecurityLevel(),
response, event.getMaxSizeResponsePDU(),
event.getStateReference(), new StatusInformation());
if (response != null) {
response.setRequestID(pdu.getRequestID());
commandResponder.getMessageDispatcher().returnResponsePdu(
event.getMessageProcessingModel(), event.getSecurityModel(),
event.getSecurityName(), event.getSecurityLevel(),
response, event.getMaxSizeResponsePDU(),
event.getStateReference(), new StatusInformation());
}
} catch (MessageException e) {
Assertions.assertNull(e);
}
Expand All @@ -140,13 +136,72 @@ private PDU makeResponse(int counter, int version, Vector<? extends VariableBind
responsePDU.setErrorStatus(PDU.noError);
responsePDU.setErrorIndex(0);
if (vbs.isEmpty()) {
responsePDU.add(new VariableBinding(new OID(SnmpConstants.sysDescr),
new OctetString("Response from the test #" + counter)));
VariableBinding vb = generateResponseBinding(counter, SnmpTest.PRODUCE_PDU_OID);
if (vb != null) {
responsePDU.add(vb);
}
} else {
vbs.stream().forEach(vb -> responsePDU.add(new VariableBinding(vb.getOid(),
new OctetString("Response from the test #" + counter))));
vbs.stream().forEach(vb -> responsePDU.add(generateResponseBinding(counter, vb.getOid())));
}
if (responsePDU.getVariableBindings().isEmpty()) {
return null;
}
return responsePDU;
}

private VariableBinding generateResponseBinding(int counter, OID oid) {
//get next test
if (SnmpTest.GET_NEXT_OID.equals(oid)) {
//if counter < 2 return the same oid
if (counter < 3) {
return new VariableBinding(SnmpTest.GET_NEXT_OID, new OctetString("" + counter));
}
if (counter == 3) {
//else return sysDescr
return new VariableBinding(SnmpTest.GET_NEXT_OID,
new OctetString("My GET_NEXT Printer - response #" + counter));
}
//else do not send response
return null;
}

if (SnmpTest.POLL_OID.equals(oid)) {
if (counter < 4) {
return new VariableBinding(SnmpTest.POLL_OID,
new OctetString("My POLL Printer - response #" + counter));
}

}

if (SnmpTest.PRODUCE_PDU_OID.equals(oid)) {
if (counter < 4) {
return new VariableBinding(SnmpTest.PRODUCE_PDU_OID,
new OctetString("My PRODUCE_PDU Printer - response #" + counter));
}
}

if (SnmpTest.TWO_OIDS_A.equals(oid)) {
if (counter < 4) {
return new VariableBinding(SnmpTest.TWO_OIDS_A,
new OctetString("My 2 OIDs A Printer - response #" + counter));
}
}

if (SnmpTest.TWO_OIDS_B.equals(oid)) {
if (counter < 4) {
return new VariableBinding(SnmpTest.TWO_OIDS_B,
new OctetString("My 2 OIDs B Printer - response #" + counter));
}
}

if (SnmpTest.DOT_OID.equals(oid)) {
if (counter < 4) {
return new VariableBinding(SnmpTest.DOT_OID,
new OctetString("My DOT Printer - response #" + counter));
}
}

return null;
}
}
}