Instruction related fixes

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

Conflicts:
	core/api/src/main/java/org/onosproject/net/flow/instructions/Instructions.java
	providers/openflow/group/src/main/java/org/onosproject/provider/of/group/impl/GroupModBuilder.java
	web/api/src/main/java/org/onosproject/codec/impl/InstructionCodec.java
	web/api/src/test/java/org/onosproject/codec/impl/InstructionJsonMatcher.java
	web/api/src/test/java/org/onosproject/rest/FlowsResourceTest.java

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 4dd2c48..d1e7dee 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
@@ -148,7 +148,7 @@
      */
     public static Instruction pushMpls() {
         return new PushHeaderInstructions(L2SubType.MPLS_PUSH,
-                                          new Ethernet().setEtherType(Ethernet.MPLS_UNICAST));
+                                          Ethernet.MPLS_UNICAST);
     }
 
     /**
@@ -157,7 +157,18 @@
      */
     public static Instruction popMpls() {
         return new PushHeaderInstructions(L2SubType.MPLS_POP,
-                                          new Ethernet().setEtherType(Ethernet.MPLS_UNICAST));
+                                          Ethernet.MPLS_UNICAST);
+    }
+
+    /**
+     * Creates a mpls header instruction.
+     *
+     * @param etherType Ethernet type to set
+     * @return a L2 modification.
+     */
+    public static Instruction popMpls(Short etherType) {
+        checkNotNull(etherType, "Ethernet type cannot be null");
+        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 6baeceb..aa69ae9 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;
 
@@ -134,15 +133,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
@@ -152,12 +151,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
@@ -167,9 +168,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 64ebe0d..a0309af 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
@@ -230,12 +230,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;