Add truncate instruction and support it with PI framework

To support truncate by P4Runtime clone/mirror session, we need to pass the
truncate size/length from ONOS northbound to the southbound.
As discussed in the SDFabric syncup, we decide to pass this information via
the instruction in group bucket so applications or pipeliners can simply
reuse current APIs.

Change-Id: I15cc822b7c8008b6b9f8b02f3f399769ae396ef0
(cherry picked from commit 9f94a13bf5695996708eedc17166b5b09308147f)
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 621c007..d330dcd 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
@@ -49,6 +49,7 @@
 import java.util.Objects;
 
 import static com.google.common.base.MoreObjects.toStringHelper;
+import static com.google.common.base.Preconditions.checkArgument;
 import static com.google.common.base.Preconditions.checkNotNull;
 
 /**
@@ -545,6 +546,17 @@
     }
 
     /**
+     * Creates a truncate instruction.
+     *
+     * @param maxLen the maximum frame length in bytes, must be a positive integer
+     * @return truncate instruction
+     */
+    public static TruncateInstruction truncate(int maxLen) {
+        checkArgument(maxLen > 0, "Truncate max length must be a positive integer.");
+        return new TruncateInstruction(maxLen);
+    }
+
+    /**
      *  No Action instruction.
      */
     public static final class NoActionInstruction implements Instruction {
@@ -974,6 +986,44 @@
         }
     }
 
+    public static final class TruncateInstruction implements Instruction {
+        private int maxLen;
+
+        public TruncateInstruction(int maxLen) {
+            this.maxLen = maxLen;
+        }
+
+        public int maxLen() {
+            return maxLen;
+        }
+
+        @Override
+        public Type type() {
+            return Type.TRUNCATE;
+        }
+
+        @Override
+        public boolean equals(Object o) {
+            if (this == o) {
+                return true;
+            }
+            if (o == null || getClass() != o.getClass()) {
+                return false;
+            }
+            TruncateInstruction that = (TruncateInstruction) o;
+            return maxLen == that.maxLen;
+        }
+
+        @Override
+        public int hashCode() {
+            return com.google.common.base.Objects.hashCode(maxLen);
+        }
+
+        @Override
+        public String toString() {
+            return type() + SEPARATOR + maxLen;
+        }
+    }
 }