Minor model refactor
[openflowjava.git] / openflow-protocol-impl / src / main / java / org / opendaylight / openflowjava / protocol / impl / util / ActionsSerializer.java
index c7e07ee716f179494a941388af99c22eba5a4fa3..6c26cc2c65e1c9a879a2ff407cc558cea726e511 100644 (file)
-/* Copyright (C)2013 Pantheon Technologies, s.r.o. All rights reserved. */\r
-package org.opendaylight.openflowjava.protocol.impl.util;\r
-\r
-import io.netty.buffer.ByteBuf;\r
-\r
-import java.util.List;\r
-\r
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.EthertypeAction;\r
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.ExperimenterAction;\r
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.GroupIdAction;\r
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.MaxLengthAction;\r
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.MplsTtlAction;\r
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.NwTtlAction;\r
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.OxmFieldsAction;\r
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.PortAction;\r
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.QueueIdAction;\r
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev130731.CopyTtlIn;\r
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev130731.CopyTtlOut;\r
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev130731.DecMplsTtl;\r
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev130731.DecNwTtl;\r
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev130731.Experimenter;\r
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev130731.Group;\r
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev130731.Output;\r
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev130731.PopMpls;\r
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev130731.PopPbb;\r
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev130731.PopVlan;\r
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev130731.PushMpls;\r
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev130731.PushPbb;\r
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev130731.PushVlan;\r
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev130731.SetField;\r
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev130731.SetMplsTtl;\r
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev130731.SetNwTtl;\r
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev130731.SetQueue;\r
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev130731.actions.ActionsList;\r
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev130731.actions.actions.list.Action;\r
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev130731.oxm.fields.MatchEntries;\r
-\r
-/**\r
- * Serializes ofp_actions (OpenFlow v1.3)\r
- * @author michal.polkorab\r
- * @author timotej.kubas\r
- */\r
-public abstract class ActionsSerializer {\r
-\r
-    /**\r
-     * Encodes actions to ByteBuf\r
-     * @param actionsList list of actions to be encoded\r
-     * @param outBuffer output ByteBuf\r
-     */\r
-    public static void encodeActions(List<ActionsList> actionsList, ByteBuf outBuffer) {\r
-        if (actionsList == null) {\r
-            return;\r
-        }\r
-        for (ActionsList list : actionsList) {\r
-            Action action = list.getAction();\r
-            if (action.getType().isAssignableFrom(Output.class)) {\r
-                encodeOutputAction(action, outBuffer);\r
-            } else if (action.getType().isAssignableFrom(CopyTtlOut.class)) {\r
-                encodeCopyTtlOutAction(outBuffer);\r
-            } else if (action.getType().isAssignableFrom(CopyTtlIn.class)) {\r
-                encodeCopyTtlInAction(outBuffer);\r
-            } else if (action.getType().isAssignableFrom(SetMplsTtl.class)) {\r
-                encodeSetMplsTtltAction(action, outBuffer);\r
-            } else if (action.getType().isAssignableFrom(DecMplsTtl.class)) {\r
-                encodeDecMplsTtlAction(outBuffer);\r
-            } else if (action.getType().isAssignableFrom(PushVlan.class)) {\r
-                encodePushVlanAction(action, outBuffer);\r
-            } else if (action.getType().isAssignableFrom(PopVlan.class)) {\r
-                encodePopVlanAction(outBuffer);\r
-            } else if (action.getType().isAssignableFrom(PushMpls.class)) {\r
-                encodePushMplsAction(action, outBuffer);\r
-            } else if (action.getType().isAssignableFrom(PopMpls.class)) {\r
-                encodePopMplsAction(action, outBuffer);\r
-            } else if (action.getType().isAssignableFrom(SetQueue.class)) {\r
-                encodeSetQueueAction(action, outBuffer);\r
-            } else if (action.getType().isAssignableFrom(Group.class)) {\r
-                encodeGroupAction(action, outBuffer);\r
-            } else if (action.getType().isAssignableFrom(SetNwTtl.class)) {\r
-                encodeSetNwTtlAction(action, outBuffer);\r
-            } else if (action.getType().isAssignableFrom(DecNwTtl.class)) {\r
-                encodeDecNwTtlAction(outBuffer);\r
-            } else if (action.getType().isAssignableFrom(SetField.class)) {\r
-                encodeSetFieldAction(action, outBuffer);\r
-            } else if (action.getType().isAssignableFrom(PushPbb.class)) {\r
-                encodePushPbbAction(action, outBuffer);\r
-            } else if (action.getType().isAssignableFrom(PopPbb.class)) {\r
-                encodePopPbbAction(outBuffer);\r
-            } else if (action.getType().isAssignableFrom(Experimenter.class)) {\r
-                encodeExperimenterAction(action, outBuffer);\r
-            } \r
-        }\r
-    }\r
-\r
-    private static void encodeOutputAction(Action action, ByteBuf outBuffer) {\r
-        final byte OUTPUT_CODE = 0;\r
-        final byte OUTPUT_LENGTH = 16;\r
-        final byte OUTPUT_PADDING = 6;\r
-        outBuffer.writeShort(OUTPUT_CODE);\r
-        outBuffer.writeShort(OUTPUT_LENGTH);\r
-        PortAction port = action.getAugmentation(PortAction.class);\r
-        outBuffer.writeInt(port.getPort().getValue().intValue());\r
-        MaxLengthAction maxlength = action.getAugmentation(MaxLengthAction.class);\r
-        outBuffer.writeShort(maxlength.getMaxLength());\r
-        ByteBufUtils.padBuffer(OUTPUT_PADDING, outBuffer);\r
-    }\r
-\r
-    private static void encodeCopyTtlOutAction(ByteBuf outBuffer) {\r
-        final byte COPY_TTL_OUT_CODE = 11;\r
-        outBuffer.writeShort(COPY_TTL_OUT_CODE);\r
-        encodeRestOfActionHeader(outBuffer);\r
-    }\r
-    \r
-    private static void encodeCopyTtlInAction(ByteBuf outBuffer) {\r
-        final byte COPY_TTL_IN_CODE = 12;\r
-        outBuffer.writeShort(COPY_TTL_IN_CODE);\r
-        encodeRestOfActionHeader(outBuffer);\r
-    }\r
-    \r
-    private static void encodeSetMplsTtltAction(Action action, ByteBuf outBuffer) {\r
-        final byte SET_MPLS_TTL_CODE = 15;\r
-        final byte SET_MPLS_TTL_LENGTH = 8;\r
-        final byte SET_MPLS_TTL_PADDING = 3;\r
-        outBuffer.writeShort(SET_MPLS_TTL_CODE);\r
-        outBuffer.writeShort(SET_MPLS_TTL_LENGTH);\r
-        MplsTtlAction mplsTtl = action.getAugmentation(MplsTtlAction.class);\r
-        outBuffer.writeByte(mplsTtl.getMplsTtl());\r
-        ByteBufUtils.padBuffer(SET_MPLS_TTL_PADDING, outBuffer);\r
-    }\r
-    \r
-    private static void encodeDecMplsTtlAction(ByteBuf outBuffer) {\r
-        final byte DEC_MPLS_TTL_CODE = 16;\r
-        outBuffer.writeShort(DEC_MPLS_TTL_CODE);\r
-        encodeRestOfActionHeader(outBuffer);\r
-    }\r
-    \r
-    private static void encodePushVlanAction(Action action, ByteBuf outBuffer) {\r
-        final byte PUSH_VLAN_CODE = 17;\r
-        outBuffer.writeShort(PUSH_VLAN_CODE);\r
-        encodeCommonEthertype(action, outBuffer);\r
-    }\r
-\r
-    private static void encodePopVlanAction(ByteBuf outBuffer) {\r
-        final byte POP_VLAN_CODE = 18;\r
-        outBuffer.writeShort(POP_VLAN_CODE);\r
-        encodeRestOfActionHeader(outBuffer);\r
-    }\r
-    \r
-    private static void encodePushMplsAction(Action action, ByteBuf outBuffer) {\r
-        final byte PUSH_MPLS_CODE = 19;\r
-        outBuffer.writeShort(PUSH_MPLS_CODE);\r
-        encodeCommonEthertype(action, outBuffer);\r
-    }\r
-    \r
-    private static void encodePopMplsAction(Action action, ByteBuf outBuffer) {\r
-        final byte POP_MPLS_CODE = 20;\r
-        outBuffer.writeShort(POP_MPLS_CODE);\r
-        encodeCommonEthertype(action, outBuffer);\r
-    }\r
-    \r
-    private static void encodeSetQueueAction(Action action, ByteBuf outBuffer) {\r
-        final byte SET_QUEUE_CODE = 21;\r
-        final byte SET_QUEUE_LENGTH = 8;\r
-        outBuffer.writeShort(SET_QUEUE_CODE);\r
-        outBuffer.writeShort(SET_QUEUE_LENGTH);\r
-        QueueIdAction queueId = action.getAugmentation(QueueIdAction.class);\r
-        outBuffer.writeInt(queueId.getQueueId().intValue());\r
-    }\r
-\r
-    private static void encodeGroupAction(Action action, ByteBuf outBuffer) {\r
-        final byte GROUP_CODE = 22;\r
-        final byte GROUP_LENGTH = 8;\r
-        outBuffer.writeShort(GROUP_CODE);\r
-        outBuffer.writeShort(GROUP_LENGTH);\r
-        GroupIdAction groupId = action.getAugmentation(GroupIdAction.class);\r
-        outBuffer.writeInt(groupId.getGroupId().intValue());\r
-    }\r
-    \r
-    private static void encodeSetNwTtlAction(Action action, ByteBuf outBuffer) {\r
-        final byte SET_NW_TTL_CODE = 23;\r
-        final byte SET_NW_TTL_LENGTH = 8;\r
-        final byte SET_NW_TTL_PADDING = 3;\r
-        outBuffer.writeShort(SET_NW_TTL_CODE);\r
-        outBuffer.writeShort(SET_NW_TTL_LENGTH);\r
-        NwTtlAction nwTtl = action.getAugmentation(NwTtlAction.class);\r
-        outBuffer.writeByte(nwTtl.getNwTtl());\r
-        ByteBufUtils.padBuffer(SET_NW_TTL_PADDING, outBuffer);\r
-    }\r
-    \r
-    private static void encodeDecNwTtlAction(ByteBuf outBuffer) {\r
-        final byte DEC_NW_TTL_CODE = 24;\r
-        outBuffer.writeShort(DEC_NW_TTL_CODE);\r
-        encodeRestOfActionHeader(outBuffer);\r
-    }\r
-    \r
-    private static void encodeSetFieldAction(Action action, ByteBuf outBuffer) {\r
-        final int SET_FIELD_CODE = 25;\r
-        final byte SET_FIELD_HEADER_LENGTH = 4; // only type and length\r
-        OxmFieldsAction oxmField = action.getAugmentation(OxmFieldsAction.class);\r
-        int length = MatchSerializer.computeMatchEntriesLength(oxmField.getMatchEntries()) + SET_FIELD_HEADER_LENGTH;\r
-        outBuffer.writeShort(SET_FIELD_CODE);\r
-        int paddingRemainder = length % EncodeConstants.PADDING;\r
-        if (paddingRemainder != 0) {\r
-            length += EncodeConstants.PADDING - paddingRemainder;\r
-        }\r
-        outBuffer.writeShort(length);\r
-        MatchSerializer.encodeMatchEntries(oxmField.getMatchEntries(), outBuffer);\r
-        ByteBufUtils.padBuffer(EncodeConstants.PADDING - paddingRemainder, outBuffer);\r
-    }\r
-    \r
-    private static void encodePushPbbAction(Action action, ByteBuf outBuffer) {\r
-        final byte PUSH_PBB_CODE = 26;\r
-        outBuffer.writeShort(PUSH_PBB_CODE);\r
-        encodeCommonEthertype(action, outBuffer);\r
-    }\r
-    \r
-    private static void encodePopPbbAction(ByteBuf outBuffer) {\r
-        final byte POP_PBB_CODE = 27;\r
-        outBuffer.writeShort(POP_PBB_CODE);\r
-        encodeRestOfActionHeader(outBuffer);\r
-    }\r
-\r
-    private static void encodeExperimenterAction(Action action, ByteBuf outBuffer) {\r
-        final int EXPERIMENTER_CODE = 65535; // 0xFFFF\r
-        final byte EXPERIMENTER_LENGTH = 8;\r
-        outBuffer.writeShort(EXPERIMENTER_CODE);\r
-        outBuffer.writeShort(EXPERIMENTER_LENGTH);\r
-        ExperimenterAction experimenter = action.getAugmentation(ExperimenterAction.class);\r
-        outBuffer.writeInt(experimenter.getExperimenter().intValue());\r
-    }\r
-    \r
-    private static void encodeRestOfActionHeader(ByteBuf outBuffer) {\r
-        final byte ACTION_HEADER_LENGTH = 8;\r
-        final byte PADDING_IN_ACTION_HEADER = 4;\r
-        outBuffer.writeShort(ACTION_HEADER_LENGTH);\r
-        ByteBufUtils.padBuffer(PADDING_IN_ACTION_HEADER, outBuffer);\r
-    }\r
-    \r
-    private static void encodeCommonEthertype(Action action, ByteBuf outBuffer) {\r
-        final byte LENGTH_OF_ETHERTYPE_ACTION = 8;\r
-        final byte ETHERTYPE_ACTION_PADDING = 2;\r
-        outBuffer.writeShort(LENGTH_OF_ETHERTYPE_ACTION);\r
-        EthertypeAction ethertype = action.getAugmentation(EthertypeAction.class);\r
-        outBuffer.writeShort(ethertype.getEthertype().getValue());\r
-        ByteBufUtils.padBuffer(ETHERTYPE_ACTION_PADDING, outBuffer);\r
-    }\r
-    \r
-    /**\r
-     * Computes length of actions\r
-     * @param actionsList list of actions\r
-     * @return actions length\r
-     */\r
-    public static int computeLengthOfActions(List<ActionsList> actionsList) {\r
-        final byte OUTPUT_LENGTH = 16;\r
-        final byte LENGTH_OF_OTHER_ACTIONS = 8;\r
-        final byte ACTION_HEADER_LENGTH = 4;\r
-        int lengthOfActions = 0;\r
-        if (actionsList != null) {\r
-            for (ActionsList list : actionsList) {\r
-                Action action = list.getAction();\r
-                if (action.getType().isAssignableFrom(Output.class)) {\r
-                    lengthOfActions += OUTPUT_LENGTH;\r
-                } else if (action.getType().isAssignableFrom(SetField.class)){\r
-                    List<MatchEntries> entries = action.getAugmentation(OxmFieldsAction.class).getMatchEntries();\r
-                    int actionLength = ACTION_HEADER_LENGTH + MatchSerializer.computeMatchEntriesLength(entries);\r
-                    lengthOfActions += actionLength;\r
-                    int paddingRemainder = actionLength % EncodeConstants.PADDING;\r
-                    if ((paddingRemainder) != 0) {\r
-                        lengthOfActions += EncodeConstants.PADDING - paddingRemainder;\r
-                    }\r
-                } else {\r
-                    lengthOfActions += LENGTH_OF_OTHER_ACTIONS;\r
-                }\r
-            }\r
-        }\r
-        return lengthOfActions;\r
-    }\r
-}\r
+/*
+ * Copyright (c) 2013 Pantheon Technologies s.r.o. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.openflowjava.protocol.impl.util;
+
+import io.netty.buffer.ByteBuf;
+
+import java.util.List;
+
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.EthertypeAction;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.ExperimenterAction;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.GroupIdAction;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.MaxLengthAction;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.MplsTtlAction;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.NwTtlAction;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.OxmFieldsAction;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.PortAction;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.QueueIdAction;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev130731.CopyTtlIn;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev130731.CopyTtlOut;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev130731.DecMplsTtl;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev130731.DecNwTtl;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev130731.Experimenter;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev130731.Group;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev130731.Output;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev130731.PopMpls;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev130731.PopPbb;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev130731.PopVlan;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev130731.PushMpls;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev130731.PushPbb;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev130731.PushVlan;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev130731.SetField;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev130731.SetMplsTtl;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev130731.SetNwTtl;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev130731.SetQueue;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev130731.actions.grouping.Action;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev130731.oxm.fields.grouping.MatchEntries;
+
+/**
+ * Serializes ofp_actions (OpenFlow v1.3)
+ * @author michal.polkorab
+ * @author timotej.kubas
+ */
+public abstract class ActionsSerializer {
+
+    private static final byte OUTPUT_CODE = 0;
+    private static final byte COPY_TTL_OUT_CODE = 11;
+    private static final byte COPY_TTL_IN_CODE = 12;
+    private static final byte SET_MPLS_TTL_CODE = 15;
+    private static final byte DEC_MPLS_TTL_CODE = 16;
+    private static final byte PUSH_VLAN_CODE = 17;
+    private static final byte POP_VLAN_CODE = 18;
+    private static final byte PUSH_MPLS_CODE = 19;
+    private static final byte POP_MPLS_CODE = 20;
+    private static final byte SET_QUEUE_CODE = 21;
+    private static final byte GROUP_CODE = 22;
+    private static final byte SET_NW_TTL_CODE = 23;
+    private static final byte DEC_NW_TTL_CODE = 24;
+    private static final int SET_FIELD_CODE = 25;
+    private static final byte PUSH_PBB_CODE = 26;
+    private static final byte POP_PBB_CODE = 27;
+    private static final int EXPERIMENTER_CODE = 65535; // 0xFFFF
+    private static final byte OUTPUT_LENGTH = 16;
+    private static final byte SET_MPLS_TTL_LENGTH = 8;
+    private static final byte SET_QUEUE_LENGTH = 8;
+    private static final byte GROUP_LENGTH = 8;
+    private static final byte SET_NW_TTL_LENGTH = 8;
+    private static final byte EXPERIMENTER_LENGTH = 8;
+    private static final byte ACTION_HEADER_LENGTH = 8;
+    private static final byte LENGTH_OF_ETHERTYPE_ACTION = 8;
+    private static final byte LENGTH_OF_OTHER_ACTIONS = 8;
+    private static final byte SET_FIELD_HEADER_LENGTH = 4; // only type and length
+    private static final byte OUTPUT_PADDING = 6;
+    private static final byte SET_MPLS_TTL_PADDING = 3;
+    private static final byte SET_NW_TTL_PADDING = 3;
+    private static final byte PADDING_IN_ACTION_HEADER = 4;
+    private static final byte ETHERTYPE_ACTION_PADDING = 2;
+    private static final byte ACTION_IDS_LENGTH = 4;
+
+
+    /**
+     * Encodes actions to ByteBuf
+     * @param actionsList list of actions to be encoded
+     * @param outBuffer output ByteBuf
+     */
+    public static void encodeActions(List<Action> actionsList, ByteBuf outBuffer) {
+        if (actionsList == null) {
+            return;
+        }
+        for (Action action : actionsList) {
+            if (action.getType().isAssignableFrom(Output.class)) {
+                encodeOutputAction(action, outBuffer);
+            } else if (action.getType().isAssignableFrom(CopyTtlOut.class)) {
+                encodeCopyTtlOutAction(outBuffer);
+            } else if (action.getType().isAssignableFrom(CopyTtlIn.class)) {
+                encodeCopyTtlInAction(outBuffer);
+            } else if (action.getType().isAssignableFrom(SetMplsTtl.class)) {
+                encodeSetMplsTtltAction(action, outBuffer);
+            } else if (action.getType().isAssignableFrom(DecMplsTtl.class)) {
+                encodeDecMplsTtlAction(outBuffer);
+            } else if (action.getType().isAssignableFrom(PushVlan.class)) {
+                encodePushVlanAction(action, outBuffer);
+            } else if (action.getType().isAssignableFrom(PopVlan.class)) {
+                encodePopVlanAction(outBuffer);
+            } else if (action.getType().isAssignableFrom(PushMpls.class)) {
+                encodePushMplsAction(action, outBuffer);
+            } else if (action.getType().isAssignableFrom(PopMpls.class)) {
+                encodePopMplsAction(action, outBuffer);
+            } else if (action.getType().isAssignableFrom(SetQueue.class)) {
+                encodeSetQueueAction(action, outBuffer);
+            } else if (action.getType().isAssignableFrom(Group.class)) {
+                encodeGroupAction(action, outBuffer);
+            } else if (action.getType().isAssignableFrom(SetNwTtl.class)) {
+                encodeSetNwTtlAction(action, outBuffer);
+            } else if (action.getType().isAssignableFrom(DecNwTtl.class)) {
+                encodeDecNwTtlAction(outBuffer);
+            } else if (action.getType().isAssignableFrom(SetField.class)) {
+                encodeSetFieldAction(action, outBuffer);
+            } else if (action.getType().isAssignableFrom(PushPbb.class)) {
+                encodePushPbbAction(action, outBuffer);
+            } else if (action.getType().isAssignableFrom(PopPbb.class)) {
+                encodePopPbbAction(outBuffer);
+            } else if (action.getType().isAssignableFrom(Experimenter.class)) {
+                encodeExperimenterAction(action, outBuffer);
+            } 
+        }
+    }
+    
+    /**
+     * Encodes action ids to ByteBuf (for Multipart - TableFeatures messages)
+     * @param actionsList list of actions to be encoded
+     * @param outBuffer output ByteBuf
+     */
+    public static void encodeActionIds(List<Action> actionsList, ByteBuf outBuffer) {
+        if (actionsList == null) {
+            return;
+        }
+        for (Action action : actionsList) {
+            if (action.getType().isAssignableFrom(Output.class)) {
+                writeTypeAndLength(outBuffer, OUTPUT_CODE, ACTION_IDS_LENGTH);
+            } else if (action.getType().isAssignableFrom(CopyTtlOut.class)) {
+                writeTypeAndLength(outBuffer, COPY_TTL_OUT_CODE, ACTION_IDS_LENGTH);
+            } else if (action.getType().isAssignableFrom(CopyTtlIn.class)) {
+                writeTypeAndLength(outBuffer, COPY_TTL_IN_CODE, ACTION_IDS_LENGTH);
+            } else if (action.getType().isAssignableFrom(SetMplsTtl.class)) {
+                writeTypeAndLength(outBuffer, SET_MPLS_TTL_CODE, ACTION_IDS_LENGTH);
+            } else if (action.getType().isAssignableFrom(DecMplsTtl.class)) {
+                writeTypeAndLength(outBuffer, DEC_MPLS_TTL_CODE, ACTION_IDS_LENGTH);
+            } else if (action.getType().isAssignableFrom(PushVlan.class)) {
+                writeTypeAndLength(outBuffer, PUSH_VLAN_CODE, ACTION_IDS_LENGTH);
+            } else if (action.getType().isAssignableFrom(PopVlan.class)) {
+                writeTypeAndLength(outBuffer, POP_VLAN_CODE, ACTION_IDS_LENGTH);
+            } else if (action.getType().isAssignableFrom(PushMpls.class)) {
+                writeTypeAndLength(outBuffer, PUSH_MPLS_CODE, ACTION_IDS_LENGTH);
+            } else if (action.getType().isAssignableFrom(PopMpls.class)) {
+                writeTypeAndLength(outBuffer, POP_MPLS_CODE, ACTION_IDS_LENGTH);
+            } else if (action.getType().isAssignableFrom(SetQueue.class)) {
+                writeTypeAndLength(outBuffer, SET_QUEUE_CODE, ACTION_IDS_LENGTH);
+            } else if (action.getType().isAssignableFrom(Group.class)) {
+                writeTypeAndLength(outBuffer, GROUP_CODE, ACTION_IDS_LENGTH);
+            } else if (action.getType().isAssignableFrom(SetNwTtl.class)) {
+                writeTypeAndLength(outBuffer, SET_NW_TTL_CODE, ACTION_IDS_LENGTH);
+            } else if (action.getType().isAssignableFrom(DecNwTtl.class)) {
+                writeTypeAndLength(outBuffer, DEC_NW_TTL_CODE, ACTION_IDS_LENGTH);
+            } else if (action.getType().isAssignableFrom(SetField.class)) {
+                writeTypeAndLength(outBuffer, SET_FIELD_CODE, ACTION_IDS_LENGTH);
+            } else if (action.getType().isAssignableFrom(PushPbb.class)) {
+                writeTypeAndLength(outBuffer, PUSH_PBB_CODE, ACTION_IDS_LENGTH);
+            } else if (action.getType().isAssignableFrom(PopPbb.class)) {
+                writeTypeAndLength(outBuffer, POP_PBB_CODE, ACTION_IDS_LENGTH);
+            } else if (action.getType().isAssignableFrom(Experimenter.class)) {
+                writeTypeAndLength(outBuffer, EXPERIMENTER_CODE, EncodeConstants.EXPERIMENTER_IDS_LENGTH);
+                ExperimenterAction experimenter = action.getAugmentation(ExperimenterAction.class);
+                outBuffer.writeInt(experimenter.getExperimenter().intValue());
+            } 
+        }
+    }
+    
+    private static void writeTypeAndLength(ByteBuf out, int type, int length) {
+        out.writeShort(type);
+        out.writeShort(length);
+    }
+
+    private static void encodeOutputAction(Action action, ByteBuf outBuffer) {
+        outBuffer.writeShort(OUTPUT_CODE);
+        outBuffer.writeShort(OUTPUT_LENGTH);
+        PortAction port = action.getAugmentation(PortAction.class);
+        outBuffer.writeInt(port.getPort().getValue().intValue());
+        MaxLengthAction maxlength = action.getAugmentation(MaxLengthAction.class);
+        outBuffer.writeShort(maxlength.getMaxLength());
+        ByteBufUtils.padBuffer(OUTPUT_PADDING, outBuffer);
+    }
+
+    private static void encodeCopyTtlOutAction(ByteBuf outBuffer) {
+        outBuffer.writeShort(COPY_TTL_OUT_CODE);
+        encodeRestOfActionHeader(outBuffer);
+    }
+    
+    private static void encodeCopyTtlInAction(ByteBuf outBuffer) {
+        outBuffer.writeShort(COPY_TTL_IN_CODE);
+        encodeRestOfActionHeader(outBuffer);
+    }
+    
+    private static void encodeSetMplsTtltAction(Action action, ByteBuf outBuffer) {
+        outBuffer.writeShort(SET_MPLS_TTL_CODE);
+        outBuffer.writeShort(SET_MPLS_TTL_LENGTH);
+        MplsTtlAction mplsTtl = action.getAugmentation(MplsTtlAction.class);
+        outBuffer.writeByte(mplsTtl.getMplsTtl());
+        ByteBufUtils.padBuffer(SET_MPLS_TTL_PADDING, outBuffer);
+    }
+    
+    private static void encodeDecMplsTtlAction(ByteBuf outBuffer) {
+        outBuffer.writeShort(DEC_MPLS_TTL_CODE);
+        encodeRestOfActionHeader(outBuffer);
+    }
+    
+    private static void encodePushVlanAction(Action action, ByteBuf outBuffer) {
+        outBuffer.writeShort(PUSH_VLAN_CODE);
+        encodeCommonEthertype(action, outBuffer);
+    }
+
+    private static void encodePopVlanAction(ByteBuf outBuffer) {
+        outBuffer.writeShort(POP_VLAN_CODE);
+        encodeRestOfActionHeader(outBuffer);
+    }
+    
+    private static void encodePushMplsAction(Action action, ByteBuf outBuffer) {
+        outBuffer.writeShort(PUSH_MPLS_CODE);
+        encodeCommonEthertype(action, outBuffer);
+    }
+    
+    private static void encodePopMplsAction(Action action, ByteBuf outBuffer) {
+        outBuffer.writeShort(POP_MPLS_CODE);
+        encodeCommonEthertype(action, outBuffer);
+    }
+    
+    private static void encodeSetQueueAction(Action action, ByteBuf outBuffer) {
+        outBuffer.writeShort(SET_QUEUE_CODE);
+        outBuffer.writeShort(SET_QUEUE_LENGTH);
+        QueueIdAction queueId = action.getAugmentation(QueueIdAction.class);
+        outBuffer.writeInt(queueId.getQueueId().intValue());
+    }
+
+    private static void encodeGroupAction(Action action, ByteBuf outBuffer) {
+        outBuffer.writeShort(GROUP_CODE);
+        outBuffer.writeShort(GROUP_LENGTH);
+        GroupIdAction groupId = action.getAugmentation(GroupIdAction.class);
+        outBuffer.writeInt(groupId.getGroupId().intValue());
+    }
+    
+    private static void encodeSetNwTtlAction(Action action, ByteBuf outBuffer) {
+        outBuffer.writeShort(SET_NW_TTL_CODE);
+        outBuffer.writeShort(SET_NW_TTL_LENGTH);
+        NwTtlAction nwTtl = action.getAugmentation(NwTtlAction.class);
+        outBuffer.writeByte(nwTtl.getNwTtl());
+        ByteBufUtils.padBuffer(SET_NW_TTL_PADDING, outBuffer);
+    }
+    
+    private static void encodeDecNwTtlAction(ByteBuf outBuffer) {
+        outBuffer.writeShort(DEC_NW_TTL_CODE);
+        encodeRestOfActionHeader(outBuffer);
+    }
+    
+    private static void encodeSetFieldAction(Action action, ByteBuf outBuffer) {
+        OxmFieldsAction oxmField = action.getAugmentation(OxmFieldsAction.class);
+        int length = MatchSerializer.computeMatchEntriesLength(oxmField.getMatchEntries()) + SET_FIELD_HEADER_LENGTH;
+        outBuffer.writeShort(SET_FIELD_CODE);
+        int paddingRemainder = length % EncodeConstants.PADDING;
+        if (paddingRemainder != 0) {
+            length += EncodeConstants.PADDING - paddingRemainder;
+        }
+        outBuffer.writeShort(length);
+        MatchSerializer.encodeMatchEntries(oxmField.getMatchEntries(), outBuffer);
+        if (paddingRemainder != 0) {
+            ByteBufUtils.padBuffer(EncodeConstants.PADDING - paddingRemainder, outBuffer);
+        }
+    }
+    
+    private static void encodePushPbbAction(Action action, ByteBuf outBuffer) {
+        outBuffer.writeShort(PUSH_PBB_CODE);
+        encodeCommonEthertype(action, outBuffer);
+    }
+    
+    private static void encodePopPbbAction(ByteBuf outBuffer) {
+        outBuffer.writeShort(POP_PBB_CODE);
+        encodeRestOfActionHeader(outBuffer);
+    }
+
+    private static void encodeExperimenterAction(Action action, ByteBuf outBuffer) {
+        outBuffer.writeShort(EXPERIMENTER_CODE);
+        outBuffer.writeShort(EXPERIMENTER_LENGTH);
+        ExperimenterAction experimenter = action.getAugmentation(ExperimenterAction.class);
+        outBuffer.writeInt(experimenter.getExperimenter().intValue());
+    }
+    
+    private static void encodeRestOfActionHeader(ByteBuf outBuffer) {
+        outBuffer.writeShort(ACTION_HEADER_LENGTH);
+        ByteBufUtils.padBuffer(PADDING_IN_ACTION_HEADER, outBuffer);
+    }
+    
+    private static void encodeCommonEthertype(Action action, ByteBuf outBuffer) {
+        EthertypeAction ethertype = action.getAugmentation(EthertypeAction.class);
+        outBuffer.writeShort(LENGTH_OF_ETHERTYPE_ACTION);
+        outBuffer.writeShort(ethertype.getEthertype().getValue());
+        ByteBufUtils.padBuffer(ETHERTYPE_ACTION_PADDING, outBuffer);
+    }
+    
+    /**
+     * Computes length of actions
+     * @param actionsList list of actions
+     * @return actions length
+     */
+    public static int computeLengthOfActions(List<Action> actionsList) {
+        int lengthOfActions = 0;
+        if (actionsList != null) {
+            for (Action action : actionsList) {
+                if (action.getType().isAssignableFrom(Output.class)) {
+                    lengthOfActions += OUTPUT_LENGTH;
+                } else if (action.getType().isAssignableFrom(SetField.class)){
+                    List<MatchEntries> entries = action.getAugmentation(OxmFieldsAction.class).getMatchEntries();
+                    int actionLength = (2 * EncodeConstants.SIZE_OF_SHORT_IN_BYTES) + MatchSerializer.computeMatchEntriesLength(entries);
+                    lengthOfActions += actionLength;
+                    int paddingRemainder = actionLength % EncodeConstants.PADDING;
+                    if ((paddingRemainder) != 0) {
+                        lengthOfActions += EncodeConstants.PADDING - paddingRemainder;
+                    }
+                } else {
+                    lengthOfActions += LENGTH_OF_OTHER_ACTIONS;
+                }
+            }
+        }
+        return lengthOfActions;
+    }
+}