changes for config subsystem - BUG 754
[openflowjava.git] / openflow-protocol-impl / src / main / java / org / opendaylight / openflowjava / protocol / impl / util / InstructionsSerializer.java
index 8106459c631edac39244c9065e7289b4afeaf24a..b652432c3cb6cbda4ec34694c8a774813a8a4edd 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.ActionsInstruction;\r
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.ExperimenterInstruction;\r
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.MetadataInstruction;\r
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.MeterIdInstruction;\r
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.TableIdInstruction;\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.instruction.rev130731.ApplyActions;\r
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.instruction.rev130731.ClearActions;\r
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.instruction.rev130731.Experimenter;\r
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.instruction.rev130731.GotoTable;\r
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.instruction.rev130731.Meter;\r
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.instruction.rev130731.WriteActions;\r
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.instruction.rev130731.WriteMetadata;\r
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.instruction.rev130731.instructions.Instructions;\r
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.Instruction;\r
-\r
-/**\r
- * Serializes ofp_instruction (OpenFlow v 1.3) structure\r
- * @author michal.polkorab\r
- * @author timotej.kubas\r
- */\r
-public abstract class InstructionsSerializer {\r
-\r
-    /**\r
-     * Encodes instructions\r
-     * @param instructions List of instructions\r
-     * @param out output buffer\r
-     */\r
-    public static void encodeInstructions(List<Instructions> instructions, ByteBuf out) {\r
-        if (instructions != null) {\r
-            for (Instructions instruction : instructions) {\r
-                Class<? extends Instruction> type = instruction.getType();\r
-                if (type.isAssignableFrom(GotoTable.class)) {\r
-                    final byte GOTO_TABLE_TYPE = 1;\r
-                    final byte GOTO_TABLE_LENGTH = 8;\r
-                    final byte PADDING_IN_GOTO_TABLE = 3;\r
-                    writeTypeAndLength(out, GOTO_TABLE_TYPE, GOTO_TABLE_LENGTH);\r
-                    out.writeByte(instruction.getAugmentation(TableIdInstruction.class).getTableId());\r
-                    ByteBufUtils.padBuffer(PADDING_IN_GOTO_TABLE, out);\r
-                } else if (type.isAssignableFrom(WriteMetadata.class)) {\r
-                    final byte WRITE_METADATA_TYPE = 2;\r
-                    final byte WRITE_METADATA_LENGTH = 24;\r
-                    final byte PADDING_IN_WRITE_METADATA = 4;\r
-                    writeTypeAndLength(out, WRITE_METADATA_TYPE, WRITE_METADATA_LENGTH);\r
-                    ByteBufUtils.padBuffer(PADDING_IN_WRITE_METADATA, out);\r
-                    MetadataInstruction metadata = instruction.getAugmentation(MetadataInstruction.class);\r
-                    out.writeBytes(metadata.getMetadata());\r
-                    out.writeBytes(metadata.getMetadataMask());\r
-                } else if (type.isAssignableFrom(WriteActions.class)) {\r
-                    final byte WRITE_ACTIONS_TYPE = 3;\r
-                    writeActionsInstruction(out, instruction, WRITE_ACTIONS_TYPE);\r
-                } else if (type.isAssignableFrom(ApplyActions.class)) {\r
-                    final byte APPLY_ACTIONS_TYPE = 4;\r
-                    writeActionsInstruction(out, instruction, APPLY_ACTIONS_TYPE);\r
-                } else if (type.isAssignableFrom(ClearActions.class)) {\r
-                    final byte CLEAR_ACTIONS_TYPE = 5;\r
-                    final byte CLEAR_ACTIONS_LENGTH = 8;\r
-                    final byte PADDING_IN_CLEAR_ACTIONS = 4;\r
-                    writeTypeAndLength(out, CLEAR_ACTIONS_TYPE, CLEAR_ACTIONS_LENGTH);\r
-                    ByteBufUtils.padBuffer(PADDING_IN_CLEAR_ACTIONS, out);\r
-                } else if (type.isAssignableFrom(Meter.class)) {\r
-                    final byte METER_TYPE = 6;\r
-                    final byte METER_LENGTH = 8;\r
-                    writeTypeAndLength(out, METER_TYPE, METER_LENGTH);\r
-                    out.writeInt(instruction.getAugmentation(MeterIdInstruction.class).getMeterId().intValue());\r
-                } else if (type.isAssignableFrom(Experimenter.class)) {\r
-                    final byte EXPERIMENTER_TYPE = 7;\r
-                    final byte EXPERIMENTER_LENGTH = 8;\r
-                    ExperimenterInstruction experimenter = instruction.getAugmentation(ExperimenterInstruction.class);\r
-                    byte[] data = experimenter.getData();\r
-                    writeTypeAndLength(out, EXPERIMENTER_TYPE, EXPERIMENTER_LENGTH + data.length);\r
-                    out.writeInt(experimenter.getExperimenter().intValue());\r
-                    out.writeBytes(data);\r
-                }\r
-            }\r
-        }\r
-        \r
-    }\r
-\r
-    private static void writeTypeAndLength(ByteBuf out, int type, int length) {\r
-        out.writeShort(type);\r
-        out.writeShort(length);\r
-    }\r
-\r
-    private static void writeActionsInstruction(ByteBuf out,\r
-            Instructions instruction, int type) {\r
-        final byte ACTIONS_INSTRUCTION_LENGTH = 8;\r
-        final byte PADDING_IN_ACTIONS_INSTRUCTION = 4;\r
-        out.writeShort(type);\r
-        List<ActionsList> actions = instruction.getAugmentation(ActionsInstruction.class).getActionsList();\r
-        out.writeShort(ACTIONS_INSTRUCTION_LENGTH + ActionsSerializer.computeLengthOfActions(actions));\r
-        ByteBufUtils.padBuffer(PADDING_IN_ACTIONS_INSTRUCTION, out);\r
-        ActionsSerializer.encodeActions(actions, out);\r
-    }\r
-    \r
-    /**\r
-     * Computes length of instructions\r
-     * @param instructions List of instructions\r
-     * @return length of instructions (in bytes)\r
-     */\r
-    public static int computeInstructionsLength(List<Instructions> instructions) {\r
-        int length = 0;\r
-        if (instructions != null) {\r
-            for (Instructions instruction : instructions) {\r
-                Class<? extends Instruction> type = instruction.getType();\r
-                if (type.isAssignableFrom(GotoTable.class)) {\r
-                    final byte GOTO_TABLE_LENGTH = 8;\r
-                    length += GOTO_TABLE_LENGTH;\r
-                } else if (type.isAssignableFrom(WriteMetadata.class)) {\r
-                    final byte WRITE_METADATA_LENGTH = 24;\r
-                    length += WRITE_METADATA_LENGTH;\r
-                } else if (type.isAssignableFrom(WriteActions.class)) {\r
-                    final byte WRITE_ACTIONS_LENGTH = 8;\r
-                    length += WRITE_ACTIONS_LENGTH + ActionsSerializer.computeLengthOfActions(\r
-                            instruction.getAugmentation(ActionsInstruction.class).getActionsList());\r
-                } else if (type.isAssignableFrom(ApplyActions.class)) {\r
-                    final byte APPLY_ACTIONS_LENGTH = 8;\r
-                    length += APPLY_ACTIONS_LENGTH + ActionsSerializer.computeLengthOfActions(\r
-                            instruction.getAugmentation(ActionsInstruction.class).getActionsList());\r
-                } else if (type.isAssignableFrom(ClearActions.class)) {\r
-                    final byte CLEAR_ACTIONS_LENGTH = 8;\r
-                    length += CLEAR_ACTIONS_LENGTH;\r
-                } else if (type.isAssignableFrom(Meter.class)) {\r
-                    final byte METER_LENGTH = 8;\r
-                    length += METER_LENGTH;\r
-                } else if (type.isAssignableFrom(Experimenter.class)) {\r
-                    final byte EXPERIMENTER_LENGTH = 8;\r
-                    ExperimenterInstruction experimenter = instruction.getAugmentation(ExperimenterInstruction.class);\r
-                    byte[] data = experimenter.getData();\r
-                    length += EXPERIMENTER_LENGTH + data.length;\r
-                }\r
-            }\r
-        }\r
-        return length;\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.ActionsInstruction;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.ExperimenterInstruction;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.MetadataInstruction;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.MeterIdInstruction;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.TableIdInstruction;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev130731.actions.grouping.Action;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.instruction.rev130731.ApplyActions;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.instruction.rev130731.ClearActions;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.instruction.rev130731.Experimenter;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.instruction.rev130731.GotoTable;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.instruction.rev130731.Meter;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.instruction.rev130731.WriteActions;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.instruction.rev130731.WriteMetadata;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.instruction.rev130731.instructions.grouping.Instruction;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.InstructionBase;
+
+/**
+ * Serializes ofp_instruction (OpenFlow v 1.3) structure
+ * @author michal.polkorab
+ * @author timotej.kubas
+ */
+public abstract class InstructionsSerializer {
+
+    private static final byte GOTO_TABLE_TYPE = 1;
+    private static final byte WRITE_METADATA_TYPE = 2;
+    private static final byte WRITE_ACTIONS_TYPE = 3;
+    private static final byte APPLY_ACTIONS_TYPE = 4;
+    private static final byte CLEAR_ACTIONS_TYPE = 5;
+    private static final byte METER_TYPE = 6;
+    private static final byte EXPERIMENTER_TYPE = 7;
+    private static final byte GOTO_TABLE_LENGTH = 8;
+    private static final byte WRITE_METADATA_LENGTH = 24;
+    private static final byte METER_LENGTH = 8;
+    private static final byte EXPERIMENTER_LENGTH = 8;
+    private static final byte ACTIONS_INSTRUCTION_LENGTH = 8;
+    private static final byte PADDING_IN_GOTO_TABLE = 3;
+    private static final byte PADDING_IN_WRITE_METADATA = 4;
+    private static final byte PADDING_IN_CLEAR_ACTIONS = 4;
+    private static final byte INSTRUCTION_IDS_LENGTH = 4;
+    private static final byte PADDING_IN_ACTIONS_INSTRUCTION = 4;
+    
+    /**
+     * Encodes instructions
+     * @param instructions List of instructions
+     * @param out output buffer
+     */
+    public static void encodeInstructions(List<Instruction> instructions, ByteBuf out) {
+        if (instructions != null) {
+            for (Instruction instruction : instructions) {
+                Class<? extends InstructionBase> type = instruction.getType();
+                if (type.isAssignableFrom(GotoTable.class)) {
+                    writeTypeAndLength(out, GOTO_TABLE_TYPE, GOTO_TABLE_LENGTH);
+                    out.writeByte(instruction.getAugmentation(TableIdInstruction.class).getTableId());
+                    ByteBufUtils.padBuffer(PADDING_IN_GOTO_TABLE, out);
+                } else if (type.isAssignableFrom(WriteMetadata.class)) {
+                    writeTypeAndLength(out, WRITE_METADATA_TYPE, WRITE_METADATA_LENGTH);
+                    ByteBufUtils.padBuffer(PADDING_IN_WRITE_METADATA, out);
+                    MetadataInstruction metadata = instruction.getAugmentation(MetadataInstruction.class);
+                    out.writeBytes(metadata.getMetadata());
+                    out.writeBytes(metadata.getMetadataMask());
+                } else if (type.isAssignableFrom(WriteActions.class)) {
+                    writeActionsInstruction(out, instruction, WRITE_ACTIONS_TYPE);
+                } else if (type.isAssignableFrom(ApplyActions.class)) {
+                    writeActionsInstruction(out, instruction, APPLY_ACTIONS_TYPE);
+                } else if (type.isAssignableFrom(ClearActions.class)) {
+                    writeTypeAndLength(out, CLEAR_ACTIONS_TYPE, ACTIONS_INSTRUCTION_LENGTH);
+                    ByteBufUtils.padBuffer(PADDING_IN_CLEAR_ACTIONS, out);
+                } else if (type.isAssignableFrom(Meter.class)) {
+                    writeTypeAndLength(out, METER_TYPE, METER_LENGTH);
+                    out.writeInt(instruction.getAugmentation(MeterIdInstruction.class).getMeterId().intValue());
+                } else if (type.isAssignableFrom(Experimenter.class)) {
+                    ExperimenterInstruction experimenter = instruction.getAugmentation(ExperimenterInstruction.class);
+                    byte[] data = experimenter.getData();
+                    writeTypeAndLength(out, EXPERIMENTER_TYPE, EXPERIMENTER_LENGTH + data.length);
+                    out.writeInt(experimenter.getExperimenter().intValue());
+                    out.writeBytes(data);
+                }
+            }
+        }
+        
+    }
+    
+    /**
+     * Encodes instruction ids (for Multipart - TableFeatures messages)
+     * @param instructions List of instruction identifiers (without values)
+     * @param out output buffer
+     */
+    public static void encodeInstructionIds(List<Instruction> instructions, ByteBuf out) {
+        if (instructions != null) {
+            for (Instruction instruction : instructions) {
+                Class<? extends InstructionBase> type = instruction.getType();
+                if (type.isAssignableFrom(GotoTable.class)) {
+                    writeTypeAndLength(out, GOTO_TABLE_TYPE, INSTRUCTION_IDS_LENGTH);
+                } else if (type.isAssignableFrom(WriteMetadata.class)) {
+                    writeTypeAndLength(out, WRITE_METADATA_TYPE, INSTRUCTION_IDS_LENGTH);
+                } else if (type.isAssignableFrom(WriteActions.class)) {
+                    writeTypeAndLength(out, WRITE_ACTIONS_TYPE, INSTRUCTION_IDS_LENGTH);
+                } else if (type.isAssignableFrom(ApplyActions.class)) {
+                    writeTypeAndLength(out, APPLY_ACTIONS_TYPE, INSTRUCTION_IDS_LENGTH);
+                } else if (type.isAssignableFrom(ClearActions.class)) {
+                    writeTypeAndLength(out, CLEAR_ACTIONS_TYPE, INSTRUCTION_IDS_LENGTH);
+                } else if (type.isAssignableFrom(Meter.class)) {
+                    writeTypeAndLength(out, METER_TYPE, INSTRUCTION_IDS_LENGTH);
+                } else if (type.isAssignableFrom(Experimenter.class)) {
+                    ExperimenterInstruction experimenter = instruction.getAugmentation(ExperimenterInstruction.class);
+                    writeTypeAndLength(out, EXPERIMENTER_TYPE, EncodeConstants.EXPERIMENTER_IDS_LENGTH);
+                    out.writeInt(experimenter.getExperimenter().intValue());
+                }
+            }
+        }
+    }
+
+    private static void writeTypeAndLength(ByteBuf out, int type, int length) {
+        out.writeShort(type);
+        out.writeShort(length);
+    }
+
+    private static void writeActionsInstruction(ByteBuf out,
+            Instruction instruction, int type) {
+        out.writeShort(type);
+        if (instruction.getAugmentation(ActionsInstruction.class) != null) {
+            List<Action> actions = instruction.getAugmentation(ActionsInstruction.class).getAction();
+            out.writeShort(ACTIONS_INSTRUCTION_LENGTH + ActionsSerializer.computeLengthOfActions(actions));
+            ByteBufUtils.padBuffer(PADDING_IN_ACTIONS_INSTRUCTION, out);
+            ActionsSerializer.encodeActions(actions, out);
+        } else {
+            out.writeShort(ACTIONS_INSTRUCTION_LENGTH);
+            ByteBufUtils.padBuffer(PADDING_IN_ACTIONS_INSTRUCTION, out);
+        }
+    }
+    
+    /**
+     * Computes length of instructions
+     * @param instructions List of instructions
+     * @return length of instructions (in bytes)
+     */
+    public static int computeInstructionsLength(List<Instruction> instructions) {
+        int length = 0;
+        if (instructions != null) {
+            for (Instruction instruction : instructions) {
+                Class<? extends InstructionBase> type = instruction.getType();
+                if (type.isAssignableFrom(GotoTable.class)) {
+                    length += GOTO_TABLE_LENGTH;
+                } else if (type.isAssignableFrom(WriteMetadata.class)) {
+                    length += WRITE_METADATA_LENGTH;
+                } else if (type.isAssignableFrom(WriteActions.class)) {
+                    length += ACTIONS_INSTRUCTION_LENGTH;
+                    if (instruction.getAugmentation(ActionsInstruction.class) != null) {
+                        length += ActionsSerializer.computeLengthOfActions(
+                            instruction.getAugmentation(ActionsInstruction.class).getAction());
+                    }
+                } else if (type.isAssignableFrom(ApplyActions.class)) {
+                    length += ACTIONS_INSTRUCTION_LENGTH;
+                    if (instruction.getAugmentation(ActionsInstruction.class) != null) {
+                        length += ActionsSerializer.computeLengthOfActions(
+                                instruction.getAugmentation(ActionsInstruction.class).getAction());
+                    }
+                } else if (type.isAssignableFrom(ClearActions.class)) {
+                    length += ACTIONS_INSTRUCTION_LENGTH;
+                } else if (type.isAssignableFrom(Meter.class)) {
+                    length += METER_LENGTH;
+                } else if (type.isAssignableFrom(Experimenter.class)) {
+                    ExperimenterInstruction experimenter = instruction.getAugmentation(ExperimenterInstruction.class);
+                    byte[] data = experimenter.getData();
+                    length += EXPERIMENTER_LENGTH + data.length;
+                }
+            }
+        }
+        return length;
+    }
+}