From df937333df8136bfd10a0213673ef39e07b72b29 Mon Sep 17 00:00:00 2001 From: Subrata Banerjee <subrata.banerjee@bigswitch.com> Date: Tue, 10 Jan 2012 21:32:53 -0800 Subject: [PATCH] Cleanup of event-history infra. --- .../core/web/CoreWebRoutable.java | 5 +++ .../EventHistoryAttachmentPointResource.java | 43 ++++++++++++++++++ .../web/EventHistoryPacketInResource.java | 34 ++++++++++++++ .../core/web/JacksonCustomConverter.java | 26 ++++++++--- ...tHistoryAttachmentPointJSONSerializer.java | 45 +++++++++++++++++++ ...> EventHistoryBaseInfoJSONSerializer.java} | 37 ++++++++++----- .../serializers/OFMatchJSONSerializer.java | 2 +- .../internal/DeviceManagerImpl.java | 40 ++--------------- .../internal/EventHistoryAttachmentPoint.java | 33 ++++++++++++++ .../util/EventHistory.java | 32 ++----------- .../util/EventHistoryBaseInfo.java | 22 +++++++++ 11 files changed, 235 insertions(+), 84 deletions(-) create mode 100644 src/main/java/net/floodlightcontroller/core/web/EventHistoryAttachmentPointResource.java create mode 100644 src/main/java/net/floodlightcontroller/core/web/EventHistoryPacketInResource.java create mode 100644 src/main/java/net/floodlightcontroller/core/web/serializers/EventHistoryAttachmentPointJSONSerializer.java rename src/main/java/net/floodlightcontroller/core/web/serializers/{BaseInfoJSONSerializer.java => EventHistoryBaseInfoJSONSerializer.java} (59%) create mode 100644 src/main/java/net/floodlightcontroller/devicemanager/internal/EventHistoryAttachmentPoint.java create mode 100644 src/main/java/net/floodlightcontroller/util/EventHistoryBaseInfo.java diff --git a/src/main/java/net/floodlightcontroller/core/web/CoreWebRoutable.java b/src/main/java/net/floodlightcontroller/core/web/CoreWebRoutable.java index 71578dfa1..51e092bc8 100644 --- a/src/main/java/net/floodlightcontroller/core/web/CoreWebRoutable.java +++ b/src/main/java/net/floodlightcontroller/core/web/CoreWebRoutable.java @@ -44,6 +44,11 @@ public class CoreWebRoutable implements RestletRoutable { router.attach("/memory/json", ControllerMemoryResource.class); router.attach("/staticflowentrypusher/json", StaticFlowEntryPusherResource.class); router.attach("/packettrace/json", PacketTraceResource.class); + // Get the last {count} events from the event histories + router.attach("/event-history/attachment-point/{count}/json", + EventHistoryAttachmentPointResource.class); + router.attach("/event-history/packet-in/{count}/json", + EventHistoryPacketInResource.class); return router; } } diff --git a/src/main/java/net/floodlightcontroller/core/web/EventHistoryAttachmentPointResource.java b/src/main/java/net/floodlightcontroller/core/web/EventHistoryAttachmentPointResource.java new file mode 100644 index 000000000..0ada3a35a --- /dev/null +++ b/src/main/java/net/floodlightcontroller/core/web/EventHistoryAttachmentPointResource.java @@ -0,0 +1,43 @@ +/** + * + */ +package net.floodlightcontroller.core.web; + +import net.floodlightcontroller.devicemanager.internal.DeviceManagerImpl; +import net.floodlightcontroller.devicemanager.internal.EventHistoryAttachmentPoint; +import net.floodlightcontroller.util.EventHistory; + +import org.restlet.resource.ServerResource; +import org.restlet.resource.Get; + +/** + * @author subrata + * + */ +public class EventHistoryAttachmentPointResource extends ServerResource { + /*** + * Event History Names: + * (a) attachment-point + * (b) host-network-address + * (c) switch-connect + * (d) switch-link + * (g) packet-ins + * (h) packet-outs + * (i) error (for floodlight) + * (l) route-computation + * (n) pktin-drops + */ + + @Get("json") + public EventHistory<EventHistoryAttachmentPoint> handleEvHistReq() { + + // Get the event history count. Last <count> events would be returned + String evHistCount = (String)getRequestAttributes().get("count"); + + DeviceManagerImpl deviceManager = + (DeviceManagerImpl)getContext().getAttributes().get("deviceManager"); + + return new EventHistory<EventHistoryAttachmentPoint>(deviceManager.evHistDevMgrAttachPt, + Integer.parseInt(evHistCount)); + } +} diff --git a/src/main/java/net/floodlightcontroller/core/web/EventHistoryPacketInResource.java b/src/main/java/net/floodlightcontroller/core/web/EventHistoryPacketInResource.java new file mode 100644 index 000000000..ea0bb3ef9 --- /dev/null +++ b/src/main/java/net/floodlightcontroller/core/web/EventHistoryPacketInResource.java @@ -0,0 +1,34 @@ +/** + * + */ +package net.floodlightcontroller.core.web; + +import net.floodlightcontroller.devicemanager.internal.DeviceManagerImpl; +import net.floodlightcontroller.util.EventHistory; + +import org.openflow.protocol.OFMatch; +import org.restlet.resource.Get; +import org.restlet.resource.ServerResource; + +/** + * @author subrata + * + */ +public class EventHistoryPacketInResource extends ServerResource { + + @Get("json") + public EventHistory<OFMatch> handleEvHistReq() { + + EventHistory<OFMatch> ofm = null; + // Get the count (number of latest events requested), zero means all + String evHistCount = (String)getRequestAttributes().get("count"); + + DeviceManagerImpl deviceManager = + (DeviceManagerImpl)getContext().getAttributes().get("deviceManager"); + + ofm = new EventHistory<OFMatch>(deviceManager.evHistDevMgrPktIn, + Integer.parseInt(evHistCount)); + return ofm; + } + +} diff --git a/src/main/java/net/floodlightcontroller/core/web/JacksonCustomConverter.java b/src/main/java/net/floodlightcontroller/core/web/JacksonCustomConverter.java index 230389c41..452d6f1de 100644 --- a/src/main/java/net/floodlightcontroller/core/web/JacksonCustomConverter.java +++ b/src/main/java/net/floodlightcontroller/core/web/JacksonCustomConverter.java @@ -19,6 +19,8 @@ package net.floodlightcontroller.core.web; import java.util.List; +import net.floodlightcontroller.core.web.serializers.EventHistoryAttachmentPointJSONSerializer; +import net.floodlightcontroller.core.web.serializers.EventHistoryBaseInfoJSONSerializer; import net.floodlightcontroller.core.web.serializers.OFFeaturesReplyJSONSerializer; import net.floodlightcontroller.core.web.serializers.OFMatchJSONSerializer; import net.floodlightcontroller.core.web.serializers.OFPhysicalPortJSONSerializer; @@ -44,7 +46,8 @@ import org.slf4j.LoggerFactory; * */ public class JacksonCustomConverter extends JacksonConverter { - protected static Logger log = LoggerFactory.getLogger(JacksonCustomConverter.class); + protected static Logger log = + LoggerFactory.getLogger(JacksonCustomConverter.class); protected static ObjectMapper jsonObjectMapper; protected static SimpleModule jsonModule; @@ -56,19 +59,26 @@ public class JacksonCustomConverter extends JacksonConverter { jsonModule.addSerializer(new OFMatchJSONSerializer()); jsonModule.addSerializer(new OFFeaturesReplyJSONSerializer()); jsonModule.addSerializer(new OFPhysicalPortJSONSerializer()); + jsonModule.addSerializer(new EventHistoryBaseInfoJSONSerializer()); + jsonModule.addSerializer( + new EventHistoryAttachmentPointJSONSerializer()); jsonObjectMapper.registerModule(jsonModule); } @Override - protected <T> JacksonRepresentation<T> create(MediaType mediaType, T source) { - JacksonRepresentation<T> jr = new JacksonRepresentation<T>(mediaType, source); + protected <T> JacksonRepresentation<T> + create(MediaType mediaType, T source) { + JacksonRepresentation<T> jr = + new JacksonRepresentation<T>(mediaType, source); jr.setObjectMapper(jsonObjectMapper); return jr; } @Override - protected <T> JacksonRepresentation<T> create(Representation source, Class<T> objectClass) { - JacksonRepresentation<T> jr = new JacksonRepresentation<T>(source, objectClass); + protected <T> JacksonRepresentation<T> + create(Representation source, Class<T> objectClass) { + JacksonRepresentation<T> jr = + new JacksonRepresentation<T>(source, objectClass); jr.setObjectMapper(jsonObjectMapper); return jr; } @@ -81,7 +91,8 @@ public class JacksonCustomConverter extends JacksonConverter { public static void replaceConverter() { ConverterHelper oldConverter = null; - List<ConverterHelper> converters = Engine.getInstance().getRegisteredConverters(); + List<ConverterHelper> converters = + Engine.getInstance().getRegisteredConverters(); for (ConverterHelper converter : converters) { if (converter.getClass().equals(JacksonConverter.class)) { converters.remove(converter); @@ -93,7 +104,8 @@ public class JacksonCustomConverter extends JacksonConverter { converters.add(new JacksonCustomConverter()); if (oldConverter == null) { - log.debug("Added {} to Restlet Engine", JacksonCustomConverter.class); + log.debug("Added {} to Restlet Engine", + JacksonCustomConverter.class); } else { log.debug("Replaced {} with {} in Restlet Engine", oldConverter.getClass(), JacksonCustomConverter.class); diff --git a/src/main/java/net/floodlightcontroller/core/web/serializers/EventHistoryAttachmentPointJSONSerializer.java b/src/main/java/net/floodlightcontroller/core/web/serializers/EventHistoryAttachmentPointJSONSerializer.java new file mode 100644 index 000000000..6a8fb939d --- /dev/null +++ b/src/main/java/net/floodlightcontroller/core/web/serializers/EventHistoryAttachmentPointJSONSerializer.java @@ -0,0 +1,45 @@ +package net.floodlightcontroller.core.web.serializers; + +import java.io.IOException; + +import net.floodlightcontroller.devicemanager.internal.EventHistoryAttachmentPoint; + +import org.codehaus.jackson.JsonGenerator; +import org.codehaus.jackson.JsonProcessingException; +import org.codehaus.jackson.map.JsonSerializer; +import org.codehaus.jackson.map.SerializerProvider; +import org.openflow.util.HexString; + +/** + * + * @author subrata + * + */ + +public class EventHistoryAttachmentPointJSONSerializer + extends JsonSerializer<EventHistoryAttachmentPoint> { + /** + * Performs the serialization of a EventHistory.BaseInfo object + */ + @Override + public void serialize(EventHistoryAttachmentPoint attachPt, + JsonGenerator jGen, + SerializerProvider serializer) + throws IOException, JsonProcessingException { + jGen.writeStartObject(); + jGen.writeStringField("Switch", HexString.toHexString(attachPt.dpid)); + jGen.writeStringField("Host", HexString.toHexString(attachPt.mac)); + jGen.writeNumberField("Port", attachPt.port); + jGen.writeNumberField("VLAN", attachPt.vlan); + jGen.writeStringField("Reason", attachPt.reason); + jGen.writeEndObject(); + } + + /** + * Tells SimpleModule that we are the serializer for OFMatch + */ + @Override + public Class<EventHistoryAttachmentPoint> handledType() { + return EventHistoryAttachmentPoint.class; + } +} diff --git a/src/main/java/net/floodlightcontroller/core/web/serializers/BaseInfoJSONSerializer.java b/src/main/java/net/floodlightcontroller/core/web/serializers/EventHistoryBaseInfoJSONSerializer.java similarity index 59% rename from src/main/java/net/floodlightcontroller/core/web/serializers/BaseInfoJSONSerializer.java rename to src/main/java/net/floodlightcontroller/core/web/serializers/EventHistoryBaseInfoJSONSerializer.java index 82c4a2973..0ad8786da 100644 --- a/src/main/java/net/floodlightcontroller/core/web/serializers/BaseInfoJSONSerializer.java +++ b/src/main/java/net/floodlightcontroller/core/web/serializers/EventHistoryBaseInfoJSONSerializer.java @@ -17,37 +17,42 @@ package net.floodlightcontroller.core.web.serializers; import java.io.IOException; -import java.util.Date; -import net.floodlightcontroller.util.EventHistory.BaseInfo; +import java.sql.Timestamp; + +import net.floodlightcontroller.util.EventHistoryBaseInfo; import org.codehaus.jackson.JsonGenerator; import org.codehaus.jackson.JsonProcessingException; import org.codehaus.jackson.map.JsonSerializer; import org.codehaus.jackson.map.SerializerProvider; + /** * @author subrata * */ -public class BaseInfoJSONSerializer extends - JsonSerializer<BaseInfo> { +public class EventHistoryBaseInfoJSONSerializer extends + JsonSerializer<EventHistoryBaseInfo> { /** * Performs the serialization of a EventHistory.BaseInfo object */ @Override - public void serialize(BaseInfo base_info, JsonGenerator jGen, + public void serialize(EventHistoryBaseInfo base_info, JsonGenerator jGen, SerializerProvider serializer) throws IOException, JsonProcessingException { jGen.writeStartObject(); jGen.writeNumberField("Idx", base_info.getIdx()); - jGen.writeStringField("Time", + jGen.writeStringField("Time", convertNanoSecondsToStr(base_info.getTime_ns())); jGen.writeStringField("State", base_info.getState().name()); - jGen.writeStringField("Action", base_info.getAction().name()); + String acStr = base_info.getAction().name().toLowerCase(); + // Capitalize the first letter + acStr = acStr.substring(0,1).toUpperCase().concat(acStr.substring(1)); + jGen.writeStringField("Action", acStr); jGen.writeEndObject(); } @@ -55,13 +60,21 @@ public class BaseInfoJSONSerializer extends * Tells SimpleModule that we are the serializer for OFMatch */ @Override - public Class<BaseInfo> handledType() { - return BaseInfo.class; + public Class<EventHistoryBaseInfo> handledType() { + return EventHistoryBaseInfo.class; } - + public String convertNanoSecondsToStr(long nanoSeconds) { - long millisecs = nanoSeconds / 1000000; - String timeStr = (new Date(millisecs)).toString(); + long millisecs = nanoSeconds / 1000000; + int remaining_ns = (int)(nanoSeconds % 1000000000); + Timestamp ts = new Timestamp(millisecs); + ts.setNanos(remaining_ns); + // Show up to microseconds resolution + // length of "2012-01-09 14:54:45.067253" is 26 + String timeStr = ts.toString(); + while (timeStr.length() < 26) { + timeStr = timeStr.concat("0"); + } return timeStr; } } diff --git a/src/main/java/net/floodlightcontroller/core/web/serializers/OFMatchJSONSerializer.java b/src/main/java/net/floodlightcontroller/core/web/serializers/OFMatchJSONSerializer.java index 99edc0120..e08eeb61a 100644 --- a/src/main/java/net/floodlightcontroller/core/web/serializers/OFMatchJSONSerializer.java +++ b/src/main/java/net/floodlightcontroller/core/web/serializers/OFMatchJSONSerializer.java @@ -48,7 +48,7 @@ public class OFMatchJSONSerializer extends JsonSerializer<OFMatch> { jGen.writeStartObject(); jGen.writeStringField("dataLayerDestination", HexString.toHexString(match.getDataLayerDestination())); jGen.writeStringField("dataLayerSource", HexString.toHexString(match.getDataLayerSource())); - jGen.writeNumberField("dataLayerType", match.getDataLayerType()); + jGen.writeStringField("dataLayerType", "0x" + Integer.toHexString(match.getDataLayerType())); jGen.writeNumberField("dataLayerVirtualLan", match.getDataLayerVirtualLan()); jGen.writeNumberField("dataLayerVirtualLanPriorityCodePoint", match.getDataLayerVirtualLanPriorityCodePoint()); jGen.writeStringField("inputSwitch", HexString.toHexString(match.getSwitchDataPathId())); diff --git a/src/main/java/net/floodlightcontroller/devicemanager/internal/DeviceManagerImpl.java b/src/main/java/net/floodlightcontroller/devicemanager/internal/DeviceManagerImpl.java index df1d93c4b..c42ce554d 100755 --- a/src/main/java/net/floodlightcontroller/devicemanager/internal/DeviceManagerImpl.java +++ b/src/main/java/net/floodlightcontroller/devicemanager/internal/DeviceManagerImpl.java @@ -624,7 +624,7 @@ public class DeviceManagerImpl implements IDeviceManager, IOFMessageListener, this.lock = new ReentrantReadWriteLock(); this.updates = new LinkedList<Update>(); this.evHistDevMgrAttachPt = - new EventHistory<EvHistAttachmentPt>("Attachment-Point"); + new EventHistory<EventHistoryAttachmentPoint>("Attachment-Point"); this.evHistDevMgrPktIn = new EventHistory<OFMatch>("Pakcet-In"); } @@ -1910,41 +1910,9 @@ public class DeviceManagerImpl implements IDeviceManager, IOFMessageListener, // Device Manager's Event History members and methods // ************************************************** - /*** - * Attachment-Point Event history related classes and members - * @author subrata - * - */ - public class EvHistAttachmentPt { - public String reason; - // The following fields are not stored as String to save memory - // They shoudl be converted to appropriate human-readable strings by - // the front end (e.g. in cli in python) - public long mac; - public short vlan; - public short port; - public long dpid; - - public long getMac() { - return mac; - } - public short getVlan() { - return vlan; - } - public short getPort() { - return port; - } - public long getDpid() { - return dpid; - } - public String getReason() { - return reason; - } - } - // Attachment-point event history - public EventHistory<EvHistAttachmentPt> evHistDevMgrAttachPt; - public EvHistAttachmentPt evHAP; + public EventHistory<EventHistoryAttachmentPoint> evHistDevMgrAttachPt; + public EventHistoryAttachmentPoint evHAP; private void evHistAttachmtPt(Device d, SwitchPortTuple swPrt, EvAction action, String reason) { @@ -1968,7 +1936,7 @@ public class DeviceManagerImpl implements IDeviceManager, IOFMessageListener, private void evHistAttachmtPt(long mac, long dpid, short port, EvAction action, String reason) { if (evHAP == null) { - evHAP = new EvHistAttachmentPt(); + evHAP = new EventHistoryAttachmentPoint(); } evHAP.dpid = dpid; evHAP.port = port; diff --git a/src/main/java/net/floodlightcontroller/devicemanager/internal/EventHistoryAttachmentPoint.java b/src/main/java/net/floodlightcontroller/devicemanager/internal/EventHistoryAttachmentPoint.java new file mode 100644 index 000000000..fb22b6049 --- /dev/null +++ b/src/main/java/net/floodlightcontroller/devicemanager/internal/EventHistoryAttachmentPoint.java @@ -0,0 +1,33 @@ +package net.floodlightcontroller.devicemanager.internal; + +/*** + * Attachment-Point Event history related classes and members + * @author subrata + * + */ +public class EventHistoryAttachmentPoint { + public String reason; + // The following fields are not stored as String to save memory + // They shoudl be converted to appropriate human-readable strings by + // the front end (e.g. in cli in python) + public long mac; + public short vlan; + public short port; + public long dpid; + + public long getMac() { + return mac; + } + public short getVlan() { + return vlan; + } + public short getPort() { + return port; + } + public long getDpid() { + return dpid; + } + public String getReason() { + return reason; + } +} \ No newline at end of file diff --git a/src/main/java/net/floodlightcontroller/util/EventHistory.java b/src/main/java/net/floodlightcontroller/util/EventHistory.java index e57e398d3..a5cad1e80 100644 --- a/src/main/java/net/floodlightcontroller/util/EventHistory.java +++ b/src/main/java/net/floodlightcontroller/util/EventHistory.java @@ -35,30 +35,9 @@ public class EventHistory<T> { return events; } - public class BaseInfo { - public int idx; - public long time_ns; // timestamp in nanoseconds - public EvState state; - public EvAction action; - - // Getters - public int getIdx() { - return idx; - } - public long getTime_ns() { - return time_ns; - } - public EvState getState() { - return state; - } - public EvAction getAction() { - return action; - } - } - public class Event { - public BaseInfo base_info; - public T info; + public EventHistoryBaseInfo base_info; + public T info; } public enum EvState { @@ -84,7 +63,7 @@ public class EventHistory<T> { for (int idx = 0; idx < maxEvents; idx++) { Event evH = new Event(); - evH.base_info = new BaseInfo(); + evH.base_info = new EventHistoryBaseInfo(); evH.info = null; evH.base_info.state = EvState.FREE; evH.base_info.idx = idx; @@ -103,10 +82,7 @@ public class EventHistory<T> { } // Copy constructor - copy latest k items of the event history - public EventHistory(Object eventHistIn, int latestK) { - - EventHistory<T> eventHist = (EventHistory<T>)eventHistIn; - + public EventHistory(EventHistory<T> eventHist, int latestK) { int curSize = (eventHist.full)?eventHist.event_history_size: eventHist.current_index; int size = (latestK < curSize)?latestK:curSize; diff --git a/src/main/java/net/floodlightcontroller/util/EventHistoryBaseInfo.java b/src/main/java/net/floodlightcontroller/util/EventHistoryBaseInfo.java new file mode 100644 index 000000000..c23ef79d1 --- /dev/null +++ b/src/main/java/net/floodlightcontroller/util/EventHistoryBaseInfo.java @@ -0,0 +1,22 @@ +package net.floodlightcontroller.util; + +public class EventHistoryBaseInfo { + public int idx; + public long time_ns; // timestamp in nanoseconds + public EventHistory.EvState state; + public EventHistory.EvAction action; + + // Getters + public int getIdx() { + return idx; + } + public long getTime_ns() { + return time_ns; + } + public EventHistory.EvState getState() { + return state; + } + public EventHistory.EvAction getAction() { + return action; + } +} \ No newline at end of file -- GitLab