[SNMP4J] Extending Agent
Eugene R. Snider
gene at cvtt.net
Thu Nov 1 14:57:36 CET 2007
Here's some code fragments you might find useful for your UDP stuff. The
MultiThreadedUDPReciever class will hang out on a UDP port of your
specification and process incoming messages in multiple threads. When a
message is recieved the UDP stream is parsed by the (not defined)
UDPEvent constructor. This turns the UDP data stream into an event class.
Other classes may listen for incoming events by implmenting the
UDPMonitor interface defined below. Classes register for Monitor events
by type (also not included, I refer to an external UDPMonitorConstants
class which is implementation specific ) using the static method
addListener.
When parsing is complete the registered listeners are notified by via
the UDPMonitor interface handleEvent callback based on their registered
event types. The event handlers (which are probably event specific) then
take the implementation specific event class and may manipulate it in
any way they desire. The event handlers are where table management and
other agent housekeeping tasks should be performed, additionally
implmentation specific traps related to the event may be thrown from the
event handlers. These are normally co-located in the mib class
implementation so that each mib listens for the events which are of
interest to it and manages its interface. An example would be the
ifMib.java class which updates the ifTable and an enterprise or private
mib handler which manages the enterprise specific objects.
The event notifier expects two defined event types, EVENT_TYPE_UNKNOWN
and EVENT_TYPE_ALL
Gene
--- Begin UDPMonitorConstants
package com.mrcompiler.snmp.server.agent;
public class UDPMonitorConstants {
public static enum MonitorEventType {
EVENT_TYPE_NONE,
ALL_EVENTS,
UDP_EVENT_ONE,
UDP_EVENT_TWO,
UNKNOWN_EVENT_TYPE
}
}
-- Begin MutliThreadedUDPListener class
package com.mrcompiler.snmp.server.agent;
import java.io.IOException;
import java.net.UnknownHostException;
import java.nio.ByteBuffer;
import org.snmp4j.TransportMapping;
import org.snmp4j.log.LogAdapter;
import org.snmp4j.log.LogFactory;
import org.snmp4j.smi.Address;
import org.snmp4j.smi.GenericAddress;
import org.snmp4j.smi.UdpAddress;
import org.snmp4j.transport.DefaultUdpTransportMapping;
import org.snmp4j.transport.TransportListener;
import org.snmp4j.transport.UdpTransportMapping;
import org.snmp4j.util.ThreadPool;
import
com.mrcompiler.snmp.server.agent.UDPMonitorConstants.MonitorEventType;
import com.mrcompiler.snmp.server.views.PlanMonitorView;
public class MultiThreadedUDPReceiver implements TransportListener {
private int[] types;
private UDPMonitorEventListener[] listeners;
private int level;
private static final LogAdapter logger = LogFactory
.getLogger(MultiThreadedUDPReceiver.class);
public MultiThreadedUDPReceiver() {
}
public void addListener(MonitorEventType eventType,
UDPMonitorEventListener listener) {
if (types == null)
types = new int[4];
if (listeners == null)
listeners = new UDPMonitorEventListener[4];
int length = types.length, index = length - 1;
while (index >= 0) {
if (types[index] != 0)
break;
--index;
}
index++;
if (index == length) {
int[] newTypes = new int[length + 4];
System.arraycopy(types, 0, newTypes, 0, length);
types = newTypes;
UDPMonitorEventListener[] newListeners = new
UDPMonitorEventListener[length + 4];
System.arraycopy(listeners, 0, newListeners, 0, length);
listeners = newListeners;
}
types[index] = eventType.ordinal();
listeners[index] = listener;
}
void remove(int index) {
if (level == 0) {
int end = types.length - 1;
System.arraycopy(types, index + 1, types, index, end - index);
System.arraycopy(listeners, index + 1, listeners, index, end
- index);
index = end;
} else {
if (level > 0)
level = -level;
}
types[index] = 0;
listeners[index] = null;
}
public void removeListener(int eventType, Listener listener) {
if (types == null)
return;
for (int i = 0; i < types.length; i++) {
if (types[i] == eventType && listeners[i] == listener) {
remove(i);
return;
}
}
}
synchronized void postEvent(MonitorEventType eventType,
UDPMonitorEvent event) {
if (types == null)
return;
level += level >= 0 ? 1 : -1;
try {
for (int i = 0; i < types.length; i++) {
if ((event.type == MonitorEventType.UNKNOWN_EVENT_TYPE
&& types[i] == MonitorEventType.ALL_EVENTS
.ordinal())
|| (types[i] ==
MonitorEventType.ALL_EVENTS.ordinal() || types[i] == event.type
.ordinal())) {
UDPMonitorEventListener listener = listeners[i];
if (listener != null)
listener.handleEvent(eventType, event);
}
}
} catch (Exception e) {
e.printStackTrace();
} finally {
boolean compact = level < 0;
level -= level >= 0 ? 1 : -1;
if (compact && level == 0) {
int index = 0;
for (int i = 0; i < types.length; i++) {
if (types[i] != 0) {
types[index] = types[i];
listeners[index] = listeners[i];
index++;
}
}
for (int i = index; i < types.length; i++) {
types[i] = 0;
listeners[i] = null;
}
}
}
}
public class UDPMessageProcessingTask implements Runnable {
private TransportMapping sourceTransport;
private Address incomingAddress;
private ByteBuffer wholeMessage;
public UDPMessageProcessingTask() {
return;
}
public UDPMessageProcessingTask(TransportMapping sourceTransport,
Address incomingAddress, ByteBuffer wholeMessage) {
this.sourceTransport = sourceTransport;
this.incomingAddress = incomingAddress;
this.wholeMessage = wholeMessage;
}
public void run() {
// TODO Auto-generated method stub
String eventData = new String(wholeMessage.array());
logger.info("Processing UDP Message " + eventData);
UDPMonitorEvent eventInfo = new UDPMonitorEvent(eventData);
// if( eventInfo.type != MonitorEventType.UNKNOWN_EVENT_TYPE ) {
postEvent(eventInfo.type, eventInfo);
// }
}
public Address getIncomingAddress() {
return incomingAddress;
}
public void setIncomingAddress(Address incomingAddress) {
this.incomingAddress = incomingAddress;
}
public TransportMapping getSourceTransport() {
return sourceTransport;
}
public void setSourceTransport(TransportMapping sourceTransport) {
this.sourceTransport = sourceTransport;
}
public ByteBuffer getWholeMessage() {
return wholeMessage;
}
public void setWholeMessage(ByteBuffer wholeMessage) {
this.wholeMessage = wholeMessage;
}
}
private Address listenAddress;
private ThreadPool threadPool;
private UdpTransportMapping transport;
private void init() throws UnknownHostException, IOException {
if (threadPool == null) {
threadPool = ThreadPool.create("UDPStreams", 2);
}
if (listenAddress == null) {
listenAddress = GenericAddress.parse(System.getProperty(
"snmpAgent.udpListenAddress", "udp:0.0.0.0/1234"));
}
if (transport == null) {
transport = new DefaultUdpTransportMapping(
(UdpAddress) listenAddress);
transport.addTransportListener(this);
}
}
public void run() {
try {
init();
transport.listen(); // start the listener thread
} catch (Exception ex) {
ex.printStackTrace();
}
}
public void processMessage(TransportMapping sourceTransport,
Address incomingAddress, ByteBuffer wholeMessage) {
UDPMessageProcessingTask task = new UDPMessageProcessingTask(
sourceTransport, incomingAddress, wholeMessage);
threadPool.execute(task);
}
public Address getListenAddress() {
return listenAddress;
}
public void setListenAddress(Address listenAddress) {
this.listenAddress = listenAddress;
}
public void stop() throws Throwable {
super.finalize();
}
}
---- End of MultiThreadedUDPListener.class
-- Begin
package com.mrcompiler.snmp.server.agent;
import java.util.EventListener;
import
com.mrcompiler.snmp.server.agent.UDPMonitorConstants.MonitorEventType;
public interface UDPMonitor extends EventListener {
void handleEvent (MonitorEventType eventType, UDPMonitorEvent event);
}
More information about the SNMP4J
mailing list