diff --git a/src/main/java/net/floodlightcontroller/core/web/AllSwitchStatisticsResource.java b/src/main/java/net/floodlightcontroller/core/web/AllSwitchStatisticsResource.java index 18bfcc3c045de2e61f1ad8f5f15776b4495397d2..ea3c11ec5d7812d234c20eac2823ca4b8b33cdba 100644 --- a/src/main/java/net/floodlightcontroller/core/web/AllSwitchStatisticsResource.java +++ b/src/main/java/net/floodlightcontroller/core/web/AllSwitchStatisticsResource.java @@ -43,14 +43,14 @@ public class AllSwitchStatisticsResource extends SwitchResourceBase { LoggerFactory.getLogger(AllSwitchStatisticsResource.class); @Get("json") - public Map<String, Object> retrieve() { + public Map<String, StatsReply> retrieve() { String statType = (String) getRequestAttributes().get(CoreWebRoutable.STR_STAT_TYPE); return retrieveInternal(statType); } - private Map<String, Object> retrieveInternal(String statType) { - HashMap<String, Object> model = new HashMap<String, Object>(); + private Map<String, StatsReply> retrieveInternal(String statType) { + HashMap<String, StatsReply> model = new HashMap<String, StatsReply>(); OFStatsType type = null; REQUESTTYPE rType = null; @@ -108,9 +108,9 @@ public class AllSwitchStatisticsResource extends SwitchResourceBase { for (GetConcurrentStatsThread curThread : activeThreads) { if (curThread.getState() == State.TERMINATED) { if (rType == REQUESTTYPE.OFSTATS) { - model.put(curThread.getSwitchId().toString(), curThread.getStatisticsReply()); + model.put(curThread.getSwitchId().toString(), new StatsReply(curThread.getSwitchId(), curThread.getStatisticsReply(), type)); } else if (rType == REQUESTTYPE.OFFEATURES) { - model.put(curThread.getSwitchId().toString(), curThread.getFeaturesReply()); + model.put(curThread.getSwitchId().toString(), new StatsReply(curThread.getSwitchId(), curThread.getFeaturesReply(), type)); } pendingRemovalThreads.add(curThread); } diff --git a/src/main/java/net/floodlightcontroller/core/web/serializers/MatchSerializer.java b/src/main/java/net/floodlightcontroller/core/web/serializers/MatchSerializer.java new file mode 100644 index 0000000000000000000000000000000000000000..c242cc6305711654eff318152d0348b6e5e34a89 --- /dev/null +++ b/src/main/java/net/floodlightcontroller/core/web/serializers/MatchSerializer.java @@ -0,0 +1,164 @@ +package net.floodlightcontroller.core.web.serializers; + +import java.io.IOException; +import java.util.Iterator; + +import net.floodlightcontroller.util.MatchUtils; + +import org.projectfloodlight.openflow.protocol.match.Match; +import org.projectfloodlight.openflow.protocol.match.MatchField; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.fasterxml.jackson.core.JsonGenerator; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.JsonSerializer; +import com.fasterxml.jackson.databind.SerializerProvider; + +/** + * Serialize any Match in JSON. + * + * Use automatically by Jackson via JsonSerialize(using=MatchSerializer.class), + * or use the static function within this class within another serializer. + * + * @author Ryan Izard, ryan.izard@bigswitch.com, rizard@g.clemson.edu + */ +public class MatchSerializer extends JsonSerializer<Match> { + protected static Logger logger = LoggerFactory.getLogger(OFActionListSerializer.class); + + @Override + public void serialize(Match match, JsonGenerator jGen, SerializerProvider serializer) throws IOException, + JsonProcessingException { + serializeMatch(jGen, match); + } + + public static void serializeMatch(JsonGenerator jGen, Match match) throws IOException, JsonProcessingException { + // list flow matches + jGen.writeObjectFieldStart("match"); + Iterator<MatchField<?>> mi = match.getMatchFields().iterator(); // get iter to any match field type + Match m = match; + + while (mi.hasNext()) { + MatchField<?> mf = mi.next(); + switch (mf.id) { + case IN_PORT: + jGen.writeStringField(MatchUtils.STR_IN_PORT, m.get(MatchField.IN_PORT).toString()); + break; + case IN_PHY_PORT: + jGen.writeStringField(MatchUtils.STR_IN_PHYS_PORT, m.get(MatchField.IN_PHY_PORT).toString()); + break; + case ARP_OP: + jGen.writeNumberField(MatchUtils.STR_ARP_OPCODE, m.get(MatchField.ARP_OP).getOpcode()); + break; + case ARP_SHA: + jGen.writeStringField(MatchUtils.STR_ARP_SHA, m.get(MatchField.ARP_SHA).toString()); + break; + case ARP_SPA: + jGen.writeStringField(MatchUtils.STR_ARP_SPA, m.get(MatchField.ARP_SPA).toString()); + break; + case ARP_THA: + jGen.writeStringField(MatchUtils.STR_ARP_DHA, m.get(MatchField.ARP_THA).toString()); + break; + case ARP_TPA: + jGen.writeStringField(MatchUtils.STR_ARP_DPA, m.get(MatchField.ARP_TPA).toString()); + break; + case ETH_TYPE: + jGen.writeNumberField(MatchUtils.STR_DL_TYPE, m.get(MatchField.ETH_TYPE).getValue()); + break; + case ETH_SRC: + jGen.writeStringField(MatchUtils.STR_DL_SRC, m.get(MatchField.ETH_SRC).toString()); + break; + case ETH_DST: + jGen.writeStringField(MatchUtils.STR_DL_DST, m.get(MatchField.ETH_DST).toString()); + break; + case VLAN_VID: + jGen.writeNumberField(MatchUtils.STR_DL_VLAN, m.get(MatchField.VLAN_VID).getVlan()); + break; + case VLAN_PCP: + jGen.writeNumberField(MatchUtils.STR_DL_VLAN_PCP, m.get(MatchField.VLAN_PCP).getValue()); + break; + case ICMPV4_TYPE: + jGen.writeNumberField(MatchUtils.STR_ICMP_TYPE, m.get(MatchField.ICMPV4_TYPE).getType()); + break; + case ICMPV4_CODE: + jGen.writeNumberField(MatchUtils.STR_ICMP_CODE, m.get(MatchField.ICMPV4_CODE).getCode()); + break; + case ICMPV6_TYPE: + jGen.writeNumberField(MatchUtils.STR_ICMPV6_TYPE, m.get(MatchField.ICMPV6_TYPE).getValue()); + break; + case ICMPV6_CODE: + jGen.writeNumberField(MatchUtils.STR_ICMPV6_CODE, m.get(MatchField.ICMPV6_CODE).getValue()); + break; + case IP_DSCP: + jGen.writeNumberField(MatchUtils.STR_NW_DSCP, m.get(MatchField.IP_DSCP).getDscpValue()); + break; + case IP_ECN: + jGen.writeNumberField(MatchUtils.STR_NW_ECN, m.get(MatchField.IP_ECN).getEcnValue()); + break; + case IP_PROTO: + jGen.writeNumberField(MatchUtils.STR_NW_PROTO, m.get(MatchField.IP_PROTO).getIpProtocolNumber()); + break; + case IPV4_SRC: + jGen.writeStringField(MatchUtils.STR_NW_SRC, m.get(MatchField.IPV4_SRC).toString()); + break; + case IPV4_DST: + jGen.writeStringField(MatchUtils.STR_NW_DST, m.get(MatchField.IPV4_DST).toString()); + break; + case IPV6_SRC: + jGen.writeStringField(MatchUtils.STR_IPV6_SRC, m.get(MatchField.IPV6_SRC).toString()); + break; + case IPV6_DST: + jGen.writeStringField(MatchUtils.STR_IPV6_DST, m.get(MatchField.IPV6_DST).toString()); + break; + case IPV6_FLABEL: + jGen.writeNumberField(MatchUtils.STR_IPV6_FLOW_LABEL, m.get(MatchField.IPV6_FLABEL).getIPv6FlowLabelValue()); + break; + case IPV6_ND_SLL: + jGen.writeNumberField(MatchUtils.STR_IPV6_ND_SSL, m.get(MatchField.IPV6_ND_SLL).getLong()); + break; + case IPV6_ND_TARGET: + jGen.writeNumberField(MatchUtils.STR_IPV6_ND_TARGET, m.get(MatchField.IPV6_ND_TARGET).getZeroCompressStart()); + break; + case IPV6_ND_TLL: + jGen.writeNumberField(MatchUtils.STR_IPV6_ND_TTL, m.get(MatchField.IPV6_ND_TLL).getLong()); + break; + case METADATA: + jGen.writeNumberField(MatchUtils.STR_METADATA, m.get(MatchField.METADATA).getValue().getValue()); + break; + case MPLS_LABEL: + jGen.writeNumberField(MatchUtils.STR_MPLS_LABEL, m.get(MatchField.MPLS_LABEL).getValue()); + break; + case MPLS_TC: + jGen.writeNumberField(MatchUtils.STR_MPLS_TC, m.get(MatchField.MPLS_TC).getValue()); + break; + case MPLS_BOS: + jGen.writeStringField(MatchUtils.STR_MPLS_BOS, m.get(MatchField.MPLS_BOS).toString()); + break; + case SCTP_SRC: + jGen.writeNumberField(MatchUtils.STR_SCTP_SRC, m.get(MatchField.SCTP_SRC).getPort()); + break; + case SCTP_DST: + jGen.writeNumberField(MatchUtils.STR_SCTP_DST, m.get(MatchField.SCTP_DST).getPort()); + break; + case TCP_SRC: + jGen.writeNumberField(MatchUtils.STR_TCP_SRC, m.get(MatchField.TCP_SRC).getPort()); + break; + case TCP_DST: + jGen.writeNumberField(MatchUtils.STR_TCP_DST, m.get(MatchField.TCP_DST).getPort()); + break; + case UDP_SRC: + jGen.writeNumberField(MatchUtils.STR_UDP_SRC, m.get(MatchField.UDP_SRC).getPort()); + break; + case UDP_DST: + jGen.writeNumberField(MatchUtils.STR_UDP_DST, m.get(MatchField.UDP_DST).getPort()); + break; + default: + // either a BSN or unknown match type + break; + } // end switch of match type + } // end while over non-wildcarded matches + + jGen.writeEndObject(); // end match + } +} + diff --git a/src/main/java/net/floodlightcontroller/core/web/serializers/OFActionListSerializer.java b/src/main/java/net/floodlightcontroller/core/web/serializers/OFActionListSerializer.java new file mode 100644 index 0000000000000000000000000000000000000000..bb17f34f9400fea90755c996c5341e869ee8b863 --- /dev/null +++ b/src/main/java/net/floodlightcontroller/core/web/serializers/OFActionListSerializer.java @@ -0,0 +1,268 @@ +package net.floodlightcontroller.core.web.serializers; + +import java.io.IOException; +import java.util.List; + +import net.floodlightcontroller.util.ActionUtils; +import net.floodlightcontroller.util.MatchUtils; + +import org.projectfloodlight.openflow.protocol.action.OFAction; +import org.projectfloodlight.openflow.protocol.action.OFActionEnqueue; +import org.projectfloodlight.openflow.protocol.action.OFActionExperimenter; +import org.projectfloodlight.openflow.protocol.action.OFActionGroup; +import org.projectfloodlight.openflow.protocol.action.OFActionOutput; +import org.projectfloodlight.openflow.protocol.action.OFActionPopMpls; +import org.projectfloodlight.openflow.protocol.action.OFActionPushMpls; +import org.projectfloodlight.openflow.protocol.action.OFActionPushPbb; +import org.projectfloodlight.openflow.protocol.action.OFActionPushVlan; +import org.projectfloodlight.openflow.protocol.action.OFActionSetDlDst; +import org.projectfloodlight.openflow.protocol.action.OFActionSetDlSrc; +import org.projectfloodlight.openflow.protocol.action.OFActionSetField; +import org.projectfloodlight.openflow.protocol.action.OFActionSetMplsLabel; +import org.projectfloodlight.openflow.protocol.action.OFActionSetMplsTc; +import org.projectfloodlight.openflow.protocol.action.OFActionSetMplsTtl; +import org.projectfloodlight.openflow.protocol.action.OFActionSetNwDst; +import org.projectfloodlight.openflow.protocol.action.OFActionSetNwEcn; +import org.projectfloodlight.openflow.protocol.action.OFActionSetNwSrc; +import org.projectfloodlight.openflow.protocol.action.OFActionSetNwTos; +import org.projectfloodlight.openflow.protocol.action.OFActionSetNwTtl; +import org.projectfloodlight.openflow.protocol.action.OFActionSetQueue; +import org.projectfloodlight.openflow.protocol.action.OFActionSetTpDst; +import org.projectfloodlight.openflow.protocol.action.OFActionSetTpSrc; +import org.projectfloodlight.openflow.protocol.action.OFActionSetVlanPcp; +import org.projectfloodlight.openflow.protocol.action.OFActionSetVlanVid; +import org.projectfloodlight.openflow.protocol.oxm.OFOxmArpOp; +import org.projectfloodlight.openflow.protocol.oxm.OFOxmArpSha; +import org.projectfloodlight.openflow.protocol.oxm.OFOxmArpSpa; +import org.projectfloodlight.openflow.protocol.oxm.OFOxmArpTha; +import org.projectfloodlight.openflow.protocol.oxm.OFOxmArpTpa; +import org.projectfloodlight.openflow.protocol.oxm.OFOxmEthDst; +import org.projectfloodlight.openflow.protocol.oxm.OFOxmEthSrc; +import org.projectfloodlight.openflow.protocol.oxm.OFOxmEthType; +import org.projectfloodlight.openflow.protocol.oxm.OFOxmIcmpv4Code; +import org.projectfloodlight.openflow.protocol.oxm.OFOxmIcmpv4Type; +import org.projectfloodlight.openflow.protocol.oxm.OFOxmIpDscp; +import org.projectfloodlight.openflow.protocol.oxm.OFOxmIpEcn; +import org.projectfloodlight.openflow.protocol.oxm.OFOxmIpProto; +import org.projectfloodlight.openflow.protocol.oxm.OFOxmIpv4Dst; +import org.projectfloodlight.openflow.protocol.oxm.OFOxmIpv4Src; +import org.projectfloodlight.openflow.protocol.oxm.OFOxmMetadata; +import org.projectfloodlight.openflow.protocol.oxm.OFOxmMplsBos; +import org.projectfloodlight.openflow.protocol.oxm.OFOxmMplsLabel; +import org.projectfloodlight.openflow.protocol.oxm.OFOxmMplsTc; +import org.projectfloodlight.openflow.protocol.oxm.OFOxmSctpDst; +import org.projectfloodlight.openflow.protocol.oxm.OFOxmSctpSrc; +import org.projectfloodlight.openflow.protocol.oxm.OFOxmTcpDst; +import org.projectfloodlight.openflow.protocol.oxm.OFOxmTcpSrc; +import org.projectfloodlight.openflow.protocol.oxm.OFOxmUdpDst; +import org.projectfloodlight.openflow.protocol.oxm.OFOxmUdpSrc; +import org.projectfloodlight.openflow.protocol.oxm.OFOxmVlanPcp; +import org.projectfloodlight.openflow.protocol.oxm.OFOxmVlanVid; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.fasterxml.jackson.core.JsonGenerator; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.JsonSerializer; +import com.fasterxml.jackson.databind.SerializerProvider; + +/** + * Serialize any List of OFAction in JSON. + * + * Use automatically by Jackson via JsonSerialize(using=OFActionListSerializer.class), + * or use the static function within this class within another serializer. + * + * @author Ryan Izard, ryan.izard@bigswitch.com, rizard@g.clemson.edu + */ +public class OFActionListSerializer extends JsonSerializer<List<OFAction>> { + protected static Logger logger = LoggerFactory.getLogger(OFActionListSerializer.class); + + @Override + public void serialize(List<OFAction> actions, JsonGenerator jGen, SerializerProvider serializer) throws IOException, + JsonProcessingException { + jGen.writeStartObject(); + serializeActions(jGen, actions); + jGen.writeEndObject(); + } + + /** + * Write a JSON string given a list of OFAction. Supports OF1.0 - OF1.3. + * This is the only place actions are serialized, for any OF version. Because + * some OF version share actions, it makes sense to have them in one place. + * @param jsonGenerator + * @param actions + * @throws IOException + * @throws JsonProcessingException + */ + public static void serializeActions(JsonGenerator jsonGenerator, List<OFAction> actions) throws IOException, JsonProcessingException { + if (actions.isEmpty()) { + jsonGenerator.writeStringField("none", "drop"); + } + for (OFAction a : actions) { + switch (a.getType()) { + case OUTPUT: + jsonGenerator.writeStringField(ActionUtils.STR_OUTPUT, ((OFActionOutput)a).getPort().toString()); + break; + /* begin OF1.0 ONLY actions */ + case SET_VLAN_VID: + jsonGenerator.writeNumberField(ActionUtils.STR_VLAN_SET_VID, ((OFActionSetVlanVid)a).getVlanVid().getVlan()); + break; + case SET_VLAN_PCP: + jsonGenerator.writeNumberField(ActionUtils.STR_VLAN_SET_PCP, ((OFActionSetVlanPcp)a).getVlanPcp().getValue()); + break; + case SET_QUEUE: + jsonGenerator.writeNumberField(ActionUtils.STR_QUEUE_SET, ((OFActionSetQueue)a).getQueueId()); + break; + case SET_DL_SRC: + jsonGenerator.writeStringField(ActionUtils.STR_DL_SRC_SET, ((OFActionSetDlSrc)a).getDlAddr().toString()); + break; + case SET_DL_DST: + jsonGenerator.writeStringField(ActionUtils.STR_DL_DST_SET, ((OFActionSetDlDst)a).getDlAddr().toString()); + break; + case SET_NW_SRC: + jsonGenerator.writeStringField(ActionUtils.STR_NW_SRC_SET, ((OFActionSetNwSrc)a).getNwAddr().toString()); + break; + case SET_NW_DST: + jsonGenerator.writeStringField(ActionUtils.STR_NW_DST_SET, ((OFActionSetNwDst)a).getNwAddr().toString()); + break; + case SET_NW_TOS: + jsonGenerator.writeNumberField(ActionUtils.STR_NW_TOS_SET, ((OFActionSetNwTos)a).getNwTos()); + break; + case SET_TP_SRC: + jsonGenerator.writeNumberField(ActionUtils.STR_TP_SRC_SET, ((OFActionSetTpSrc)a).getTpPort().getPort()); + break; + case SET_TP_DST: + jsonGenerator.writeNumberField(ActionUtils.STR_TP_DST_SET, ((OFActionSetTpDst)a).getTpPort().getPort()); + break; + /* end OF1.0 ONLY actions; begin OF1.1+ actions */ + case ENQUEUE: + jsonGenerator.writeNumberField(ActionUtils.STR_ENQUEUE, ((OFActionEnqueue)a).getPort().getPortNumber()); + break; + case GROUP: + jsonGenerator.writeStringField(ActionUtils.STR_GROUP, ((OFActionGroup)a).getGroup().toString()); + break; + case STRIP_VLAN: + jsonGenerator.writeString(ActionUtils.STR_VLAN_STRIP); + break; + case PUSH_VLAN: + jsonGenerator.writeNumberField(ActionUtils.STR_VLAN_PUSH, ((OFActionPushVlan)a).getEthertype().getValue()); + break; + case PUSH_MPLS: + jsonGenerator.writeNumberField(ActionUtils.STR_MPLS_PUSH, ((OFActionPushMpls)a).getEthertype().getValue()); + break; + case PUSH_PBB: + jsonGenerator.writeNumberField(ActionUtils.STR_PBB_PUSH, ((OFActionPushPbb)a).getEthertype().getValue()); + break; + case POP_VLAN: + jsonGenerator.writeString(ActionUtils.STR_VLAN_POP); + break; + case POP_MPLS: + jsonGenerator.writeNumberField(ActionUtils.STR_MPLS_POP, ((OFActionPopMpls)a).getEthertype().getValue()); + break; + case POP_PBB: + jsonGenerator.writeString(ActionUtils.STR_PBB_POP); + break; + case COPY_TTL_IN: + jsonGenerator.writeString(ActionUtils.STR_TTL_IN_COPY); + break; + case COPY_TTL_OUT: + jsonGenerator.writeString(ActionUtils.STR_TTL_OUT_COPY); + break; + case DEC_NW_TTL: + jsonGenerator.writeString(ActionUtils.STR_NW_TTL_DEC); + break; + case DEC_MPLS_TTL: + jsonGenerator.writeString(ActionUtils.STR_MPLS_TTL_DEC); + break; + case SET_MPLS_LABEL: + jsonGenerator.writeNumberField(ActionUtils.STR_MPLS_LABEL_SET, ((OFActionSetMplsLabel)a).getMplsLabel()); + break; + case SET_MPLS_TC: + jsonGenerator.writeNumberField(ActionUtils.STR_MPLS_TC_SET, ((OFActionSetMplsTc)a).getMplsTc()); + break; + case SET_MPLS_TTL: + jsonGenerator.writeNumberField(ActionUtils.STR_MPLS_TTL_SET, ((OFActionSetMplsTtl)a).getMplsTtl()); + break; + case SET_NW_ECN: + jsonGenerator.writeNumberField(ActionUtils.STR_NW_ECN_SET, ((OFActionSetNwEcn)a).getNwEcn().getEcnValue()); + break; + case SET_NW_TTL: + jsonGenerator.writeNumberField(ActionUtils.STR_NW_TTL_SET, ((OFActionSetNwTtl)a).getNwTtl()); + break; + case EXPERIMENTER: + jsonGenerator.writeNumberField(ActionUtils.STR_EXPERIMENTER, ((OFActionExperimenter)a).getExperimenter()); + break; + case SET_FIELD: + if (((OFActionSetField)a).getField() instanceof OFOxmArpOp) { + jsonGenerator.writeNumberField(MatchUtils.STR_ARP_OPCODE, ((OFOxmArpOp) ((OFActionSetField) a).getField()).getValue().getOpcode()); + } else if (((OFActionSetField)a).getField() instanceof OFOxmArpSha) { + jsonGenerator.writeStringField(MatchUtils.STR_ARP_SHA, ((OFOxmArpSha) ((OFActionSetField) a).getField()).getValue().toString()); // macaddress formats string already + } else if (((OFActionSetField)a).getField() instanceof OFOxmArpTha) { + jsonGenerator.writeStringField(MatchUtils.STR_ARP_DHA, ((OFOxmArpTha) ((OFActionSetField) a).getField()).getValue().toString()); + } else if (((OFActionSetField)a).getField() instanceof OFOxmArpSpa) { + jsonGenerator.writeStringField(MatchUtils.STR_ARP_SPA, ((OFOxmArpSpa) ((OFActionSetField) a).getField()).getValue().toString()); // ipaddress formats string already + } else if (((OFActionSetField)a).getField() instanceof OFOxmArpTpa) { + jsonGenerator.writeStringField(MatchUtils.STR_ARP_DPA, ((OFOxmArpTpa) ((OFActionSetField) a).getField()).getValue().toString()); + } + /* DATA LAYER */ + else if (((OFActionSetField)a).getField() instanceof OFOxmEthType) { + jsonGenerator.writeNumberField(MatchUtils.STR_DL_TYPE, ((OFOxmEthType) ((OFActionSetField) a).getField()).getValue().getValue()); + } else if (((OFActionSetField)a).getField() instanceof OFOxmEthSrc) { + jsonGenerator.writeStringField(MatchUtils.STR_DL_SRC, ((OFOxmEthSrc) ((OFActionSetField) a).getField()).getValue().toString()); + } else if (((OFActionSetField)a).getField() instanceof OFOxmEthDst) { + jsonGenerator.writeStringField(MatchUtils.STR_DL_DST, ((OFOxmEthDst) ((OFActionSetField) a).getField()).getValue().toString()); + } else if (((OFActionSetField)a).getField() instanceof OFOxmVlanVid) { + jsonGenerator.writeNumberField(MatchUtils.STR_DL_VLAN, ((OFOxmVlanVid) ((OFActionSetField) a).getField()).getValue().getVlan()); + } else if (((OFActionSetField)a).getField() instanceof OFOxmVlanPcp) { + } + /* ICMP */ + else if (((OFActionSetField)a).getField() instanceof OFOxmIcmpv4Code) { + jsonGenerator.writeNumberField(MatchUtils.STR_ICMP_CODE, ((OFOxmIcmpv4Code) ((OFActionSetField) a).getField()).getValue().getCode()); + } else if (((OFActionSetField)a).getField() instanceof OFOxmIcmpv4Type) { + jsonGenerator.writeNumberField(MatchUtils.STR_ICMP_TYPE, ((OFOxmIcmpv4Type) ((OFActionSetField) a).getField()).getValue().getType()); + } + /* NETWORK LAYER */ + else if (((OFActionSetField)a).getField() instanceof OFOxmIpProto) { + jsonGenerator.writeNumberField(MatchUtils.STR_NW_PROTO, ((OFOxmIpProto) ((OFActionSetField) a).getField()).getValue().getIpProtocolNumber()); + } else if (((OFActionSetField)a).getField() instanceof OFOxmIpv4Src) { + jsonGenerator.writeStringField(MatchUtils.STR_NW_SRC, ((OFOxmIpv4Src) ((OFActionSetField) a).getField()).getValue().toString()); + } else if (((OFActionSetField)a).getField() instanceof OFOxmIpv4Dst) { + jsonGenerator.writeStringField(MatchUtils.STR_NW_DST, ((OFOxmIpv4Dst) ((OFActionSetField) a).getField()).getValue().toString()); + } else if (((OFActionSetField)a).getField() instanceof OFOxmIpEcn) { + jsonGenerator.writeNumberField(MatchUtils.STR_NW_ECN, ((OFOxmIpEcn) ((OFActionSetField) a).getField()).getValue().getEcnValue()); + } else if (((OFActionSetField)a).getField() instanceof OFOxmIpDscp) { + jsonGenerator.writeNumberField(MatchUtils.STR_NW_DSCP, ((OFOxmIpDscp) ((OFActionSetField) a).getField()).getValue().getDscpValue()); + } + /* TRANSPORT LAYER, TCP, UDP, and SCTP */ + else if (((OFActionSetField)a).getField() instanceof OFOxmTcpSrc) { + jsonGenerator.writeNumberField(MatchUtils.STR_TCP_SRC, ((OFOxmTcpSrc) ((OFActionSetField) a).getField()).getValue().getPort()); + } else if (((OFActionSetField)a).getField() instanceof OFOxmTcpDst) { + jsonGenerator.writeNumberField(MatchUtils.STR_TCP_DST, ((OFOxmTcpDst) ((OFActionSetField) a).getField()).getValue().getPort()); + } else if (((OFActionSetField)a).getField() instanceof OFOxmUdpSrc) { + jsonGenerator.writeNumberField(MatchUtils.STR_UDP_SRC, ((OFOxmUdpSrc) ((OFActionSetField) a).getField()).getValue().getPort()); + } else if (((OFActionSetField)a).getField() instanceof OFOxmUdpDst) { + jsonGenerator.writeNumberField(MatchUtils.STR_UDP_DST, ((OFOxmUdpDst) ((OFActionSetField) a).getField()).getValue().getPort()); + } else if (((OFActionSetField)a).getField() instanceof OFOxmSctpSrc) { + jsonGenerator.writeNumberField(MatchUtils.STR_SCTP_SRC, ((OFOxmSctpSrc) ((OFActionSetField) a).getField()).getValue().getPort()); + } else if (((OFActionSetField)a).getField() instanceof OFOxmSctpDst) { + jsonGenerator.writeNumberField(MatchUtils.STR_SCTP_DST, ((OFOxmSctpDst) ((OFActionSetField) a).getField()).getValue().getPort()); + } + /* MPLS */ + else if (((OFActionSetField)a).getField() instanceof OFOxmMplsLabel) { + jsonGenerator.writeNumberField(MatchUtils.STR_MPLS_LABEL, ((OFOxmMplsLabel) ((OFActionSetField) a).getField()).getValue().getValue()); + } else if (((OFActionSetField)a).getField() instanceof OFOxmMplsTc) { + jsonGenerator.writeNumberField(MatchUtils.STR_MPLS_TC, ((OFOxmMplsTc) ((OFActionSetField) a).getField()).getValue().getValue()); + } else if (((OFActionSetField)a).getField() instanceof OFOxmMplsBos) { + jsonGenerator.writeStringField(MatchUtils.STR_MPLS_TC, ((OFOxmMplsBos) ((OFActionSetField) a).getField()).getValue().toString()); + } + /* METADATA */ + else if (((OFActionSetField)a).getField() instanceof OFOxmMetadata) { + jsonGenerator.writeNumberField(MatchUtils.STR_METADATA, ((OFOxmMetadata) ((OFActionSetField) a).getField()).getValue().getValue().getValue()); + } else { + logger.error("Could not decode Set-Field action field: {}", ((OFActionSetField) a)); + // need to get a logger in here somehow log.error("Could not decode Set-Field action field: {}", ((OFActionSetField) a)); + } + } // end switch over action type + } // end for over all actions + } // end method +} diff --git a/src/main/java/net/floodlightcontroller/core/web/serializers/OFFlowModSerializer.java b/src/main/java/net/floodlightcontroller/core/web/serializers/OFFlowModSerializer.java index b9462235c89348d82d7ffa1119cffe3bea6438bf..a0ebe5b006d43a77097ae14ae6717d27a7f830fc 100644 --- a/src/main/java/net/floodlightcontroller/core/web/serializers/OFFlowModSerializer.java +++ b/src/main/java/net/floodlightcontroller/core/web/serializers/OFFlowModSerializer.java @@ -1,158 +1,102 @@ package net.floodlightcontroller.core.web.serializers; /** -* Copyright 2011,2012 Big Switch Networks, Inc. -* Originally created by David Erickson, Stanford University -* -* Licensed under the Apache License, Version 2.0 (the "License"); you may -* not use this file except in compliance with the License. You may obtain -* a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -* License for the specific language governing permissions and limitations -* under the License. -**/ + * Copyright 2011,2012 Big Switch Networks, Inc. + * Originally created by David Erickson, Stanford University + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. You may obtain + * a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + **/ import java.io.IOException; -import java.util.List; import com.fasterxml.jackson.core.JsonGenerator; import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.core.JsonGenerator.Feature; import com.fasterxml.jackson.databind.JsonSerializer; import com.fasterxml.jackson.databind.SerializerProvider; import org.projectfloodlight.openflow.protocol.OFFlowMod; import org.projectfloodlight.openflow.protocol.OFVersion; -import org.projectfloodlight.openflow.protocol.action.OFAction; -import org.projectfloodlight.openflow.protocol.instruction.OFInstruction; -import org.projectfloodlight.openflow.protocol.instruction.OFInstructionApplyActions; -import org.projectfloodlight.openflow.protocol.instruction.OFInstructionExperimenter; -import org.projectfloodlight.openflow.protocol.instruction.OFInstructionGotoTable; -import org.projectfloodlight.openflow.protocol.instruction.OFInstructionMeter; -import org.projectfloodlight.openflow.protocol.instruction.OFInstructionWriteActions; -import org.projectfloodlight.openflow.protocol.instruction.OFInstructionWriteMetadata; -import org.projectfloodlight.openflow.protocol.match.Match; -import org.projectfloodlight.openflow.protocol.match.MatchField; +import org.projectfloodlight.openflow.protocol.ver10.OFFlowModFlagsSerializerVer10; +import org.projectfloodlight.openflow.protocol.ver11.OFFlowModFlagsSerializerVer11; +import org.projectfloodlight.openflow.protocol.ver12.OFFlowModFlagsSerializerVer12; +import org.projectfloodlight.openflow.protocol.ver13.OFFlowModFlagsSerializerVer13; +import org.projectfloodlight.openflow.protocol.ver14.OFFlowModFlagsSerializerVer14; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** - * Serialize an OFFlowMod into JSON format - * for output from the static flow pusher. + * Serialize any OFFlowMod in JSON. + * + * Use automatically by Jackson via JsonSerialize(using=OFFlowModSerializer.class), + * or use the static function within this class within another serializer. * * @author Ryan Izard, ryan.izard@bigswitch.com, rizard@g.clemson.edu */ public class OFFlowModSerializer extends JsonSerializer<OFFlowMod> { + protected static Logger logger = LoggerFactory.getLogger(OFFlowModSerializer.class); + + @Override + public void serialize(OFFlowMod fm, JsonGenerator jGen, SerializerProvider serializer) + throws IOException, JsonProcessingException { + + } + + public static void serializeFlowMod(JsonGenerator jGen, OFFlowMod flowMod) throws IOException, JsonProcessingException { + + jGen.configure(Feature.WRITE_NUMBERS_AS_STRINGS, true); // IMHO this just looks nicer and is easier to read if everything is quoted + + jGen.writeStartObject(); + jGen.writeStringField("version", flowMod.getVersion().toString()); // return the enum names + jGen.writeStringField("command", flowMod.getCommand().toString()); + jGen.writeNumberField("cookie", flowMod.getCookie().getValue()); + jGen.writeNumberField("cookieMask", flowMod.getCookieMask().getValue()); + jGen.writeStringField("tableId", flowMod.getTableId().toString()); + jGen.writeNumberField("priority", flowMod.getPriority()); + jGen.writeNumberField("idleTimeoutSec", flowMod.getIdleTimeout()); + jGen.writeNumberField("hardTimeoutSec", flowMod.getHardTimeout()); + jGen.writeStringField("outGroup", flowMod.getOutGroup().toString()); + jGen.writeStringField("outPort", flowMod.getOutPort().toString()); + + switch (flowMod.getVersion()) { + case OF_10: + jGen.writeNumberField("flags", OFFlowModFlagsSerializerVer10.toWireValue(flowMod.getFlags())); + break; + case OF_11: + jGen.writeNumberField("flags", OFFlowModFlagsSerializerVer11.toWireValue(flowMod.getFlags())); + break; + case OF_12: + jGen.writeNumberField("flags", OFFlowModFlagsSerializerVer12.toWireValue(flowMod.getFlags())); + break; + case OF_13: + jGen.writeNumberField("flags", OFFlowModFlagsSerializerVer13.toWireValue(flowMod.getFlags())); + break; + case OF_14: + jGen.writeNumberField("flags", OFFlowModFlagsSerializerVer14.toWireValue(flowMod.getFlags())); + break; + default: + logger.error("Could not decode OFVersion {}", flowMod.getVersion()); + break; + } - @Override - public void serialize(OFFlowMod fm, JsonGenerator jGen, SerializerProvider serializer) - throws IOException, JsonProcessingException { - jGen.writeStartObject(); - jGen.writeStringField("command", fm.getCommand().toString()); - jGen.writeStringField("buffer-id", fm.getBufferId().toString()); - jGen.writeStringField("cookie", fm.getCookie().toString()); - if (fm.getVersion() != OFVersion.OF_10) { - jGen.writeStringField("cookie-mask", fm.getCookieMask().toString()); - } - jGen.writeStringField("flags", fm.getFlags().toString()); - jGen.writeNumberField("hard-timeout", fm.getHardTimeout()); - jGen.writeNumberField("idle-timeout", fm.getIdleTimeout()); - jGen.writeNumberField("priority", fm.getPriority()); - if (fm.getVersion() != OFVersion.OF_10) { - jGen.writeStringField("table-id", fm.getTableId().toString()); - } - jGen.writeStringField("of-type", fm.getType().toString()); - jGen.writeStringField("of-version", fm.getVersion().toString()); - jGen.writeStringField("out-port", fm.getOutPort().toString()); - if (fm.getVersion() != OFVersion.OF_10) { - jGen.writeStringField("out-group", fm.getOutGroup().toString()); - } - - serializeMatch(fm.getMatch(), jGen); - - if (fm.getVersion() != OFVersion.OF_10) { - serializeInstructions(fm.getInstructions(), jGen); - } else { - serializeActions(fm.getActions(), "actions", jGen); - } - - jGen.writeEndObject(); - } + MatchSerializer.serializeMatch(jGen, flowMod.getMatch()); - @SuppressWarnings({ "rawtypes", "unchecked" }) - public void serializeMatch(Match match, JsonGenerator jGen) - throws IOException, JsonProcessingException { - if (match == null) - jGen.writeStringField("match", "null"); - else { - jGen.writeFieldName("match"); - jGen.writeStartArray(); - for (MatchField mf : match.getMatchFields()) { - jGen.writeString(match.get(mf).toString()); - } - jGen.writeEndArray(); - } - } - - public void serializeInstructions(List<OFInstruction> instructions, JsonGenerator jGen) - throws IOException, JsonProcessingException { - if (instructions == null) - jGen.writeStringField("instructions", "null"); - else { - jGen.writeFieldName("instructions"); - jGen.writeStartArray(); - for (OFInstruction instruction : instructions) { - switch (instruction.getType()) { - case APPLY_ACTIONS: - serializeActions(((OFInstructionApplyActions) instruction).getActions(), "apply-actions", jGen); - break; - case WRITE_ACTIONS: - serializeActions(((OFInstructionWriteActions) instruction).getActions(), "write-actions", jGen); - break; - case CLEAR_ACTIONS: - jGen.writeStringField("clear-actions", "n/a"); - break; - case GOTO_TABLE: - jGen.writeStringField("goto-table", ((OFInstructionGotoTable) instruction).getTableId().toString()); - break; - case METER: - jGen.writeNumberField("goto-meter", ((OFInstructionMeter) instruction).getMeterId()); - break; - case WRITE_METADATA: - jGen.writeFieldName("write-metadata"); - jGen.writeStartArray(); - jGen.writeStringField("metadata", ((OFInstructionWriteMetadata) instruction).getMetadata().toString()); - jGen.writeStringField("metadata-mask", ((OFInstructionWriteMetadata) instruction).getMetadataMask().toString()); - jGen.writeEndArray(); - break; - case EXPERIMENTER: - jGen.writeNumberField("metadata", ((OFInstructionExperimenter) instruction).getExperimenter()); - break; - default: - jGen.writeStringField("unknown-instruction", "Could not determine instruction type during JSON output serialization"); - break; - } - } - jGen.writeEndArray(); - } - } - - public void serializeActions(List<OFAction> actions, String fieldName, JsonGenerator jGen) - throws IOException, JsonProcessingException { - if (actions == null) { - jGen.writeStartObject(); - jGen.writeStringField(fieldName, "null"); - jGen.writeEndObject(); - } else { - jGen.writeStartObject(); - jGen.writeArrayFieldStart(fieldName); - for (OFAction action : actions) { - jGen.writeString(action.toString()); - } - jGen.writeEndArray(); - jGen.writeEndObject(); - } - } + // handle OF1.1+ instructions with actions within + if (flowMod.getVersion() == OFVersion.OF_10) { + OFActionListSerializer.serializeActions(jGen, flowMod.getActions()); + } else { + OFInstructionListSerializer.serializeInstructionList(jGen, flowMod.getInstructions()); + } // end not-empty instructions (else) + jGen.writeEndObject(); + } // end method } diff --git a/src/main/java/net/floodlightcontroller/core/web/serializers/OFInstructionListSerializer.java b/src/main/java/net/floodlightcontroller/core/web/serializers/OFInstructionListSerializer.java new file mode 100644 index 0000000000000000000000000000000000000000..e16b1854826c709812cb9e79ab5cb638671efb68 --- /dev/null +++ b/src/main/java/net/floodlightcontroller/core/web/serializers/OFInstructionListSerializer.java @@ -0,0 +1,80 @@ +package net.floodlightcontroller.core.web.serializers; + +import java.io.IOException; +import java.util.List; + +import net.floodlightcontroller.util.InstructionUtils; + +import org.projectfloodlight.openflow.protocol.instruction.OFInstruction; +import org.projectfloodlight.openflow.protocol.instruction.OFInstructionApplyActions; +import org.projectfloodlight.openflow.protocol.instruction.OFInstructionExperimenter; +import org.projectfloodlight.openflow.protocol.instruction.OFInstructionGotoTable; +import org.projectfloodlight.openflow.protocol.instruction.OFInstructionMeter; +import org.projectfloodlight.openflow.protocol.instruction.OFInstructionWriteActions; +import org.projectfloodlight.openflow.protocol.instruction.OFInstructionWriteMetadata; + +import com.fasterxml.jackson.core.JsonGenerator; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.JsonSerializer; +import com.fasterxml.jackson.databind.SerializerProvider; + +/** + * Serialize any List of OFInstruction in JSON. + * + * Use automatically by Jackson via JsonSerialize(using=OFInstructionListSerializer.class), + * or use the static function within this class within another serializer. + * + * @author Ryan Izard, ryan.izard@bigswitch.com, rizard@g.clemson.edu + */ +public class OFInstructionListSerializer extends JsonSerializer<List<OFInstruction>> { + + @Override + public void serialize(List<OFInstruction> instructions, JsonGenerator jGen, SerializerProvider serializer) throws IOException, + JsonProcessingException { + serializeInstructionList(jGen, instructions); + } + + public static void serializeInstructionList(JsonGenerator jGen, List<OFInstruction> instructions) throws IOException, JsonProcessingException { + jGen.writeObjectFieldStart("instructions"); + if (instructions.isEmpty()) { + jGen.writeStringField("none", "drop"); + } else { + for (OFInstruction i : instructions) { + switch (i.getType()) { + case CLEAR_ACTIONS: + jGen.writeObjectFieldStart(InstructionUtils.STR_CLEAR_ACTIONS); + break; + case WRITE_METADATA: + jGen.writeStartObject(); + jGen.writeNumberField(InstructionUtils.STR_WRITE_METADATA, ((OFInstructionWriteMetadata)i).getMetadata().getValue()); + jGen.writeNumberField(InstructionUtils.STR_WRITE_METADATA + "_mask", ((OFInstructionWriteMetadata)i).getMetadataMask().getValue()); + break; + case EXPERIMENTER: + jGen.writeStartObject(); + jGen.writeNumberField(InstructionUtils.STR_EXPERIMENTER, ((OFInstructionExperimenter)i).getExperimenter()); + break; + case GOTO_TABLE: + jGen.writeStartObject(); + jGen.writeNumberField(InstructionUtils.STR_GOTO_TABLE, ((OFInstructionGotoTable)i).getTableId().getValue()); + break; + case METER: + jGen.writeStartObject(); + jGen.writeNumberField(InstructionUtils.STR_GOTO_METER, ((OFInstructionMeter)i).getMeterId()); + break; + case APPLY_ACTIONS: + jGen.writeObjectFieldStart(InstructionUtils.STR_APPLY_ACTIONS); + OFActionListSerializer.serializeActions(jGen, ((OFInstructionApplyActions)i).getActions()); + break; + case WRITE_ACTIONS: + jGen.writeObjectFieldStart(InstructionUtils.STR_WRITE_ACTIONS); + OFActionListSerializer.serializeActions(jGen, ((OFInstructionWriteActions)i).getActions()); + default: + // shouldn't ever get here + break; + } // end switch on instruction + jGen.writeEndObject(); // end specific instruction + } // end for instructions + jGen.writeEndObject(); + } // end process instructions (OF1.1+ only) + } // end not-empty instructions (else) +} 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 e001f62f8bec506d89ebb9bea34e8e8081219e36..b176bbc1cdd86024e5c49f2554067a88db460b4d 100644 --- a/src/main/java/net/floodlightcontroller/core/web/serializers/StatsReplySerializer.java +++ b/src/main/java/net/floodlightcontroller/core/web/serializers/StatsReplySerializer.java @@ -19,7 +19,6 @@ package net.floodlightcontroller.core.web.serializers; import java.io.IOException; import java.util.List; -import java.util.Iterator; import com.fasterxml.jackson.core.JsonGenerator; import com.fasterxml.jackson.core.JsonGenerator.Feature; @@ -29,9 +28,6 @@ import com.fasterxml.jackson.databind.SerializerProvider; import net.floodlightcontroller.core.web.OFStatsTypeStrings; import net.floodlightcontroller.core.web.StatsReply; -import net.floodlightcontroller.util.ActionUtils; -import net.floodlightcontroller.util.InstructionUtils; -import net.floodlightcontroller.util.MatchUtils; import org.projectfloodlight.openflow.protocol.OFFlowStatsReply; import org.projectfloodlight.openflow.protocol.OFFlowStatsEntry; @@ -60,15 +56,18 @@ 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.protocol.match.*; -import org.projectfloodlight.openflow.protocol.oxm.*; -import org.projectfloodlight.openflow.protocol.instruction.*; -import org.projectfloodlight.openflow.protocol.action.*; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** - * Serialize a DPID as colon-separated hexadecimal + * Serialize any OFStatsReply or OFFeaturesReply in JSON + * wrapped by a StatsReply object. + * + * Use automatically by Jackson via JsonSerialize(using=StatsReplySerializer.class), + * or use the static functions within this class to serializer a specific OFStatType + * within another serializer. + * + * @author Ryan Izard, ryan.izard@bigswitch.com, rizard@g.clemson.edu */ public class StatsReplySerializer extends JsonSerializer<StatsReply> { protected static Logger logger = LoggerFactory.getLogger(StatsReplySerializer.class); @@ -105,7 +104,7 @@ public class StatsReplySerializer extends JsonSerializer<StatsReply> { jGen.configure(Feature.WRITE_NUMBERS_AS_STRINGS, true); // IMHO this just looks nicer and is easier to read if everything is quoted jGen.writeStartObject(); - jGen.writeStringField("dpid", reply.getDatapathId().toString()); + //jGen.writeStringField("dpid", reply.getDatapathId().toString()); switch (reply.getStatType()) { case PORT: // handle port @@ -156,7 +155,7 @@ public class StatsReplySerializer extends JsonSerializer<StatsReply> { jGen.writeEndObject(); } - public void serializePortReply(List<OFPortStatsReply> portReplies, JsonGenerator jGen) throws IOException, JsonProcessingException{ + 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 jGen.writeFieldName("port"); @@ -184,7 +183,8 @@ public class StatsReplySerializer extends JsonSerializer<StatsReply> { } jGen.writeEndArray(); } - public void serializeFlowReply(List<OFFlowStatsReply> flowReplies, JsonGenerator jGen) throws IOException, JsonProcessingException{ + + public static void serializeFlowReply(List<OFFlowStatsReply> flowReplies, JsonGenerator jGen) throws IOException, JsonProcessingException{ for (OFFlowStatsReply flowReply : flowReplies) { // for each flow stats reply //Dose the switch will reply multiple OFFlowStatsReply ? //Or we juse need to use the first item of the list. @@ -196,7 +196,7 @@ public class StatsReplySerializer extends JsonSerializer<StatsReply> { // list flow stats/info jGen.writeStringField("version", entry.getVersion().toString()); // return the enum name jGen.writeNumberField("cookie", entry.getCookie().getValue()); - jGen.writeNumberField("tableId", entry.getTableId().getValue()); + jGen.writeStringField("tableId", entry.getTableId().toString()); jGen.writeNumberField("packetCount", entry.getPacketCount().getValue()); jGen.writeNumberField("byteCount", entry.getByteCount().getValue()); jGen.writeNumberField("durationSeconds", entry.getDurationSec()); @@ -224,364 +224,22 @@ public class StatsReplySerializer extends JsonSerializer<StatsReply> { break; } - // list flow matches - jGen.writeObjectFieldStart("match"); - Iterator<MatchField<?>> mi = entry.getMatch().getMatchFields().iterator(); // get iter to any match field type - Match m = entry.getMatch(); - - while (mi.hasNext()) { - MatchField<?> mf = mi.next(); - switch (mf.id) { - case IN_PORT: - jGen.writeNumberField(MatchUtils.STR_IN_PORT, m.get(MatchField.IN_PORT).getPortNumber()); - break; - case IN_PHY_PORT: - jGen.writeNumberField(MatchUtils.STR_IN_PHYS_PORT, m.get(MatchField.IN_PHY_PORT).getPortNumber()); - break; - case ARP_OP: - jGen.writeNumberField(MatchUtils.STR_ARP_OPCODE, m.get(MatchField.ARP_OP).getOpcode()); - break; - case ARP_SHA: - jGen.writeStringField(MatchUtils.STR_ARP_SHA, m.get(MatchField.ARP_SHA).toString()); - break; - case ARP_SPA: - jGen.writeStringField(MatchUtils.STR_ARP_SPA, m.get(MatchField.ARP_SPA).toString()); - break; - case ARP_THA: - jGen.writeStringField(MatchUtils.STR_ARP_DHA, m.get(MatchField.ARP_THA).toString()); - break; - case ARP_TPA: - jGen.writeStringField(MatchUtils.STR_ARP_DPA, m.get(MatchField.ARP_TPA).toString()); - break; - case ETH_TYPE: - jGen.writeNumberField(MatchUtils.STR_DL_TYPE, m.get(MatchField.ETH_TYPE).getValue()); - break; - case ETH_SRC: - jGen.writeStringField(MatchUtils.STR_DL_SRC, m.get(MatchField.ETH_SRC).toString()); - break; - case ETH_DST: - jGen.writeStringField(MatchUtils.STR_DL_DST, m.get(MatchField.ETH_DST).toString()); - break; - case VLAN_VID: - jGen.writeNumberField(MatchUtils.STR_DL_VLAN, m.get(MatchField.VLAN_VID).getVlan()); - break; - case VLAN_PCP: - jGen.writeNumberField(MatchUtils.STR_DL_VLAN_PCP, m.get(MatchField.VLAN_PCP).getValue()); - break; - case ICMPV4_TYPE: - jGen.writeNumberField(MatchUtils.STR_ICMP_TYPE, m.get(MatchField.ICMPV4_TYPE).getType()); - break; - case ICMPV4_CODE: - jGen.writeNumberField(MatchUtils.STR_ICMP_CODE, m.get(MatchField.ICMPV4_CODE).getCode()); - break; - case ICMPV6_TYPE: - jGen.writeNumberField(MatchUtils.STR_ICMPV6_TYPE, m.get(MatchField.ICMPV6_TYPE).getValue()); - break; - case ICMPV6_CODE: - jGen.writeNumberField(MatchUtils.STR_ICMPV6_CODE, m.get(MatchField.ICMPV6_CODE).getValue()); - break; - case IP_DSCP: - jGen.writeNumberField(MatchUtils.STR_NW_DSCP, m.get(MatchField.IP_DSCP).getDscpValue()); - break; - case IP_ECN: - jGen.writeNumberField(MatchUtils.STR_NW_ECN, m.get(MatchField.IP_ECN).getEcnValue()); - break; - case IP_PROTO: - jGen.writeNumberField(MatchUtils.STR_NW_PROTO, m.get(MatchField.IP_PROTO).getIpProtocolNumber()); - break; - case IPV4_SRC: - jGen.writeStringField(MatchUtils.STR_NW_SRC, m.get(MatchField.IPV4_SRC).toString()); - break; - case IPV4_DST: - jGen.writeStringField(MatchUtils.STR_NW_DST, m.get(MatchField.IPV4_DST).toString()); - break; - case IPV6_SRC: - jGen.writeStringField(MatchUtils.STR_IPV6_SRC, m.get(MatchField.IPV6_SRC).toString()); - break; - case IPV6_DST: - jGen.writeStringField(MatchUtils.STR_IPV6_DST, m.get(MatchField.IPV6_DST).toString()); - break; - case IPV6_FLABEL: - jGen.writeNumberField(MatchUtils.STR_IPV6_FLOW_LABEL, m.get(MatchField.IPV6_FLABEL).getIPv6FlowLabelValue()); - break; - case IPV6_ND_SLL: - jGen.writeNumberField(MatchUtils.STR_IPV6_ND_SSL, m.get(MatchField.IPV6_ND_SLL).getLong()); - break; - case IPV6_ND_TARGET: - jGen.writeNumberField(MatchUtils.STR_IPV6_ND_TARGET, m.get(MatchField.IPV6_ND_TARGET).getZeroCompressStart()); - break; - case IPV6_ND_TLL: - jGen.writeNumberField(MatchUtils.STR_IPV6_ND_TTL, m.get(MatchField.IPV6_ND_TLL).getLong()); - break; - case METADATA: - jGen.writeNumberField(MatchUtils.STR_METADATA, m.get(MatchField.METADATA).getValue().getValue()); - break; - case MPLS_LABEL: - jGen.writeNumberField(MatchUtils.STR_MPLS_LABEL, m.get(MatchField.MPLS_LABEL).getValue()); - break; - case MPLS_TC: - jGen.writeNumberField(MatchUtils.STR_MPLS_TC, m.get(MatchField.MPLS_TC).getValue()); - break; - case SCTP_SRC: - jGen.writeNumberField(MatchUtils.STR_SCTP_SRC, m.get(MatchField.SCTP_SRC).getPort()); - break; - case SCTP_DST: - jGen.writeNumberField(MatchUtils.STR_SCTP_DST, m.get(MatchField.SCTP_DST).getPort()); - break; - case TCP_SRC: - jGen.writeNumberField(MatchUtils.STR_TCP_SRC, m.get(MatchField.TCP_SRC).getPort()); - break; - case TCP_DST: - jGen.writeNumberField(MatchUtils.STR_TCP_DST, m.get(MatchField.TCP_DST).getPort()); - break; - case UDP_SRC: - jGen.writeNumberField(MatchUtils.STR_UDP_SRC, m.get(MatchField.UDP_SRC).getPort()); - break; - case UDP_DST: - jGen.writeNumberField(MatchUtils.STR_UDP_DST, m.get(MatchField.UDP_DST).getPort()); - break; - default: - // either a BSN or unknown match type - break; - } // end switch of match type - } // end while over non-wildcarded matches - - jGen.writeEndObject(); // end match + MatchSerializer.serializeMatch(jGen, entry.getMatch()); // handle OF1.1+ instructions with actions within if (entry.getVersion() == OFVersion.OF_10) { - serializeActions(jGen, entry.getActions()); + OFActionListSerializer.serializeActions(jGen, entry.getActions()); } else { - List<OFInstruction> instructions = entry.getInstructions(); - jGen.writeObjectFieldStart("instructions"); - if (instructions.isEmpty()) { - jGen.writeStringField("none", "drop"); - } else { - for (OFInstruction i : instructions) { - switch (i.getType()) { - case CLEAR_ACTIONS: - jGen.writeObjectFieldStart(InstructionUtils.STR_CLEAR_ACTIONS); - break; - case WRITE_METADATA: - jGen.writeStartObject(); - jGen.writeNumberField(InstructionUtils.STR_WRITE_METADATA, ((OFInstructionWriteMetadata)i).getMetadata().getValue()); - jGen.writeNumberField(InstructionUtils.STR_WRITE_METADATA + "_mask", ((OFInstructionWriteMetadata)i).getMetadataMask().getValue()); - break; - case EXPERIMENTER: - jGen.writeStartObject(); - jGen.writeNumberField(InstructionUtils.STR_EXPERIMENTER, ((OFInstructionExperimenter)i).getExperimenter()); - break; - case GOTO_TABLE: - jGen.writeStartObject(); - jGen.writeNumberField(InstructionUtils.STR_GOTO_TABLE, ((OFInstructionGotoTable)i).getTableId().getValue()); - break; - case METER: - jGen.writeStartObject(); - jGen.writeNumberField(InstructionUtils.STR_GOTO_METER, ((OFInstructionMeter)i).getMeterId()); - break; - case APPLY_ACTIONS: - jGen.writeObjectFieldStart(InstructionUtils.STR_APPLY_ACTIONS); - serializeActions(jGen, ((OFInstructionApplyActions)i).getActions()); - break; - case WRITE_ACTIONS: - jGen.writeObjectFieldStart(InstructionUtils.STR_WRITE_ACTIONS); - serializeActions(jGen, ((OFInstructionWriteActions)i).getActions()); - default: - // shouldn't ever get here - break; - } // end switch on instruction - jGen.writeEndObject(); // end specific instruction - } // end for instructions - jGen.writeEndObject(); - } // end process instructions (OF1.1+ only) - } // end not-empty instructions (else) + OFInstructionListSerializer.serializeInstructionList(jGen, entry.getInstructions()); + } + jGen.writeEndObject(); } // end for each OFFlowStatsReply entry jGen.writeEndArray(); } // end for each OFStatsReply } // end method - /** - * Write a JSON string given a list of OFAction. Supports OF1.0 - OF1.3. - * This is the only place actions are serialized, for any OF version. Because - * some OF version share actions, it makes sense to have them in one place. - * @param jsonGenerator - * @param actions - * @throws IOException - * @throws JsonProcessingException - */ - public void serializeActions(JsonGenerator jsonGenerator, List<OFAction> actions) throws IOException, JsonProcessingException { - //jsonGenerator.writeStartObject(); - if (actions.isEmpty()) { - jsonGenerator.writeStringField("none", "drop"); - } - for (OFAction a : actions) { - switch (a.getType()) { - case OUTPUT: - jsonGenerator.writeNumberField(ActionUtils.STR_OUTPUT, ((OFActionOutput)a).getPort().getPortNumber()); - break; - /* begin OF1.0 ONLY actions */ - case SET_VLAN_VID: - jsonGenerator.writeNumberField(ActionUtils.STR_VLAN_SET_VID, ((OFActionSetVlanVid)a).getVlanVid().getVlan()); - break; - case SET_VLAN_PCP: - jsonGenerator.writeNumberField(ActionUtils.STR_VLAN_SET_PCP, ((OFActionSetVlanPcp)a).getVlanPcp().getValue()); - break; - case SET_QUEUE: - jsonGenerator.writeNumberField(ActionUtils.STR_QUEUE_SET, ((OFActionSetQueue)a).getQueueId()); - break; - case SET_DL_SRC: - jsonGenerator.writeStringField(ActionUtils.STR_DL_SRC_SET, ((OFActionSetDlSrc)a).getDlAddr().toString()); - break; - case SET_DL_DST: - jsonGenerator.writeStringField(ActionUtils.STR_DL_DST_SET, ((OFActionSetDlDst)a).getDlAddr().toString()); - break; - case SET_NW_SRC: - jsonGenerator.writeStringField(ActionUtils.STR_NW_SRC_SET, ((OFActionSetNwSrc)a).getNwAddr().toString()); - break; - case SET_NW_DST: - jsonGenerator.writeStringField(ActionUtils.STR_NW_DST_SET, ((OFActionSetNwDst)a).getNwAddr().toString()); - break; - case SET_NW_TOS: - jsonGenerator.writeNumberField(ActionUtils.STR_NW_TOS_SET, ((OFActionSetNwTos)a).getNwTos()); - break; - case SET_TP_SRC: - jsonGenerator.writeNumberField(ActionUtils.STR_TP_SRC_SET, ((OFActionSetTpSrc)a).getTpPort().getPort()); - break; - case SET_TP_DST: - jsonGenerator.writeNumberField(ActionUtils.STR_TP_DST_SET, ((OFActionSetTpDst)a).getTpPort().getPort()); - break; - /* end OF1.0 ONLY actions; begin OF1.1+ actions */ - case ENQUEUE: - jsonGenerator.writeNumberField(ActionUtils.STR_ENQUEUE, ((OFActionEnqueue)a).getPort().getPortNumber()); - break; - case GROUP: - jsonGenerator.writeNumberField(ActionUtils.STR_GROUP, ((OFActionGroup)a).getGroup().getGroupNumber()); - break; - case STRIP_VLAN: - jsonGenerator.writeString(ActionUtils.STR_VLAN_STRIP); - break; - case PUSH_VLAN: - jsonGenerator.writeNumberField(ActionUtils.STR_VLAN_PUSH, ((OFActionPushVlan)a).getEthertype().getValue()); - break; - case PUSH_MPLS: - jsonGenerator.writeNumberField(ActionUtils.STR_MPLS_PUSH, ((OFActionPushMpls)a).getEthertype().getValue()); - break; - case PUSH_PBB: - jsonGenerator.writeNumberField(ActionUtils.STR_PBB_PUSH, ((OFActionPushPbb)a).getEthertype().getValue()); - break; - case POP_VLAN: - jsonGenerator.writeString(ActionUtils.STR_VLAN_POP); - break; - case POP_MPLS: - jsonGenerator.writeNumberField(ActionUtils.STR_MPLS_POP, ((OFActionPopMpls)a).getEthertype().getValue()); - break; - case POP_PBB: - jsonGenerator.writeString(ActionUtils.STR_PBB_POP); - break; - case COPY_TTL_IN: - jsonGenerator.writeString(ActionUtils.STR_TTL_IN_COPY); - break; - case COPY_TTL_OUT: - jsonGenerator.writeString(ActionUtils.STR_TTL_OUT_COPY); - break; - case DEC_NW_TTL: - jsonGenerator.writeString(ActionUtils.STR_NW_TTL_DEC); - break; - case DEC_MPLS_TTL: - jsonGenerator.writeString(ActionUtils.STR_MPLS_TTL_DEC); - break; - case SET_MPLS_LABEL: - jsonGenerator.writeNumberField(ActionUtils.STR_MPLS_LABEL_SET, ((OFActionSetMplsLabel)a).getMplsLabel()); - break; - case SET_MPLS_TC: - jsonGenerator.writeNumberField(ActionUtils.STR_MPLS_TC_SET, ((OFActionSetMplsTc)a).getMplsTc()); - break; - case SET_MPLS_TTL: - jsonGenerator.writeNumberField(ActionUtils.STR_MPLS_TTL_SET, ((OFActionSetMplsTtl)a).getMplsTtl()); - break; - case SET_NW_ECN: - jsonGenerator.writeNumberField(ActionUtils.STR_NW_ECN_SET, ((OFActionSetNwEcn)a).getNwEcn().getEcnValue()); - break; - case SET_NW_TTL: - jsonGenerator.writeNumberField(ActionUtils.STR_NW_TTL_SET, ((OFActionSetNwTtl)a).getNwTtl()); - break; - case EXPERIMENTER: - jsonGenerator.writeNumberField(ActionUtils.STR_EXPERIMENTER, ((OFActionExperimenter)a).getExperimenter()); - break; - case SET_FIELD: - if (((OFActionSetField)a).getField() instanceof OFOxmArpOp) { - jsonGenerator.writeNumberField(MatchUtils.STR_ARP_OPCODE, ((OFOxmArpOp) ((OFActionSetField) a).getField()).getValue().getOpcode()); - } else if (((OFActionSetField)a).getField() instanceof OFOxmArpSha) { - jsonGenerator.writeStringField(MatchUtils.STR_ARP_SHA, ((OFOxmArpSha) ((OFActionSetField) a).getField()).getValue().toString()); // macaddress formats string already - } else if (((OFActionSetField)a).getField() instanceof OFOxmArpTha) { - jsonGenerator.writeStringField(MatchUtils.STR_ARP_DHA, ((OFOxmArpTha) ((OFActionSetField) a).getField()).getValue().toString()); - } else if (((OFActionSetField)a).getField() instanceof OFOxmArpSpa) { - jsonGenerator.writeStringField(MatchUtils.STR_ARP_SPA, ((OFOxmArpSpa) ((OFActionSetField) a).getField()).getValue().toString()); // ipaddress formats string already - } else if (((OFActionSetField)a).getField() instanceof OFOxmArpTpa) { - jsonGenerator.writeStringField(MatchUtils.STR_ARP_DPA, ((OFOxmArpTpa) ((OFActionSetField) a).getField()).getValue().toString()); - } - /* DATA LAYER */ - else if (((OFActionSetField)a).getField() instanceof OFOxmEthType) { - jsonGenerator.writeNumberField(MatchUtils.STR_DL_TYPE, ((OFOxmEthType) ((OFActionSetField) a).getField()).getValue().getValue()); - } else if (((OFActionSetField)a).getField() instanceof OFOxmEthSrc) { - jsonGenerator.writeStringField(MatchUtils.STR_DL_SRC, ((OFOxmEthSrc) ((OFActionSetField) a).getField()).getValue().toString()); - } else if (((OFActionSetField)a).getField() instanceof OFOxmEthDst) { - jsonGenerator.writeStringField(MatchUtils.STR_DL_DST, ((OFOxmEthDst) ((OFActionSetField) a).getField()).getValue().toString()); - } else if (((OFActionSetField)a).getField() instanceof OFOxmVlanVid) { - jsonGenerator.writeNumberField(MatchUtils.STR_DL_VLAN, ((OFOxmVlanVid) ((OFActionSetField) a).getField()).getValue().getVlan()); - } else if (((OFActionSetField)a).getField() instanceof OFOxmVlanPcp) { - } - /* ICMP */ - else if (((OFActionSetField)a).getField() instanceof OFOxmIcmpv4Code) { - jsonGenerator.writeNumberField(MatchUtils.STR_ICMP_CODE, ((OFOxmIcmpv4Code) ((OFActionSetField) a).getField()).getValue().getCode()); - } else if (((OFActionSetField)a).getField() instanceof OFOxmIcmpv4Type) { - jsonGenerator.writeNumberField(MatchUtils.STR_ICMP_TYPE, ((OFOxmIcmpv4Type) ((OFActionSetField) a).getField()).getValue().getType()); - } - /* NETWORK LAYER */ - else if (((OFActionSetField)a).getField() instanceof OFOxmIpProto) { - jsonGenerator.writeNumberField(MatchUtils.STR_NW_PROTO, ((OFOxmIpProto) ((OFActionSetField) a).getField()).getValue().getIpProtocolNumber()); - } else if (((OFActionSetField)a).getField() instanceof OFOxmIpv4Src) { - jsonGenerator.writeStringField(MatchUtils.STR_NW_SRC, ((OFOxmIpv4Src) ((OFActionSetField) a).getField()).getValue().toString()); - } else if (((OFActionSetField)a).getField() instanceof OFOxmIpv4Dst) { - jsonGenerator.writeStringField(MatchUtils.STR_NW_DST, ((OFOxmIpv4Dst) ((OFActionSetField) a).getField()).getValue().toString()); - } else if (((OFActionSetField)a).getField() instanceof OFOxmIpEcn) { - jsonGenerator.writeNumberField(MatchUtils.STR_NW_ECN, ((OFOxmIpEcn) ((OFActionSetField) a).getField()).getValue().getEcnValue()); - } else if (((OFActionSetField)a).getField() instanceof OFOxmIpDscp) { - jsonGenerator.writeNumberField(MatchUtils.STR_NW_DSCP, ((OFOxmIpDscp) ((OFActionSetField) a).getField()).getValue().getDscpValue()); - } - /* TRANSPORT LAYER, TCP, UDP, and SCTP */ - else if (((OFActionSetField)a).getField() instanceof OFOxmTcpSrc) { - jsonGenerator.writeNumberField(MatchUtils.STR_TCP_SRC, ((OFOxmTcpSrc) ((OFActionSetField) a).getField()).getValue().getPort()); - } else if (((OFActionSetField)a).getField() instanceof OFOxmTcpDst) { - jsonGenerator.writeNumberField(MatchUtils.STR_TCP_DST, ((OFOxmTcpDst) ((OFActionSetField) a).getField()).getValue().getPort()); - } else if (((OFActionSetField)a).getField() instanceof OFOxmUdpSrc) { - jsonGenerator.writeNumberField(MatchUtils.STR_UDP_SRC, ((OFOxmUdpSrc) ((OFActionSetField) a).getField()).getValue().getPort()); - } else if (((OFActionSetField)a).getField() instanceof OFOxmUdpDst) { - jsonGenerator.writeNumberField(MatchUtils.STR_UDP_DST, ((OFOxmUdpDst) ((OFActionSetField) a).getField()).getValue().getPort()); - } else if (((OFActionSetField)a).getField() instanceof OFOxmSctpSrc) { - jsonGenerator.writeNumberField(MatchUtils.STR_SCTP_SRC, ((OFOxmSctpSrc) ((OFActionSetField) a).getField()).getValue().getPort()); - } else if (((OFActionSetField)a).getField() instanceof OFOxmSctpDst) { - jsonGenerator.writeNumberField(MatchUtils.STR_SCTP_DST, ((OFOxmSctpDst) ((OFActionSetField) a).getField()).getValue().getPort()); - } - /* MPLS */ - else if (((OFActionSetField)a).getField() instanceof OFOxmMplsLabel) { - jsonGenerator.writeNumberField(MatchUtils.STR_MPLS_LABEL, ((OFOxmMplsLabel) ((OFActionSetField) a).getField()).getValue().getValue()); - } else if (((OFActionSetField)a).getField() instanceof OFOxmMplsTc) { - jsonGenerator.writeNumberField(MatchUtils.STR_MPLS_TC, ((OFOxmMplsTc) ((OFActionSetField) a).getField()).getValue().getValue()); - } // MPLS_BOS not implemented in loxi - /* METADATA */ - else if (((OFActionSetField)a).getField() instanceof OFOxmMetadata) { - jsonGenerator.writeNumberField(MatchUtils.STR_METADATA, ((OFOxmMetadata) ((OFActionSetField) a).getField()).getValue().getValue().getValue()); - } else { - logger.error("Could not decode Set-Field action field: {}", ((OFActionSetField) a)); - // need to get a logger in here somehow log.error("Could not decode Set-Field action field: {}", ((OFActionSetField) a)); - } - } // end switch over action type - } // end for over all actions - } // end method - - public void serializeDescReply(List<OFDescStatsReply> descReplies, JsonGenerator jGen) throws IOException, JsonProcessingException{ + public static void serializeDescReply(List<OFDescStatsReply> descReplies, JsonGenerator jGen) throws IOException, JsonProcessingException{ OFDescStatsReply descReply = descReplies.get(0); // There are only one descReply from the switch jGen.writeObjectFieldStart("desc"); jGen.writeStringField("version", descReply.getVersion().toString()); //return the enum name @@ -592,7 +250,8 @@ public class StatsReplySerializer extends JsonSerializer<StatsReply> { jGen.writeStringField("datapathDescription", descReply.getDpDesc()); jGen.writeEndObject(); // end match } - public void serializeAggregateReply(List<OFAggregateStatsReply> aggregateReplies, JsonGenerator jGen) throws IOException, JsonProcessingException{ + + public static void serializeAggregateReply(List<OFAggregateStatsReply> aggregateReplies, JsonGenerator jGen) throws IOException, JsonProcessingException{ OFAggregateStatsReply aggregateReply = aggregateReplies.get(0); // There are only one aggregateReply from the switch jGen.writeObjectFieldStart("aggregate"); jGen.writeStringField("version", aggregateReply.getVersion().toString()); //return the enum name @@ -602,7 +261,7 @@ public class StatsReplySerializer extends JsonSerializer<StatsReply> { jGen.writeEndObject(); // end match } - public void serializePortDescReply(List<OFPortDescStatsReply> portDescReplies, JsonGenerator jGen) throws IOException, JsonProcessingException{ + public static void serializePortDescReply(List<OFPortDescStatsReply> portDescReplies, JsonGenerator jGen) throws IOException, JsonProcessingException{ OFPortDescStatsReply portDescReply = portDescReplies.get(0); // we will get only one PortDescReply and it will contains many OFPortDescStatsEntry ? jGen.writeStringField("version", portDescReply.getVersion().toString()); //return the enum name jGen.writeFieldName("portDesc"); diff --git a/src/main/java/net/floodlightcontroller/staticflowentry/web/OFFlowModMap.java b/src/main/java/net/floodlightcontroller/staticflowentry/web/OFFlowModMap.java index d79e7817c76b8dc8b2e114cdf99bf6fe73fdd9d8..f91fdedc36e0c5cefe68955e2ad27602df91cbdf 100644 --- a/src/main/java/net/floodlightcontroller/staticflowentry/web/OFFlowModMap.java +++ b/src/main/java/net/floodlightcontroller/staticflowentry/web/OFFlowModMap.java @@ -1,7 +1,6 @@ package net.floodlightcontroller.staticflowentry.web; import java.util.Map; -import net.floodlightcontroller.core.web.serializers.OFFlowModMapSerializer; import org.projectfloodlight.openflow.protocol.OFFlowMod; diff --git a/src/main/java/net/floodlightcontroller/core/web/serializers/OFFlowModMapSerializer.java b/src/main/java/net/floodlightcontroller/staticflowentry/web/OFFlowModMapSerializer.java similarity index 78% rename from src/main/java/net/floodlightcontroller/core/web/serializers/OFFlowModMapSerializer.java rename to src/main/java/net/floodlightcontroller/staticflowentry/web/OFFlowModMapSerializer.java index 853c9d7f8e9e170d222d77e9fb7505db0417d7b1..368716790868845ded5ab967568fc02d81d5df8e 100644 --- a/src/main/java/net/floodlightcontroller/core/web/serializers/OFFlowModMapSerializer.java +++ b/src/main/java/net/floodlightcontroller/staticflowentry/web/OFFlowModMapSerializer.java @@ -1,14 +1,15 @@ -package net.floodlightcontroller.core.web.serializers; +package net.floodlightcontroller.staticflowentry.web; import java.io.IOException; import java.util.Map; -import net.floodlightcontroller.staticflowentry.web.OFFlowModMap; +import net.floodlightcontroller.core.web.serializers.OFFlowModSerializer; import org.projectfloodlight.openflow.protocol.OFFlowMod; import com.fasterxml.jackson.core.JsonGenerator; import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.core.JsonGenerator.Feature; import com.fasterxml.jackson.databind.JsonSerializer; import com.fasterxml.jackson.databind.SerializerProvider; @@ -29,6 +30,8 @@ public class OFFlowModMapSerializer extends JsonSerializer<OFFlowModMap> { @Override public void serialize(OFFlowModMap fmm, JsonGenerator jGen, SerializerProvider serializer) throws IOException, JsonProcessingException { + + jGen.configure(Feature.WRITE_NUMBERS_AS_STRINGS, true); // IMHO this just looks nicer and is easier to read if everything is quoted if (fmm == null) { jGen.writeStartObject(); @@ -38,7 +41,6 @@ public class OFFlowModMapSerializer extends JsonSerializer<OFFlowModMap> { } Map<String, Map<String, OFFlowMod>> theMap = fmm.getMap(); - OFFlowModSerializer fms = new OFFlowModSerializer(); jGen.writeStartObject(); if (theMap.keySet() != null) { @@ -47,9 +49,8 @@ public class OFFlowModMapSerializer extends JsonSerializer<OFFlowModMap> { jGen.writeArrayFieldStart(dpid); for (String name : theMap.get(dpid).keySet()) { jGen.writeStartObject(); - jGen.writeArrayFieldStart(name); - fms.serialize(theMap.get(dpid).get(name), jGen, serializer); - jGen.writeEndArray(); + jGen.writeFieldName(name); + OFFlowModSerializer.serializeFlowMod(jGen, theMap.get(dpid).get(name)); jGen.writeEndObject(); } jGen.writeEndArray(); diff --git a/src/main/java/net/floodlightcontroller/testmodule/TestModule.java b/src/main/java/net/floodlightcontroller/testmodule/TestModule.java index 0949bf55535891c0ce839e5c2a19a27ec529f96f..3c345ce6ab6ab0042b1818f456417f0884d6abd3 100644 --- a/src/main/java/net/floodlightcontroller/testmodule/TestModule.java +++ b/src/main/java/net/floodlightcontroller/testmodule/TestModule.java @@ -3,6 +3,7 @@ package net.floodlightcontroller.testmodule; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; +import java.util.HashSet; import java.util.List; import java.util.Map; @@ -11,11 +12,18 @@ import org.projectfloodlight.openflow.protocol.OFFactory; import org.projectfloodlight.openflow.protocol.OFFlowAdd; import org.projectfloodlight.openflow.protocol.OFMeterBandStats; import org.projectfloodlight.openflow.protocol.OFMeterBandType; +import org.projectfloodlight.openflow.protocol.OFMeterConfig; import org.projectfloodlight.openflow.protocol.OFMeterMod; import org.projectfloodlight.openflow.protocol.OFMeterModCommand; import org.projectfloodlight.openflow.protocol.OFOxmClass; import org.projectfloodlight.openflow.protocol.OFPortDesc; import org.projectfloodlight.openflow.protocol.OFSetConfig; +import org.projectfloodlight.openflow.protocol.OFTableFeaturePropWriteActions; +import org.projectfloodlight.openflow.protocol.OFTableFeaturePropWriteSetfield; +import org.projectfloodlight.openflow.protocol.OFTableMod; +import org.projectfloodlight.openflow.protocol.OFTableModProp; +import org.projectfloodlight.openflow.protocol.OFTableModPropEviction; +import org.projectfloodlight.openflow.protocol.OFTableModPropEvictionFlag; import org.projectfloodlight.openflow.protocol.OFVersion; import org.projectfloodlight.openflow.protocol.action.OFAction; import org.projectfloodlight.openflow.protocol.action.OFActionOutput; @@ -59,6 +67,8 @@ import org.projectfloodlight.openflow.types.VlanVid; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import com.google.common.collect.ImmutableList; + import net.floodlightcontroller.core.IOFSwitchListener; import net.floodlightcontroller.core.PortChangeType; import net.floodlightcontroller.core.internal.IOFSwitchService; @@ -114,7 +124,36 @@ public class TestModule implements IFloodlightModule, IOFSwitchListener { @Override public void switchAdded(DatapathId switchId) { OFFactory factory = switchService.getSwitch(switchId).getOFFactory(); - OFFlowAdd.Builder fmb = factory.buildFlowAdd(); + + /* + * An attempt at meters, but they aren't supported anywhere, yet... + * OFMeterBand mb = factory.meterBands().buildDrop() + .setRate(1000) + .setBurstSize(1000) + .build(); + ArrayList<OFMeterBand> mbl = new ArrayList<OFMeterBand>(); + mbl.add(mb); + + OFMeterMod mm = factory.buildMeterMod() + .setMeters(mbl) + .setMeterId(1) + .setCommand(0) + .build(); */ + + /*HashSet<OFTableModPropEvictionFlag> efs = new HashSet<OFTableModPropEvictionFlag>(); + efs.add(OFTableModPropEvictionFlag.IMPORTANCE); + + ArrayList<OFTableModProp> tabModPropList = new ArrayList<OFTableModProp>(); + OFTableFeaturePropWriteActions propEvic = switchService.getActiveSwitch(switchId).getOFFactory().buildTableFeaturePropWriteActions() + .setActionIds(actionIds) + .build(); + tabModPropList.add(propEvic); + OFTableMod tm = switchService.getActiveSwitch(switchId).getOFFactory().buildTableMod() + .setProperties(pro) + + switchService.getActiveSwitch(switchId).write(mm);*/ + + /*OFFlowAdd.Builder fmb = factory.buildFlowAdd(); List<OFAction> actions = new ArrayList<OFAction>(); Match.Builder mb = factory.buildMatch(); List<OFInstruction> instructions = new ArrayList<OFInstruction>(); @@ -166,7 +205,7 @@ public class TestModule implements IFloodlightModule, IOFSwitchListener { actions.add(factory.actions().setField(factory.oxms().arpTpa(IPv4Address.of("255.255.255.255")))); fmb.setTableId(TableId.of(16)); */ - /* TP, IP OPT, VLAN TESTS */ mb.setExact(MatchField.ETH_TYPE, EthType.IPv4); + /* TP, IP OPT, VLAN TESTS mb.setExact(MatchField.ETH_TYPE, EthType.IPv4); mb.setExact(MatchField.VLAN_PCP, VlanPcp.of((byte) 1)); // might as well test these now too //mb.setExact(MatchField.VLAN_VID, OFVlanVidMatch.ofVlan(512)); mb.setExact(MatchField.MPLS_LABEL, U32.of(32)); @@ -202,17 +241,17 @@ public class TestModule implements IFloodlightModule, IOFSwitchListener { actions.add(factory.actions().setField(factory.oxms().mplsTc(U8.ZERO))); */ /* METADATA TEST - mb.setExact(MatchField.METADATA, OFMetadata.ofRaw(1)); */ + mb.setExact(MatchField.METADATA, OFMetadata.ofRaw(1)); //fmb.setActions(actions); // this will automatically create the apply actions instruction applyActInstBldr.setActions(actions); //mtrBldr.setMeterId(1); instructions.add(applyActInstBldr.build()); //instructions.add(mtrBldr.build()); fmb.setInstructions(instructions); - fmb.setMatch(mb.build()); + fmb.setMatch(mb.build()); sfps.addFlow("test-flow", fmb.build(), switchId); - //sfps.deleteFlow("test-flow"); + //sfps.deleteFlow("test-flow"); */ }