Add bundle control and ONF experimenter error deserializers 26/47726/6
authorAndrej Leitner <andrej.leitner@pantheon.tech>
Thu, 27 Oct 2016 09:43:07 +0000 (11:43 +0200)
committerAndrej Leitner <andrej.leitner@pantheon.tech>
Fri, 4 Nov 2016 08:34:08 +0000 (09:34 +0100)
 - created and registered deserializers for ONF_ET_BUNDLE_CONTROL
   message and ONF experimenter errors
 - added tests

Reference: ONF approved extension #230
Resolves: Bug 6806

Change-Id: Iaa584aae6ee2e9962f962803d363f3213d99fa2e
Signed-off-by: Andrej Leitner <andrej.leitner@pantheon.tech>
openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/MessageDeserializerInitializer.java
openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/experimenter/BundleControlFactory.java [new file with mode: 0644]
openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/experimenter/OnfExperimenterErrorFactory.java [new file with mode: 0644]
openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/util/SimpleDeserializerRegistryHelper.java
openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/experimenter/BundleControlFactoryTest.java [new file with mode: 0644]
openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/experimenter/OnfExperimenterErrorFactoryTest.java [new file with mode: 0644]
openflowjava-util/src/main/java/org/opendaylight/openflowjava/util/ExperimenterDeserializerKeyFactory.java

index 79873cc1b49a31329d6dc3ba906034981c29e459..488db9c6a7cd851fd9f21f9055ea984bff878e0a 100644 (file)
@@ -9,6 +9,8 @@ package org.opendaylight.openflowjava.protocol.impl.deserialization;
 
 import org.opendaylight.openflowjava.protocol.api.extensibility.DeserializerRegistry;
 import org.opendaylight.openflowjava.protocol.api.util.EncodeConstants;
+import org.opendaylight.openflowjava.protocol.impl.deserialization.experimenter.BundleControlFactory;
+import org.opendaylight.openflowjava.protocol.impl.deserialization.experimenter.OnfExperimenterErrorFactory;
 import org.opendaylight.openflowjava.protocol.impl.deserialization.factories.BarrierReplyMessageFactory;
 import org.opendaylight.openflowjava.protocol.impl.deserialization.factories.EchoReplyMessageFactory;
 import org.opendaylight.openflowjava.protocol.impl.deserialization.factories.EchoRequestMessageFactory;
@@ -101,6 +103,12 @@ public final class MessageDeserializerInitializer {
         helper.registerDeserializer(25, RoleRequestOutput.class, new RoleReplyMessageFactory());
         helper.registerDeserializer(27, GetAsyncOutput.class, new GetAsyncReplyMessageFactory());
 
+        // register ONF approved experimenter serializers
+        helper.registerExperimenterErrorDeserializer(EncodeConstants.ONF_EXPERIMENTER_ID,
+                new OnfExperimenterErrorFactory());
+        helper.registerExperimenterDeserializer(EncodeConstants.ONF_EXPERIMENTER_ID,
+                EncodeConstants.ONF_ET_BUNDLE_CONTROL, new BundleControlFactory());
+
         // register OF v1.4 message deserializers
         helper = new SimpleDeserializerRegistryHelper(EncodeConstants.OF14_VERSION_ID, registry);
         helper.registerDeserializer(0, HelloMessage.class, new HelloMessageFactory());
diff --git a/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/experimenter/BundleControlFactory.java b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/experimenter/BundleControlFactory.java
new file mode 100644 (file)
index 0000000..0d52e0c
--- /dev/null
@@ -0,0 +1,96 @@
+/*
+ * 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.openflowjava.protocol.impl.deserialization.experimenter;
+
+import io.netty.buffer.ByteBuf;
+import java.util.ArrayList;
+import java.util.List;
+import org.opendaylight.openflowjava.protocol.api.extensibility.DeserializerRegistry;
+import org.opendaylight.openflowjava.protocol.api.extensibility.DeserializerRegistryInjector;
+import org.opendaylight.openflowjava.protocol.api.extensibility.OFDeserializer;
+import org.opendaylight.openflowjava.protocol.api.util.EncodeConstants;
+import org.opendaylight.openflowjava.util.ExperimenterDeserializerKeyFactory;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.approved.extensions.rev160802.BundleControlType;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.approved.extensions.rev160802.BundleFlags;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.approved.extensions.rev160802.BundleId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.approved.extensions.rev160802.BundlePropertyType;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.approved.extensions.rev160802.bundle.properties.BundleProperty;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.approved.extensions.rev160802.bundle.properties.BundlePropertyBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.approved.extensions.rev160802.bundle.properties.bundle.property.bundle.property.entry.BundleExperimenterPropertyBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.approved.extensions.rev160802.bundle.properties.bundle.property.bundle.property.entry.bundle.experimenter.property.BundleExperimenterPropertyData;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.approved.extensions.rev160802.experimenter.input.experimenter.data.of.choice.BundleControl;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.approved.extensions.rev160802.experimenter.input.experimenter.data.of.choice.BundleControlBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.ExperimenterId;
+
+/**
+ * Translates BundleControl messages (OpenFlow v1.3 extension #230).
+ */
+public class BundleControlFactory implements OFDeserializer<BundleControl>, DeserializerRegistryInjector {
+
+    private DeserializerRegistry deserializerRegistry;
+
+    @Override
+    public BundleControl deserialize(ByteBuf message) {
+        BundleId bundleId = new BundleId(message.readUnsignedInt());
+        BundleControlType type = BundleControlType.forValue(message.readUnsignedShort());
+        BundleFlags flags = createBundleFlags(message.readUnsignedShort());
+        BundleControlBuilder builder = new BundleControlBuilder();
+        List<BundleProperty> properties = createBundleProperties(message);
+        return builder.setBundleId(bundleId)
+                .setType(type)
+                .setFlags(flags)
+                .setBundleProperty(properties)
+                .build();
+    }
+
+    private static BundleFlags createBundleFlags(final int flags) {
+        Boolean isAtomic = (flags & (1 << 0)) != 0;
+        Boolean isOrdered = (flags & (1 << 1)) != 0;
+        return new BundleFlags(isAtomic, isOrdered);
+    }
+
+    private List<BundleProperty> createBundleProperties(final ByteBuf message) {
+        List<BundleProperty> properties = new ArrayList<>();
+        while (message.readableBytes() > 0) {
+            BundlePropertyType type = BundlePropertyType.forValue(message.readUnsignedShort());
+            int length = message.readUnsignedShort();
+            if (type != null && type.equals(BundlePropertyType.ONFETBPTEXPERIMENTER)) {
+                properties.add(createExperimenterBundleProperty(length, message));
+            } else {
+                message.skipBytes(length);
+            }
+        }
+        return properties;
+    }
+
+    private BundleProperty createExperimenterBundleProperty(final int length, final ByteBuf message) {
+        BundleExperimenterPropertyBuilder experimenterProperty = new BundleExperimenterPropertyBuilder();
+        long experimenterId = message.readUnsignedInt();
+        long expType = message.readUnsignedInt();
+        experimenterProperty.setExperimenter(new ExperimenterId(experimenterId));
+        experimenterProperty.setExpType(expType);
+
+        OFDeserializer<BundleExperimenterPropertyData> deserializer = deserializerRegistry.getDeserializer(
+                ExperimenterDeserializerKeyFactory.createBundlePropertyDeserializerKey(EncodeConstants.OF13_VERSION_ID,
+                        experimenterId, expType));
+        experimenterProperty.setBundleExperimenterPropertyData(deserializer.deserialize(message.readBytes(length - 12)));
+
+        return new BundlePropertyBuilder().setType(BundlePropertyType.ONFETBPTEXPERIMENTER)
+                .setBundlePropertyEntry(experimenterProperty.build())
+                .build();
+    }
+
+    @Override
+    public void injectDeserializerRegistry(DeserializerRegistry deserializerRegistry) {
+        this.deserializerRegistry = deserializerRegistry;
+    }
+
+}
+
+
diff --git a/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/experimenter/OnfExperimenterErrorFactory.java b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/experimenter/OnfExperimenterErrorFactory.java
new file mode 100644 (file)
index 0000000..a104531
--- /dev/null
@@ -0,0 +1,72 @@
+/*
+ * 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.openflowjava.protocol.impl.deserialization.experimenter;
+
+import io.netty.buffer.ByteBuf;
+import org.opendaylight.openflowjava.protocol.api.extensibility.OFDeserializer;
+import org.opendaylight.openflowjava.protocol.api.util.EncodeConstants;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.approved.extensions.rev160802.OnfExperimenterErrorCode;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev150225.ExperimenterIdError;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev150225.ExperimenterIdErrorBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.ErrorType;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.ExperimenterId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.ErrorMessage;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.ErrorMessageBuilder;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Translates (ONF approved) experimenter error messages.
+ */
+public class OnfExperimenterErrorFactory implements OFDeserializer<ErrorMessage> {
+
+    private static final Logger LOG = LoggerFactory.getLogger(OnfExperimenterErrorFactory.class);
+    private static final String UNKNOWN_TYPE = "UNKNOWN_TYPE";
+    private static final String UNKNOWN_CODE = "UNKNOWN_CODE";
+
+    @Override
+    public ErrorMessage deserialize(ByteBuf message) {
+        ErrorMessageBuilder builder = new ErrorMessageBuilder();
+        builder.setVersion((short) EncodeConstants.OF13_VERSION_ID);
+        builder.setXid(message.readUnsignedInt());
+
+        int type = message.readUnsignedShort();
+        ErrorType errorType = ErrorType.forValue(type);
+        if (errorType != null && errorType.equals(ErrorType.EXPERIMENTER)) {
+            builder.setType(errorType.getIntValue());
+            builder.setTypeString(errorType.getName());
+        } else {
+            LOG.warn("Deserializing other than {} error message with {}", ErrorType.EXPERIMENTER.getName(),
+                    this.getClass().getCanonicalName());
+            builder.setType(type);
+            builder.setTypeString(UNKNOWN_TYPE);
+        }
+
+        int code = message.readUnsignedShort();
+        OnfExperimenterErrorCode errorCode = OnfExperimenterErrorCode.forValue(code);
+        if (errorCode != null) {
+            builder.setCode(errorCode.getIntValue());
+            builder.setCodeString(errorCode.getName());
+        } else {
+            builder.setCode(code);
+            builder.setCodeString(UNKNOWN_CODE);
+        }
+
+        builder.addAugmentation(ExperimenterIdError.class, new ExperimenterIdErrorBuilder()
+                .setExperimenter(new ExperimenterId(message.readUnsignedInt()))
+                .build());
+
+        if (message.readableBytes() > 0) {
+            byte[] data = new byte[message.readableBytes()];
+            message.readBytes(data);
+            builder.setData(data);
+        }
+        return builder.build();
+    }
+}
index 25b29d1dcfa7365c93ae7dd5c338aab5f50c97e9..752ac3e32f0405226ccdd99c0e2dd838d1905f99 100644 (file)
@@ -57,4 +57,15 @@ public class SimpleDeserializerRegistryHelper {
                 .createExperimenterMessageDeserializerKey(version, experimenterId, type), deserializer);
     }
 
+    /**
+     * Register experimenter error deserializer in registry.
+     * @param experimenterId experimenterID of experimenter message
+     * @param deserializer deserializer instance
+     */
+    public void registerExperimenterErrorDeserializer (final long experimenterId,
+                                                       final OFGeneralDeserializer deserializer) {
+        registry.registerDeserializer(ExperimenterDeserializerKeyFactory
+                .createExperimenterErrorDeserializerKey(version, experimenterId), deserializer);
+    }
+
 }
diff --git a/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/experimenter/BundleControlFactoryTest.java b/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/experimenter/BundleControlFactoryTest.java
new file mode 100644 (file)
index 0000000..77aca38
--- /dev/null
@@ -0,0 +1,100 @@
+/*
+ * 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.openflowjava.protocol.impl.deserialization.experimenter;
+
+import io.netty.buffer.ByteBuf;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Matchers;
+import org.mockito.Mock;
+import org.mockito.Mockito;
+import org.mockito.runners.MockitoJUnitRunner;
+import org.opendaylight.openflowjava.protocol.api.extensibility.DeserializerRegistry;
+import org.opendaylight.openflowjava.protocol.api.extensibility.DeserializerRegistryInjector;
+import org.opendaylight.openflowjava.protocol.api.extensibility.OFDeserializer;
+import org.opendaylight.openflowjava.protocol.api.keys.MessageCodeKey;
+import org.opendaylight.openflowjava.protocol.api.util.EncodeConstants;
+import org.opendaylight.openflowjava.protocol.impl.deserialization.DeserializerRegistryImpl;
+import org.opendaylight.openflowjava.protocol.impl.util.BufferHelper;
+import org.opendaylight.openflowjava.util.ByteBufUtils;
+import org.opendaylight.openflowjava.util.ExperimenterDeserializerKeyFactory;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.approved.extensions.rev160802.BundleControlType;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.approved.extensions.rev160802.BundleFlags;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.approved.extensions.rev160802.BundlePropertyType;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.approved.extensions.rev160802.bundle.properties.BundleProperty;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.approved.extensions.rev160802.bundle.properties.bundle.property.bundle.property.entry.BundleExperimenterProperty;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.approved.extensions.rev160802.bundle.properties.bundle.property.bundle.property.entry.bundle.experimenter.property.BundleExperimenterPropertyData;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.approved.extensions.rev160802.experimenter.input.experimenter.data.of.choice.BundleControl;
+
+/**
+ * Tests for {@link org.opendaylight.openflowjava.protocol.impl.deserialization.experimenter.BundleControlFactory}.
+ */
+@RunWith(MockitoJUnitRunner.class)
+public class BundleControlFactoryTest {
+
+    private OFDeserializer<BundleControl> factory;
+    @Mock
+    DeserializerRegistry registry;
+    @Mock
+    OFDeserializer<BundleExperimenterPropertyData> experimenterPropertyDeserializer;
+
+    @Before
+    public void startUp() {
+        DeserializerRegistry registry = new DeserializerRegistryImpl();
+        registry.init();
+        factory = registry.getDeserializer(ExperimenterDeserializerKeyFactory.createExperimenterMessageDeserializerKey(
+                EncodeConstants.OF13_VERSION_ID, EncodeConstants.ONF_EXPERIMENTER_ID, EncodeConstants.ONF_ET_BUNDLE_CONTROL));
+    }
+
+    @Test
+    public void testDeserializeWithoutProperties() {
+        ByteBuf buffer = ByteBufUtils.hexStringToByteBuf("00 00 00 01 " // bundle ID
+                                                       + "00 01 " // type
+                                                       + "00 03"); // flags
+        BundleControl builtByFactory = factory.deserialize(buffer);
+        Assert.assertEquals(1, builtByFactory.getBundleId().getValue().intValue());
+        BundleFlags flags = new BundleFlags(true, true);
+        Assert.assertEquals("Wrong atomic flag", flags.isAtomic(), builtByFactory.getFlags().isAtomic());
+        Assert.assertEquals("Wrong ordered flag", flags.isOrdered(), builtByFactory.getFlags().isOrdered());
+        Assert.assertEquals("Wrong type", BundleControlType.ONFBCTOPENREPLY, builtByFactory.getType());
+        Assert.assertTrue("Properties not empty", builtByFactory.getBundleProperty().isEmpty());
+    }
+
+    @Test
+    public void testDeserializeWithProperties() {
+        ByteBuf buffer = ByteBufUtils.hexStringToByteBuf("00 00 00 01 " // bundle ID
+                                                       + "00 05 " // type
+                                                       + "00 02 " // flags
+                                                       + "ff ff " // type 1
+                                                       + "00 0c " // length 1
+                                                       + "00 00 00 01 " // experimenter ID 1
+                                                       + "00 00 00 02 " // experimenter type 1
+                                                       + "00 00 00 00 " // experimenter data 1
+                                                       + "00 00 " // type 2
+                                                       + "00 04 " // length 2
+                                                       + "00 00 00 00"); // data 2
+        Mockito.when(registry.getDeserializer(Matchers.any(MessageCodeKey.class))).thenReturn(experimenterPropertyDeserializer);
+        ((DeserializerRegistryInjector)factory).injectDeserializerRegistry(registry);
+        BundleControl builtByFactory = BufferHelper.deserialize(factory, buffer);
+        Assert.assertEquals(1, builtByFactory.getBundleId().getValue().intValue());
+        BundleFlags flags = new BundleFlags(false, true);
+        Assert.assertEquals("Wrong atomic flag", flags.isAtomic(), builtByFactory.getFlags().isAtomic());
+        Assert.assertEquals("Wrong ordered flag", flags.isOrdered(), builtByFactory.getFlags().isOrdered());
+        Assert.assertEquals("Wrong type", BundleControlType.ONFBCTCOMMITREPLY, builtByFactory.getType());
+        BundleProperty property = builtByFactory.getBundleProperty().get(0);
+        Assert.assertEquals("Wrong bundle property type", BundlePropertyType.ONFETBPTEXPERIMENTER, property.getType());
+        BundleExperimenterProperty experimenterProperty = (BundleExperimenterProperty) property.getBundlePropertyEntry();
+        Assert.assertEquals("Wrong experimenter ID", 1, experimenterProperty.getExperimenter().getValue().intValue());
+        Assert.assertEquals("Wrong experimenter type", 2, experimenterProperty.getExpType().longValue());
+        Mockito.verify(experimenterPropertyDeserializer, Mockito.times(1)).deserialize(buffer);
+    }
+
+}
\ No newline at end of file
diff --git a/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/experimenter/OnfExperimenterErrorFactoryTest.java b/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/experimenter/OnfExperimenterErrorFactoryTest.java
new file mode 100644 (file)
index 0000000..6989141
--- /dev/null
@@ -0,0 +1,140 @@
+/*
+ * 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.openflowjava.protocol.impl.deserialization.experimenter;
+
+import io.netty.buffer.ByteBuf;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+import org.opendaylight.openflowjava.protocol.api.extensibility.DeserializerRegistry;
+import org.opendaylight.openflowjava.protocol.api.extensibility.OFDeserializer;
+import org.opendaylight.openflowjava.protocol.api.util.EncodeConstants;
+import org.opendaylight.openflowjava.protocol.impl.deserialization.DeserializerRegistryImpl;
+import org.opendaylight.openflowjava.protocol.impl.util.BufferHelper;
+import org.opendaylight.openflowjava.util.ExperimenterDeserializerKeyFactory;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev150225.ExperimenterIdError;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.ErrorMessage;
+
+/**
+ * Tests for {@link org.opendaylight.openflowjava.protocol.impl.deserialization.experimenter.OnfExperimenterErrorFactory}.
+ */
+public class OnfExperimenterErrorFactoryTest {
+
+    private OFDeserializer<ErrorMessage> factory;
+
+    @Before
+    public void startUp() {
+        DeserializerRegistry registry = new DeserializerRegistryImpl();
+        registry.init();
+        factory = registry.getDeserializer(ExperimenterDeserializerKeyFactory.createExperimenterErrorDeserializerKey(
+                EncodeConstants.OF13_VERSION_ID, EncodeConstants.ONF_EXPERIMENTER_ID));
+    }
+
+    @Test
+    public void testVersion() {
+        ByteBuf buffer = BufferHelper.buildBuffer("ff ff 08 fc 00 00 00 01");
+        ErrorMessage builtByFactory = factory.deserialize(buffer);
+        BufferHelper.checkHeaderV13(builtByFactory);
+    }
+
+    @Test
+    public void testDeserializeBase() {
+        ByteBuf buffer = BufferHelper.buildBuffer("ff ff 08 fc 4f 4e 46 00");
+        ErrorMessage builtByFactory = factory.deserialize(buffer);
+        Assert.assertEquals("Wrong type", EncodeConstants.EXPERIMENTER_VALUE, builtByFactory.getType().intValue());
+        Assert.assertEquals("Wrong type string", "EXPERIMENTER", builtByFactory.getTypeString());
+        Assert.assertEquals("Wrong experimenter ID", EncodeConstants.ONF_EXPERIMENTER_ID,
+                builtByFactory.getAugmentation(ExperimenterIdError.class).getExperimenter().getValue().intValue());
+        Assert.assertNull("Data is not null", builtByFactory.getData());
+    }
+
+    @Test
+    public void testDeserializeCodes() {
+        ByteBuf buffer = BufferHelper.buildBuffer("ff ff 08 fc 00 00 00 01");
+        ErrorMessage builtByFactory = factory.deserialize(buffer);
+        Assert.assertEquals("Wrong code", 2300, builtByFactory.getCode().intValue());
+        Assert.assertEquals("Wrong code string", "ONFERR_ET_UNKNOWN", builtByFactory.getCodeString());
+
+        buffer = BufferHelper.buildBuffer("ff ff 08 fd 00 00 00 01");
+        builtByFactory = factory.deserialize(buffer);
+        Assert.assertEquals("Wrong code", 2301, builtByFactory.getCode().intValue());
+        Assert.assertEquals("Wrong code string", "ONFERR_ET_EPERM", builtByFactory.getCodeString());
+
+        buffer = BufferHelper.buildBuffer("ff ff 08 fe 00 00 00 01");
+        builtByFactory = factory.deserialize(buffer);
+        Assert.assertEquals("Wrong code", 2302, builtByFactory.getCode().intValue());
+        Assert.assertEquals("Wrong code string", "ONFERR_ET_BAD_ID", builtByFactory.getCodeString());
+
+        buffer = BufferHelper.buildBuffer("ff ff 08 ff 00 00 00 01");
+        builtByFactory = factory.deserialize(buffer);
+        Assert.assertEquals("Wrong code", 2303, builtByFactory.getCode().intValue());
+        Assert.assertEquals("Wrong code string", "ONFERR_ET_BUNDLE_EXIST", builtByFactory.getCodeString());
+
+        buffer = BufferHelper.buildBuffer("ff ff 09 00 00 00 00 01");
+        builtByFactory = factory.deserialize(buffer);
+        Assert.assertEquals("Wrong code", 2304, builtByFactory.getCode().intValue());
+        Assert.assertEquals("Wrong code string", "ONFERR_ET_BUNDLE_CLOSED", builtByFactory.getCodeString());
+
+        buffer = BufferHelper.buildBuffer("ff ff 09 01 00 00 00 01");
+        builtByFactory = factory.deserialize(buffer);
+        Assert.assertEquals("Wrong code", 2305, builtByFactory.getCode().intValue());
+        Assert.assertEquals("Wrong code string", "ONFERR_ET_OUT_OF_BUNDLES", builtByFactory.getCodeString());
+
+        buffer = BufferHelper.buildBuffer("ff ff 09 02 00 00 00 01");
+        builtByFactory = factory.deserialize(buffer);
+        Assert.assertEquals("Wrong code", 2306, builtByFactory.getCode().intValue());
+        Assert.assertEquals("Wrong code string", "ONFERR_ET_BAD_TYPE", builtByFactory.getCodeString());
+
+        buffer = BufferHelper.buildBuffer("ff ff 09 03 00 00 00 01");
+        builtByFactory = factory.deserialize(buffer);
+        Assert.assertEquals("Wrong code", 2307, builtByFactory.getCode().intValue());
+        Assert.assertEquals("Wrong code string", "ONFERR_ET_BAD_FLAGS", builtByFactory.getCodeString());
+
+        buffer = BufferHelper.buildBuffer("ff ff 09 04 00 00 00 01");
+        builtByFactory = factory.deserialize(buffer);
+        Assert.assertEquals("Wrong code", 2308, builtByFactory.getCode().intValue());
+        Assert.assertEquals("Wrong code string", "ONFERR_ET_MSG_BAD_LEN", builtByFactory.getCodeString());
+
+        buffer = BufferHelper.buildBuffer("ff ff 09 05 00 00 00 01");
+        builtByFactory = factory.deserialize(buffer);
+        Assert.assertEquals("Wrong code", 2309, builtByFactory.getCode().intValue());
+        Assert.assertEquals("Wrong code string", "ONFERR_ET_MSG_BAD_XID", builtByFactory.getCodeString());
+
+        buffer = BufferHelper.buildBuffer("ff ff 09 06 00 00 00 01");
+        builtByFactory = factory.deserialize(buffer);
+        Assert.assertEquals("Wrong code", 2310, builtByFactory.getCode().intValue());
+        Assert.assertEquals("Wrong code string", "ONFERR_ET_MSG_UNSUP", builtByFactory.getCodeString());
+
+        buffer = BufferHelper.buildBuffer("ff ff 09 07 00 00 00 01");
+        builtByFactory = factory.deserialize(buffer);
+        Assert.assertEquals("Wrong code", 2311, builtByFactory.getCode().intValue());
+        Assert.assertEquals("Wrong code string", "ONFERR_ET_MSG_CONFLICT", builtByFactory.getCodeString());
+
+        buffer = BufferHelper.buildBuffer("ff ff 09 08 00 00 00 01");
+        builtByFactory = factory.deserialize(buffer);
+        Assert.assertEquals("Wrong code", 2312, builtByFactory.getCode().intValue());
+        Assert.assertEquals("Wrong code string", "ONFERR_ET_MSG_TOO_MANY", builtByFactory.getCodeString());
+
+        buffer = BufferHelper.buildBuffer("ff ff 09 09 00 00 00 01");
+        builtByFactory = factory.deserialize(buffer);
+        Assert.assertEquals("Wrong code", 2313, builtByFactory.getCode().intValue());
+        Assert.assertEquals("Wrong code string", "ONFERR_ET_MSG_FAILED", builtByFactory.getCodeString());
+
+        buffer = BufferHelper.buildBuffer("ff ff 09 0a 00 00 00 01");
+        builtByFactory = factory.deserialize(buffer);
+        Assert.assertEquals("Wrong code", 2314, builtByFactory.getCode().intValue());
+        Assert.assertEquals("Wrong code string", "ONFERR_ET_TIMEOUT", builtByFactory.getCodeString());
+
+        buffer = BufferHelper.buildBuffer("ff ff 09 0b 00 00 00 01");
+        builtByFactory = factory.deserialize(buffer);
+        Assert.assertEquals("Wrong code", 2315, builtByFactory.getCode().intValue());
+        Assert.assertEquals("Wrong code string", "ONFERR_ET_BUNDLE_IN_PROGRESS", builtByFactory.getCodeString());
+    }
+
+}
\ No newline at end of file
index bbb9ee871282bfdaf409cbfa8b94e74c23406a70..75ada6fbd287b3e15cab6f32199fc6b9f5130c8b 100644 (file)
@@ -10,6 +10,7 @@ package org.opendaylight.openflowjava.util;
 
 import org.opendaylight.openflowjava.protocol.api.keys.ExperimenterIdDeserializerKey;
 import org.opendaylight.openflowjava.protocol.api.keys.ExperimenterIdTypeDeserializerKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.approved.extensions.rev160802.bundle.properties.bundle.property.bundle.property.entry.bundle.experimenter.property.BundleExperimenterPropertyData;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.ErrorMessage;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.experimenter.core.ExperimenterDataOfChoice;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.meter.band.header.meter.band.MeterBandExperimenterCase;
@@ -106,4 +107,15 @@ public abstract class ExperimenterDeserializerKeyFactory {
             short version, Long experimenterId) {
         return new ExperimenterIdDeserializerKey(version, experimenterId, MeterBandExperimenterCase.class);
     }
+
+    /**
+     * @param version openflow wire version
+     * @param experimenterId experimenter ID
+     * @param type experimenter type according to vendor implementation
+     * @return key instance
+     */
+    public static ExperimenterIdTypeDeserializerKey createBundlePropertyDeserializerKey(
+            short version, long experimenterId, long type) {
+        return new ExperimenterIdTypeDeserializerKey(version, experimenterId, type, BundleExperimenterPropertyData.class);
+    }
 }
\ No newline at end of file