Inject instruction deserializers into DeserializerRegistry.
These deserializers will deserialize these instructions:
- GoToTable
- WriteMetadata
- WriteActions
- ApplyActions
- ClearActions
- Meter
See also: bug 7140
Change-Id: Ie38961458157cac46a4bdeba18c0e6c9020d3671
Signed-off-by: Tomas Slusny <tomas.slusny@pantheon.tech>
import org.opendaylight.openflowjava.protocol.api.extensibility.DeserializerExtensionProvider;
import org.opendaylight.openflowjava.protocol.api.extensibility.OFDeserializer;
import org.opendaylight.openflowjava.protocol.api.util.EncodeConstants;
+import org.opendaylight.openflowjava.protocol.impl.util.InstructionConstants;
import org.opendaylight.openflowplugin.api.openflow.protocol.deserialization.MessageCodeExperimenterKey;
import org.opendaylight.openflowplugin.extension.api.path.ActionPath;
import org.opendaylight.openflowplugin.impl.protocol.deserialization.key.MessageCodeActionExperimenterKey;
+import org.opendaylight.openflowplugin.impl.protocol.deserialization.instruction.ApplyActionsInstructionDeserializer;
+import org.opendaylight.openflowplugin.impl.protocol.deserialization.instruction.ClearActionsInstructionDeserializer;
+import org.opendaylight.openflowplugin.impl.protocol.deserialization.instruction.GoToTableInstructionDeserializer;
+import org.opendaylight.openflowplugin.impl.protocol.deserialization.instruction.MeterInstructionDeserializer;
+import org.opendaylight.openflowplugin.impl.protocol.deserialization.instruction.WriteActionsInstructionDeserializer;
+import org.opendaylight.openflowplugin.impl.protocol.deserialization.instruction.WriteMetadataInstructionDeserializer;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.Instruction;
import com.google.common.annotations.VisibleForTesting;
// Inject new instruction deserializers here using injector created by createInjector method
final Function<Byte, Function<ActionPath, Consumer<OFDeserializer<Instruction>>>> injector =
createInjector(provider, EncodeConstants.OF13_VERSION_ID);
+
+ injector.apply(InstructionConstants.GOTO_TABLE_TYPE).apply(null).accept(new GoToTableInstructionDeserializer());
+ injector.apply(InstructionConstants.WRITE_METADATA_TYPE).apply(null).accept(new WriteMetadataInstructionDeserializer());
+ injector.apply(InstructionConstants.CLEAR_ACTIONS_TYPE).apply(null).accept(new ClearActionsInstructionDeserializer());
+ injector.apply(InstructionConstants.METER_TYPE).apply(null).accept(new MeterInstructionDeserializer());
+
+ for (ActionPath path : ActionPath.values()) {
+ injector.apply(InstructionConstants.WRITE_ACTIONS_TYPE).apply(path).accept(new WriteActionsInstructionDeserializer(path));
+ injector.apply(InstructionConstants.APPLY_ACTIONS_TYPE).apply(path).accept(new ApplyActionsInstructionDeserializer(path));
+ }
}
/**
import org.opendaylight.openflowjava.protocol.api.util.EncodeConstants;
import org.opendaylight.openflowplugin.extension.api.path.ActionPath;
import org.opendaylight.openflowplugin.impl.protocol.deserialization.util.ActionUtil;
+import org.opendaylight.openflowplugin.api.openflow.protocol.deserialization.MessageCodeExperimenterKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.Action;
+import org.opendaylight.openflowjava.protocol.impl.util.InstructionConstants;
+import org.opendaylight.openflowplugin.api.openflow.protocol.deserialization.MessageCodeExperimenterKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.Action;
import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.list.ActionBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.list.ActionKey;
protected List<org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.list
.Action> readActions(ByteBuf message, int length) {
+ final int instrLength = length - InstructionConstants.STANDARD_INSTRUCTION_LENGTH;
+
final List<org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.list
.Action> actions = new ArrayList<>();
final int startIndex = message.readerIndex();
int offset = 0;
- while ((message.readerIndex() - startIndex) < length) {
+ while ((message.readerIndex() - startIndex) < instrLength) {
actions.add(new ActionBuilder()
.setKey(new ActionKey(offset))
.setOrder(offset)
--- /dev/null
+/*
+ * Copyright (c) 2016 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.openflowplugin.impl.protocol.deserialization.instruction;
+
+import org.opendaylight.openflowjava.protocol.impl.util.InstructionConstants;
+import org.opendaylight.openflowplugin.extension.api.path.ActionPath;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.Instruction;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.ApplyActionsCaseBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.apply.actions._case.ApplyActionsBuilder;
+
+import io.netty.buffer.ByteBuf;
+
+public class ApplyActionsInstructionDeserializer extends AbstractActionInstructionDeserializer {
+
+ public ApplyActionsInstructionDeserializer(ActionPath path) {
+ super(path);
+ }
+
+ @Override
+ public Instruction deserialize(ByteBuf message) {
+ final int length = readHeader(message);
+ message.skipBytes(InstructionConstants.PADDING_IN_ACTIONS_INSTRUCTION);
+
+ return new ApplyActionsCaseBuilder()
+ .setApplyActions(new ApplyActionsBuilder()
+ .setAction(readActions(message, length))
+ .build())
+ .build();
+ }
+
+ @Override
+ public Instruction deserializeHeader(ByteBuf message) {
+ processHeader(message);
+ return new ApplyActionsCaseBuilder().build();
+ }
+
+}
--- /dev/null
+/*
+ * Copyright (c) 2016 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.openflowplugin.impl.protocol.deserialization.instruction;
+
+import org.opendaylight.openflowjava.protocol.impl.util.InstructionConstants;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.Instruction;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.ClearActionsCaseBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.clear.actions._case.ClearActionsBuilder;
+
+import io.netty.buffer.ByteBuf;
+
+public class ClearActionsInstructionDeserializer extends AbstractInstructionDeserializer {
+
+ @Override
+ public Instruction deserialize(ByteBuf message) {
+ processHeader(message);
+ message.skipBytes(InstructionConstants.PADDING_IN_ACTIONS_INSTRUCTION);
+
+ return new ClearActionsCaseBuilder()
+ .setClearActions(new ClearActionsBuilder().build())
+ .build();
+ }
+
+ @Override
+ public Instruction deserializeHeader(ByteBuf message) {
+ processHeader(message);
+ return new ClearActionsCaseBuilder().build();
+ }
+
+}
--- /dev/null
+/*
+ * Copyright (c) 2016 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.openflowplugin.impl.protocol.deserialization.instruction;
+
+import org.opendaylight.openflowjava.protocol.impl.util.InstructionConstants;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.Instruction;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.GoToTableCaseBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.go.to.table._case.GoToTableBuilder;
+
+import io.netty.buffer.ByteBuf;
+
+public class GoToTableInstructionDeserializer extends AbstractInstructionDeserializer {
+
+ @Override
+ public Instruction deserialize(ByteBuf message) {
+ processHeader(message);
+ final short tableId = message.readUnsignedByte();
+ message.skipBytes(InstructionConstants.PADDING_IN_GOTO_TABLE);
+
+ return new GoToTableCaseBuilder()
+ .setGoToTable(new GoToTableBuilder()
+ .setTableId(tableId)
+ .build())
+ .build();
+ }
+
+ @Override
+ public Instruction deserializeHeader(ByteBuf message) {
+ processHeader(message);
+ return new GoToTableCaseBuilder().build();
+ }
+
+}
--- /dev/null
+/*
+ * Copyright (c) 2016 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.openflowplugin.impl.protocol.deserialization.instruction;
+
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.Instruction;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.MeterCaseBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.meter._case.MeterBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.types.rev130918.MeterId;
+
+import io.netty.buffer.ByteBuf;
+
+public class MeterInstructionDeserializer extends AbstractInstructionDeserializer {
+
+ @Override
+ public Instruction deserialize(ByteBuf message) {
+ processHeader(message);
+
+ return new MeterCaseBuilder()
+ .setMeter(new MeterBuilder()
+ .setMeterId(new MeterId(message.readUnsignedInt()))
+ .build())
+ .build();
+ }
+
+ @Override
+ public Instruction deserializeHeader(ByteBuf message) {
+ processHeader(message);
+ return new MeterCaseBuilder().build();
+ }
+
+}
--- /dev/null
+/*
+ * Copyright (c) 2016 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.openflowplugin.impl.protocol.deserialization.instruction;
+
+import org.opendaylight.openflowjava.protocol.impl.util.InstructionConstants;
+import org.opendaylight.openflowplugin.extension.api.path.ActionPath;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.Instruction;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.WriteActionsCaseBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.write.actions._case.WriteActionsBuilder;
+
+import io.netty.buffer.ByteBuf;
+
+public class WriteActionsInstructionDeserializer extends AbstractActionInstructionDeserializer {
+
+ public WriteActionsInstructionDeserializer(ActionPath path) {
+ super(path);
+ }
+
+ @Override
+ public Instruction deserialize(ByteBuf message) {
+ final int length = readHeader(message);
+ message.skipBytes(InstructionConstants.PADDING_IN_ACTIONS_INSTRUCTION);
+
+ return new WriteActionsCaseBuilder()
+ .setWriteActions(new WriteActionsBuilder()
+ .setAction(readActions(message, length))
+ .build())
+ .build();
+ }
+
+ @Override
+ public Instruction deserializeHeader(ByteBuf message) {
+ processHeader(message);
+ return new WriteActionsCaseBuilder().build();
+ }
+
+}
--- /dev/null
+/*
+ * Copyright (c) 2016 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.openflowplugin.impl.protocol.deserialization.instruction;
+
+import java.math.BigInteger;
+
+import org.opendaylight.openflowjava.protocol.impl.util.InstructionConstants;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.Instruction;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.WriteMetadataCaseBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.write.metadata._case.WriteMetadataBuilder;
+
+import io.netty.buffer.ByteBuf;
+
+public class WriteMetadataInstructionDeserializer extends AbstractInstructionDeserializer {
+
+ @Override
+ public Instruction deserialize(ByteBuf message) {
+ processHeader(message);
+ message.skipBytes(InstructionConstants.PADDING_IN_WRITE_METADATA);
+
+ return new WriteMetadataCaseBuilder()
+ .setWriteMetadata(new WriteMetadataBuilder()
+ .setMetadata(BigInteger.valueOf(message.readLong()))
+ .setMetadataMask(BigInteger.valueOf(message.readLong()))
+ .build())
+ .build();
+ }
+
+ @Override
+ public Instruction deserializeHeader(ByteBuf message) {
+ processHeader(message);
+ return new WriteMetadataCaseBuilder().build();
+ }
+
+}
--- /dev/null
+/*
+ * Copyright (c) 2016 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.openflowplugin.impl.protocol.deserialization.instruction;
+
+import static org.junit.Assert.assertEquals;
+
+import org.junit.Test;
+import org.opendaylight.openflowjava.protocol.api.extensibility.OFDeserializer;
+import org.opendaylight.openflowjava.protocol.api.util.EncodeConstants;
+import org.opendaylight.openflowjava.protocol.impl.util.ActionConstants;
+import org.opendaylight.openflowjava.protocol.impl.util.InstructionConstants;
+import org.opendaylight.openflowplugin.extension.api.path.ActionPath;
+import org.opendaylight.openflowplugin.impl.protocol.deserialization.key.MessageCodeActionExperimenterKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.PopPbbActionCase;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.Instruction;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.ApplyActionsCase;
+
+import io.netty.buffer.ByteBuf;
+import io.netty.buffer.UnpooledByteBufAllocator;
+
+public class ApplyActionsInstructionDeserializerTest extends AbstractInstructionDeserializerTest {
+
+ private OFDeserializer<Instruction> deserializer;
+
+ @Override
+ protected void init() {
+ deserializer = getRegistry().getDeserializer(
+ new MessageCodeActionExperimenterKey(EncodeConstants.OF13_VERSION_ID, getType(), Instruction.class,
+ ActionPath.NODES_NODE_TABLE_FLOW_INSTRUCTIONS_INSTRUCTION_APPLYACTIONSCASE_APPLYACTIONS_ACTION_ACTION_EXTENSIONLIST_EXTENSION,
+ null));
+ }
+
+ @Test
+ public void testDeserialize() throws Exception {
+ final ByteBuf in = UnpooledByteBufAllocator.DEFAULT.buffer();
+
+ // Header
+ final int startIndex = in.writerIndex();
+ in.writeShort(getType());
+ final int index = in.writerIndex();
+ in.writeShort(getLength());
+ in.writeZero(InstructionConstants.PADDING_IN_ACTIONS_INSTRUCTION);
+
+ // POP PBB action
+ in.writeShort(ActionConstants.POP_PBB_CODE);
+ in.writeShort(ActionConstants.GENERAL_ACTION_LENGTH);
+ in.writeZero(ActionConstants.PADDING_IN_ACTION_HEADER);
+
+ in.setShort(index, in.writerIndex() - startIndex);
+
+ final Instruction instruction = deserializer.deserialize(in);
+ assertEquals(ApplyActionsCase.class, instruction.getImplementedInterface());
+ final ApplyActionsCase actionCase = ApplyActionsCase.class.cast(instruction);
+ assertEquals(1, actionCase.getApplyActions().getAction().size());
+ assertEquals(PopPbbActionCase.class, actionCase.getApplyActions().getAction().get(0)
+ .getAction().getImplementedInterface());
+ assertEquals(0, in.readableBytes());
+ }
+
+ @Override
+ protected short getType() {
+ return InstructionConstants.APPLY_ACTIONS_TYPE;
+ }
+
+ @Override
+ protected short getLength() {
+ return EncodeConstants.EMPTY_LENGTH;
+ }
+
+}
--- /dev/null
+/*
+ * Copyright (c) 2016 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.openflowplugin.impl.protocol.deserialization.instruction;
+
+import static org.junit.Assert.assertEquals;
+
+import org.junit.Test;
+import org.opendaylight.openflowjava.protocol.impl.util.InstructionConstants;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.Instruction;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.ClearActionsCase;
+
+import io.netty.buffer.ByteBuf;
+import io.netty.buffer.UnpooledByteBufAllocator;
+
+public class ClearActionsInstructionDeserializerTest extends AbstractInstructionDeserializerTest {
+
+ @Test
+ public void testDeserialize() throws Exception {
+ final ByteBuf in = UnpooledByteBufAllocator.DEFAULT.buffer();
+ writeHeader(in);
+ in.writeZero(InstructionConstants.PADDING_IN_ACTIONS_INSTRUCTION);
+
+ final Instruction instruction = deserializeInstruction(in);
+ assertEquals(ClearActionsCase.class, instruction.getImplementedInterface());
+ assertEquals(0, in.readableBytes());
+ }
+
+ @Override
+ protected short getType() {
+ return InstructionConstants.CLEAR_ACTIONS_TYPE;
+ }
+
+ @Override
+ protected short getLength() {
+ return InstructionConstants.STANDARD_INSTRUCTION_LENGTH;
+ }
+
+}
--- /dev/null
+/*
+ * Copyright (c) 2016 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.openflowplugin.impl.protocol.deserialization.instruction;
+
+import static org.junit.Assert.assertEquals;
+
+import org.junit.Test;
+import org.opendaylight.openflowjava.protocol.impl.util.InstructionConstants;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.Instruction;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.GoToTableCase;
+
+import io.netty.buffer.ByteBuf;
+import io.netty.buffer.UnpooledByteBufAllocator;
+
+public class GoToTableInstructionDeserializerTest extends AbstractInstructionDeserializerTest {
+
+ @Test
+ public void testDeserialize() throws Exception {
+ final ByteBuf in = UnpooledByteBufAllocator.DEFAULT.buffer();
+ final short tableId = 3;
+ writeHeader(in);
+ in.writeByte(tableId);
+ in.writeZero(InstructionConstants.PADDING_IN_GOTO_TABLE);
+
+ final Instruction instruction = deserializeInstruction(in);
+ assertEquals(GoToTableCase.class, instruction.getImplementedInterface());
+ assertEquals(tableId, GoToTableCase.class.cast(instruction).getGoToTable().getTableId().shortValue());
+ assertEquals(0, in.readableBytes());
+ }
+
+ @Override
+ protected short getType() {
+ return InstructionConstants.GOTO_TABLE_TYPE;
+ }
+
+ @Override
+ protected short getLength() {
+ return InstructionConstants.STANDARD_INSTRUCTION_LENGTH;
+ }
+
+}
--- /dev/null
+/*
+ * Copyright (c) 2016 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.openflowplugin.impl.protocol.deserialization.instruction;
+
+import static org.junit.Assert.assertEquals;
+
+import org.junit.Test;
+import org.opendaylight.openflowjava.protocol.impl.util.InstructionConstants;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.Instruction;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.MeterCase;
+
+import io.netty.buffer.ByteBuf;
+import io.netty.buffer.UnpooledByteBufAllocator;
+
+public class MeterInstructionDeserializerTest extends AbstractInstructionDeserializerTest {
+
+ @Test
+ public void testDeserialize() throws Exception {
+ final ByteBuf in = UnpooledByteBufAllocator.DEFAULT.buffer();
+ final int meterId = 3;
+ writeHeader(in);
+ in.writeInt(meterId);
+
+ final Instruction instruction = deserializeInstruction(in);
+ assertEquals(MeterCase.class, instruction.getImplementedInterface());
+ assertEquals(meterId, MeterCase.class.cast(instruction).getMeter().getMeterId().getValue().intValue());
+ assertEquals(0, in.readableBytes());
+ }
+
+ @Override
+ protected short getType() {
+ return InstructionConstants.METER_TYPE;
+ }
+
+ @Override
+ protected short getLength() {
+ return InstructionConstants.STANDARD_INSTRUCTION_LENGTH;
+ }
+
+}
--- /dev/null
+/*
+ * Copyright (c) 2016 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.openflowplugin.impl.protocol.deserialization.instruction;
+
+import static org.junit.Assert.assertEquals;
+
+import org.junit.Test;
+import org.opendaylight.openflowjava.protocol.api.extensibility.OFDeserializer;
+import org.opendaylight.openflowjava.protocol.api.util.EncodeConstants;
+import org.opendaylight.openflowjava.protocol.impl.util.ActionConstants;
+import org.opendaylight.openflowjava.protocol.impl.util.InstructionConstants;
+import org.opendaylight.openflowplugin.extension.api.path.ActionPath;
+import org.opendaylight.openflowplugin.impl.protocol.deserialization.key.MessageCodeActionExperimenterKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.PopPbbActionCase;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.Instruction;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.WriteActionsCase;
+
+import io.netty.buffer.ByteBuf;
+import io.netty.buffer.UnpooledByteBufAllocator;
+
+public class WriteActionsInstructionDeserializerTest extends AbstractInstructionDeserializerTest {
+
+ private OFDeserializer<Instruction> deserializer;
+
+ @Override
+ protected void init() {
+ deserializer = getRegistry().getDeserializer(
+ new MessageCodeActionExperimenterKey(EncodeConstants.OF13_VERSION_ID, getType(), Instruction.class,
+ ActionPath.NODES_NODE_TABLE_FLOW_INSTRUCTIONS_INSTRUCTION_WRITEACTIONSCASE_WRITEACTIONS_ACTION_ACTION_EXTENSIONLIST_EXTENSION,
+ null));
+ }
+
+ @Test
+ public void testDeserialize() throws Exception {
+ final ByteBuf in = UnpooledByteBufAllocator.DEFAULT.buffer();
+
+ // Header
+ final int startIndex = in.writerIndex();
+ in.writeShort(getType());
+ final int index = in.writerIndex();
+ in.writeShort(getLength());
+ in.writeZero(InstructionConstants.PADDING_IN_ACTIONS_INSTRUCTION);
+
+ // POP PBB action
+ in.writeShort(ActionConstants.POP_PBB_CODE);
+ in.writeShort(ActionConstants.GENERAL_ACTION_LENGTH);
+ in.writeZero(ActionConstants.PADDING_IN_ACTION_HEADER);
+
+ in.setShort(index, in.writerIndex() - startIndex);
+
+ final Instruction instruction = deserializer.deserialize(in);
+ assertEquals(WriteActionsCase.class, instruction.getImplementedInterface());
+ final WriteActionsCase actionCase = WriteActionsCase.class.cast(instruction);
+ assertEquals(1, actionCase.getWriteActions().getAction().size());
+ assertEquals(PopPbbActionCase.class, actionCase.getWriteActions().getAction().get(0)
+ .getAction().getImplementedInterface());
+ assertEquals(0, in.readableBytes());
+ }
+
+ @Override
+ protected short getType() {
+ return InstructionConstants.WRITE_ACTIONS_TYPE;
+ }
+
+ @Override
+ protected short getLength() {
+ return EncodeConstants.EMPTY_LENGTH;
+ }
+
+}
--- /dev/null
+/*
+ * Copyright (c) 2016 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.openflowplugin.impl.protocol.deserialization.instruction;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertArrayEquals;
+
+import java.math.BigInteger;
+
+import org.junit.Test;
+import org.opendaylight.openflowjava.protocol.api.util.EncodeConstants;
+import org.opendaylight.openflowjava.protocol.impl.util.InstructionConstants;
+import org.opendaylight.openflowplugin.openflow.md.util.ByteUtil;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.Instruction;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.WriteMetadataCase;
+
+import io.netty.buffer.ByteBuf;
+import io.netty.buffer.UnpooledByteBufAllocator;
+
+public class WriteMetadataInstructionDeserializerTest extends AbstractInstructionDeserializerTest {
+
+ @Test
+ public void testDeserialize() throws Exception {
+ final ByteBuf in = UnpooledByteBufAllocator.DEFAULT.buffer();
+ final BigInteger metadata = BigInteger.valueOf(1234567890L);
+ final BigInteger metadataMask = BigInteger.valueOf(9876543210L);
+ writeHeader(in);
+ in.writeZero(InstructionConstants.PADDING_IN_WRITE_METADATA);
+ in.writeBytes(ByteUtil.convertBigIntegerToNBytes(metadata, EncodeConstants.SIZE_OF_LONG_IN_BYTES));
+ in.writeBytes(ByteUtil.convertBigIntegerToNBytes(metadataMask, EncodeConstants.SIZE_OF_LONG_IN_BYTES));
+
+ final Instruction instruction = deserializeInstruction(in);
+ assertEquals(WriteMetadataCase.class, instruction.getImplementedInterface());
+ assertArrayEquals(metadata.toByteArray(),
+ WriteMetadataCase.class.cast(instruction).getWriteMetadata().getMetadata().toByteArray());
+ assertArrayEquals(metadataMask.toByteArray(),
+ WriteMetadataCase.class.cast(instruction).getWriteMetadata().getMetadataMask().toByteArray());
+ assertEquals(0, in.readableBytes());
+ }
+
+ @Override
+ protected short getType() {
+ return InstructionConstants.WRITE_METADATA_TYPE;
+ }
+
+ @Override
+ protected short getLength() {
+ return InstructionConstants.STANDARD_INSTRUCTION_LENGTH;
+ }
+
+}