Support to encode and decode setqueue id in InstructionCodec

Change-Id: I911e14b750d5264755687a9eff322502ba9ed118
diff --git a/core/common/src/main/java/org/onosproject/codec/impl/DecodeInstructionCodecHelper.java b/core/common/src/main/java/org/onosproject/codec/impl/DecodeInstructionCodecHelper.java
index 20d6fac..c8b6f26 100644
--- a/core/common/src/main/java/org/onosproject/codec/impl/DecodeInstructionCodecHelper.java
+++ b/core/common/src/main/java/org/onosproject/codec/impl/DecodeInstructionCodecHelper.java
@@ -233,6 +233,32 @@
     }
 
     /**
+     * Extracts port number of the given json node.
+     *
+     * @param jsonNode json node
+     * @return port number
+     */
+    private PortNumber getPortNumber(ObjectNode jsonNode) {
+        PortNumber portNumber;
+        if (jsonNode.get(InstructionCodec.PORT).isLong() || jsonNode.get(InstructionCodec.PORT).isInt()) {
+            portNumber = PortNumber
+                    .portNumber(nullIsIllegal(jsonNode.get(InstructionCodec.PORT)
+                            .asLong(), InstructionCodec.PORT
+                            + InstructionCodec.MISSING_MEMBER_MESSAGE));
+        } else if (jsonNode.get(InstructionCodec.PORT).isTextual()) {
+            portNumber = PortNumber
+                    .fromString(nullIsIllegal(jsonNode.get(InstructionCodec.PORT)
+                            .textValue(), InstructionCodec.PORT
+                            + InstructionCodec.MISSING_MEMBER_MESSAGE));
+        } else {
+            throw new IllegalArgumentException("Port value "
+                    + jsonNode.get(InstructionCodec.PORT).toString()
+                    + " is not supported");
+        }
+        return portNumber;
+    }
+
+    /**
      * Decodes the JSON into an instruction object.
      *
      * @return Criterion object
@@ -242,23 +268,7 @@
         String type = json.get(InstructionCodec.TYPE).asText();
 
         if (type.equals(Instruction.Type.OUTPUT.name())) {
-            PortNumber portNumber;
-            if (json.get(InstructionCodec.PORT).isLong() || json.get(InstructionCodec.PORT).isInt()) {
-                portNumber = PortNumber
-                        .portNumber(nullIsIllegal(json.get(InstructionCodec.PORT)
-                                                          .asLong(), InstructionCodec.PORT
-                                                          + InstructionCodec.MISSING_MEMBER_MESSAGE));
-            } else if (json.get(InstructionCodec.PORT).isTextual()) {
-                portNumber = PortNumber
-                        .fromString(nullIsIllegal(json.get(InstructionCodec.PORT)
-                                                          .textValue(), InstructionCodec.PORT
-                                                          + InstructionCodec.MISSING_MEMBER_MESSAGE));
-            } else {
-                throw new IllegalArgumentException("Port value "
-                                                           + json.get(InstructionCodec.PORT).toString()
-                                                           + " is not supported");
-            }
-            return Instructions.createOutput(portNumber);
+            return Instructions.createOutput(getPortNumber(json));
         } else if (type.equals(Instruction.Type.NOACTION.name())) {
             return Instructions.createNoAction();
         } else if (type.equals(Instruction.Type.TABLE.name())) {
@@ -272,6 +282,10 @@
             MeterId meterId = MeterId.meterId(nullIsIllegal(json.get(InstructionCodec.METER_ID)
                     .asLong(), InstructionCodec.METER_ID + InstructionCodec.MISSING_MEMBER_MESSAGE));
             return Instructions.meterTraffic(meterId);
+        } else if (type.equals(Instruction.Type.QUEUE.name())) {
+            long queueId = nullIsIllegal(json.get(InstructionCodec.QUEUE_ID)
+                    .asLong(), InstructionCodec.QUEUE_ID + InstructionCodec.MISSING_MEMBER_MESSAGE);
+            return Instructions.setQueue(queueId, getPortNumber(json));
         } else if (type.equals(Instruction.Type.L0MODIFICATION.name())) {
             return decodeL0();
         } else if (type.equals(Instruction.Type.L1MODIFICATION.name())) {
diff --git a/core/common/src/main/java/org/onosproject/codec/impl/EncodeInstructionCodecHelper.java b/core/common/src/main/java/org/onosproject/codec/impl/EncodeInstructionCodecHelper.java
index fc6935d..e025475 100644
--- a/core/common/src/main/java/org/onosproject/codec/impl/EncodeInstructionCodecHelper.java
+++ b/core/common/src/main/java/org/onosproject/codec/impl/EncodeInstructionCodecHelper.java
@@ -256,6 +256,13 @@
                 result.put(InstructionCodec.METER_ID, meterInstruction.meterId().toString());
                 break;
 
+            case QUEUE:
+                final Instructions.SetQueueInstruction setQueueInstruction =
+                        (Instructions.SetQueueInstruction) instruction;
+                result.put(InstructionCodec.QUEUE_ID, setQueueInstruction.queueId());
+                result.put(InstructionCodec.PORT, setQueueInstruction.port().toString());
+                break;
+
             case L0MODIFICATION:
                 encodeL0(result);
                 break;
diff --git a/core/common/src/main/java/org/onosproject/codec/impl/InstructionCodec.java b/core/common/src/main/java/org/onosproject/codec/impl/InstructionCodec.java
index 2d646b0..7e1c96a 100644
--- a/core/common/src/main/java/org/onosproject/codec/impl/InstructionCodec.java
+++ b/core/common/src/main/java/org/onosproject/codec/impl/InstructionCodec.java
@@ -52,6 +52,7 @@
     protected static final String TABLE_ID = "tableId";
     protected static final String GROUP_ID = "groupId";
     protected static final String METER_ID = "meterId";
+    protected static final String QUEUE_ID = "queueId";
     protected static final String TRIBUTARY_PORT_NUMBER = "tributaryPortNumber";
     protected static final String TRIBUTARY_SLOT_LEN = "tributarySlotLength";
     protected static final String TRIBUTARY_SLOT_BITMAP = "tributarySlotBitmap";
diff --git a/core/common/src/test/java/org/onosproject/codec/impl/InstructionJsonMatcher.java b/core/common/src/test/java/org/onosproject/codec/impl/InstructionJsonMatcher.java
index 6e539a8..dc3c497 100644
--- a/core/common/src/test/java/org/onosproject/codec/impl/InstructionJsonMatcher.java
+++ b/core/common/src/test/java/org/onosproject/codec/impl/InstructionJsonMatcher.java
@@ -25,6 +25,7 @@
 import org.onosproject.net.flow.instructions.Instructions.MeterInstruction;
 import org.onosproject.net.flow.instructions.Instructions.NoActionInstruction;
 import org.onosproject.net.flow.instructions.Instructions.OutputInstruction;
+import org.onosproject.net.flow.instructions.Instructions.SetQueueInstruction;
 import org.onosproject.net.flow.instructions.L0ModificationInstruction.ModLambdaInstruction;
 import org.onosproject.net.flow.instructions.L0ModificationInstruction.ModOchSignalInstruction;
 import org.onosproject.net.flow.instructions.L1ModificationInstruction.ModOduSignalIdInstruction;
@@ -115,7 +116,7 @@
             }
         } else {
             final String jsonPort = instructionJson.get("port").toString();
-            description.appendText("Unmathcing types ");
+            description.appendText("Unmatching types ");
             description.appendText("instructionToMatch " + instructionToMatch.port().toString());
             description.appendText("jsonPort " + jsonPort);
         }
@@ -174,6 +175,51 @@
     }
 
     /**
+     * Matches the contents of a set queue instruction.
+     *
+     * @param instructionJson JSON instruction to match
+     * @param description Description object used for recording errors
+     * @return true if contents match, false otherwise
+     */
+    private boolean matchSetQueueInstruction(JsonNode instructionJson,
+                                             Description description) {
+        final String jsonType = instructionJson.get("type").textValue();
+        SetQueueInstruction instructionToMatch = (SetQueueInstruction) instruction;
+        if (!instructionToMatch.type().name().equals(jsonType)) {
+            description.appendText("type was " + jsonType);
+            return false;
+        }
+
+        final long jsonQueueId = instructionJson.get("queueId").longValue();
+        if (instructionToMatch.queueId() != jsonQueueId) {
+            description.appendText("queueId was " + jsonQueueId);
+            return false;
+        }
+
+        if (instructionJson.get("port").isLong() ||
+                instructionJson.get("port").isInt()) {
+            final long jsonPort = instructionJson.get("port").asLong();
+            if (instructionToMatch.port().toLong() != (jsonPort)) {
+                description.appendText("port was " + jsonPort);
+                return false;
+            }
+        } else if (instructionJson.get("port").isTextual()) {
+            final String jsonPort = instructionJson.get("port").textValue();
+            if (!instructionToMatch.port().toString().equals(jsonPort)) {
+                description.appendText("port was " + jsonPort);
+                return false;
+            }
+        } else {
+            final String jsonPort = instructionJson.get("port").toString();
+            description.appendText("Unmatching types ");
+            description.appendText("instructionToMatch " + instructionToMatch.port().toString());
+            description.appendText("jsonPort " + jsonPort);
+        }
+
+        return true;
+    }
+
+    /**
      * Matches the contents of a mod lambda instruction.
      *
      * @param instructionJson JSON instruction to match
@@ -508,6 +554,8 @@
             return matchGroupInstruction(jsonInstruction, description);
         } else if (instruction instanceof MeterInstruction) {
             return matchMeterInstruction(jsonInstruction, description);
+        } else if (instruction instanceof SetQueueInstruction) {
+            return matchSetQueueInstruction(jsonInstruction, description);
         } else if (instruction instanceof ModLambdaInstruction) {
             return matchModLambdaInstruction(jsonInstruction, description);
         } else if (instruction instanceof ModOchSignalInstruction) {
@@ -521,8 +569,7 @@
         } else if (instruction instanceof ModIPInstruction) {
             return matchModIpInstruction(jsonInstruction, description);
         } else if (instruction instanceof ModIPv6FlowLabelInstruction) {
-            return matchModIPv6FlowLabelInstruction(jsonInstruction,
-                                                    description);
+            return matchModIPv6FlowLabelInstruction(jsonInstruction, description);
         } else if (instruction instanceof ModMplsLabelInstruction) {
             return matchModMplsLabelInstruction(jsonInstruction, description);
         } else if (instruction instanceof ModOduSignalIdInstruction) {