From 5abf1a2547c3a35fce87b7cbcb971e5e4019035b Mon Sep 17 00:00:00 2001 From: Michal Polkorab Date: Thu, 9 Jan 2014 16:42:20 +0100 Subject: [PATCH] Experimenter support for TableFeatures + deserialization fix + MatchIdsReader renamed to MatchIdsDeserializer + MatchIdsWriter renamed to MatchIdsSerializer Change-Id: I86dc16b7cc8c1d83e5212f3c3cd8502bb0f8335d Signed-off-by: Michal Polkorab --- .../MultipartReplyMessageFactory.java | 8 + .../MultipartRequestInputFactory.java | 21 +- .../impl/util/ActionsDeserializer.java | 3 + .../protocol/impl/util/ActionsSerializer.java | 5 +- .../protocol/impl/util/EncodeConstants.java | 2 + .../impl/util/InstructionsDeserializer.java | 3 + .../impl/util/InstructionsSerializer.java | 4 +- .../protocol/impl/util/MatchDeserializer.java | 2 +- ...sReader.java => MatchIdsDeserializer.java} | 6 +- ...IdsWriter.java => MatchIdsSerializer.java} | 2 +- .../protocol/impl/util/MatchSerializer.java | 2 +- .../MultipartRequestInputFactoryTest.java | 94 +----- .../multipart/TableFeaturesTest.java | 284 ++++++++++++++++++ 13 files changed, 335 insertions(+), 101 deletions(-) rename openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/util/{MatchIdsReader.java => MatchIdsDeserializer.java} (96%) rename openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/util/{MatchIdsWriter.java => MatchIdsSerializer.java} (98%) create mode 100644 openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/multipart/TableFeaturesTest.java diff --git a/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/MultipartReplyMessageFactory.java b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/MultipartReplyMessageFactory.java index 628d388d..eb066916 100644 --- a/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/MultipartReplyMessageFactory.java +++ b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/MultipartReplyMessageFactory.java @@ -23,6 +23,7 @@ import org.opendaylight.openflowjava.protocol.impl.util.MatchDeserializer; import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev100924.MacAddress; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.ActionRelatedTableFeatureProperty; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.ActionRelatedTableFeaturePropertyBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.ExperimenterRelatedTableFeatureProperty; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.ExperimenterRelatedTableFeaturePropertyBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.InstructionRelatedTableFeatureProperty; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.InstructionRelatedTableFeaturePropertyBuilder; @@ -426,6 +427,13 @@ public class MultipartReplyMessageFactory implements OFDeserializer 0) { + byte[] data = new byte[dataLength]; + input.readBytes(data); + expBuilder.setData(data); + } + builder.addAugmentation(ExperimenterRelatedTableFeatureProperty.class, expBuilder.build()); } if (paddingRemainder != 0) { input.skipBytes(EncodeConstants.PADDING - paddingRemainder); diff --git a/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/MultipartRequestInputFactory.java b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/MultipartRequestInputFactory.java index c1e37fba..ac4a3105 100644 --- a/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/MultipartRequestInputFactory.java +++ b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/MultipartRequestInputFactory.java @@ -27,6 +27,7 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.OxmRelatedTableFeatureProperty; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.table.features.properties.container.table.feature.properties.NextTableIds; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev130731.actions.ActionsList; +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.instructions.Instructions; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.MultipartRequestFlags; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.MultipartType; @@ -480,7 +481,13 @@ public class MultipartRequestInputFactory implements OFSerializer createMatchIds(ByteBuf in, int matchLength) { - return MatchIdsReader.createOxmIds(in, matchLength); + return MatchIdsDeserializer.createOxmIds(in, matchLength); } private static void addMaskAugmentation(MatchEntriesBuilder builder, ByteBuf in, int matchEntryLength) { diff --git a/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/util/MatchIdsReader.java b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/util/MatchIdsDeserializer.java similarity index 96% rename from openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/util/MatchIdsReader.java rename to openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/util/MatchIdsDeserializer.java index 9ecdc0cc..6961ed87 100644 --- a/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/util/MatchIdsReader.java +++ b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/util/MatchIdsDeserializer.java @@ -63,7 +63,7 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev130731.oxm. * Encodes match ids (oxm_ids) needed in Multipart-TableFeatures messages * @author michal.polkorab */ -public abstract class MatchIdsReader { +public abstract class MatchIdsDeserializer { /** Decodes oxm ids * @param in input ByteBuf @@ -96,9 +96,9 @@ public abstract class MatchIdsReader { boolean hasMask = (fieldAndMask & 1) != 0; matchEntriesBuilder.setHasMask(hasMask); int matchField = fieldAndMask >> 1; - int matchEntryLength = in.readUnsignedByte(); + in.skipBytes(EncodeConstants.SIZE_OF_BYTE_IN_BYTES); currLength += EncodeConstants.SIZE_OF_SHORT_IN_BYTES + - (2 * EncodeConstants.SIZE_OF_BYTE_IN_BYTES) + matchEntryLength; + (2 * EncodeConstants.SIZE_OF_BYTE_IN_BYTES); switch(matchField) { case 0: diff --git a/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/util/MatchIdsWriter.java b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/util/MatchIdsSerializer.java similarity index 98% rename from openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/util/MatchIdsWriter.java rename to openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/util/MatchIdsSerializer.java index e3961078..85d92adf 100644 --- a/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/util/MatchIdsWriter.java +++ b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/util/MatchIdsSerializer.java @@ -56,7 +56,7 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev130731.oxm. * Encodes match ids (oxm_ids) needed in Multipart-TableFeatures messages * @author michal.polkorab */ -public abstract class MatchIdsWriter { +public abstract class MatchIdsSerializer { /** * Encodes oxm headers (without values) diff --git a/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/util/MatchSerializer.java b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/util/MatchSerializer.java index e54087c8..adae1e24 100644 --- a/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/util/MatchSerializer.java +++ b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/util/MatchSerializer.java @@ -166,7 +166,7 @@ public abstract class MatchSerializer { } for (MatchEntries entry : matchEntries) { encodeClass(entry.getOxmClass(), out); - MatchIdsWriter.encodeIdsRest(entry, out); + MatchIdsSerializer.encodeIdsRest(entry, out); } } diff --git a/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/MultipartRequestInputFactoryTest.java b/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/MultipartRequestInputFactoryTest.java index d18def9c..fe50e878 100644 --- a/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/MultipartRequestInputFactoryTest.java +++ b/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/MultipartRequestInputFactoryTest.java @@ -12,11 +12,8 @@ import io.netty.buffer.ByteBuf; import io.netty.buffer.UnpooledByteBufAllocator; import java.math.BigInteger; -import java.util.ArrayList; -import java.util.List; - -import junit.framework.Assert; +import org.junit.Assert; import org.junit.Test; import org.opendaylight.openflowjava.protocol.impl.deserialization.factories.HelloMessageFactoryTest; import org.opendaylight.openflowjava.protocol.impl.util.BufferHelper; @@ -25,7 +22,6 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev13 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.MeterId; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.MultipartRequestFlags; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.MultipartType; -import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.TableConfig; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.MultipartRequestInput; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.MultipartRequestInputBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.MultipartRequestBody; @@ -46,8 +42,6 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.MultipartRequestPortStatsCaseBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.MultipartRequestQueueCase; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.MultipartRequestQueueCaseBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.MultipartRequestTableFeaturesCase; -import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.MultipartRequestTableFeaturesCaseBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.multipart.request.aggregate._case.MultipartRequestAggregateBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.multipart.request.desc._case.MultipartRequestDescBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.multipart.request.experimenter._case.MultipartRequestExperimenterBuilder; @@ -57,17 +51,14 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.multipart.request.meter.config._case.MultipartRequestMeterConfigBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.multipart.request.port.stats._case.MultipartRequestPortStatsBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.multipart.request.queue._case.MultipartRequestQueueBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.multipart.request.table.features._case.MultipartRequestTableFeatures; -import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.multipart.request.table.features._case.MultipartRequestTableFeaturesBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.multipart.request.table.features._case.multipart.request.table.features.TableFeatures; -import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.multipart.request.table.features._case.multipart.request.table.features.TableFeaturesBuilder; /** * @author timotej.kubas * @author michal.polkorab */ public class MultipartRequestInputFactoryTest { - private static final byte PADDING_IN_MULTIPART_REQUEST_MESSAGE = 4; + /** padding in MultipartRequest message */ + public static final byte PADDING_IN_MULTIPART_REQUEST_MESSAGE = 4; /** * @throws Exception @@ -497,83 +488,4 @@ public class MultipartRequestInputFactoryTest { return caseBuilder.build(); } - /** - * @throws Exception - * Testing of {@link MultipartRequestInputFactory} for correct translation from POJO - */ - @Test - public void testMultipartRequestTableFeaturesMessageFactory() throws Exception { - MultipartRequestInputBuilder builder = new MultipartRequestInputBuilder(); - BufferHelper.setupHeader(builder, EncodeConstants.OF13_VERSION_ID); - builder.setType(MultipartType.forValue(12)); - builder.setFlags(new MultipartRequestFlags(true)); - builder.setMultipartRequestBody(createRequestTableFeatures()); - MultipartRequestInput message = builder.build(); - - ByteBuf out = UnpooledByteBufAllocator.DEFAULT.buffer(); - MultipartRequestInputFactory factory = MultipartRequestInputFactory.getInstance(); - factory.messageToBuffer(HelloMessageFactoryTest.VERSION_YET_SUPPORTED, out, message); - - BufferHelper.checkHeaderV13(out, factory.getMessageType(), factory.computeLength(message)); - Assert.assertEquals("Wrong type", message.getType().getIntValue(), out.readUnsignedShort()); - Assert.assertEquals("Wrong flags", message.getFlags(), decodeMultipartRequestFlags(out.readShort())); - out.skipBytes(PADDING_IN_MULTIPART_REQUEST_MESSAGE); - MultipartRequestTableFeaturesCase messageTableFeaturesCase = (MultipartRequestTableFeaturesCase) message.getMultipartRequestBody(); - MultipartRequestTableFeatures messageTableFeatures = messageTableFeaturesCase.getMultipartRequestTableFeatures(); - Assert.assertEquals("Wrong tableFeaturesBody", messageTableFeatures.getTableFeatures(), decodeRequestTableFeatures(out). - getMultipartRequestTableFeatures().getTableFeatures()); - } - - private static MultipartRequestTableFeaturesCase createRequestTableFeatures() { - MultipartRequestTableFeaturesCaseBuilder caseBuilder = new MultipartRequestTableFeaturesCaseBuilder(); - MultipartRequestTableFeaturesBuilder builder = new MultipartRequestTableFeaturesBuilder(); - List tableFeaturesList = new ArrayList<>(); - TableFeaturesBuilder tableFeaturesBuilder = new TableFeaturesBuilder(); - tableFeaturesBuilder.setTableId((short) 8); - tableFeaturesBuilder.setName("AAAABBBBCCCCDDDDEEEEFFFFGGGG"); - tableFeaturesBuilder.setMetadataMatch(new BigInteger(1, new byte[] {0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01})); - tableFeaturesBuilder.setMetadataWrite(new BigInteger(1, new byte[] {0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01})); - tableFeaturesBuilder.setConfig(new TableConfig(true)); - tableFeaturesBuilder.setMaxEntries(65L); - TableFeatures tableFeature = tableFeaturesBuilder.build(); - tableFeaturesList.add(tableFeature); - builder.setTableFeatures(tableFeaturesList); - caseBuilder.setMultipartRequestTableFeatures(builder.build()); - return caseBuilder.build(); - } - - private static MultipartRequestTableFeaturesCase decodeRequestTableFeatures(ByteBuf output) { - final byte PADDING_IN_MULTIPART_REQUEST_TABLE_FEATURES_BODY = 5; - final byte OFP_MAX_TABLE_NAME_LEN = 32; - MultipartRequestTableFeaturesCaseBuilder caseBuilder = new MultipartRequestTableFeaturesCaseBuilder(); - MultipartRequestTableFeaturesBuilder builder = new MultipartRequestTableFeaturesBuilder(); - List tableFeaturesList = new ArrayList<>(); - TableFeaturesBuilder tableFeaturesBuilder = new TableFeaturesBuilder(); - output.skipBytes(2); - tableFeaturesBuilder.setTableId(output.readUnsignedByte()); - output.skipBytes(PADDING_IN_MULTIPART_REQUEST_TABLE_FEATURES_BODY); - byte[] tableNameBytes = new byte[OFP_MAX_TABLE_NAME_LEN]; - output.readBytes(tableNameBytes); - String tableName = new String(tableNameBytes); - tableFeaturesBuilder.setName(tableName.trim()); - byte[] metadataMatch = new byte[EncodeConstants.SIZE_OF_LONG_IN_BYTES]; - output.readBytes(metadataMatch); - tableFeaturesBuilder.setMetadataMatch(new BigInteger(1, metadataMatch)); - byte[] metadataWrite = new byte[EncodeConstants.SIZE_OF_LONG_IN_BYTES]; - output.readBytes(metadataWrite); - tableFeaturesBuilder.setMetadataWrite(new BigInteger(1, metadataWrite)); - tableFeaturesBuilder.setConfig(decodeTableConfig(output.readInt())); - tableFeaturesBuilder.setMaxEntries(output.readUnsignedInt()); - TableFeatures tableFeature = tableFeaturesBuilder.build(); - tableFeaturesList.add(tableFeature); - builder.setTableFeatures(tableFeaturesList); - caseBuilder.setMultipartRequestTableFeatures(builder.build()); - return caseBuilder.build(); - } - - private static TableConfig decodeTableConfig(int input) { - final Boolean _oFPTCDEPRECATEDMASK = (input & (1 << 3)) > 0; - return new TableConfig(_oFPTCDEPRECATEDMASK); - } - } diff --git a/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/multipart/TableFeaturesTest.java b/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/multipart/TableFeaturesTest.java new file mode 100644 index 00000000..a8843e53 --- /dev/null +++ b/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/multipart/TableFeaturesTest.java @@ -0,0 +1,284 @@ +/* + * 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.serialization.factories.multipart; + +import io.netty.buffer.ByteBuf; +import io.netty.buffer.UnpooledByteBufAllocator; + +import java.math.BigInteger; +import java.util.ArrayList; +import java.util.List; + +import org.junit.Assert; +import org.junit.Test; +import org.opendaylight.openflowjava.protocol.impl.deserialization.factories.HelloMessageFactoryTest; +import org.opendaylight.openflowjava.protocol.impl.serialization.factories.MultipartRequestInputFactory; +import org.opendaylight.openflowjava.protocol.impl.serialization.factories.MultipartRequestInputFactoryTest; +import org.opendaylight.openflowjava.protocol.impl.util.BufferHelper; +import org.opendaylight.openflowjava.protocol.impl.util.ByteBufUtils; +import org.opendaylight.openflowjava.protocol.impl.util.EncodeConstants; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.InstructionRelatedTableFeatureProperty; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.InstructionRelatedTableFeaturePropertyBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.NextTableRelatedTableFeatureProperty; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.NextTableRelatedTableFeaturePropertyBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.OxmRelatedTableFeatureProperty; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.OxmRelatedTableFeaturePropertyBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.table.features.properties.container.table.feature.properties.NextTableIds; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.table.features.properties.container.table.feature.properties.NextTableIdsBuilder; +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.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.Instructions; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.instruction.rev130731.instructions.InstructionsBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.MultipartRequestFlags; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.MultipartType; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.TableConfig; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.TableFeaturesPropType; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev130731.InPhyPort; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev130731.InPort; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev130731.IpEcn; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev130731.IpProto; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev130731.Nxm0Class; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev130731.Nxm1Class; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev130731.OpenflowBasicClass; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev130731.oxm.fields.MatchEntries; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev130731.oxm.fields.MatchEntriesBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.MultipartRequestInput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.MultipartRequestInputBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.MultipartRequestTableFeaturesCaseBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.multipart.request.table.features._case.MultipartRequestTableFeaturesBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.multipart.request.table.features._case.multipart.request.table.features.TableFeatures; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.multipart.request.table.features._case.multipart.request.table.features.TableFeaturesBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.table.features.properties.TableFeatureProperties; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.table.features.properties.TableFeaturePropertiesBuilder; + +/** + * @author michal.polkorab + * + */ +public class TableFeaturesTest { + private static final byte PADDING_IN_MULTIPART_REQUEST_MESSAGE = + MultipartRequestInputFactoryTest.PADDING_IN_MULTIPART_REQUEST_MESSAGE; + + /** + * @throws Exception + * Testing of {@link MultipartRequestInputFactory} for correct translation from POJO + */ + @Test + public void testMultipartRequestTableFeaturesMessageFactory() throws Exception { + MultipartRequestInputBuilder builder = new MultipartRequestInputBuilder(); + BufferHelper.setupHeader(builder, EncodeConstants.OF13_VERSION_ID); + builder.setType(MultipartType.forValue(12)); + builder.setFlags(new MultipartRequestFlags(true)); + MultipartRequestTableFeaturesCaseBuilder caseBuilder = new MultipartRequestTableFeaturesCaseBuilder(); + MultipartRequestTableFeaturesBuilder featuresBuilder = new MultipartRequestTableFeaturesBuilder(); + List tableFeaturesList = new ArrayList<>(); + TableFeaturesBuilder tableFeaturesBuilder = new TableFeaturesBuilder(); + tableFeaturesBuilder.setTableId((short) 8); + tableFeaturesBuilder.setName("AAAABBBBCCCCDDDDEEEEFFFFGGGG"); + tableFeaturesBuilder.setMetadataMatch(new BigInteger(new byte[] {0x00, 0x01, 0x02, 0x03, 0x01, 0x04, 0x08, 0x01})); + tableFeaturesBuilder.setMetadataWrite(new BigInteger(new byte[] {0x00, 0x07, 0x01, 0x05, 0x01, 0x00, 0x03, 0x01})); + tableFeaturesBuilder.setConfig(new TableConfig(true)); + tableFeaturesBuilder.setMaxEntries(65L); + List properties = new ArrayList<>(); + TableFeaturePropertiesBuilder propBuilder = new TableFeaturePropertiesBuilder(); + propBuilder.setType(TableFeaturesPropType.OFPTFPTNEXTTABLES); + NextTableRelatedTableFeaturePropertyBuilder nextPropBuilder = + new NextTableRelatedTableFeaturePropertyBuilder(); + List nextIds = new ArrayList<>(); + nextIds.add(new NextTableIdsBuilder().setTableId((short) 1).build()); + nextIds.add(new NextTableIdsBuilder().setTableId((short) 2).build()); + nextPropBuilder.setNextTableIds(nextIds); + propBuilder.addAugmentation(NextTableRelatedTableFeatureProperty.class, nextPropBuilder.build()); + properties.add(propBuilder.build()); + propBuilder = new TableFeaturePropertiesBuilder(); + propBuilder.setType(TableFeaturesPropType.OFPTFPTNEXTTABLESMISS); + nextPropBuilder = new NextTableRelatedTableFeaturePropertyBuilder(); + nextIds = new ArrayList<>(); + nextIds.add(new NextTableIdsBuilder().setTableId((short) 3).build()); + nextPropBuilder.setNextTableIds(nextIds); + propBuilder.addAugmentation(NextTableRelatedTableFeatureProperty.class, nextPropBuilder.build()); + properties.add(propBuilder.build()); + propBuilder = new TableFeaturePropertiesBuilder(); + propBuilder.setType(TableFeaturesPropType.OFPTFPTINSTRUCTIONS); + InstructionRelatedTableFeaturePropertyBuilder insPropBuilder = + new InstructionRelatedTableFeaturePropertyBuilder(); + List insIds = new ArrayList<>(); + InstructionsBuilder insBuilder = new InstructionsBuilder(); + insBuilder.setType(WriteActions.class); + insIds.add(insBuilder.build()); + insBuilder = new InstructionsBuilder(); + insBuilder.setType(GotoTable.class); + insIds.add(insBuilder.build()); + insPropBuilder.setInstructions(insIds); + propBuilder.addAugmentation(InstructionRelatedTableFeatureProperty.class, insPropBuilder.build()); + properties.add(propBuilder.build()); + propBuilder = new TableFeaturePropertiesBuilder(); + propBuilder.setType(TableFeaturesPropType.OFPTFPTINSTRUCTIONSMISS); + insPropBuilder = new InstructionRelatedTableFeaturePropertyBuilder(); + insIds = new ArrayList<>(); + insBuilder = new InstructionsBuilder(); + insBuilder.setType(WriteMetadata.class); + insIds.add(insBuilder.build()); + insBuilder = new InstructionsBuilder(); + insBuilder.setType(ApplyActions.class); + insIds.add(insBuilder.build()); + insBuilder = new InstructionsBuilder(); + insBuilder.setType(Meter.class); + insIds.add(insBuilder.build()); + insBuilder = new InstructionsBuilder(); + insBuilder.setType(ClearActions.class); + insIds.add(insBuilder.build()); + insBuilder = new InstructionsBuilder(); + insBuilder.setType(GotoTable.class); + insIds.add(insBuilder.build()); + insPropBuilder.setInstructions(insIds); + propBuilder.addAugmentation(InstructionRelatedTableFeatureProperty.class, insPropBuilder.build()); + properties.add(propBuilder.build()); + tableFeaturesBuilder.setTableFeatureProperties(properties); + tableFeaturesList.add(tableFeaturesBuilder.build()); + tableFeaturesBuilder = new TableFeaturesBuilder(); + tableFeaturesBuilder.setTableId((short) 8); + tableFeaturesBuilder.setName("AAAABBBBCCCCDDDDEEEEFFFFGGGG"); + tableFeaturesBuilder.setMetadataMatch(new BigInteger(new byte[] {0x00, 0x01, 0x02, 0x03, 0x01, 0x04, 0x08, 0x01})); + tableFeaturesBuilder.setMetadataWrite(new BigInteger(new byte[] {0x00, 0x07, 0x01, 0x05, 0x01, 0x00, 0x03, 0x01})); + tableFeaturesBuilder.setConfig(new TableConfig(true)); + tableFeaturesBuilder.setMaxEntries(67L); + properties = new ArrayList<>(); + propBuilder = new TableFeaturePropertiesBuilder(); + propBuilder.setType(TableFeaturesPropType.OFPTFPTMATCH); + OxmRelatedTableFeaturePropertyBuilder oxmBuilder = new OxmRelatedTableFeaturePropertyBuilder(); + List entries = new ArrayList<>(); + MatchEntriesBuilder entriesBuilder = new MatchEntriesBuilder(); + entriesBuilder.setOxmClass(OpenflowBasicClass.class); + entriesBuilder.setOxmMatchField(InPhyPort.class); + entriesBuilder.setHasMask(false); + entries.add(entriesBuilder.build()); + entriesBuilder = new MatchEntriesBuilder(); + entriesBuilder.setOxmClass(Nxm0Class.class); + entriesBuilder.setOxmMatchField(InPort.class); + entriesBuilder.setHasMask(false); + entries.add(entriesBuilder.build()); + oxmBuilder.setMatchEntries(entries); + propBuilder.addAugmentation(OxmRelatedTableFeatureProperty.class, oxmBuilder.build()); + properties.add(propBuilder.build()); + propBuilder = new TableFeaturePropertiesBuilder(); + propBuilder.setType(TableFeaturesPropType.OFPTFPTAPPLYSETFIELD); + oxmBuilder = new OxmRelatedTableFeaturePropertyBuilder(); + entries = new ArrayList<>(); + entriesBuilder = new MatchEntriesBuilder(); + entriesBuilder.setOxmClass(OpenflowBasicClass.class); + entriesBuilder.setOxmMatchField(IpProto.class); + entriesBuilder.setHasMask(false); + entries.add(entriesBuilder.build()); + entriesBuilder = new MatchEntriesBuilder(); + entriesBuilder.setOxmClass(Nxm1Class.class); + entriesBuilder.setOxmMatchField(IpEcn.class); + entriesBuilder.setHasMask(false); + entries.add(entriesBuilder.build()); + oxmBuilder.setMatchEntries(entries); + propBuilder.addAugmentation(OxmRelatedTableFeatureProperty.class, oxmBuilder.build()); + properties.add(propBuilder.build()); + tableFeaturesBuilder.setTableFeatureProperties(properties); + tableFeaturesList.add(tableFeaturesBuilder.build()); + featuresBuilder.setTableFeatures(tableFeaturesList); + caseBuilder.setMultipartRequestTableFeatures(featuresBuilder.build()); + builder.setMultipartRequestBody(caseBuilder.build()); + MultipartRequestInput message = builder.build(); + + ByteBuf out = UnpooledByteBufAllocator.DEFAULT.buffer(); + MultipartRequestInputFactory factory = MultipartRequestInputFactory.getInstance(); + factory.messageToBuffer(HelloMessageFactoryTest.VERSION_YET_SUPPORTED, out, message); + + BufferHelper.checkHeaderV13(out, factory.getMessageType(), factory.computeLength(message)); + Assert.assertEquals("Wrong type", 12, out.readUnsignedShort()); + Assert.assertEquals("Wrong flags", 1, out.readUnsignedShort()); + out.skipBytes(PADDING_IN_MULTIPART_REQUEST_MESSAGE); + Assert.assertEquals("Wrong length", 120, out.readUnsignedShort()); + Assert.assertEquals("Wrong table-id", 8, out.readUnsignedByte()); + out.skipBytes(5); + Assert.assertEquals("Wrong name", "AAAABBBBCCCCDDDDEEEEFFFFGGGG", + ByteBufUtils.decodeNullTerminatedString(out, 32)); + byte[] metadataMatch = new byte[EncodeConstants.SIZE_OF_LONG_IN_BYTES]; + out.readBytes(metadataMatch); + Assert.assertArrayEquals("Wrong metadata-match", + new byte[] {0x00, 0x01, 0x02, 0x03, 0x01, 0x04, 0x08, 0x01}, metadataMatch); + byte[] metadataWrite = new byte[EncodeConstants.SIZE_OF_LONG_IN_BYTES]; + out.readBytes(metadataWrite); + Assert.assertArrayEquals("Wrong metadata-write", + new byte[] {0x00, 0x07, 0x01, 0x05, 0x01, 0x00, 0x03, 0x01}, metadataWrite); + Assert.assertEquals("Wrong config", 8, out.readUnsignedInt()); + Assert.assertEquals("Wrong max-entries", 65, out.readUnsignedInt()); + Assert.assertEquals("Wrong property type", 2, out.readUnsignedShort()); + Assert.assertEquals("Wrong property length", 6, out.readUnsignedShort()); + Assert.assertEquals("Wrong next-table-id", 1, out.readUnsignedByte()); + Assert.assertEquals("Wrong next-table-id", 2, out.readUnsignedByte()); + out.skipBytes(2); + Assert.assertEquals("Wrong property type", 3, out.readUnsignedShort()); + Assert.assertEquals("Wrong property length", 5, out.readUnsignedShort()); + Assert.assertEquals("Wrong next-table-id", 3, out.readUnsignedByte()); + out.skipBytes(3); + Assert.assertEquals("Wrong property type", 0, out.readUnsignedShort()); + Assert.assertEquals("Wrong property length", 12, out.readUnsignedShort()); + Assert.assertEquals("Wrong instruction type", 3, out.readUnsignedShort()); + Assert.assertEquals("Wrong instruction length", 4, out.readUnsignedShort()); + Assert.assertEquals("Wrong instruction type", 1, out.readUnsignedShort()); + Assert.assertEquals("Wrong instruction length", 4, out.readUnsignedShort()); + out.skipBytes(4); + Assert.assertEquals("Wrong property type", 1, out.readUnsignedShort()); + Assert.assertEquals("Wrong property length", 24, out.readUnsignedShort()); + Assert.assertEquals("Wrong instruction type", 2, out.readUnsignedShort()); + Assert.assertEquals("Wrong instruction length", 4, out.readUnsignedShort()); + Assert.assertEquals("Wrong instruction type", 4, out.readUnsignedShort()); + Assert.assertEquals("Wrong instruction length", 4, out.readUnsignedShort()); + Assert.assertEquals("Wrong instruction type", 6, out.readUnsignedShort()); + Assert.assertEquals("Wrong instruction length", 4, out.readUnsignedShort()); + Assert.assertEquals("Wrong instruction type", 5, out.readUnsignedShort()); + Assert.assertEquals("Wrong instruction length", 4, out.readUnsignedShort()); + Assert.assertEquals("Wrong instruction type", 1, out.readUnsignedShort()); + Assert.assertEquals("Wrong instruction length", 4, out.readUnsignedShort()); + Assert.assertEquals("Wrong length", 96, out.readUnsignedShort()); + Assert.assertEquals("Wrong table-id", 8, out.readUnsignedByte()); + out.skipBytes(5); + Assert.assertEquals("Wrong name", "AAAABBBBCCCCDDDDEEEEFFFFGGGG", + ByteBufUtils.decodeNullTerminatedString(out, 32)); + metadataMatch = new byte[EncodeConstants.SIZE_OF_LONG_IN_BYTES]; + out.readBytes(metadataMatch); + Assert.assertArrayEquals("Wrong metadata-match", + new byte[] {0x00, 0x01, 0x02, 0x03, 0x01, 0x04, 0x08, 0x01}, metadataMatch); + metadataWrite = new byte[EncodeConstants.SIZE_OF_LONG_IN_BYTES]; + out.readBytes(metadataWrite); + Assert.assertArrayEquals("Wrong metadata-write", + new byte[] {0x00, 0x07, 0x01, 0x05, 0x01, 0x00, 0x03, 0x01}, metadataWrite); + Assert.assertEquals("Wrong config", 8, out.readUnsignedInt()); + Assert.assertEquals("Wrong max-entries", 67, out.readUnsignedInt()); + Assert.assertEquals("Wrong property type", 8, out.readUnsignedShort()); + Assert.assertEquals("Wrong property length", 12, out.readUnsignedShort()); + Assert.assertEquals("Wrong match class", 0x8000, out.readUnsignedShort()); + Assert.assertEquals("Wrong match field&mask", 2, out.readUnsignedByte()); + Assert.assertEquals("Wrong match length", 4, out.readUnsignedByte()); + Assert.assertEquals("Wrong match class", 0, out.readUnsignedShort()); + Assert.assertEquals("Wrong match field&mask", 0, out.readUnsignedByte()); + Assert.assertEquals("Wrong match length", 4, out.readUnsignedByte()); + out.skipBytes(4); + Assert.assertEquals("Wrong property type", 14, out.readUnsignedShort()); + Assert.assertEquals("Wrong property length", 12, out.readUnsignedShort()); + Assert.assertEquals("Wrong match class", 0x8000, out.readUnsignedShort()); + Assert.assertEquals("Wrong match field&mask", 20, out.readUnsignedByte()); + Assert.assertEquals("Wrong match length", 1, out.readUnsignedByte()); + Assert.assertEquals("Wrong match class", 1, out.readUnsignedShort()); + Assert.assertEquals("Wrong match field&mask", 18, out.readUnsignedByte()); + Assert.assertEquals("Wrong match length", 1, out.readUnsignedByte()); + out.skipBytes(4); + Assert.assertTrue("Unread data", out.readableBytes() == 0); + } + +} -- 2.36.6