diff --git a/src/main/java/net/floodlightcontroller/core/web/AllSwitchStatisticsResource.java b/src/main/java/net/floodlightcontroller/core/web/AllSwitchStatisticsResource.java index ea3c11ec5d7812d234c20eac2823ca4b8b33cdba..657a2d2fe8abc5eb28c727a7cee0c7db7308d12b 100644 --- a/src/main/java/net/floodlightcontroller/core/web/AllSwitchStatisticsResource.java +++ b/src/main/java/net/floodlightcontroller/core/web/AllSwitchStatisticsResource.java @@ -80,6 +80,31 @@ public class AllSwitchStatisticsResource extends SwitchResourceBase { type = OFStatsType.TABLE; rType = REQUESTTYPE.OFSTATS; break; + + case OFStatsTypeStrings.GROUP: + type = OFStatsType.GROUP; + rType = REQUESTTYPE.OFSTATS; + break; + case OFStatsTypeStrings.GROUP_DESC: + type = OFStatsType.GROUP_DESC; + rType = REQUESTTYPE.OFSTATS; + break; + case OFStatsTypeStrings.GROUP_FEATURES: + type = OFStatsType.GROUP_FEATURES; + rType = REQUESTTYPE.OFSTATS; + break; + case OFStatsTypeStrings.METER: + type = OFStatsType.METER; + rType = REQUESTTYPE.OFSTATS; + break; + case OFStatsTypeStrings.METER_CONFIG: + type = OFStatsType.METER_CONFIG; + rType = REQUESTTYPE.OFSTATS; + break; + case OFStatsTypeStrings.METER_FEATURES: + type = OFStatsType.METER_FEATURES; + rType = REQUESTTYPE.OFSTATS; + break; case OFStatsTypeStrings.FEATURES: rType = REQUESTTYPE.OFFEATURES; break; diff --git a/src/main/java/net/floodlightcontroller/core/web/SwitchResourceBase.java b/src/main/java/net/floodlightcontroller/core/web/SwitchResourceBase.java index 1a235085d4b3b58f7840bbe2abbdc0dba49858cb..bd146a72b1d0dcb126bf5ab9d1b0c69bdb0a550b 100644 --- a/src/main/java/net/floodlightcontroller/core/web/SwitchResourceBase.java +++ b/src/main/java/net/floodlightcontroller/core/web/SwitchResourceBase.java @@ -27,6 +27,7 @@ import net.floodlightcontroller.core.internal.IOFSwitchService; import org.projectfloodlight.openflow.protocol.OFFeaturesReply; import org.projectfloodlight.openflow.protocol.match.Match; +import org.projectfloodlight.openflow.protocol.ver13.OFMeterSerializerVer13; import org.projectfloodlight.openflow.types.DatapathId; import org.projectfloodlight.openflow.types.OFPort; import org.projectfloodlight.openflow.types.TableId; @@ -114,22 +115,55 @@ public class SwitchResourceBase extends ServerResource { .build(); break; case DESC: - case TABLE: // pass - nothing todo besides set the type above req = sw.getOFFactory().buildDescStatsRequest() .build(); break; - case PORT_DESC: - req = sw.getOFFactory().buildPortDescStatsRequest() + case GROUP: + req = sw.getOFFactory().buildGroupStatsRequest() .build(); - case EXPERIMENTER: //TODO @Ryan support new OF1.1+ stats types - case GROUP: - case GROUP_DESC: - case GROUP_FEATURES: + break; + case METER: + req = sw.getOFFactory().buildMeterStatsRequest() + .setMeterId(OFMeterSerializerVer13.ALL_VAL) + .build(); + break; + + case GROUP_DESC: + req = sw.getOFFactory().buildGroupDescStatsRequest() + .build(); + break; + + case GROUP_FEATURES: + req = sw.getOFFactory().buildGroupFeaturesStatsRequest() + .build(); + break; + case METER_CONFIG: + req = sw.getOFFactory().buildMeterConfigStatsRequest() + .build(); + break; + case METER_FEATURES: - case TABLE_FEATURES: + req = sw.getOFFactory().buildMeterFeaturesStatsRequest() + .build(); + break; + + case TABLE: + req = sw.getOFFactory().buildTableStatsRequest() + .build(); + break; + + case TABLE_FEATURES: + req = sw.getOFFactory().buildTableFeaturesStatsRequest() + .build(); + break; + case PORT_DESC: + req = sw.getOFFactory().buildPortDescStatsRequest() + .build(); + break; + case EXPERIMENTER: //TODO @Ryan support new OF1.1+ stats types default: log.error("Stats Request Type {} not implemented yet", statType.name()); break; @@ -174,6 +208,5 @@ public class SwitchResourceBase extends ServerResource { protected OFFeaturesReply getSwitchFeaturesReply(String switchId) { return getSwitchFeaturesReply(DatapathId.of(switchId)); - } - + } } diff --git a/src/main/java/net/floodlightcontroller/core/web/SwitchStatisticsResource.java b/src/main/java/net/floodlightcontroller/core/web/SwitchStatisticsResource.java index a100ddaf0b01fe1867e9d5738beaeca3ece335f1..2b79909daff60eaed71013cf3c984ecb50faf817 100644 --- a/src/main/java/net/floodlightcontroller/core/web/SwitchStatisticsResource.java +++ b/src/main/java/net/floodlightcontroller/core/web/SwitchStatisticsResource.java @@ -36,6 +36,7 @@ public class SwitchStatisticsResource extends SwitchResourceBase { @Get("json") public StatsReply retrieve(){ + StatsReply result = new StatsReply(); Object values = null; // set for error detection in serializer String switchIdStr = (String) getRequestAttributes().get(CoreWebRoutable.STR_SWITCH_ID); @@ -77,47 +78,47 @@ public class SwitchStatisticsResource extends SwitchResourceBase { case OFStatsTypeStrings.DESC: values = getSwitchStatistics(switchId, OFStatsType.DESC); result.setStatType(OFStatsType.DESC); - break; - case OFStatsTypeStrings.TABLE: - values = getSwitchStatistics(switchId, OFStatsType.TABLE); - result.setStatType(OFStatsType.TABLE); - break; - case OFStatsTypeStrings.TABLE_FEATURES: - values = getSwitchFeaturesReply(switchId); - result.setStatType(OFStatsType.TABLE_FEATURES); - break; - case OFStatsTypeStrings.EXPERIMENTER: - values = getSwitchFeaturesReply(switchId); - result.setStatType(OFStatsType.EXPERIMENTER); - break; + break; case OFStatsTypeStrings.PORT_DESC: values = getSwitchStatistics(switchId, OFStatsType.PORT_DESC); result.setStatType(OFStatsType.PORT_DESC); break; case OFStatsTypeStrings.GROUP: - values = getSwitchFeaturesReply(switchId); + values = getSwitchStatistics(switchId, OFStatsType.GROUP); result.setStatType(OFStatsType.GROUP); break; case OFStatsTypeStrings.GROUP_DESC: - values = getSwitchFeaturesReply(switchId); + values = getSwitchStatistics(switchId, OFStatsType.GROUP_DESC); result.setStatType(OFStatsType.GROUP_DESC); break; case OFStatsTypeStrings.GROUP_FEATURES: - values = getSwitchFeaturesReply(switchId); + values = getSwitchStatistics(switchId, OFStatsType.GROUP_FEATURES); result.setStatType(OFStatsType.GROUP_FEATURES); break; case OFStatsTypeStrings.METER: - values = getSwitchFeaturesReply(switchId); + values = getSwitchStatistics(switchId, OFStatsType.METER); result.setStatType(OFStatsType.METER); break; case OFStatsTypeStrings.METER_CONFIG: - values = getSwitchFeaturesReply(switchId); + values = getSwitchStatistics(switchId, OFStatsType.METER_CONFIG); result.setStatType(OFStatsType.METER_CONFIG); break; case OFStatsTypeStrings.METER_FEATURES: - values = getSwitchFeaturesReply(switchId); + values = getSwitchStatistics(switchId, OFStatsType.METER_FEATURES); result.setStatType(OFStatsType.METER_FEATURES); break; + case OFStatsTypeStrings.TABLE: + values = getSwitchStatistics(switchId, OFStatsType.TABLE); + result.setStatType(OFStatsType.TABLE); + break; + case OFStatsTypeStrings.TABLE_FEATURES: + values = getSwitchStatistics(switchId, OFStatsType.TABLE_FEATURES); + result.setStatType(OFStatsType.TABLE_FEATURES); + break; + case OFStatsTypeStrings.EXPERIMENTER: + values = getSwitchFeaturesReply(switchId); + result.setStatType(OFStatsType.EXPERIMENTER); + break; default: log.error("Invalid or unimplemented stat request type {}", statType); break; diff --git a/src/main/java/net/floodlightcontroller/core/web/serializers/StatsReplySerializer.java b/src/main/java/net/floodlightcontroller/core/web/serializers/StatsReplySerializer.java index b176bbc1cdd86024e5c49f2554067a88db460b4d..b7a34c277ad4b400d283674a30a7b4798431aafb 100644 --- a/src/main/java/net/floodlightcontroller/core/web/serializers/StatsReplySerializer.java +++ b/src/main/java/net/floodlightcontroller/core/web/serializers/StatsReplySerializer.java @@ -29,16 +29,58 @@ import com.fasterxml.jackson.databind.SerializerProvider; import net.floodlightcontroller.core.web.OFStatsTypeStrings; import net.floodlightcontroller.core.web.StatsReply; +import org.projectfloodlight.openflow.protocol.OFBucket; +import org.projectfloodlight.openflow.protocol.OFBucketCounter; import org.projectfloodlight.openflow.protocol.OFFlowStatsReply; import org.projectfloodlight.openflow.protocol.OFFlowStatsEntry; import org.projectfloodlight.openflow.protocol.OFDescStatsReply; +import org.projectfloodlight.openflow.protocol.OFGroupDescStatsEntry; +import org.projectfloodlight.openflow.protocol.OFGroupDescStatsReply; +import org.projectfloodlight.openflow.protocol.OFGroupFeaturesStatsReply; +import org.projectfloodlight.openflow.protocol.OFGroupStatsEntry; +import org.projectfloodlight.openflow.protocol.OFGroupStatsReply; +import org.projectfloodlight.openflow.protocol.OFMeterBandStats; +import org.projectfloodlight.openflow.protocol.OFMeterConfigStatsReply; +import org.projectfloodlight.openflow.protocol.OFMeterFeatures; +import org.projectfloodlight.openflow.protocol.OFMeterFeaturesStatsReply; +import org.projectfloodlight.openflow.protocol.OFMeterStats; +import org.projectfloodlight.openflow.protocol.OFMeterStatsReply; import org.projectfloodlight.openflow.protocol.OFPortStatsReply; import org.projectfloodlight.openflow.protocol.OFPortStatsEntry; import org.projectfloodlight.openflow.protocol.OFPortDescStatsReply; import org.projectfloodlight.openflow.protocol.OFPortDesc; +import org.projectfloodlight.openflow.protocol.OFTableFeatureProp; +import org.projectfloodlight.openflow.protocol.OFTableFeaturePropApplyActions; +import org.projectfloodlight.openflow.protocol.OFTableFeaturePropApplyActionsMiss; +import org.projectfloodlight.openflow.protocol.OFTableFeaturePropApplySetfield; +import org.projectfloodlight.openflow.protocol.OFTableFeaturePropApplySetfieldMiss; +import org.projectfloodlight.openflow.protocol.OFTableFeaturePropExperimenter; +import org.projectfloodlight.openflow.protocol.OFTableFeaturePropExperimenterMiss; +import org.projectfloodlight.openflow.protocol.OFTableFeaturePropInstructions; +import org.projectfloodlight.openflow.protocol.OFTableFeaturePropInstructionsMiss; +import org.projectfloodlight.openflow.protocol.OFTableFeaturePropMatch; +import org.projectfloodlight.openflow.protocol.OFTableFeaturePropNextTables; +import org.projectfloodlight.openflow.protocol.OFTableFeaturePropNextTablesMiss; +import org.projectfloodlight.openflow.protocol.OFTableFeaturePropWildcards; +import org.projectfloodlight.openflow.protocol.OFTableFeaturePropWriteActions; +import org.projectfloodlight.openflow.protocol.OFTableFeaturePropWriteActionsMiss; +import org.projectfloodlight.openflow.protocol.OFTableFeaturePropWriteSetfield; +import org.projectfloodlight.openflow.protocol.OFTableFeaturePropWriteSetfieldMiss; +import org.projectfloodlight.openflow.protocol.OFTableFeatures; +import org.projectfloodlight.openflow.protocol.OFTableFeaturesStatsReply; +import org.projectfloodlight.openflow.protocol.OFTableStatsEntry; +import org.projectfloodlight.openflow.protocol.OFTableStatsReply; +import org.projectfloodlight.openflow.protocol.actionid.OFActionId; +import org.projectfloodlight.openflow.protocol.instructionid.OFInstructionId; +import org.projectfloodlight.openflow.protocol.meterband.OFMeterBand; +import org.projectfloodlight.openflow.protocol.meterband.OFMeterBandDrop; +import org.projectfloodlight.openflow.protocol.meterband.OFMeterBandDscpRemark; +import org.projectfloodlight.openflow.protocol.meterband.OFMeterBandExperimenter; import org.projectfloodlight.openflow.protocol.ver13.OFFlowModFlagsSerializerVer13; +import org.projectfloodlight.openflow.protocol.ver13.OFMeterBandTypeSerializerVer13; // Use Loxigen's serializer import org.projectfloodlight.openflow.protocol.ver13.OFPortFeaturesSerializerVer13; +import org.projectfloodlight.openflow.protocol.ver13.OFTableFeaturePropTypeSerializerVer13; import org.projectfloodlight.openflow.protocol.ver12.OFFlowModFlagsSerializerVer12; import org.projectfloodlight.openflow.protocol.ver12.OFPortFeaturesSerializerVer12; import org.projectfloodlight.openflow.protocol.ver11.OFFlowModFlagsSerializerVer11; @@ -56,6 +98,8 @@ import org.projectfloodlight.openflow.protocol.ver11.OFPortConfigSerializerVer11 import org.projectfloodlight.openflow.protocol.ver10.OFPortConfigSerializerVer10; import org.projectfloodlight.openflow.protocol.OFAggregateStatsReply; import org.projectfloodlight.openflow.protocol.OFVersion; +import org.projectfloodlight.openflow.types.U32; +import org.projectfloodlight.openflow.types.U8; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -124,37 +168,529 @@ public class StatsReplySerializer extends JsonSerializer<StatsReply> { case DESC: // handle desc serializeDescReply((List<OFDescStatsReply>) reply.getValues(), jGen); - break; - case TABLE: - // handle table - break; - case TABLE_FEATURES: - // handle features - break; - // TODO need to handle new OF1.1+ stats reply types - case EXPERIMENTER: - break; + break; case GROUP: - break; + // handle group stats + serializeGroupReply((List<OFGroupStatsReply>) reply.getValues(), jGen); + break; case GROUP_DESC: + // handle group desc + serializeGroupDescReply((List<OFGroupDescStatsReply>) reply.getValues(), jGen); break; case GROUP_FEATURES: + // handle group features + serializeGroupFeaturesReply((List<OFGroupFeaturesStatsReply>) reply.getValues(), jGen); break; case METER: + // handle meter stats + serializeMeterReply((List<OFMeterStatsReply>) reply.getValues(), jGen); break; case METER_CONFIG: + // handle meter config + serializeMeterConfigReply((List<OFMeterConfigStatsReply>) reply.getValues(), jGen); break; case METER_FEATURES: + // handle meter features + serializeMeterFeaturesReply((List<OFMeterFeaturesStatsReply>) reply.getValues(), jGen); + break; + case TABLE: + // handle table + serializeTableReply((List<OFTableStatsReply>) reply.getValues(), jGen); + break; + case TABLE_FEATURES: + //handle table features + serializeTableFeaturesReply((List<OFTableFeaturesStatsReply>) reply.getValues(), jGen); break; case PORT_DESC: serializePortDescReply((List<OFPortDescStatsReply>) reply.getValues(), jGen); break; + case EXPERIMENTER: + break; default: break; } jGen.writeEndObject(); } + /*** + * Serializes the Group Statistics Reply + * @author Naveen + * @param groupReplies + * @param jGen + * @throws IOException + * @throws JsonProcessingException + */ + public void serializeGroupReply(List<OFGroupStatsReply> groupReplies, JsonGenerator jGen) throws IOException, JsonProcessingException{ + + OFGroupStatsReply groupReply = groupReplies.get(0); // we will get only one GroupReply and it will contains many OFGroupStatsEntry ? + jGen.writeStringField("version", groupReply.getVersion().toString()); //return the enum name + jGen.writeFieldName("group"); + jGen.writeStartArray(); + for(OFGroupStatsEntry entry : groupReply.getEntries()) { + jGen.writeStartObject(); + jGen.writeStringField("groupNumber",entry.getGroup().toString()); + jGen.writeNumberField("refCount", entry.getRefCount()); + jGen.writeNumberField("packetCount", entry.getPacketCount().getValue()); + jGen.writeNumberField("byteCount", entry.getByteCount().getValue()); + jGen.writeFieldName("BucketCounters"); + jGen.writeStartArray(); + for(OFBucketCounter bCounter : entry.getBucketStats()) { + jGen.writeStartObject(); + jGen.writeNumberField("packetCount", bCounter.getPacketCount().getValue()); + jGen.writeNumberField("byteCount", bCounter.getByteCount().getValue()); + jGen.writeEndObject(); + }//end of for loop - BucketCounter + jGen.writeEndArray(); + if (OFVersion.OF_13 == entry.getVersion()) { + jGen.writeNumberField("durationSec", entry.getDurationSec()); + jGen.writeNumberField("durationNsec", entry.getDurationNsec()); + } + jGen.writeEndObject(); + }//end of for loop - groupStats + jGen.writeEndArray(); + } + + /*** + * Serializes Group Desc Reply + * @author Naveen + * @param groupDescReplies + * @param jGen + * @throws IOException + * @throws JsonProcessingException + */ + public void serializeGroupDescReply(List<OFGroupDescStatsReply> groupDescReplies, JsonGenerator jGen) throws IOException, JsonProcessingException{ + OFGroupDescStatsReply groupDescReply = groupDescReplies.get(0); + jGen.writeStringField("version", groupDescReply.getVersion().toString()); //return the enum name + jGen.writeFieldName("groupDesc"); + jGen.writeStartArray(); + for(OFGroupDescStatsEntry entry : groupDescReply.getEntries()) { + jGen.writeStartObject(); + jGen.writeStringField("groupType",entry.getGroupType().toString()); + jGen.writeStringField("groupNumber",entry.getGroup().toString()); + jGen.writeFieldName("Buckets"); + jGen.writeStartArray(); + for(OFBucket buckets : entry.getBuckets()) { + jGen.writeStartObject(); + jGen.writeNumberField("weight", buckets.getWeight()); + jGen.writeNumberField("watchPortNumber", buckets.getWatchPort().getPortNumber()); + jGen.writeStringField("watchGroup", buckets.getWatchGroup().toString()); + OFActionListSerializer.serializeActions(jGen, buckets.getActions()); + jGen.writeEndObject(); + }//End of for loop - buckets + jGen.writeEndArray();//end of buckets + jGen.writeEndObject();//end of group Desc iteration + }//End of for loop - GroupDescStats + jGen.writeEndArray();//end of group Desc + } + + /*** + * Serializes Group Feature Reply + * @author Naveen + * @param groupFeaturesReplies + * @param jGen + * @throws IOException + * @throws JsonProcessingException + */ + public void serializeGroupFeaturesReply(List<OFGroupFeaturesStatsReply> groupFeaturesReplies, JsonGenerator jGen) throws IOException, JsonProcessingException{ + + OFGroupFeaturesStatsReply groupFeaturesReply = groupFeaturesReplies.get(0); + jGen.writeStringField("version", groupFeaturesReply.getVersion().toString()); //return the enum name + + jGen.writeFieldName("groupFeatures"); + jGen.writeStartObject(); + jGen.writeNumberField("capabilities",groupFeaturesReply.getCapabilities()); + jGen.writeNumberField("maxGroupsAll",groupFeaturesReply.getMaxGroupsAll()); + jGen.writeNumberField("maxGroupsSelect",groupFeaturesReply.getMaxGroupsSelect()); + jGen.writeNumberField("maxGroupsIndirect",groupFeaturesReply.getMaxGroupsIndirect()); + jGen.writeNumberField("maxGroupsFf",groupFeaturesReply.getMaxGroupsFf()); + jGen.writeNumberField("actionsAll",groupFeaturesReply.getActionsAll()); + jGen.writeNumberField("actionsSelect",groupFeaturesReply.getActionsSelect()); + jGen.writeNumberField("actionsIndirect",groupFeaturesReply.getActionsIndirect()); + jGen.writeNumberField("actionsFf",groupFeaturesReply.getActionsFf()); + + jGen.writeEndObject();//end of group Feature + } + + /*** + * Serializes the Meter Statistics Reply + * @author Naveen + * @param meterReplies + * @param jGen + * @throws IOException + * @throws JsonProcessingException + */ + public void serializeMeterReply(List<OFMeterStatsReply> meterReplies, JsonGenerator jGen) throws IOException, JsonProcessingException{ + OFMeterStatsReply meterReply = meterReplies.get(0); // we will get only one meterReply and it will contains many OFMeterStatsEntry ? + jGen.writeStringField("version", meterReply.getVersion().toString()); //return the enum name + jGen.writeFieldName("meter"); + jGen.writeStartArray(); + for(OFMeterStats entry : meterReply.getEntries()) { + jGen.writeStartObject(); + jGen.writeNumberField("meterId",entry.getMeterId()); + jGen.writeNumberField("flowCount", entry.getFlowCount()); + jGen.writeNumberField("packetInCount", entry.getPacketInCount().getValue()); + jGen.writeNumberField("byteInCount", entry.getByteInCount().getValue()); + jGen.writeFieldName("MeterBandStats"); + jGen.writeStartArray(); + for(OFMeterBandStats bandStats : entry.getBandStats()) { + jGen.writeStartObject(); + jGen.writeNumberField("packetBandCount", bandStats.getPacketBandCount().getValue()); + jGen.writeNumberField("byteBandCount", bandStats.getByteBandCount().getValue()); + jGen.writeEndObject(); + }//End of for loop - bandStats + jGen.writeEndArray(); + + jGen.writeNumberField("durationSec", entry.getDurationSec()); + jGen.writeNumberField("durationNsec", entry.getDurationNsec()); + jGen.writeEndObject(); + }//End of for loop - MeterStats + jGen.writeEndArray(); + } + + /*** + * Serializes Meter Feature Reply + * @author Naveen + * @param meterFeaturesReplies + * @param jGen + * @throws IOException + * @throws JsonProcessingException + */ + public void serializeMeterFeaturesReply(List<OFMeterFeaturesStatsReply> meterFeaturesReplies, JsonGenerator jGen) throws IOException, JsonProcessingException{ + OFMeterFeaturesStatsReply meterFeaturesReply = meterFeaturesReplies.get(0); + jGen.writeStringField("version", meterFeaturesReply.getVersion().toString()); //return the enum name + + OFMeterFeatures meterFeatures = meterFeaturesReply.getFeatures(); + jGen.writeFieldName("meterFeatures"); + jGen.writeStartObject(); + + jGen.writeNumberField("maxGroupsAll",meterFeatures.getMaxMeter()); + jGen.writeNumberField("maxGroupsSelect",meterFeatures.getBandTypes()); + jGen.writeNumberField("capabilities",meterFeatures.getCapabilities()); + jGen.writeNumberField("maxGroupsIndirect",meterFeatures.getMaxBands()); + jGen.writeNumberField("maxGroupsFf",meterFeatures.getMaxColor()); + + jGen.writeEndObject();//end of group Feature + } + + /*** + * Serializes Meter Config Reply + * @author Naveen + * @param meterConfigReplies + * @param jGen + * @throws IOException + * @throws JsonProcessingException + */ + public void serializeMeterConfigReply(List<OFMeterConfigStatsReply> meterConfigReplies, JsonGenerator jGen) throws IOException, JsonProcessingException{ + OFMeterConfigStatsReply meterConfigReply = meterConfigReplies.get(0); + jGen.writeStringField("version", meterConfigReply.getVersion().toString()); //return the enum name + jGen.writeFieldName("meterConfig"); + jGen.writeStartArray(); + for(OFMeterBand band : meterConfigReply.getEntries()) { + jGen.writeStartObject(); + short type = (short)band.getType(); + jGen.writeNumberField("bandType",type); + + switch (type) { + case OFMeterBandTypeSerializerVer13.DROP_VAL: + OFMeterBandDrop bandDrop = (OFMeterBandDrop) band; + jGen.writeNumberField("rate", bandDrop.getRate()); + jGen.writeNumberField("burstSize", bandDrop.getBurstSize()); + break; + + case OFMeterBandTypeSerializerVer13.DSCP_REMARK_VAL: + OFMeterBandDscpRemark bandDscp = (OFMeterBandDscpRemark) band; + jGen.writeNumberField("rate", bandDscp.getRate()); + jGen.writeNumberField("burstSize", bandDscp.getBurstSize()); + jGen.writeNumberField("precLevel", bandDscp.getPrecLevel()); + break; + + case OFMeterBandTypeSerializerVer13.EXPERIMENTER_VAL: + OFMeterBandExperimenter bandExp = (OFMeterBandExperimenter) band; + jGen.writeNumberField("rate", bandExp.getRate()); + jGen.writeNumberField("burstSize", bandExp.getBurstSize()); + jGen.writeNumberField("experimenter", bandExp.getExperimenter()); + break; + + default: + // shouldn't ever get here + break; + }//end of Switch Case + + jGen.writeEndObject(); + }//end of for loop + jGen.writeEndArray(); + } + + /*** + * Serializes Table Statistics + * @author Naveen + * @param tableReplies + * @param jGen + * @throws IOException + * @throws JsonProcessingException + */ + public void serializeTableReply(List<OFTableStatsReply> tableReplies, JsonGenerator jGen) throws IOException, JsonProcessingException{ + + OFTableStatsReply tableReply = tableReplies.get(0); // we will get only one tableReply and it will contains many OFTableStatsEntry ? + jGen.writeStringField("version", tableReply.getVersion().toString()); //return the enum name + jGen.writeFieldName("table"); + jGen.writeStartArray(); + for(OFTableStatsEntry entry : tableReply.getEntries()) { + jGen.writeStartObject(); + + //Fields common to all OF versions + //For OF 1.3, only these fields are applicable + jGen.writeStringField("tableId",entry.getTableId().toString()); + jGen.writeNumberField("activeCount", entry.getActiveCount()); + jGen.writeNumberField("lookUpCount", entry.getLookupCount().getValue()); + jGen.writeNumberField("matchCount", entry.getMatchedCount().getValue()); + + //Fields Applicable only for specific Versions + switch (entry.getVersion()) { + case OF_12: + //Fields applicable only to OF 1.2 + jGen.writeNumberField("writeSetFields", entry.getWriteSetfields().getValue()); + jGen.writeNumberField("applySetFields", entry.getApplySetfields().getValue()); + jGen.writeNumberField("metaDataMatch", entry.getMetadataMatch().getValue()); + jGen.writeNumberField("metaDataWrite", entry.getMetadataWrite().getValue()); + case OF_11: + //Fields applicable to OF 1.1 & 1.2 + jGen.writeStringField("match", entry.getMatch().toString()); + jGen.writeNumberField("instructions", entry.getInstructions()); + jGen.writeNumberField("writeActions", entry.getWriteActions()); + jGen.writeNumberField("applyActions", entry.getApplyActions()); + jGen.writeNumberField("config", entry.getConfig()); + case OF_10: + //Fields applicable to OF 1.0, 1.1 & 1.2 + jGen.writeStringField("name",entry.getName()); + jGen.writeNumberField("wildcards", entry.getWildcards()); + jGen.writeNumberField("maxEntries", entry.getMaxEntries()); + break; + default: + //no extra fields for OF_13 + break; + }//End of switch case + jGen.writeEndObject(); + }//End of for loop + jGen.writeEndArray(); + } + + /*** + * Serializes Table Features Reply + * @author Naveen + * @param tableFeaturesReplies + * @param jGen + * @throws IOException + * @throws JsonProcessingException + */ + public void serializeTableFeaturesReply(List<OFTableFeaturesStatsReply> tableFeaturesReplies, JsonGenerator jGen) throws IOException, JsonProcessingException{ + + OFTableFeaturesStatsReply tableFeaturesReply = tableFeaturesReplies.get(0); + jGen.writeStringField("version", tableFeaturesReply.getVersion().toString()); //return the enum name + + jGen.writeFieldName("tableFeatures"); + jGen.writeStartArray(); + for(OFTableFeatures tableFeature : tableFeaturesReply.getEntries()) { + jGen.writeStartObject(); + jGen.writeNumberField("tableId", tableFeature.getTableId().getValue()); + jGen.writeStringField("name", tableFeature.getName()); + jGen.writeNumberField("metadataMatch", tableFeature.getMetadataMatch().getValue()); + jGen.writeNumberField("metadataWrite", tableFeature.getMetadataWrite().getValue()); + jGen.writeNumberField("config", tableFeature.getConfig()); + jGen.writeNumberField("maxEntries", tableFeature.getMaxEntries()); + + jGen.writeFieldName("properties"); + jGen.writeStartArray(); + for (OFTableFeatureProp properties : tableFeature.getProperties()) { + jGen.writeStartObject(); + short type = (short)properties.getType(); + jGen.writeNumberField("tableFeaturePropType",type); + + switch (type) { + case OFTableFeaturePropTypeSerializerVer13.INSTRUCTIONS_VAL: + OFTableFeaturePropInstructions propInstruct = (OFTableFeaturePropInstructions) properties; + jGen.writeFieldName("instructions"); + jGen.writeStartArray(); + for (OFInstructionId id : propInstruct.getInstructionIds()) { + jGen.writeStartObject(); + jGen.writeString(id.getType().toString()); + jGen.writeEndObject(); + } + jGen.writeEndArray(); + break; + case OFTableFeaturePropTypeSerializerVer13.INSTRUCTIONS_MISS_VAL: + OFTableFeaturePropInstructionsMiss propInstructMiss = (OFTableFeaturePropInstructionsMiss) properties; + jGen.writeFieldName("instructionsMiss"); + jGen.writeStartArray(); + for (OFInstructionId id : propInstructMiss.getInstructionIds()) { + jGen.writeStartObject(); + jGen.writeString(id.getType().toString()); + jGen.writeEndObject(); + } + jGen.writeEndArray(); + break; + case OFTableFeaturePropTypeSerializerVer13.NEXT_TABLES_VAL: + OFTableFeaturePropNextTables propNxtTables = (OFTableFeaturePropNextTables) properties; + jGen.writeFieldName("nextTables"); + jGen.writeStartArray(); + for (U8 id : propNxtTables.getNextTableIds()) { + jGen.writeStartObject(); + jGen.writeNumber(id.getValue()); + jGen.writeEndObject(); + } + jGen.writeEndArray(); + break; + case OFTableFeaturePropTypeSerializerVer13.NEXT_TABLES_MISS_VAL: + OFTableFeaturePropNextTablesMiss propNxtTablesMiss = (OFTableFeaturePropNextTablesMiss) properties; + jGen.writeFieldName("nextTablesMiss"); + jGen.writeStartArray(); + for (U8 id : propNxtTablesMiss.getNextTableIds()) { + jGen.writeStartObject(); + jGen.writeNumber(id.getValue()); + jGen.writeEndObject(); + } + jGen.writeEndArray(); + break; + case OFTableFeaturePropTypeSerializerVer13.WRITE_ACTIONS_VAL: + OFTableFeaturePropWriteActions propWrAct = (OFTableFeaturePropWriteActions) properties; + jGen.writeFieldName("writeActions"); + jGen.writeStartArray(); + for (OFActionId id : propWrAct.getActionIds()) { + jGen.writeStartObject(); + jGen.writeString(id.getType().toString()); + jGen.writeEndObject(); + } + jGen.writeEndArray(); + break; + case OFTableFeaturePropTypeSerializerVer13.WRITE_ACTIONS_MISS_VAL: + OFTableFeaturePropWriteActionsMiss propWrActMiss = (OFTableFeaturePropWriteActionsMiss) properties; + jGen.writeFieldName("writeActionsMiss"); + jGen.writeStartArray(); + for (OFActionId id : propWrActMiss.getActionIds()) { + jGen.writeStartObject(); + jGen.writeString(id.getType().toString()); + jGen.writeEndObject(); + } + jGen.writeEndArray(); + break; + case OFTableFeaturePropTypeSerializerVer13.APPLY_ACTIONS_VAL: + OFTableFeaturePropApplyActions propAppAct = (OFTableFeaturePropApplyActions) properties; + jGen.writeFieldName("applyActions"); + jGen.writeStartArray(); + for (OFActionId id : propAppAct.getActionIds()) { + jGen.writeStartObject(); + jGen.writeString(id.getType().toString()); + jGen.writeEndObject(); + } + jGen.writeEndArray(); + break; + case OFTableFeaturePropTypeSerializerVer13.APPLY_ACTIONS_MISS_VAL: + OFTableFeaturePropApplyActionsMiss propAppActMiss = (OFTableFeaturePropApplyActionsMiss) properties; + jGen.writeFieldName("applyActionsMiss"); + jGen.writeStartArray(); + for (OFActionId id : propAppActMiss.getActionIds()) { + jGen.writeStartObject(); + jGen.writeString(id.getType().toString()); + jGen.writeEndObject(); + } + jGen.writeEndArray(); + break; + case OFTableFeaturePropTypeSerializerVer13.MATCH_VAL: + OFTableFeaturePropMatch propMatch = (OFTableFeaturePropMatch) properties; + jGen.writeFieldName("match"); + jGen.writeStartArray(); + for (U32 id : propMatch.getOxmIds()) { + jGen.writeStartObject(); + jGen.writeNumber(id.getValue()); + jGen.writeEndObject(); + } + jGen.writeEndArray(); + break; + case OFTableFeaturePropTypeSerializerVer13.WILDCARDS_VAL: + OFTableFeaturePropWildcards propWildcards = (OFTableFeaturePropWildcards) properties; + jGen.writeFieldName("wildcards"); + jGen.writeStartArray(); + for (U32 id : propWildcards.getOxmIds()) { + jGen.writeStartObject(); + jGen.writeNumber(id.getValue()); + jGen.writeEndObject(); + } + jGen.writeEndArray(); + break; + case OFTableFeaturePropTypeSerializerVer13.WRITE_SETFIELD_VAL: + OFTableFeaturePropWriteSetfield propWrSetfield = (OFTableFeaturePropWriteSetfield) properties; + jGen.writeFieldName("writeSetfield"); + jGen.writeStartArray(); + for (U32 id : propWrSetfield.getOxmIds()) { + jGen.writeStartObject(); + jGen.writeNumber(id.getValue()); + jGen.writeEndObject(); + } + jGen.writeEndArray(); + break; + case OFTableFeaturePropTypeSerializerVer13.WRITE_SETFIELD_MISS_VAL: + OFTableFeaturePropWriteSetfieldMiss propWrSetfieldMiss = (OFTableFeaturePropWriteSetfieldMiss) properties; + jGen.writeFieldName("writeSetfieldMiss"); + jGen.writeStartArray(); + for (U32 id : propWrSetfieldMiss.getOxmIds()) { + jGen.writeStartObject(); + jGen.writeNumber(id.getValue()); + jGen.writeEndObject(); + } + jGen.writeEndArray(); + break; + case OFTableFeaturePropTypeSerializerVer13.APPLY_SETFIELD_VAL: + OFTableFeaturePropApplySetfield propAppSetfield = (OFTableFeaturePropApplySetfield) properties; + jGen.writeFieldName("applySetfield"); + jGen.writeStartArray(); + for (U32 id : propAppSetfield.getOxmIds()) { + jGen.writeStartObject(); + jGen.writeNumber(id.getValue()); + jGen.writeEndObject(); + } + jGen.writeEndArray(); + break; + case OFTableFeaturePropTypeSerializerVer13.APPLY_SETFIELD_MISS_VAL: + OFTableFeaturePropApplySetfieldMiss propAppSetfieldMiss = (OFTableFeaturePropApplySetfieldMiss) properties; + jGen.writeFieldName("applySetfieldMiss"); + jGen.writeStartArray(); + for (U32 id : propAppSetfieldMiss.getOxmIds()) { + jGen.writeStartObject(); + jGen.writeNumber(id.getValue()); + jGen.writeEndObject(); + } + jGen.writeEndArray(); + break; + case OFTableFeaturePropTypeSerializerVer13.EXPERIMENTER_VAL: + OFTableFeaturePropExperimenter propExp = (OFTableFeaturePropExperimenter) properties; + jGen.writeFieldName("experimenter"); + jGen.writeStartObject(); + jGen.writeNumberField("subType", propExp.getSubtype()); + jGen.writeNumberField("experimenter", propExp.getExperimenter()); + jGen.writeStringField("subType", propExp.getExperimenterData().toString()); + jGen.writeEndObject(); + break; + case OFTableFeaturePropTypeSerializerVer13.EXPERIMENTER_MISS_VAL: + OFTableFeaturePropExperimenterMiss propExpMiss = (OFTableFeaturePropExperimenterMiss) properties; + jGen.writeFieldName("experimenterMiss"); + jGen.writeStartObject(); + jGen.writeNumberField("subType", propExpMiss.getSubtype()); + jGen.writeNumberField("experimenter", propExpMiss.getExperimenter()); + jGen.writeStringField("subType", propExpMiss.getExperimenterData().toString()); + jGen.writeEndObject(); + break; + default: + // shouldn't ever get here + break; + }//end of Switch Case + jGen.writeEndObject(); + }//end of for loop - properties + jGen.writeEndObject(); + }//end of for loop - features + jGen.writeEndArray(); + } + + public static void serializePortReply(List<OFPortStatsReply> portReplies, JsonGenerator jGen) throws IOException, JsonProcessingException{ OFPortStatsReply portReply = portReplies.get(0); // we will get only one PortReply and it will contains many OFPortStatsEntry ? jGen.writeStringField("version", portReply.getVersion().toString()); //return the enum name