From 82c3cbb989bacdcca3814a0b5601cc812ee57d6b Mon Sep 17 00:00:00 2001
From: Ryan Izard <rizard@g.clemson.edu>
Date: Fri, 29 May 2015 14:05:15 -0400
Subject: [PATCH] Comma-delimited now. There will be an issue if a key is
 invalid, but this is a good start. If a key is invalid, we might output a
 double-comma where the key would have normally been inbetween.

---
 .../serializers/OFActionListSerializer.java   | 146 +++++++++---------
 .../StaticFlowEntryPusher.java                |  33 ++--
 2 files changed, 98 insertions(+), 81 deletions(-)

diff --git a/src/main/java/net/floodlightcontroller/core/web/serializers/OFActionListSerializer.java b/src/main/java/net/floodlightcontroller/core/web/serializers/OFActionListSerializer.java
index 394966f39..e0cbf88e0 100644
--- a/src/main/java/net/floodlightcontroller/core/web/serializers/OFActionListSerializer.java
+++ b/src/main/java/net/floodlightcontroller/core/web/serializers/OFActionListSerializer.java
@@ -41,7 +41,6 @@ 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.OFOxmIcmpv6Code;
 import org.projectfloodlight.openflow.protocol.oxm.OFOxmIcmpv6Type;
 import org.projectfloodlight.openflow.protocol.oxm.OFOxmIpDscp;
@@ -49,7 +48,6 @@ 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.OFOxmIpv6Dst;
 import org.projectfloodlight.openflow.protocol.oxm.OFOxmIpv6Flabel;
 import org.projectfloodlight.openflow.protocol.oxm.OFOxmIpv6NdSll;
@@ -105,191 +103,199 @@ public class OFActionListSerializer extends JsonSerializer<List<OFAction>> {
      * @throws JsonProcessingException
      */
     public static void serializeActions(JsonGenerator jsonGenerator, List<OFAction> actions) throws IOException, JsonProcessingException {
-        if (actions.isEmpty()) {
-            jsonGenerator.writeStringField("none", "drop");
-        }
         StringBuilder sb = new StringBuilder();
+        int len = actions.size();
+        int pos = 0;
         for (OFAction a : actions) {
             switch (a.getType()) {
             case OUTPUT:
-                sb.append(ActionUtils.STR_OUTPUT).append(((OFActionOutput)a).getPort().toString());
+                sb.append(ActionUtils.STR_OUTPUT).append("=").append(((OFActionOutput)a).getPort().toString());
                 break;
             /* begin OF1.0 ONLY actions */
             case SET_VLAN_VID:
-                sb.append(ActionUtils.STR_VLAN_SET_VID).append(((OFActionSetVlanVid)a).getVlanVid().getVlan());
+                sb.append(ActionUtils.STR_VLAN_SET_VID).append("=").append(((OFActionSetVlanVid)a).getVlanVid().getVlan());
                 break;
             case SET_VLAN_PCP:
-                sb.append(ActionUtils.STR_VLAN_SET_PCP).append(((OFActionSetVlanPcp)a).getVlanPcp().getValue());
+                sb.append(ActionUtils.STR_VLAN_SET_PCP).append("=").append(((OFActionSetVlanPcp)a).getVlanPcp().getValue());
                 break;
             case SET_QUEUE:
-                sb.append(ActionUtils.STR_QUEUE_SET).append(((OFActionSetQueue)a).getQueueId());
+                sb.append(ActionUtils.STR_QUEUE_SET).append("=").append(((OFActionSetQueue)a).getQueueId());
                 break;
             case SET_DL_SRC:
-                sb.append(ActionUtils.STR_DL_SRC_SET).append(((OFActionSetDlSrc)a).getDlAddr().toString());
+                sb.append(ActionUtils.STR_DL_SRC_SET).append("=").append(((OFActionSetDlSrc)a).getDlAddr().toString());
                 break;
             case SET_DL_DST:
-                sb.append(ActionUtils.STR_DL_DST_SET).append(((OFActionSetDlDst)a).getDlAddr().toString());
+                sb.append(ActionUtils.STR_DL_DST_SET).append("=").append(((OFActionSetDlDst)a).getDlAddr().toString());
                 break;
             case SET_NW_SRC:
-                sb.append(ActionUtils.STR_NW_SRC_SET).append(((OFActionSetNwSrc)a).getNwAddr().toString());
+                sb.append(ActionUtils.STR_NW_SRC_SET).append("=").append(((OFActionSetNwSrc)a).getNwAddr().toString());
                 break;
             case SET_NW_DST:
-                sb.append(ActionUtils.STR_NW_DST_SET).append(((OFActionSetNwDst)a).getNwAddr().toString());
+                sb.append(ActionUtils.STR_NW_DST_SET).append("=").append(((OFActionSetNwDst)a).getNwAddr().toString());
                 break;
             case SET_NW_TOS:
-            	sb.append(ActionUtils.STR_NW_TOS_SET).append(((OFActionSetNwTos)a).getNwTos());
+            	sb.append(ActionUtils.STR_NW_TOS_SET).append("=").append(((OFActionSetNwTos)a).getNwTos());
                 break;    
             case SET_TP_SRC:
-            	sb.append(ActionUtils.STR_TP_SRC_SET).append(((OFActionSetTpSrc)a).getTpPort().getPort());
+            	sb.append(ActionUtils.STR_TP_SRC_SET).append("=").append(((OFActionSetTpSrc)a).getTpPort().getPort());
                 break;
             case SET_TP_DST:
-            	sb.append(ActionUtils.STR_TP_DST_SET).append(((OFActionSetTpDst)a).getTpPort().getPort());
+            	sb.append(ActionUtils.STR_TP_DST_SET).append("=").append(((OFActionSetTpDst)a).getTpPort().getPort());
                 break;
             /* end OF1.0 ONLY actions; begin OF1.1+ actions */
             case ENQUEUE:
-                sb.append(ActionUtils.STR_ENQUEUE).append(((OFActionEnqueue)a).getPort().getPortNumber());
+                sb.append(ActionUtils.STR_ENQUEUE).append("=").append(((OFActionEnqueue)a).getPort().getPortNumber());
                 break;
             case GROUP:
-            	sb.append(ActionUtils.STR_GROUP).append(((OFActionGroup)a).getGroup().toString());
+            	sb.append(ActionUtils.STR_GROUP).append("=").append(((OFActionGroup)a).getGroup().toString());
                 break;
             case STRIP_VLAN:
-            	sb.append(ActionUtils.STR_VLAN_STRIP).append(ActionUtils.STR_NOT_APPLICABLE);
+            	sb.append(ActionUtils.STR_VLAN_STRIP).append("=").append(ActionUtils.STR_NOT_APPLICABLE);
                 break;
             case PUSH_VLAN:
-            	sb.append(ActionUtils.STR_VLAN_PUSH).append(((OFActionPushVlan)a).getEthertype().getValue());
+            	sb.append(ActionUtils.STR_VLAN_PUSH).append("=").append(((OFActionPushVlan)a).getEthertype().getValue());
                 break;
             case PUSH_MPLS:
-            	sb.append(ActionUtils.STR_MPLS_PUSH).append(((OFActionPushMpls)a).getEthertype().getValue());
+            	sb.append(ActionUtils.STR_MPLS_PUSH).append("=").append(((OFActionPushMpls)a).getEthertype().getValue());
                 break;
             case PUSH_PBB:
-            	sb.append(ActionUtils.STR_PBB_PUSH).append(((OFActionPushPbb)a).getEthertype().getValue());
+            	sb.append(ActionUtils.STR_PBB_PUSH).append("=").append(((OFActionPushPbb)a).getEthertype().getValue());
                 break;
             case POP_VLAN:
-            	sb.append(ActionUtils.STR_VLAN_POP).append(ActionUtils.STR_NOT_APPLICABLE);
+            	sb.append(ActionUtils.STR_VLAN_POP).append("=").append(ActionUtils.STR_NOT_APPLICABLE);
                 break;
             case POP_MPLS:
-            	sb.append(ActionUtils.STR_MPLS_POP).append(((OFActionPopMpls)a).getEthertype().getValue());
+            	sb.append(ActionUtils.STR_MPLS_POP).append("=").append(((OFActionPopMpls)a).getEthertype().getValue());
                 break;
             case POP_PBB:
-            	sb.append(ActionUtils.STR_PBB_POP).append(ActionUtils.STR_NOT_APPLICABLE);
+            	sb.append(ActionUtils.STR_PBB_POP).append("=").append(ActionUtils.STR_NOT_APPLICABLE);
                 break;
             case COPY_TTL_IN:
-            	sb.append(ActionUtils.STR_TTL_IN_COPY).append(ActionUtils.STR_NOT_APPLICABLE);
+            	sb.append(ActionUtils.STR_TTL_IN_COPY).append("=").append(ActionUtils.STR_NOT_APPLICABLE);
                 break;
             case COPY_TTL_OUT:
-            	sb.append(ActionUtils.STR_TTL_OUT_COPY).append(ActionUtils.STR_NOT_APPLICABLE);
+            	sb.append(ActionUtils.STR_TTL_OUT_COPY).append("=").append(ActionUtils.STR_NOT_APPLICABLE);
                 break;
             case DEC_NW_TTL:
-            	sb.append(ActionUtils.STR_NW_TTL_DEC).append(ActionUtils.STR_NOT_APPLICABLE);
+            	sb.append(ActionUtils.STR_NW_TTL_DEC).append("=").append(ActionUtils.STR_NOT_APPLICABLE);
                 break;
             case DEC_MPLS_TTL:
-            	sb.append(ActionUtils.STR_MPLS_TTL_DEC).append(ActionUtils.STR_NOT_APPLICABLE);
+            	sb.append(ActionUtils.STR_MPLS_TTL_DEC).append("=").append(ActionUtils.STR_NOT_APPLICABLE);
                 break;
             case SET_MPLS_LABEL:
-            	sb.append(ActionUtils.STR_MPLS_LABEL_SET).append(((OFActionSetMplsLabel)a).getMplsLabel());
+            	sb.append(ActionUtils.STR_MPLS_LABEL_SET).append("=").append(((OFActionSetMplsLabel)a).getMplsLabel());
                 break;
             case SET_MPLS_TC:
-            	sb.append(ActionUtils.STR_MPLS_TC_SET).append(((OFActionSetMplsTc)a).getMplsTc());
+            	sb.append(ActionUtils.STR_MPLS_TC_SET).append("=").append(((OFActionSetMplsTc)a).getMplsTc());
                 break;
             case SET_MPLS_TTL:
-                sb.append(ActionUtils.STR_MPLS_TTL_SET).append(((OFActionSetMplsTtl)a).getMplsTtl());
+                sb.append(ActionUtils.STR_MPLS_TTL_SET).append("=").append(((OFActionSetMplsTtl)a).getMplsTtl());
                 break;
             case SET_NW_ECN:
-            	sb.append(ActionUtils.STR_NW_ECN_SET).append(((OFActionSetNwEcn)a).getNwEcn().getEcnValue());
+            	sb.append(ActionUtils.STR_NW_ECN_SET).append("=").append(((OFActionSetNwEcn)a).getNwEcn().getEcnValue());
                 break;
             case SET_NW_TTL:
-            	sb.append(ActionUtils.STR_NW_TTL_SET).append(((OFActionSetNwTtl)a).getNwTtl());
+            	sb.append(ActionUtils.STR_NW_TTL_SET).append("=").append(((OFActionSetNwTtl)a).getNwTtl());
                 break;
             case EXPERIMENTER:
-            	sb.append(ActionUtils.STR_EXPERIMENTER).append(((OFActionExperimenter)a).getExperimenter());
+            	sb.append(ActionUtils.STR_EXPERIMENTER).append("=").append(((OFActionExperimenter)a).getExperimenter());
                 break;
             case SET_FIELD:
                 if (((OFActionSetField)a).getField() instanceof OFOxmArpOp) {
-                	sb.append(MatchUtils.STR_ARP_OPCODE).append(((OFOxmArpOp) ((OFActionSetField) a).getField()).getValue().getOpcode());
+                	sb.append(MatchUtils.STR_ARP_OPCODE).append("=").append(((OFOxmArpOp) ((OFActionSetField) a).getField()).getValue().getOpcode());
                 } else if (((OFActionSetField)a).getField() instanceof OFOxmArpSha) {
-                	sb.append(MatchUtils.STR_ARP_SHA).append(((OFOxmArpSha) ((OFActionSetField) a).getField()).getValue().toString()); // macaddress formats string already
+                	sb.append(MatchUtils.STR_ARP_SHA).append("=").append(((OFOxmArpSha) ((OFActionSetField) a).getField()).getValue().toString()); // macaddress formats string already
                 } else if (((OFActionSetField)a).getField() instanceof OFOxmArpTha) {
-                	sb.append(MatchUtils.STR_ARP_DHA).append(((OFOxmArpTha) ((OFActionSetField) a).getField()).getValue().toString());
+                	sb.append(MatchUtils.STR_ARP_DHA).append("=").append(((OFOxmArpTha) ((OFActionSetField) a).getField()).getValue().toString());
                 } else if (((OFActionSetField)a).getField() instanceof OFOxmArpSpa) {
-                	sb.append(MatchUtils.STR_ARP_SPA).append(((OFOxmArpSpa) ((OFActionSetField) a).getField()).getValue().toString()); // ipaddress formats string already
+                	sb.append(MatchUtils.STR_ARP_SPA).append("=").append(((OFOxmArpSpa) ((OFActionSetField) a).getField()).getValue().toString()); // ipaddress formats string already
                 } else if (((OFActionSetField)a).getField() instanceof OFOxmArpTpa) {
-                	sb.append(MatchUtils.STR_ARP_DPA).append(((OFOxmArpTpa) ((OFActionSetField) a).getField()).getValue().toString()); 
+                	sb.append(MatchUtils.STR_ARP_DPA).append("=").append(((OFOxmArpTpa) ((OFActionSetField) a).getField()).getValue().toString()); 
                 } else if (((OFActionSetField)a).getField() instanceof OFOxmIpv6NdSll) {                		
-                	sb.append(MatchUtils.STR_IPV6_ND_SSL).append(((OFOxmIpv6NdSll) ((OFActionSetField) a).getField()).getValue().toString());
+                	sb.append(MatchUtils.STR_IPV6_ND_SSL).append("=").append(((OFOxmIpv6NdSll) ((OFActionSetField) a).getField()).getValue().toString());
             	} else if (((OFActionSetField)a).getField() instanceof OFOxmIpv6NdTll) {                		
-            		sb.append(MatchUtils.STR_IPV6_ND_TTL).append(((OFOxmIpv6NdTll) ((OFActionSetField) a).getField()).getValue().toString());
+            		sb.append(MatchUtils.STR_IPV6_ND_TTL).append("=").append(((OFOxmIpv6NdTll) ((OFActionSetField) a).getField()).getValue().toString());
             	} else if (((OFActionSetField)a).getField() instanceof OFOxmIpv6NdTarget) {                		
-            		sb.append(MatchUtils.STR_IPV6_ND_TARGET).append(((OFOxmIpv6NdTarget) ((OFActionSetField) a).getField()).getValue().toString()); 
+            		sb.append(MatchUtils.STR_IPV6_ND_TARGET).append("=").append(((OFOxmIpv6NdTarget) ((OFActionSetField) a).getField()).getValue().toString()); 
             	}
                 /* DATA LAYER */
                 else if (((OFActionSetField)a).getField() instanceof OFOxmEthType) {
-                	sb.append(MatchUtils.STR_DL_TYPE).append(((OFOxmEthType) ((OFActionSetField) a).getField()).getValue().getValue());
+                	sb.append(MatchUtils.STR_DL_TYPE).append("=").append(((OFOxmEthType) ((OFActionSetField) a).getField()).getValue().getValue());
                 } else if (((OFActionSetField)a).getField() instanceof OFOxmEthSrc) {
-                	sb.append(MatchUtils.STR_DL_SRC).append(((OFOxmEthSrc) ((OFActionSetField) a).getField()).getValue().toString());
+                	sb.append(MatchUtils.STR_DL_SRC).append("=").append(((OFOxmEthSrc) ((OFActionSetField) a).getField()).getValue().toString());
                 } else if (((OFActionSetField)a).getField() instanceof OFOxmEthDst) {
-                	sb.append(MatchUtils.STR_DL_DST).append(((OFOxmEthDst) ((OFActionSetField) a).getField()).getValue().toString()); 
+                	sb.append(MatchUtils.STR_DL_DST).append("=").append(((OFOxmEthDst) ((OFActionSetField) a).getField()).getValue().toString()); 
                 } else if (((OFActionSetField)a).getField() instanceof OFOxmVlanVid) {
-                	sb.append(MatchUtils.STR_DL_VLAN).append(((OFOxmVlanVid) ((OFActionSetField) a).getField()).getValue().getVlan()); 
+                	sb.append(MatchUtils.STR_DL_VLAN).append("=").append(((OFOxmVlanVid) ((OFActionSetField) a).getField()).getValue().getVlan()); 
                 } else if (((OFActionSetField)a).getField() instanceof OFOxmVlanPcp) {
                 } 
                 /* ICMP */
                 else if (((OFActionSetField)a).getField() instanceof OFOxmIcmpv4Code) {
-                	sb.append(MatchUtils.STR_ICMP_CODE).append(((OFOxmIcmpv4Code) ((OFActionSetField) a).getField()).getValue().getCode()); 
+                	sb.append(MatchUtils.STR_ICMP_CODE).append("=").append(((OFOxmIcmpv4Code) ((OFActionSetField) a).getField()).getValue().getCode()); 
                 } else if (((OFActionSetField)a).getField() instanceof OFOxmIcmpv4Type) {
-                	sb.append(MatchUtils.STR_ICMP_TYPE).append(((OFOxmIcmpv4Type) ((OFActionSetField) a).getField()).getValue().getType()); 
+                	sb.append(MatchUtils.STR_ICMP_TYPE).append("=").append(((OFOxmIcmpv4Type) ((OFActionSetField) a).getField()).getValue().getType()); 
                 } else if (((OFActionSetField)a).getField() instanceof OFOxmIcmpv6Code) {                		
-                	sb.append(MatchUtils.STR_ICMPV6_CODE).append(((OFOxmIcmpv6Code) ((OFActionSetField) a).getField()).getValue().getRaw()); 
+                	sb.append(MatchUtils.STR_ICMPV6_CODE).append("=").append(((OFOxmIcmpv6Code) ((OFActionSetField) a).getField()).getValue().getRaw()); 
             	}  else if (((OFActionSetField)a).getField() instanceof OFOxmIcmpv6Type) {                		
-            		sb.append(MatchUtils.STR_ICMPV6_TYPE).append(((OFOxmIcmpv6Type) ((OFActionSetField) a).getField()).getValue().getRaw()); 
+            		sb.append(MatchUtils.STR_ICMPV6_TYPE).append("=").append(((OFOxmIcmpv6Type) ((OFActionSetField) a).getField()).getValue().getRaw()); 
             	}
                 /* NETWORK LAYER */
                 else if (((OFActionSetField)a).getField() instanceof OFOxmIpProto) {
-                	sb.append(MatchUtils.STR_NW_PROTO).append(((OFOxmIpProto) ((OFActionSetField) a).getField()).getValue().getIpProtocolNumber()); 
+                	sb.append(MatchUtils.STR_NW_PROTO).append("=").append(((OFOxmIpProto) ((OFActionSetField) a).getField()).getValue().getIpProtocolNumber()); 
                 } else if (((OFActionSetField)a).getField() instanceof OFOxmIpv4Src) {
-                	sb.append(MatchUtils.STR_NW_SRC).append(((OFOxmIpv4Src) ((OFActionSetField) a).getField()).getValue().toString()); 
+                	sb.append(MatchUtils.STR_NW_SRC).append("=").append(((OFOxmIpv4Src) ((OFActionSetField) a).getField()).getValue().toString()); 
                 } else if (((OFActionSetField)a).getField() instanceof OFOxmIpv4Dst) {
-                	sb.append(MatchUtils.STR_NW_DST).append(((OFOxmIpv4Dst) ((OFActionSetField) a).getField()).getValue().toString()); 
+                	sb.append(MatchUtils.STR_NW_DST).append("=").append(((OFOxmIpv4Dst) ((OFActionSetField) a).getField()).getValue().toString()); 
                 } else if (((OFActionSetField)a).getField() instanceof OFOxmIpv6Src) {                		
-                	sb.append(MatchUtils.STR_IPV6_SRC).append(((OFOxmIpv6Src) ((OFActionSetField) a).getField()).getValue().toString()); 
+                	sb.append(MatchUtils.STR_IPV6_SRC).append("=").append(((OFOxmIpv6Src) ((OFActionSetField) a).getField()).getValue().toString()); 
             	} else if (((OFActionSetField)a).getField() instanceof OFOxmIpv6Dst) {                		
-            		sb.append(MatchUtils.STR_IPV6_DST).append(((OFOxmIpv6Dst) ((OFActionSetField) a).getField()).getValue().toString()); 
+            		sb.append(MatchUtils.STR_IPV6_DST).append("=").append(((OFOxmIpv6Dst) ((OFActionSetField) a).getField()).getValue().toString()); 
             	} else if (((OFActionSetField)a).getField() instanceof OFOxmIpv6Flabel) {                		
-            		sb.append(MatchUtils.STR_IPV6_FLOW_LABEL).append(((OFOxmIpv6Flabel) ((OFActionSetField) a).getField()).getValue().toString()); 
+            		sb.append(MatchUtils.STR_IPV6_FLOW_LABEL).append("=").append(((OFOxmIpv6Flabel) ((OFActionSetField) a).getField()).getValue().toString()); 
             	} else if (((OFActionSetField)a).getField() instanceof OFOxmIpEcn) {
-            		sb.append(MatchUtils.STR_NW_ECN).append(((OFOxmIpEcn) ((OFActionSetField) a).getField()).getValue().getEcnValue()); 
+            		sb.append(MatchUtils.STR_NW_ECN).append("=").append(((OFOxmIpEcn) ((OFActionSetField) a).getField()).getValue().getEcnValue()); 
                 } else if (((OFActionSetField)a).getField() instanceof OFOxmIpDscp) {
-                	sb.append(MatchUtils.STR_NW_DSCP).append(((OFOxmIpDscp) ((OFActionSetField) a).getField()).getValue().getDscpValue()); 
+                	sb.append(MatchUtils.STR_NW_DSCP).append("=").append(((OFOxmIpDscp) ((OFActionSetField) a).getField()).getValue().getDscpValue()); 
                 } 
                 /* TRANSPORT LAYER, TCP, UDP, and SCTP */
                 else if (((OFActionSetField)a).getField() instanceof OFOxmTcpSrc) {
-                	sb.append(MatchUtils.STR_TCP_SRC).append(((OFOxmTcpSrc) ((OFActionSetField) a).getField()).getValue().getPort()); 
+                	sb.append(MatchUtils.STR_TCP_SRC).append("=").append(((OFOxmTcpSrc) ((OFActionSetField) a).getField()).getValue().getPort()); 
                 } else if (((OFActionSetField)a).getField() instanceof OFOxmTcpDst) {
-                	sb.append(MatchUtils.STR_TCP_DST).append(((OFOxmTcpDst) ((OFActionSetField) a).getField()).getValue().getPort()); 
+                	sb.append(MatchUtils.STR_TCP_DST).append("=").append(((OFOxmTcpDst) ((OFActionSetField) a).getField()).getValue().getPort()); 
                 } else if (((OFActionSetField)a).getField() instanceof OFOxmUdpSrc) {
-                	sb.append(MatchUtils.STR_UDP_SRC).append(((OFOxmUdpSrc) ((OFActionSetField) a).getField()).getValue().getPort()); 
+                	sb.append(MatchUtils.STR_UDP_SRC).append("=").append(((OFOxmUdpSrc) ((OFActionSetField) a).getField()).getValue().getPort()); 
                 } else if (((OFActionSetField)a).getField() instanceof OFOxmUdpDst) {
-                	sb.append(MatchUtils.STR_UDP_DST).append(((OFOxmUdpDst) ((OFActionSetField) a).getField()).getValue().getPort()); 
+                	sb.append(MatchUtils.STR_UDP_DST).append("=").append(((OFOxmUdpDst) ((OFActionSetField) a).getField()).getValue().getPort()); 
                 } else if (((OFActionSetField)a).getField() instanceof OFOxmSctpSrc) {
-                	sb.append(MatchUtils.STR_SCTP_SRC).append(((OFOxmSctpSrc) ((OFActionSetField) a).getField()).getValue().getPort()); 
+                	sb.append(MatchUtils.STR_SCTP_SRC).append("=").append(((OFOxmSctpSrc) ((OFActionSetField) a).getField()).getValue().getPort()); 
                 } else if (((OFActionSetField)a).getField() instanceof OFOxmSctpDst) {
-                	sb.append(MatchUtils.STR_SCTP_DST).append(((OFOxmSctpDst) ((OFActionSetField) a).getField()).getValue().getPort()); 
+                	sb.append(MatchUtils.STR_SCTP_DST).append("=").append(((OFOxmSctpDst) ((OFActionSetField) a).getField()).getValue().getPort()); 
                 }
                 /* MPLS */
                 else if (((OFActionSetField)a).getField() instanceof OFOxmMplsLabel) {
-                	sb.append(MatchUtils.STR_MPLS_LABEL).append(((OFOxmMplsLabel) ((OFActionSetField) a).getField()).getValue().getValue()); 
+                	sb.append(MatchUtils.STR_MPLS_LABEL).append("=").append(((OFOxmMplsLabel) ((OFActionSetField) a).getField()).getValue().getValue()); 
                 } else if (((OFActionSetField)a).getField() instanceof OFOxmMplsTc) {
-                	sb.append(MatchUtils.STR_MPLS_TC).append(((OFOxmMplsTc) ((OFActionSetField) a).getField()).getValue().getValue()); 
+                	sb.append(MatchUtils.STR_MPLS_TC).append("=").append(((OFOxmMplsTc) ((OFActionSetField) a).getField()).getValue().getValue()); 
                 } else if (((OFActionSetField)a).getField() instanceof OFOxmMplsBos) {
-                	sb.append(MatchUtils.STR_MPLS_TC).append(((OFOxmMplsBos) ((OFActionSetField) a).getField()).getValue().toString()); 
+                	sb.append(MatchUtils.STR_MPLS_TC).append("=").append(((OFOxmMplsBos) ((OFActionSetField) a).getField()).getValue().toString()); 
                 } 
                 /* METADATA */
                 else if (((OFActionSetField)a).getField() instanceof OFOxmMetadata) {
-                	sb.append(MatchUtils.STR_METADATA).append(((OFOxmMetadata) ((OFActionSetField) a).getField()).getValue().getValue().getValue()); 
+                	sb.append(MatchUtils.STR_METADATA).append("=").append(((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
+            pos++;
+            if (pos < len) {
+            	sb.append(",");
+            }
         } // end for over all actions
+        
+        if (actions.isEmpty()) {
+            jsonGenerator.writeStringField("none", "drop");
+        } else {
+        	jsonGenerator.writeStringField("actions", sb.toString());
+        }
     } // end method
 }
diff --git a/src/main/java/net/floodlightcontroller/staticflowentry/StaticFlowEntryPusher.java b/src/main/java/net/floodlightcontroller/staticflowentry/StaticFlowEntryPusher.java
index 89f351627..87367e007 100644
--- a/src/main/java/net/floodlightcontroller/staticflowentry/StaticFlowEntryPusher.java
+++ b/src/main/java/net/floodlightcontroller/staticflowentry/StaticFlowEntryPusher.java
@@ -362,7 +362,14 @@ implements IOFSwitchListener, IFloodlightModule, IStaticFlowEntryPusherService,
 			}
 
 			// get the correct builder for the OF version supported by the switch
-			fmb = OFFactories.getFactory(switchService.getSwitch(DatapathId.of(switchName)).getOFFactory().getVersion()).buildFlowModify();
+			try {
+				fmb = OFFactories.getFactory(switchService.getSwitch(DatapathId.of(switchName)).getOFFactory().getVersion()).buildFlowModify();
+			} catch (NullPointerException e) {
+				/* switch was not connected/known */
+				storageSourceService.deleteRowAsync(TABLE_NAME, entryName);
+				log.error("Deleting entry {}. Switch {} was not connected to the controller, and we need to know the OF protocol version to compose the flow mod.", entryName, switchName);
+				return;
+			}
 
 			StaticFlowEntries.initDefaultFlowMod(fmb, entryName);
 
@@ -587,16 +594,20 @@ implements IOFSwitchListener, IFloodlightModule, IStaticFlowEntryPusherService,
 		}
 
 		// send flow_mod delete
-		OFFlowDeleteStrict flowMod = FlowModUtils.toFlowDeleteStrict(entriesFromStorage.get(dpid).get(entryName));
+		if (switchService.getSwitch(DatapathId.of(dpid)) != null) {
+			OFFlowDeleteStrict flowMod = FlowModUtils.toFlowDeleteStrict(entriesFromStorage.get(dpid).get(entryName));
+
+			if (entriesFromStorage.containsKey(dpid) && entriesFromStorage.get(dpid).containsKey(entryName)) {
+				entriesFromStorage.get(dpid).remove(entryName);
+			} else {
+				log.debug("Tried to delete non-existent entry {} for switch {}", entryName, dpid);
+				return;
+			}
 
-		if (entriesFromStorage.containsKey(dpid) && entriesFromStorage.get(dpid).containsKey(entryName)) {
-			entriesFromStorage.get(dpid).remove(entryName);
+			writeFlowModToSwitch(DatapathId.of(dpid), flowMod);
 		} else {
-			log.debug("Tried to delete non-existent entry {} for switch {}", entryName, dpid);
-			return;
+			log.debug("Not sending flow delete for disconnected switch.");
 		}
-
-		writeFlowModToSwitch(DatapathId.of(dpid), flowMod);
 		return;
 	}
 
@@ -735,14 +746,14 @@ implements IOFSwitchListener, IFloodlightModule, IStaticFlowEntryPusherService,
 								msg.getMatch().equals(entry.getValue().getMatch()) &&
 								msg.getPriority() == entry.getValue().getPriority() &&
 								msg.getTableId().equals(entry.getValue().getTableId())
-							) {
+								) {
 							flowToRemove = entry.getKey();
 							break;
 						}
 					}
-					
+
 					log.debug("Flow to Remove: {}", flowToRemove);
-					
+
 					/*
 					 * Remove the flow. This will send the delete message to the switch,
 					 * since we cannot tell the storage listener rowsdeleted() that we
-- 
GitLab