Instruction related fixes

- Fixed PushHeaderInstructions bug, where half-baked Ethernet instace was used
  only to hold ethernetType. (ONOS-987)

Change-Id: I330a862c8a18206250befbd4e22ee6d189beed83
diff --git a/core/api/src/main/java/org/onosproject/net/flow/instructions/Instructions.java b/core/api/src/main/java/org/onosproject/net/flow/instructions/Instructions.java
index df4a695..8141c9a 100644
--- a/core/api/src/main/java/org/onosproject/net/flow/instructions/Instructions.java
+++ b/core/api/src/main/java/org/onosproject/net/flow/instructions/Instructions.java
@@ -194,7 +194,7 @@
      */
     public static Instruction pushMpls() {
         return new PushHeaderInstructions(L2SubType.MPLS_PUSH,
-                                          new Ethernet().setEtherType(Ethernet.MPLS_UNICAST));
+                                          Ethernet.MPLS_UNICAST);
     }
 
     /**
@@ -203,7 +203,7 @@
      */
     public static Instruction popMpls() {
         return new PushHeaderInstructions(L2SubType.MPLS_POP,
-                                          new Ethernet().setEtherType(Ethernet.MPLS_UNICAST));
+                                          Ethernet.MPLS_UNICAST);
     }
 
     /**
@@ -214,8 +214,7 @@
      */
     public static Instruction popMpls(Short etherType) {
         checkNotNull(etherType, "Ethernet type cannot be null");
-        return new PushHeaderInstructions(L2SubType.MPLS_POP,
-                new Ethernet().setEtherType(etherType));
+        return new PushHeaderInstructions(L2SubType.MPLS_POP, etherType);
     }
 
     /*
diff --git a/core/api/src/main/java/org/onosproject/net/flow/instructions/L2ModificationInstruction.java b/core/api/src/main/java/org/onosproject/net/flow/instructions/L2ModificationInstruction.java
index c6dd282..723bbe6 100644
--- a/core/api/src/main/java/org/onosproject/net/flow/instructions/L2ModificationInstruction.java
+++ b/core/api/src/main/java/org/onosproject/net/flow/instructions/L2ModificationInstruction.java
@@ -19,7 +19,6 @@
 
 import java.util.Objects;
 
-import org.onlab.packet.Ethernet;
 import org.onlab.packet.MacAddress;
 import org.onlab.packet.VlanId;
 
@@ -140,15 +139,15 @@
             L2ModificationInstruction {
 
         private final L2SubType subtype;
-        private final Ethernet ethernetType;
+        private final short ethernetType; // uint16_t
 
-        public PushHeaderInstructions(L2SubType subType, Ethernet ethernetType) {
+        PushHeaderInstructions(L2SubType subType, short ethernetType) {
             this.subtype = subType;
             this.ethernetType = ethernetType;
         }
 
-        public Ethernet ethernetType() {
-            return ethernetType;
+        public int ethernetType() {
+            return Short.toUnsignedInt(ethernetType);
         }
 
         @Override
@@ -158,12 +157,14 @@
 
         @Override
         public String toString() {
-            return toStringHelper(subtype().toString()).toString();
+            return toStringHelper(subtype().toString())
+                    .add("ethernetType", String.format("0x%04x", ethernetType()))
+                    .toString();
         }
 
         @Override
         public int hashCode() {
-            return Objects.hash(type(), subtype);
+            return Objects.hash(type(), subtype, ethernetType);
         }
 
         @Override
@@ -173,9 +174,8 @@
             }
             if (obj instanceof PushHeaderInstructions) {
                 PushHeaderInstructions that = (PushHeaderInstructions) obj;
-                return  Objects.equals(this.type(), that.type()) &&
-                        Objects.equals(subtype, that.subtype);
-
+                return  Objects.equals(subtype, that.subtype) &&
+                        Objects.equals(this.ethernetType, that.ethernetType);
             }
             return false;
         }
diff --git a/core/api/src/test/java/org/onosproject/net/flow/DefaultTrafficTreatmentTest.java b/core/api/src/test/java/org/onosproject/net/flow/DefaultTrafficTreatmentTest.java
index ed0f1f4..7d18749 100644
--- a/core/api/src/test/java/org/onosproject/net/flow/DefaultTrafficTreatmentTest.java
+++ b/core/api/src/test/java/org/onosproject/net/flow/DefaultTrafficTreatmentTest.java
@@ -20,6 +20,7 @@
 import org.junit.Test;
 import org.onosproject.net.PortNumber;
 import org.onosproject.net.flow.instructions.Instruction;
+import org.onosproject.net.flow.instructions.Instructions;
 import org.onlab.packet.IpAddress;
 import org.onlab.packet.MacAddress;
 import org.onlab.packet.VlanId;
@@ -30,8 +31,6 @@
 import static org.hamcrest.MatcherAssert.assertThat;
 import static org.hamcrest.Matchers.hasSize;
 import static org.hamcrest.Matchers.is;
-import static org.onosproject.net.flow.instructions.L0ModificationInstruction.L0SubType;
-import static org.onosproject.net.flow.instructions.L0ModificationInstruction.ModLambdaInstruction;
 
 /**
  * Unit tests for the DefaultTrafficTreatment class.
@@ -48,7 +47,7 @@
     public void testTreatmentBuilderConstructors() {
         final TrafficTreatment treatment1 =
                 DefaultTrafficTreatment.builder()
-                        .add(new ModLambdaInstruction(L0SubType.LAMBDA, (short) 4))
+                        .add(Instructions.modL0Lambda((short) 4))
                         .build();
         final TrafficTreatment treatment2 =
                 DefaultTrafficTreatment.builder(treatment1).build();
@@ -61,7 +60,7 @@
     @Test
     public void testBuilderMethods() {
         final Instruction instruction1 =
-                new ModLambdaInstruction(L0SubType.LAMBDA, (short) 4);
+                Instructions.modL0Lambda((short) 4);
 
         final TrafficTreatment.Builder builder1 =
                 DefaultTrafficTreatment.builder()
@@ -95,15 +94,15 @@
     public void testEquals() {
         final TrafficTreatment treatment1 =
                 DefaultTrafficTreatment.builder()
-                        .add(new ModLambdaInstruction(L0SubType.LAMBDA, (short) 4))
+                        .add(Instructions.modL0Lambda((short) 4))
                         .build();
         final TrafficTreatment sameAsTreatment1 =
                 DefaultTrafficTreatment.builder()
-                        .add(new ModLambdaInstruction(L0SubType.LAMBDA, (short) 4))
+                        .add(Instructions.modL0Lambda((short) 4))
                         .build();
         final TrafficTreatment treatment2 =
                 DefaultTrafficTreatment.builder()
-                        .add(new ModLambdaInstruction(L0SubType.LAMBDA, (short) 2))
+                        .add(Instructions.modL0Lambda((short) 2))
                         .build();
         new EqualsTester()
                 .addEqualityGroup(treatment1, sameAsTreatment1)
diff --git a/providers/openflow/flow/src/main/java/org/onosproject/provider/of/flow/impl/FlowModBuilderVer13.java b/providers/openflow/flow/src/main/java/org/onosproject/provider/of/flow/impl/FlowModBuilderVer13.java
index eec63fb..2db1e6f 100644
--- a/providers/openflow/flow/src/main/java/org/onosproject/provider/of/flow/impl/FlowModBuilderVer13.java
+++ b/providers/openflow/flow/src/main/java/org/onosproject/provider/of/flow/impl/FlowModBuilderVer13.java
@@ -238,12 +238,12 @@
                 PushHeaderInstructions pushHeaderInstructions =
                         (PushHeaderInstructions) l2m;
                 return factory().actions().pushMpls(EthType.of(pushHeaderInstructions
-                                                               .ethernetType().getEtherType()));
+                                                               .ethernetType()));
             case MPLS_POP:
                 PushHeaderInstructions  popHeaderInstructions =
                         (PushHeaderInstructions) l2m;
                 return factory().actions().popMpls(EthType.of(popHeaderInstructions
-                                                          .ethernetType().getEtherType()));
+                                                              .ethernetType()));
             case MPLS_LABEL:
                 ModMplsLabelInstruction mplsLabel =
                         (ModMplsLabelInstruction) l2m;
diff --git a/providers/openflow/group/src/main/java/org/onosproject/provider/of/group/impl/GroupModBuilder.java b/providers/openflow/group/src/main/java/org/onosproject/provider/of/group/impl/GroupModBuilder.java
index eac5f26..191372c 100644
--- a/providers/openflow/group/src/main/java/org/onosproject/provider/of/group/impl/GroupModBuilder.java
+++ b/providers/openflow/group/src/main/java/org/onosproject/provider/of/group/impl/GroupModBuilder.java
@@ -255,12 +255,12 @@
                 L2ModificationInstruction.PushHeaderInstructions pushHeaderInstructions =
                         (L2ModificationInstruction.PushHeaderInstructions) l2m;
                 return factory.actions().pushMpls(EthType.of(pushHeaderInstructions
-                        .ethernetType().getEtherType()));
+                                                             .ethernetType()));
             case MPLS_POP:
                 L2ModificationInstruction.PushHeaderInstructions popHeaderInstructions =
                         (L2ModificationInstruction.PushHeaderInstructions) l2m;
                 return factory.actions().popMpls(EthType.of(popHeaderInstructions
-                        .ethernetType().getEtherType()));
+                                                            .ethernetType()));
             case MPLS_LABEL:
                 L2ModificationInstruction.ModMplsLabelInstruction mplsLabel =
                         (L2ModificationInstruction.ModMplsLabelInstruction) l2m;
diff --git a/web/api/src/main/java/org/onosproject/codec/impl/InstructionCodec.java b/web/api/src/main/java/org/onosproject/codec/impl/InstructionCodec.java
index 57f95bd..913fc8b 100644
--- a/web/api/src/main/java/org/onosproject/codec/impl/InstructionCodec.java
+++ b/web/api/src/main/java/org/onosproject/codec/impl/InstructionCodec.java
@@ -15,7 +15,6 @@
  */
 package org.onosproject.codec.impl;
 
-import org.onlab.packet.Ethernet;
 import org.onosproject.codec.CodecContext;
 import org.onosproject.codec.JsonCodec;
 import org.onosproject.net.flow.instructions.Instruction;
@@ -100,11 +99,7 @@
                 final L2ModificationInstruction.PushHeaderInstructions pushHeaderInstructions =
                         (L2ModificationInstruction.PushHeaderInstructions) instruction;
 
-                final JsonCodec<Ethernet> ethernetCodec =
-                        context.codec(Ethernet.class);
-                result.set("ethernetType",
-                        ethernetCodec.encode(pushHeaderInstructions.ethernetType(),
-                                context));
+                result.put("ethernetType", pushHeaderInstructions.ethernetType());
                 break;
 
             default:
diff --git a/web/api/src/test/java/org/onosproject/codec/impl/InstructionJsonMatcher.java b/web/api/src/test/java/org/onosproject/codec/impl/InstructionJsonMatcher.java
index 001a865..0086255 100644
--- a/web/api/src/test/java/org/onosproject/codec/impl/InstructionJsonMatcher.java
+++ b/web/api/src/test/java/org/onosproject/codec/impl/InstructionJsonMatcher.java
@@ -16,13 +16,11 @@
 package org.onosproject.codec.impl;
 
 import org.hamcrest.Description;
-import org.hamcrest.Matcher;
 import org.hamcrest.TypeSafeDiagnosingMatcher;
 import org.onosproject.net.flow.instructions.Instruction;
 
 import com.fasterxml.jackson.databind.JsonNode;
 
-import static org.onosproject.codec.impl.EthernetJsonMatcher.matchesEthernet;
 import static org.onosproject.net.flow.instructions.Instructions.*;
 import static org.onosproject.net.flow.instructions.L0ModificationInstruction.*;
 import static org.onosproject.net.flow.instructions.L2ModificationInstruction.*;
@@ -67,13 +65,11 @@
             return false;
         }
 
-        final Matcher ethernetMatcher =
-                matchesEthernet(instructionToMatch.ethernetType());
-        final boolean ethernetMatches = ethernetMatcher.matches(ethJson);
-        if (!ethernetMatches) {
-            ethernetMatcher.describeMismatch(ethernetMatcher, description);
+        if (instructionToMatch.ethernetType() != ethJson.asInt()) {
+            description.appendText("ethernetType was " + ethJson);
             return false;
         }
+
         return true;
     }
 
diff --git a/web/api/src/test/java/org/onosproject/rest/FlowsResourceTest.java b/web/api/src/test/java/org/onosproject/rest/FlowsResourceTest.java
index fc28624..a02690f 100644
--- a/web/api/src/test/java/org/onosproject/rest/FlowsResourceTest.java
+++ b/web/api/src/test/java/org/onosproject/rest/FlowsResourceTest.java
@@ -45,8 +45,7 @@
 import org.onosproject.net.flow.TrafficTreatment;
 import org.onosproject.net.flow.criteria.Criterion;
 import org.onosproject.net.flow.instructions.Instruction;
-import org.onosproject.net.flow.instructions.L0ModificationInstruction;
-
+import org.onosproject.net.flow.instructions.Instructions;
 import com.eclipsesource.json.JsonArray;
 import com.eclipsesource.json.JsonObject;
 import com.google.common.collect.ImmutableSet;
@@ -187,6 +186,7 @@
             return false;
         }
 
+        @Override
         public Type type() {
             return Type.DEFAULT;
         }
@@ -197,10 +197,8 @@
      */
     private void setupMockFlows() {
         flow2.treatment = DefaultTrafficTreatment.builder()
-                .add(new L0ModificationInstruction.ModLambdaInstruction(
-                        L0ModificationInstruction.L0SubType.LAMBDA, (short) 4))
-                .add(new L0ModificationInstruction.ModLambdaInstruction(
-                        L0ModificationInstruction.L0SubType.LAMBDA, (short) 5))
+                .add(Instructions.modL0Lambda((short) 4))
+                .add(Instructions.modL0Lambda((short) 5))
                 .setEthDst(MacAddress.BROADCAST)
                 .build();
         flow2.selector = DefaultTrafficSelector.builder()
@@ -208,8 +206,7 @@
                 .matchIPProtocol((byte) 9)
                 .build();
         flow4.treatment = DefaultTrafficTreatment.builder()
-                .add(new L0ModificationInstruction.ModLambdaInstruction(
-                L0ModificationInstruction.L0SubType.LAMBDA, (short) 6))
+                .add(Instructions.modL0Lambda((short) 6))
                 .build();
         final Set<FlowEntry> flows1 = new HashSet<>();
         flows1.add(flow1);