Support ModOchSignalInstruction in InstructionCodec

Resolve ONOS-1875

Change-Id: I63e10aeb4689991bfb5c6df349843ef5aff4d6f7
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 3957beb..ef8968c 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
@@ -17,6 +17,7 @@
 
 import org.onosproject.codec.CodecContext;
 import org.onosproject.codec.JsonCodec;
+import org.onosproject.net.OchSignal;
 import org.onosproject.net.flow.instructions.Instruction;
 import org.onosproject.net.flow.instructions.Instructions;
 import org.onosproject.net.flow.instructions.L0ModificationInstruction;
@@ -52,6 +53,16 @@
                 result.put("lambda", modLambdaInstruction.lambda());
                 break;
 
+            case OCH:
+                L0ModificationInstruction.ModOchSignalInstruction ochSignalInstruction =
+                        (L0ModificationInstruction.ModOchSignalInstruction) instruction;
+                OchSignal ochSignal = ochSignalInstruction.lambda();
+                result.put("gridType", ochSignal.gridType().name());
+                result.put("channelSpacing", ochSignal.channelSpacing().name());
+                result.put("spacingMultiplier", ochSignal.spacingMultiplier());
+                result.put("slotGranularity", ochSignal.slotGranularity());
+                break;
+
             default:
                 log.info("Cannot convert L0 subtype of {}", instruction.subtype());
         }
diff --git a/core/common/src/test/java/org/onosproject/codec/impl/InstructionCodecTest.java b/core/common/src/test/java/org/onosproject/codec/impl/InstructionCodecTest.java
index 949707b..29af34a 100644
--- a/core/common/src/test/java/org/onosproject/codec/impl/InstructionCodecTest.java
+++ b/core/common/src/test/java/org/onosproject/codec/impl/InstructionCodecTest.java
@@ -24,6 +24,9 @@
 import org.onlab.packet.VlanId;
 import org.onosproject.codec.CodecContext;
 import org.onosproject.codec.JsonCodec;
+import org.onosproject.net.ChannelSpacing;
+import org.onosproject.net.GridType;
+import org.onosproject.net.Lambda;
 import org.onosproject.net.PortNumber;
 import org.onosproject.net.flow.instructions.Instruction;
 import org.onosproject.net.flow.instructions.Instructions;
@@ -105,6 +108,19 @@
     }
 
     /**
+     * Tests the encoding of mod OCh signal instructions.
+     */
+    @Test
+    public void modOchSignalInstructionTest() {
+        L0ModificationInstruction.ModOchSignalInstruction instruction =
+                (L0ModificationInstruction.ModOchSignalInstruction)
+                        Instructions.modL0Lambda(Lambda.ochSignal(GridType.DWDM, ChannelSpacing.CHL_100GHZ, 4, 8));
+        ObjectNode instructionJson =
+                instructionCodec.encode(instruction, context);
+        assertThat(instructionJson, matchesInstruction(instruction));
+    }
+
+    /**
      * Tests the encoding of mod ether instructions.
      */
     @Test
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 72d3e41..7281ed5 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
@@ -133,6 +133,57 @@
     }
 
     /**
+     * Matches teh contents of a mod OCh singal instruction.
+     *
+     * @param instructionJson JSON instruction to match
+     * @param description Description object used for recording errors
+     * @return true if contents matches, false otherwise
+     */
+    private boolean matchModOchSingalInstruction(JsonNode instructionJson,
+                                                 Description description) {
+        ModOchSignalInstruction instructionToMatch =
+                (ModOchSignalInstruction) instruction;
+
+        String jsonSubType = instructionJson.get("subtype").textValue();
+        if (!instructionToMatch.subtype().name().equals(jsonSubType)) {
+            description.appendText("subtype was " + jsonSubType);
+            return false;
+        }
+
+        String jsonType = instructionJson.get("type").textValue();
+        if (!instructionToMatch.type().name().equals(jsonType)) {
+            description.appendText("type was " + jsonType);
+            return false;
+        }
+
+        String jsonGridType = instructionJson.get("gridType").textValue();
+        if (!instructionToMatch.lambda().gridType().name().equals(jsonGridType)) {
+            description.appendText("gridType was " + jsonGridType);
+            return false;
+        }
+
+        String jsonChannelSpacing = instructionJson.get("channelSpacing").textValue();
+        if (!instructionToMatch.lambda().channelSpacing().name().equals(jsonChannelSpacing)) {
+            description.appendText("channelSpacing was " + jsonChannelSpacing);
+            return false;
+        }
+
+        int jsonSpacingMultiplier = instructionJson.get("spacingMultiplier").intValue();
+        if (instructionToMatch.lambda().spacingMultiplier() != jsonSpacingMultiplier) {
+            description.appendText("spacingMultiplier was " + jsonSpacingMultiplier);
+            return false;
+        }
+
+        int jsonSlotGranularity = instructionJson.get("slotGranularity").intValue();
+        if (instructionToMatch.lambda().slotGranularity() != jsonSlotGranularity) {
+            description.appendText("slotGranularity was " + jsonSlotGranularity);
+            return false;
+        }
+
+        return true;
+    }
+
+    /**
      * Matches the contents of a mod Ethernet instruction.
      *
      * @param instructionJson JSON instruction to match
@@ -350,6 +401,8 @@
             return matchOutputInstruction(jsonInstruction, description);
         } else if (instruction instanceof ModLambdaInstruction) {
             return matchModLambdaInstruction(jsonInstruction, description);
+        } else if (instruction instanceof ModOchSignalInstruction) {
+            return matchModOchSingalInstruction(jsonInstruction, description);
         } else if (instruction instanceof ModEtherInstruction) {
             return matchModEtherInstruction(jsonInstruction, description);
         } else if (instruction instanceof ModVlanIdInstruction) {