Bug 2756 - Action model update
[openflowjava.git] / openflow-protocol-impl / src / main / java / org / opendaylight / openflowjava / protocol / impl / deserialization / factories / OF10StatsReplyMessageFactory.java
index 4fc94355a91f5d710d414f8ce29b43361ce20a00..691a270f0905e8a5f00e3438060323734e8d9787 100644 (file)
@@ -14,12 +14,21 @@ import java.math.BigInteger;
 import java.util.ArrayList;
 import java.util.List;
 
-import org.opendaylight.openflowjava.protocol.impl.deserialization.OFDeserializer;
-import org.opendaylight.openflowjava.protocol.impl.util.EncodeConstants;
-import org.opendaylight.openflowjava.protocol.impl.util.OF10ActionsDeserializer;
+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.util.CodeKeyMaker;
+import org.opendaylight.openflowjava.protocol.impl.util.CodeKeyMakerFactory;
+import org.opendaylight.openflowjava.protocol.impl.util.ListDeserializer;
 import org.opendaylight.openflowjava.protocol.impl.util.OF10MatchDeserializer;
+import org.opendaylight.openflowjava.util.ByteBufUtils;
+import org.opendaylight.openflowjava.util.ExperimenterDeserializerKeyFactory;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev150203.actions.grouping.Action;
 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.oxm.rev150225.match.v10.grouping.MatchV10;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.MultipartReplyMessage;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.MultipartReplyMessageBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyAggregateCase;
@@ -27,7 +36,6 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyDescCase;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyDescCaseBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyExperimenterCase;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyExperimenterCaseBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyFlowCase;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyFlowCaseBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyPortStatsCase;
@@ -38,7 +46,6 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyTableCaseBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.aggregate._case.MultipartReplyAggregateBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.desc._case.MultipartReplyDescBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.experimenter._case.MultipartReplyExperimenterBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.flow._case.MultipartReplyFlowBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.flow._case.multipart.reply.flow.FlowStats;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.flow._case.multipart.reply.flow.FlowStatsBuilder;
@@ -56,7 +63,8 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731
  * Translates StatsReply messages (OpenFlow v1.0)
  * @author michal.polkorab
  */
-public class OF10StatsReplyMessageFactory implements OFDeserializer<MultipartReplyMessage> {
+public class OF10StatsReplyMessageFactory implements OFDeserializer<MultipartReplyMessage>,
+        DeserializerRegistryInjector {
 
     private static final int DESC_STR_LEN = 256;
     private static final int SERIAL_NUM_LEN = 32;
@@ -67,52 +75,39 @@ public class OF10StatsReplyMessageFactory implements OFDeserializer<MultipartRep
     private static final byte MAX_TABLE_NAME_LENGTH = 32;
     private static final byte PADDING_IN_PORT_STATS_HEADER = 6;
     private static final byte PADDING_IN_QUEUE_HEADER = 2;
-
-    private static OF10StatsReplyMessageFactory instance;
-    
-    private OF10StatsReplyMessageFactory() {
-        // singleton
-    }
-    
-    /**
-     * @return singleton factory
-     */
-    public static synchronized OF10StatsReplyMessageFactory getInstance() {
-        if (instance == null){
-            instance = new OF10StatsReplyMessageFactory();
-        }
-        return instance;
-    }
+    private static final byte LENGTH_OF_FLOW_STATS = 88;
+    private static final int TABLE_STATS_LENGTH = 64;
+    private DeserializerRegistry registry;
 
     @Override
-    public MultipartReplyMessage bufferToMessage(ByteBuf rawMessage, short version) {
+    public MultipartReplyMessage deserialize(ByteBuf rawMessage) {
         MultipartReplyMessageBuilder builder = new MultipartReplyMessageBuilder();
-        builder.setVersion(version);
+        builder.setVersion((short) EncodeConstants.OF10_VERSION_ID);
         builder.setXid(rawMessage.readUnsignedInt());
         int type = rawMessage.readUnsignedShort();
         builder.setType(MultipartType.forValue(type));
         builder.setFlags(new MultipartRequestFlags((rawMessage.readUnsignedShort() & 0x01) != 0));
-        switch (type) {
-        case 0:  builder.setMultipartReplyBody(setDesc(rawMessage));
+        switch (MultipartType.forValue(type)) {
+        case OFPMPDESC:  builder.setMultipartReplyBody(setDesc(rawMessage));
+            break;
+        case OFPMPFLOW:  builder.setMultipartReplyBody(setFlow(rawMessage));
             break;
-        case 1:  builder.setMultipartReplyBody(setFlow(rawMessage));
+        case OFPMPAGGREGATE:  builder.setMultipartReplyBody(setAggregate(rawMessage));
             break;
-        case 2:  builder.setMultipartReplyBody(setAggregate(rawMessage));
+        case OFPMPTABLE:  builder.setMultipartReplyBody(setTable(rawMessage));
             break;
-        case 3:  builder.setMultipartReplyBody(setTable(rawMessage));
-            break;         
-        case 4:  builder.setMultipartReplyBody(setPortStats(rawMessage));
+        case OFPMPPORTSTATS:  builder.setMultipartReplyBody(setPortStats(rawMessage));
             break;
-        case 5:  builder.setMultipartReplyBody(setQueue(rawMessage));
-            break;         
-        case 0xFFFF: builder.setMultipartReplyBody(setExperimenter(rawMessage));
+        case OFPMPQUEUE:  builder.setMultipartReplyBody(setQueue(rawMessage));
             break;
-        default: 
+        case OFPMPEXPERIMENTER: builder.setMultipartReplyBody(setExperimenter(rawMessage));
+            break;
+        default:
             break;
         }
         return builder.build();
     }
-    
+
     private static MultipartReplyDescCase setDesc(ByteBuf input) {
         MultipartReplyDescCaseBuilder caseBuilder = new MultipartReplyDescCaseBuilder();
         MultipartReplyDescBuilder descBuilder = new MultipartReplyDescBuilder();
@@ -139,78 +134,90 @@ public class OF10StatsReplyMessageFactory implements OFDeserializer<MultipartRep
         caseBuilder.setMultipartReplyDesc(descBuilder.build());
         return caseBuilder.build();
     }
-    
-    private static MultipartReplyFlowCase setFlow(ByteBuf input) {
+
+    private MultipartReplyFlowCase setFlow(ByteBuf input) {
         MultipartReplyFlowCaseBuilder caseBuilder = new MultipartReplyFlowCaseBuilder();
         MultipartReplyFlowBuilder flowBuilder = new MultipartReplyFlowBuilder();
         List<FlowStats> flowStatsList = new ArrayList<>();
         while (input.readableBytes() > 0) {
             FlowStatsBuilder flowStatsBuilder = new FlowStatsBuilder();
-            input.skipBytes(EncodeConstants.SIZE_OF_SHORT_IN_BYTES);
+            int length = input.readUnsignedShort();
             flowStatsBuilder.setTableId(input.readUnsignedByte());
             input.skipBytes(PADDING_IN_FLOW_STATS_HEADER);
-            flowStatsBuilder.setMatchV10(OF10MatchDeserializer.createMatchV10(input));
+            OFDeserializer<MatchV10> matchDeserializer = registry.getDeserializer(
+                    new MessageCodeKey(EncodeConstants.OF10_VERSION_ID, EncodeConstants.EMPTY_VALUE, MatchV10.class));
+            flowStatsBuilder.setMatchV10(matchDeserializer.deserialize(input));
             flowStatsBuilder.setDurationSec(input.readUnsignedInt());
             flowStatsBuilder.setDurationNsec(input.readUnsignedInt());
             flowStatsBuilder.setPriority(input.readUnsignedShort());
             flowStatsBuilder.setIdleTimeout(input.readUnsignedShort());
             flowStatsBuilder.setHardTimeout(input.readUnsignedShort());
             input.skipBytes(PADDING_IN_FLOW_STATS_HEADER_02);
-            byte[] cookie = new byte[Long.SIZE/Byte.SIZE];
+            byte[] cookie = new byte[EncodeConstants.SIZE_OF_LONG_IN_BYTES];
             input.readBytes(cookie);
-            flowStatsBuilder.setCookie(new BigInteger(cookie));
-            byte[] packetCount = new byte[Long.SIZE/Byte.SIZE];
+            flowStatsBuilder.setCookie(new BigInteger(1, cookie));
+            byte[] packetCount = new byte[EncodeConstants.SIZE_OF_LONG_IN_BYTES];
             input.readBytes(packetCount);
-            flowStatsBuilder.setPacketCount(new BigInteger(packetCount));
-            byte[] byteCount = new byte[Long.SIZE/Byte.SIZE];
+            flowStatsBuilder.setPacketCount(new BigInteger(1, packetCount));
+            byte[] byteCount = new byte[EncodeConstants.SIZE_OF_LONG_IN_BYTES];
             input.readBytes(byteCount);
-            flowStatsBuilder.setByteCount(new BigInteger(byteCount));
-            flowStatsBuilder.setActionsList(OF10ActionsDeserializer.createActionsList(input));
+            flowStatsBuilder.setByteCount(new BigInteger(1, byteCount));
+            CodeKeyMaker keyMaker = CodeKeyMakerFactory.createActionsKeyMaker(EncodeConstants.OF10_VERSION_ID);
+            List<Action> actions = ListDeserializer.deserializeList(EncodeConstants.OF10_VERSION_ID,
+                    length - LENGTH_OF_FLOW_STATS, input, keyMaker, registry);
+            flowStatsBuilder.setAction(actions);
             flowStatsList.add(flowStatsBuilder.build());
         }
         flowBuilder.setFlowStats(flowStatsList);
         caseBuilder.setMultipartReplyFlow(flowBuilder.build());
         return caseBuilder.build();
     }
-    
+
     private static MultipartReplyAggregateCase setAggregate(ByteBuf input) {
         MultipartReplyAggregateCaseBuilder caseBuilder = new MultipartReplyAggregateCaseBuilder();
         MultipartReplyAggregateBuilder builder = new MultipartReplyAggregateBuilder();
-        byte[] packetCount = new byte[Long.SIZE/Byte.SIZE];
+        byte[] packetCount = new byte[EncodeConstants.SIZE_OF_LONG_IN_BYTES];
         input.readBytes(packetCount);
-        builder.setPacketCount(new BigInteger(packetCount));
-        byte[] byteCount = new byte[Long.SIZE/Byte.SIZE];
+        builder.setPacketCount(new BigInteger(1, packetCount));
+        byte[] byteCount = new byte[EncodeConstants.SIZE_OF_LONG_IN_BYTES];
         input.readBytes(byteCount);
-        builder.setByteCount(new BigInteger(byteCount));
+        builder.setByteCount(new BigInteger(1, byteCount));
         builder.setFlowCount(input.readUnsignedInt());
         input.skipBytes(PADDING_IN_AGGREGATE_HEADER);
         caseBuilder.setMultipartReplyAggregate(builder.build());
         return caseBuilder.build();
     }
-    
+
     private static MultipartReplyTableCase setTable(ByteBuf input) {
         MultipartReplyTableCaseBuilder caseBuilder = new MultipartReplyTableCaseBuilder();
         MultipartReplyTableBuilder builder = new MultipartReplyTableBuilder();
         List<TableStats> tableStatsList = new ArrayList<>();
-        while (input.readableBytes() > 0) {
+        // TODO - replace ">= TABLE_STATS_LENGTH" with "> 0" after fix in OVS switch
+        while (input.readableBytes() >= TABLE_STATS_LENGTH) {
             TableStatsBuilder tableStatsBuilder = new TableStatsBuilder();
             tableStatsBuilder.setTableId(input.readUnsignedByte());
             input.skipBytes(PADDING_IN_TABLE_HEADER);
-            tableStatsBuilder.setName(input.readBytes(MAX_TABLE_NAME_LENGTH).toString());
+            tableStatsBuilder.setName(ByteBufUtils.decodeNullTerminatedString(input, MAX_TABLE_NAME_LENGTH));
+            long wildcards = input.readUnsignedInt();
+            tableStatsBuilder.setWildcards(OF10MatchDeserializer.createWildcards(wildcards));
+            tableStatsBuilder.setNwSrcMask(OF10MatchDeserializer.decodeNwSrcMask(wildcards));
+            tableStatsBuilder.setNwDstMask(OF10MatchDeserializer.decodeNwDstMask(wildcards));
+            tableStatsBuilder.setMaxEntries(input.readUnsignedInt());
             tableStatsBuilder.setActiveCount(input.readUnsignedInt());
-            byte[] lookupCount = new byte[Long.SIZE/Byte.SIZE];
+            byte[] lookupCount = new byte[EncodeConstants.SIZE_OF_LONG_IN_BYTES];
             input.readBytes(lookupCount);
-            tableStatsBuilder.setLookupCount(new BigInteger(lookupCount));
-            byte[] matchedCount = new byte[Long.SIZE/Byte.SIZE];
+            tableStatsBuilder.setLookupCount(new BigInteger(1, lookupCount));
+            byte[] matchedCount = new byte[EncodeConstants.SIZE_OF_LONG_IN_BYTES];
             input.readBytes(matchedCount);
-            tableStatsBuilder.setMatchedCount(new BigInteger(matchedCount));
+            tableStatsBuilder.setMatchedCount(new BigInteger(1, matchedCount));
             tableStatsList.add(tableStatsBuilder.build());
         }
+        input.skipBytes(input.readableBytes());
         builder.setTableStats(tableStatsList);
         caseBuilder.setMultipartReplyTable(builder.build());
         return caseBuilder.build();
     }
-    
+
     private static MultipartReplyPortStatsCase setPortStats(ByteBuf input) {
         MultipartReplyPortStatsCaseBuilder caseBuilder = new MultipartReplyPortStatsCaseBuilder();
         MultipartReplyPortStatsBuilder builder = new MultipartReplyPortStatsBuilder();
@@ -219,48 +226,49 @@ public class OF10StatsReplyMessageFactory implements OFDeserializer<MultipartRep
             PortStatsBuilder portStatsBuilder = new PortStatsBuilder();
             portStatsBuilder.setPortNo((long) input.readUnsignedShort());
             input.skipBytes(PADDING_IN_PORT_STATS_HEADER);
-            byte[] rxPackets = new byte[Long.SIZE/Byte.SIZE];
+            byte[] rxPackets = new byte[EncodeConstants.SIZE_OF_LONG_IN_BYTES];
             input.readBytes(rxPackets);
-            portStatsBuilder.setRxPackets(new BigInteger(rxPackets));
-            byte[] txPackets = new byte[Long.SIZE/Byte.SIZE];
+            portStatsBuilder.setRxPackets(new BigInteger(1, rxPackets));
+            byte[] txPackets = new byte[EncodeConstants.SIZE_OF_LONG_IN_BYTES];
             input.readBytes(txPackets);
-            portStatsBuilder.setTxPackets(new BigInteger(txPackets));
-            byte[] rxBytes = new byte[Long.SIZE/Byte.SIZE];
+            portStatsBuilder.setTxPackets(new BigInteger(1, txPackets));
+            byte[] rxBytes = new byte[EncodeConstants.SIZE_OF_LONG_IN_BYTES];
             input.readBytes(rxBytes);
-            portStatsBuilder.setRxBytes(new BigInteger(rxBytes));
-            byte[] txBytes = new byte[Long.SIZE/Byte.SIZE];
+            portStatsBuilder.setRxBytes(new BigInteger(1, rxBytes));
+            byte[] txBytes = new byte[EncodeConstants.SIZE_OF_LONG_IN_BYTES];
             input.readBytes(txBytes);
-            portStatsBuilder.setTxBytes(new BigInteger(txBytes));
-            byte[] rxDropped = new byte[Long.SIZE/Byte.SIZE];
+            portStatsBuilder.setTxBytes(new BigInteger(1, txBytes));
+            byte[] rxDropped = new byte[EncodeConstants.SIZE_OF_LONG_IN_BYTES];
             input.readBytes(rxDropped);
-            portStatsBuilder.setRxDropped(new BigInteger(rxDropped));
-            byte[] txDropped = new byte[Long.SIZE/Byte.SIZE];
+            portStatsBuilder.setRxDropped(new BigInteger(1, rxDropped));
+            byte[] txDropped = new byte[EncodeConstants.SIZE_OF_LONG_IN_BYTES];
             input.readBytes(txDropped);
-            portStatsBuilder.setTxDropped(new BigInteger(txDropped));
-            byte[] rxErrors = new byte[Long.SIZE/Byte.SIZE];
+            portStatsBuilder.setTxDropped(new BigInteger(1, txDropped));
+            byte[] rxErrors = new byte[EncodeConstants.SIZE_OF_LONG_IN_BYTES];
             input.readBytes(rxErrors);
-            portStatsBuilder.setRxErrors(new BigInteger(rxErrors));
-            byte[] txErrors = new byte[Long.SIZE/Byte.SIZE];
+            portStatsBuilder.setRxErrors(new BigInteger(1, rxErrors));
+            byte[] txErrors = new byte[EncodeConstants.SIZE_OF_LONG_IN_BYTES];
             input.readBytes(txErrors);
-            portStatsBuilder.setTxErrors(new BigInteger(txErrors));
-            byte[] rxFrameErr = new byte[Long.SIZE/Byte.SIZE];
+            portStatsBuilder.setTxErrors(new BigInteger(1, txErrors));
+            byte[] rxFrameErr = new byte[EncodeConstants.SIZE_OF_LONG_IN_BYTES];
             input.readBytes(rxFrameErr);
-            portStatsBuilder.setRxFrameErr(new BigInteger(rxFrameErr));
-            byte[] rxOverErr = new byte[Long.SIZE/Byte.SIZE];
+            portStatsBuilder.setRxFrameErr(new BigInteger(1, rxFrameErr));
+            byte[] rxOverErr = new byte[EncodeConstants.SIZE_OF_LONG_IN_BYTES];
             input.readBytes(rxOverErr);
-            portStatsBuilder.setRxOverErr(new BigInteger(rxOverErr));
-            byte[] rxCrcErr = new byte[Long.SIZE/Byte.SIZE];
+            portStatsBuilder.setRxOverErr(new BigInteger(1, rxOverErr));
+            byte[] rxCrcErr = new byte[EncodeConstants.SIZE_OF_LONG_IN_BYTES];
             input.readBytes(rxCrcErr);
-            portStatsBuilder.setRxCrcErr(new BigInteger(rxCrcErr));
-            byte[] collisions = new byte[Long.SIZE/Byte.SIZE];
+            portStatsBuilder.setRxCrcErr(new BigInteger(1, rxCrcErr));
+            byte[] collisions = new byte[EncodeConstants.SIZE_OF_LONG_IN_BYTES];
             input.readBytes(collisions);
-            portStatsBuilder.setCollisions(new BigInteger(collisions));
+            portStatsBuilder.setCollisions(new BigInteger(1, collisions));
+            portStatsList.add(portStatsBuilder.build());
         }
         builder.setPortStats(portStatsList);
         caseBuilder.setMultipartReplyPortStats(builder.build());
         return caseBuilder.build();
     }
-    
+
     private static MultipartReplyQueueCase setQueue(ByteBuf input) {
         MultipartReplyQueueCaseBuilder caseBuilder = new MultipartReplyQueueCaseBuilder();
         MultipartReplyQueueBuilder builder = new MultipartReplyQueueBuilder();
@@ -270,30 +278,29 @@ public class OF10StatsReplyMessageFactory implements OFDeserializer<MultipartRep
             queueStatsBuilder.setPortNo((long) input.readUnsignedShort());
             input.skipBytes(PADDING_IN_QUEUE_HEADER);
             queueStatsBuilder.setQueueId(input.readUnsignedInt());
-            byte[] txBytes = new byte[Long.SIZE/Byte.SIZE];
+            byte[] txBytes = new byte[EncodeConstants.SIZE_OF_LONG_IN_BYTES];
             input.readBytes(txBytes);
-            queueStatsBuilder.setTxBytes(new BigInteger(txBytes));
-            byte[] txPackets = new byte[Long.SIZE/Byte.SIZE];
+            queueStatsBuilder.setTxBytes(new BigInteger(1, txBytes));
+            byte[] txPackets = new byte[EncodeConstants.SIZE_OF_LONG_IN_BYTES];
             input.readBytes(txPackets);
-            queueStatsBuilder.setTxPackets(new BigInteger(txPackets));
-            byte[] txErrors = new byte[Long.SIZE/Byte.SIZE];
+            queueStatsBuilder.setTxPackets(new BigInteger(1, txPackets));
+            byte[] txErrors = new byte[EncodeConstants.SIZE_OF_LONG_IN_BYTES];
             input.readBytes(txErrors);
-            queueStatsBuilder.setTxErrors(new BigInteger(txErrors));
+            queueStatsBuilder.setTxErrors(new BigInteger(1, txErrors));
             queueStatsList.add(queueStatsBuilder.build());
         }
         builder.setQueueStats(queueStatsList);
         caseBuilder.setMultipartReplyQueue(builder.build());
         return caseBuilder.build();
     }
-    
-    private static MultipartReplyExperimenterCase setExperimenter(ByteBuf input) {
-       MultipartReplyExperimenterCaseBuilder caseBuilder = new MultipartReplyExperimenterCaseBuilder();
-        MultipartReplyExperimenterBuilder builder = new MultipartReplyExperimenterBuilder();
-        builder.setExperimenter(input.readUnsignedInt());
-        byte[] data = new byte[Long.SIZE/Byte.SIZE];
-        input.readBytes(data);
-        builder.setData(data);
-        caseBuilder.setMultipartReplyExperimenter(builder.build());
-        return caseBuilder.build();
+
+    private MultipartReplyExperimenterCase setExperimenter(ByteBuf input) {
+        return registry.getDeserializer(ExperimenterDeserializerKeyFactory.createMultipartReplyMessageDeserializerKey(
+                EncodeConstants.OF10_VERSION_ID, input.readUnsignedInt()));
+    }
+
+    @Override
+    public void injectDeserializerRegistry(DeserializerRegistry deserializerRegistry) {
+        registry = deserializerRegistry;
     }
 }