Polished BMv2 protocol module

- Improved and fixed typos in javadocs
- Added missing beta API annotations
- Refactored the default interpreter implementation

Change-Id: Ibfb21d31415d8f25cc67307f8bea2871951c9a8f
diff --git a/protocols/bmv2/ctl/src/main/java/org/onosproject/bmv2/ctl/Bmv2DefaultInterpreterImpl.java b/protocols/bmv2/ctl/src/main/java/org/onosproject/bmv2/ctl/Bmv2DefaultInterpreterImpl.java
index f5e95df..55bf60c 100644
--- a/protocols/bmv2/ctl/src/main/java/org/onosproject/bmv2/ctl/Bmv2DefaultInterpreterImpl.java
+++ b/protocols/bmv2/ctl/src/main/java/org/onosproject/bmv2/ctl/Bmv2DefaultInterpreterImpl.java
@@ -22,11 +22,14 @@
 import org.onosproject.bmv2.api.context.Bmv2Interpreter;
 import org.onosproject.bmv2.api.context.Bmv2InterpreterException;
 import org.onosproject.bmv2.api.runtime.Bmv2Action;
-import org.onosproject.bmv2.api.utils.Bmv2TranslatorUtils;
+import org.onosproject.net.PortNumber;
 import org.onosproject.net.flow.TrafficTreatment;
 import org.onosproject.net.flow.criteria.Criterion;
 import org.onosproject.net.flow.instructions.Instruction;
 
+import static org.onlab.util.ImmutableByteSequence.copyFrom;
+import static org.onosproject.bmv2.api.utils.Bmv2TranslatorUtils.ByteSequenceFitException;
+import static org.onosproject.bmv2.api.utils.Bmv2TranslatorUtils.fitByteSequence;
 import static org.onosproject.net.PortNumber.CONTROLLER;
 import static org.onosproject.net.flow.instructions.Instructions.OutputInstruction;
 
@@ -37,10 +40,10 @@
 
     public static final String TABLE0 = "table0";
     public static final String SEND_TO_CPU = "send_to_cpu";
+    public static final String PORT = "port";
     public static final String DROP = "_drop";
     public static final String SET_EGRESS_PORT = "set_egress_port";
 
-    // Lazily populate field map.
     private static final ImmutableBiMap<Criterion.Type, String> CRITERION_MAP = ImmutableBiMap.of(
             Criterion.Type.IN_PORT, "standard_metadata.ingress_port",
             Criterion.Type.ETH_DST, "ethernet.dstAddr",
@@ -64,10 +67,9 @@
     public Bmv2Action mapTreatment(TrafficTreatment treatment, Bmv2Configuration configuration)
             throws Bmv2InterpreterException {
 
-
         if (treatment.allInstructions().size() == 0) {
             // No instructions means drop for us.
-            return Bmv2Action.builder().withName(DROP).build();
+            return actionWithName(DROP);
         } else if (treatment.allInstructions().size() > 1) {
             // Otherwise, we understand treatments with only 1 instruction.
             throw new Bmv2InterpreterException("Treatment has multiple instructions");
@@ -78,47 +80,38 @@
         switch (instruction.type()) {
             case OUTPUT:
                 OutputInstruction outInstruction = (OutputInstruction) instruction;
-                if (outInstruction.port() == CONTROLLER) {
-                    return Bmv2Action.builder().withName(SEND_TO_CPU).build();
+                PortNumber port = outInstruction.port();
+                if (!port.isLogical()) {
+                    return buildEgressAction(port, configuration);
+                } else if (port.equals(CONTROLLER)) {
+                    return actionWithName(SEND_TO_CPU);
                 } else {
-                    return buildEgressAction(outInstruction, configuration);
+                    throw new Bmv2InterpreterException("Egress on logical port not supported: " + port);
                 }
             case NOACTION:
-                return Bmv2Action.builder().withName(DROP).build();
+                return actionWithName(DROP);
             default:
                 throw new Bmv2InterpreterException("Instruction type not supported: " + instruction.type().name());
         }
     }
 
-
-    /**
-     * Builds an egress action equivalent to the given output instruction for the given configuration.
-     *
-     * @param instruction   an output instruction
-     * @param configuration a configuration
-     * @return a BMv2 action
-     * @throws Bmv2InterpreterException if the instruction cannot be translated to a BMv2 action
-     */
-    private Bmv2Action buildEgressAction(OutputInstruction instruction, Bmv2Configuration configuration)
+    private Bmv2Action buildEgressAction(PortNumber port, Bmv2Configuration configuration)
             throws Bmv2InterpreterException {
 
-        Bmv2Action.Builder actionBuilder = Bmv2Action.builder();
+        int portBitWidth = configuration.action(SET_EGRESS_PORT).runtimeData(PORT).bitWidth();
 
-        actionBuilder.withName(SET_EGRESS_PORT);
-
-        if (instruction.port().isLogical()) {
-            throw new Bmv2InterpreterException("Output on logic port not supported: " + instruction);
-        }
-
-        // Get the byte sequence for the out port with the right length
-        long portNumber = instruction.port().toLong();
-        int bitWidth = configuration.action(SET_EGRESS_PORT).runtimeData("port").bitWidth();
         try {
-            ImmutableByteSequence outPort = Bmv2TranslatorUtils.fitByteSequence(
-                    ImmutableByteSequence.copyFrom(portNumber), bitWidth);
-            return Bmv2Action.builder().withName(SET_EGRESS_PORT).addParameter(outPort).build();
-        } catch (Bmv2TranslatorUtils.ByteSequenceFitException e) {
+            ImmutableByteSequence portBs = fitByteSequence(copyFrom(port.toLong()), portBitWidth);
+            return Bmv2Action.builder()
+                    .withName(SET_EGRESS_PORT)
+                    .addParameter(portBs)
+                    .build();
+        } catch (ByteSequenceFitException e) {
             throw new Bmv2InterpreterException(e.getMessage());
         }
     }
+
+    private Bmv2Action actionWithName(String name) {
+        return Bmv2Action.builder().withName(name).build();
+    }
 }
diff --git a/protocols/bmv2/ctl/src/main/java/org/onosproject/bmv2/ctl/Bmv2FlowRuleTranslatorImpl.java b/protocols/bmv2/ctl/src/main/java/org/onosproject/bmv2/ctl/Bmv2FlowRuleTranslatorImpl.java
index b3c1e8a..ef9427e 100644
--- a/protocols/bmv2/ctl/src/main/java/org/onosproject/bmv2/ctl/Bmv2FlowRuleTranslatorImpl.java
+++ b/protocols/bmv2/ctl/src/main/java/org/onosproject/bmv2/ctl/Bmv2FlowRuleTranslatorImpl.java
@@ -241,7 +241,7 @@
 
         if (extTreatment.type() == ExtensionTreatmentTypes.BMV2_ACTION.type()) {
             if (extTreatment instanceof Bmv2ExtensionTreatment) {
-                return ((Bmv2ExtensionTreatment) extTreatment).getAction();
+                return ((Bmv2ExtensionTreatment) extTreatment).action();
             } else {
                 throw new Bmv2FlowRuleTranslatorException("Unable to decode treatment extension: " + extTreatment);
             }