T3: removed fixed mpls_bos and proper mpls label removal

Change-Id: Iaa122a84a43fedb5a0814d2a34b00a682ce4f741
(cherry picked from commit d293a5aa25937530da1d297589a2e5d7dfb5aef5)
diff --git a/src/main/java/org/onosproject/t3/cli/TroubleshootTraceCommand.java b/src/main/java/org/onosproject/t3/cli/TroubleshootTraceCommand.java
index fdeb944..c809065 100644
--- a/src/main/java/org/onosproject/t3/cli/TroubleshootTraceCommand.java
+++ b/src/main/java/org/onosproject/t3/cli/TroubleshootTraceCommand.java
@@ -20,6 +20,7 @@
 import org.apache.karaf.shell.commands.Option;
 import org.onlab.packet.IpAddress;
 import org.onlab.packet.MacAddress;
+import org.onlab.packet.MplsLabel;
 import org.onlab.packet.TpPort;
 import org.onlab.packet.VlanId;
 import org.onosproject.cli.AbstractShellCommand;
@@ -84,8 +85,11 @@
     @Option(name = "-vid", aliases = "--vlanId", description = "Vlan of incoming packet", valueToShowInHelp = "None")
     String vlan = "None";
 
+    @Option(name = "-ml", aliases = "--mplsLabel", description = "Mpls label of incoming packet")
+    String mplsLabel = null;
+
     @Option(name = "-mb", aliases = "--mplsBos", description = "MPLS BOS", valueToShowInHelp = "True")
-    String mplsBos = "true";
+    String mplsBos = null;
 
     @Override
     protected void execute() {
@@ -134,8 +138,13 @@
         //if vlan option is not specified using NONE
         selectorBuilder.matchVlanId(VlanId.vlanId(vlan));
 
-        //if mplsBos option is not specified using True
-        selectorBuilder.matchMplsBos(Boolean.valueOf(mplsBos));
+        if (mplsLabel != null) {
+            selectorBuilder.matchMplsLabel(MplsLabel.mplsLabel(Integer.parseInt(mplsLabel)));
+        }
+
+        if (mplsBos != null) {
+            selectorBuilder.matchMplsBos(Boolean.valueOf(mplsBos));
+        }
 
         TrafficSelector packet = selectorBuilder.build();
 
diff --git a/src/main/java/org/onosproject/t3/impl/TroubleshootManager.java b/src/main/java/org/onosproject/t3/impl/TroubleshootManager.java
index 24cd251..b66996d 100644
--- a/src/main/java/org/onosproject/t3/impl/TroubleshootManager.java
+++ b/src/main/java/org/onosproject/t3/impl/TroubleshootManager.java
@@ -435,9 +435,11 @@
         //If the pakcet comes in with the expected elements we update it as per OFDPA spec.
         if (mplsCriterion != null && ((EthTypeCriterion) mplsCriterion).ethType()
                 .equals(EtherType.MPLS_UNICAST.ethType())) {
+            //TODO update with parsing with eth MPLS pop Instruction for treating label an bos
             Instruction ethInstruction = Instructions.popMpls(((EthTypeCriterion) trace.getInitialPacket()
                     .getCriterion(Criterion.Type.ETH_TYPE)).ethType());
             //FIXME what do we use as L3_Unicast mpls Label ?
+            //translateInstruction(builder, ethInstruction);
             builder.add(ethInstruction);
         }
         packet = updatePacket(packet, builder.build()).build();
@@ -548,9 +550,10 @@
     private TrafficSelector.Builder updatePacket(TrafficSelector packet, List<Instruction> instructions) {
         TrafficSelector.Builder newSelector = DefaultTrafficSelector.builder();
         packet.criteria().forEach(newSelector::add);
-        instructions.forEach(instruction -> {
-            translateInstruction(newSelector, instruction);
-        });
+        //FIXME optimize
+        for (Instruction instruction : instructions) {
+            newSelector = translateInstruction(newSelector, instruction);
+        }
         return newSelector;
     }
 
@@ -563,6 +566,7 @@
      */
     private TrafficSelector.Builder translateInstruction(TrafficSelector.Builder newSelector, Instruction instruction) {
         log.debug("Translating instruction {}", instruction);
+        log.debug("New Selector {}", newSelector.build());
         //TODO add as required
         Criterion criterion = null;
         switch (instruction.type()) {
@@ -587,11 +591,24 @@
                         L2ModificationInstruction.ModMplsHeaderInstruction mplsPopInstruction =
                                 (L2ModificationInstruction.ModMplsHeaderInstruction) instruction;
                         criterion = Criteria.matchEthType(mplsPopInstruction.ethernetType().toShort());
+
+                        //When popping MPLS we remove label and BOS
+                        TrafficSelector temporaryPacket = newSelector.build();
+                        if (temporaryPacket.getCriterion(Criterion.Type.MPLS_LABEL) != null) {
+                            TrafficSelector.Builder noMplsSelector = DefaultTrafficSelector.builder();
+                            temporaryPacket.criteria().stream().filter(c -> {
+                                return !c.type().equals(Criterion.Type.MPLS_LABEL) &&
+                                        !c.type().equals(Criterion.Type.MPLS_BOS);
+                            }).forEach(noMplsSelector::add);
+                            newSelector = noMplsSelector;
+                        }
+
                         break;
                     case MPLS_LABEL:
                         L2ModificationInstruction.ModMplsLabelInstruction mplsLabelInstruction =
                                 (L2ModificationInstruction.ModMplsLabelInstruction) instruction;
                         criterion = Criteria.matchMplsLabel(mplsLabelInstruction.label());
+                        newSelector.matchMplsBos(true);
                         break;
                     case ETH_DST:
                         L2ModificationInstruction.ModEtherInstruction modEtherDstInstruction =
diff --git a/src/test/java/org/onosproject/t3/impl/T3TestObjects.java b/src/test/java/org/onosproject/t3/impl/T3TestObjects.java
index 7d24bbd..15cee5f 100644
--- a/src/test/java/org/onosproject/t3/impl/T3TestObjects.java
+++ b/src/test/java/org/onosproject/t3/impl/T3TestObjects.java
@@ -21,6 +21,7 @@
 import org.onlab.packet.IpAddress;
 import org.onlab.packet.IpPrefix;
 import org.onlab.packet.MacAddress;
+import org.onlab.packet.MplsLabel;
 import org.onlab.packet.VlanId;
 import org.onosproject.core.DefaultApplicationId;
 import org.onosproject.core.GroupId;
@@ -144,6 +145,8 @@
     private static final GroupId GROUP_ID = GroupId.valueOf(1);
 
     private static final TrafficTreatment GROUP_FLOW_TREATMENT = DefaultTrafficTreatment.builder()
+            .pushMpls()
+            .setMpls(MplsLabel.mplsLabel(100))
             .group(GROUP_ID)
             .build();
     private static final FlowRule GROUP_FLOW = DefaultFlowEntry.builder().forDevice(GROUP_FLOW_DEVICE)
@@ -156,7 +159,11 @@
             .build();
     static final FlowEntry GROUP_FLOW_ENTRY = new DefaultFlowEntry(GROUP_FLOW);
 
-    private static final GroupBucket BUCKET = DefaultGroupBucket.createSelectGroupBucket(OUTPUT_FLOW_TREATMENT);
+    private static final TrafficTreatment OUTPUT_GROUP_TREATMENT = DefaultTrafficTreatment.builder()
+            .popMpls(EthType.EtherType.IPV4.ethType())
+            .setOutput(PortNumber.portNumber(2)).build();
+
+    private static final GroupBucket BUCKET = DefaultGroupBucket.createSelectGroupBucket(OUTPUT_GROUP_TREATMENT);
 
     private static final GroupBuckets BUCKETS = new GroupBuckets(ImmutableList.of(BUCKET));
 
diff --git a/src/test/java/org/onosproject/t3/impl/TroubleshootManagerTest.java b/src/test/java/org/onosproject/t3/impl/TroubleshootManagerTest.java
index 63bcc32..a8f6524 100644
--- a/src/test/java/org/onosproject/t3/impl/TroubleshootManagerTest.java
+++ b/src/test/java/org/onosproject/t3/impl/TroubleshootManagerTest.java
@@ -179,6 +179,13 @@
 
         assertTrue("Wrong Output Group", traceSuccess.getGroupOuputs(GROUP_FLOW_DEVICE)
                 .get(0).getGroups().contains(GROUP));
+        assertEquals("Packet should not have MPLS Label", EthType.EtherType.IPV4.ethType(),
+                ((EthTypeCriterion) traceSuccess.getGroupOuputs(GROUP_FLOW_DEVICE)
+                        .get(0).getFinalPacket().getCriterion(Criterion.Type.ETH_TYPE)).ethType());
+        assertNull("Packet should not have MPLS Label", traceSuccess.getGroupOuputs(GROUP_FLOW_DEVICE)
+                .get(0).getFinalPacket().getCriterion(Criterion.Type.MPLS_LABEL));
+        assertNull("Packet should not have MPLS Label", traceSuccess.getGroupOuputs(GROUP_FLOW_DEVICE)
+                .get(0).getFinalPacket().getCriterion(Criterion.Type.MPLS_BOS));
 
     }