Bug 2756 - Action model update
[openflowjava.git] / openflow-protocol-impl / src / main / java / org / opendaylight / openflowjava / protocol / impl / deserialization / factories / OF10StatsReplyMessageFactory.java
index b18efb446c880f8097d7531447260dc0bcf9bd26..691a270f0905e8a5f00e3438060323734e8d9787 100644 (file)
-/* Copyright (C)2013 Pantheon Technologies, s.r.o. All rights reserved. */\r
-package org.opendaylight.openflowjava.protocol.impl.deserialization.factories;\r
-\r
-import io.netty.buffer.ByteBuf;\r
-\r
-import java.math.BigInteger;\r
-import java.util.ArrayList;\r
-import java.util.List;\r
-\r
-import org.opendaylight.openflowjava.protocol.impl.deserialization.OFDeserializer;\r
-import org.opendaylight.openflowjava.protocol.impl.util.OF10ActionsDeserializer;\r
-import org.opendaylight.openflowjava.protocol.impl.util.OF10MatchDeserializer;\r
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.MultipartRequestFlags;\r
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.MultipartType;\r
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.MultipartReplyMessage;\r
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.MultipartReplyMessageBuilder;\r
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyAggregate;\r
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyAggregateBuilder;\r
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyDesc;\r
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyDescBuilder;\r
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyExperimenter;\r
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyExperimenterBuilder;\r
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyFlow;\r
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyFlowBuilder;\r
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyPortStats;\r
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyPortStatsBuilder;\r
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyQueue;\r
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyQueueBuilder;\r
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyTable;\r
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyTableBuilder;\r
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.flow.FlowStats;\r
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.flow.FlowStatsBuilder;\r
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.port.stats.PortStats;\r
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.port.stats.PortStatsBuilder;\r
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.queue.QueueStats;\r
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.queue.QueueStatsBuilder;\r
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.table.TableStats;\r
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.table.TableStatsBuilder;\r
-\r
-/**\r
- * @author michal.polkorab\r
- *\r
- */\r
-public class OF10StatsReplyMessageFactory implements OFDeserializer<MultipartReplyMessage> {\r
-\r
-    private static OF10StatsReplyMessageFactory instance;\r
-    \r
-    private OF10StatsReplyMessageFactory() {\r
-        // singleton\r
-    }\r
-    \r
-    /**\r
-     * @return singleton factory\r
-     */\r
-    public static synchronized OF10StatsReplyMessageFactory getInstance() {\r
-        if (instance == null){\r
-            instance = new OF10StatsReplyMessageFactory();\r
-        }\r
-        return instance;\r
-    }\r
-\r
-    @Override\r
-    public MultipartReplyMessage bufferToMessage(ByteBuf rawMessage, short version) {\r
-        MultipartReplyMessageBuilder builder = new MultipartReplyMessageBuilder();\r
-        builder.setVersion(version);\r
-        builder.setXid(rawMessage.readUnsignedInt());\r
-        int type = rawMessage.readUnsignedShort();\r
-        builder.setType(MultipartType.forValue(type));\r
-        builder.setFlags(new MultipartRequestFlags((rawMessage.readUnsignedShort() & 0x01) != 0));\r
-        switch (type) {\r
-        case 0:  builder.setMultipartReplyBody(setDesc(rawMessage));\r
-            break;\r
-        case 1:  builder.setMultipartReplyBody(setFlow(rawMessage));\r
-            break;\r
-        case 2:  builder.setMultipartReplyBody(setAggregate(rawMessage));\r
-            break;\r
-        case 3:  builder.setMultipartReplyBody(setTable(rawMessage));\r
-            break;         \r
-        case 4:  builder.setMultipartReplyBody(setPortStats(rawMessage));\r
-            break;\r
-        case 5:  builder.setMultipartReplyBody(setQueue(rawMessage));\r
-            break;         \r
-        case 0xFFFF: builder.setMultipartReplyBody(setExperimenter(rawMessage));\r
-            break;\r
-        default: \r
-            break;\r
-        }\r
-        return builder.build();\r
-    }\r
-    \r
-    private static MultipartReplyDesc setDesc(ByteBuf input) {\r
-        final int DESC_STR_LEN = 256;\r
-        final int SERIAL_NUM_LEN = 32;\r
-        MultipartReplyDescBuilder descBuilder = new MultipartReplyDescBuilder();\r
-        byte[] mfrDescBytes = new byte[DESC_STR_LEN];\r
-        input.readBytes(mfrDescBytes);\r
-        String mfrDesc = new String(mfrDescBytes);\r
-        descBuilder.setMfrDesc(mfrDesc.trim());\r
-        byte[] hwDescBytes = new byte[DESC_STR_LEN];\r
-        input.readBytes(hwDescBytes);\r
-        String hwDesc = new String(hwDescBytes);\r
-        descBuilder.setHwDesc(hwDesc.trim());\r
-        byte[] swDescBytes = new byte[DESC_STR_LEN];\r
-        input.readBytes(swDescBytes);\r
-        String swDesc = new String(swDescBytes);\r
-        descBuilder.setSwDesc(swDesc.trim());\r
-        byte[] serialNumBytes = new byte[SERIAL_NUM_LEN];\r
-        input.readBytes(serialNumBytes);\r
-        String serialNum = new String(serialNumBytes);\r
-        descBuilder.setSerialNum(serialNum.trim());\r
-        byte[] dpDescBytes = new byte[DESC_STR_LEN];\r
-        input.readBytes(dpDescBytes);\r
-        String dpDesc = new String(dpDescBytes);\r
-        descBuilder.setDpDesc(dpDesc.trim());\r
-        return descBuilder.build();\r
-    }\r
-    \r
-    private static MultipartReplyFlow setFlow(ByteBuf input) {\r
-        final byte PADDING_IN_FLOW_STATS_HEADER = 1;\r
-        final byte PADDING_IN_FLOW_STATS_HEADER_02 = 6;\r
-        MultipartReplyFlowBuilder flowBuilder = new MultipartReplyFlowBuilder();\r
-        List<FlowStats> flowStatsList = new ArrayList<>();\r
-        FlowStatsBuilder flowStatsBuilder = new FlowStatsBuilder();\r
-        input.skipBytes(Short.SIZE / Byte.SIZE);\r
-        flowStatsBuilder.setTableId(input.readUnsignedByte());\r
-        input.skipBytes(PADDING_IN_FLOW_STATS_HEADER);\r
-        flowStatsBuilder.setMatchV10(OF10MatchDeserializer.createMatchV10(input));\r
-        flowStatsBuilder.setDurationSec(input.readUnsignedInt());\r
-        flowStatsBuilder.setDurationNsec(input.readUnsignedInt());\r
-        flowStatsBuilder.setPriority(input.readUnsignedShort());\r
-        flowStatsBuilder.setIdleTimeout(input.readUnsignedShort());\r
-        flowStatsBuilder.setHardTimeout(input.readUnsignedShort());\r
-        input.skipBytes(PADDING_IN_FLOW_STATS_HEADER_02);\r
-        byte[] cookie = new byte[Long.SIZE/Byte.SIZE];\r
-        input.readBytes(cookie);\r
-        flowStatsBuilder.setCookie(new BigInteger(cookie));\r
-        byte[] packetCount = new byte[Long.SIZE/Byte.SIZE];\r
-        input.readBytes(packetCount);\r
-        flowStatsBuilder.setPacketCount(new BigInteger(packetCount));\r
-        byte[] byteCount = new byte[Long.SIZE/Byte.SIZE];\r
-        input.readBytes(byteCount);\r
-        flowStatsBuilder.setByteCount(new BigInteger(byteCount));\r
-        flowStatsBuilder.setActionsList(OF10ActionsDeserializer.createActionsList(input));\r
-        flowStatsList.add(flowStatsBuilder.build());\r
-        flowBuilder.setFlowStats(new ArrayList<>(flowStatsList));\r
-        flowStatsList.clear();\r
-        return flowBuilder.build();\r
-    }\r
-    \r
-    private static MultipartReplyAggregate setAggregate(ByteBuf input) {\r
-        final byte PADDING_IN_AGGREGATE_HEADER = 4;\r
-        MultipartReplyAggregateBuilder builder = new MultipartReplyAggregateBuilder();\r
-        byte[] packetCount = new byte[Long.SIZE/Byte.SIZE];\r
-        input.readBytes(packetCount);\r
-        builder.setPacketCount(new BigInteger(packetCount));\r
-        byte[] byteCount = new byte[Long.SIZE/Byte.SIZE];\r
-        input.readBytes(byteCount);\r
-        builder.setByteCount(new BigInteger(byteCount));\r
-        builder.setFlowCount(input.readUnsignedInt());\r
-        input.skipBytes(PADDING_IN_AGGREGATE_HEADER);\r
-        return builder.build();\r
-    }\r
-    \r
-    private static MultipartReplyTable setTable(ByteBuf input) {\r
-        final byte PADDING_IN_TABLE_HEADER = 3;\r
-        final byte MAX_TABLE_NAME_LENGTH = 32;\r
-        MultipartReplyTableBuilder builder = new MultipartReplyTableBuilder();\r
-        TableStatsBuilder tableStatsBuilder = new TableStatsBuilder();\r
-        List<TableStats> tableStatsList = new ArrayList<>();\r
-        tableStatsBuilder.setTableId(input.readUnsignedByte());\r
-        input.skipBytes(PADDING_IN_TABLE_HEADER);\r
-        tableStatsBuilder.setName(input.readBytes(MAX_TABLE_NAME_LENGTH).toString());\r
-        tableStatsBuilder.setActiveCount(input.readUnsignedInt());\r
-        byte[] lookupCount = new byte[Long.SIZE/Byte.SIZE];\r
-        input.readBytes(lookupCount);\r
-        tableStatsBuilder.setLookupCount(new BigInteger(lookupCount));\r
-        byte[] matchedCount = new byte[Long.SIZE/Byte.SIZE];\r
-        input.readBytes(matchedCount);\r
-        tableStatsBuilder.setMatchedCount(new BigInteger(matchedCount));\r
-        tableStatsList.add(tableStatsBuilder.build());\r
-        builder.setTableStats(new ArrayList<>(tableStatsList));\r
-        tableStatsList.clear();\r
-        return builder.build();\r
-    }\r
-    \r
-    private static MultipartReplyPortStats setPortStats(ByteBuf input) {\r
-        final byte PADDING_IN_PORT_STATS_HEADER = 6;\r
-        MultipartReplyPortStatsBuilder builder = new MultipartReplyPortStatsBuilder();\r
-        PortStatsBuilder portStatsBuilder = new PortStatsBuilder();\r
-        List<PortStats> portStatsList = new ArrayList<>();\r
-        while (input.readableBytes() > 0) {\r
-            portStatsBuilder.setPortNo((long) input.readUnsignedShort());\r
-            input.skipBytes(PADDING_IN_PORT_STATS_HEADER);\r
-            \r
-            byte[] rxPackets = new byte[Long.SIZE/Byte.SIZE];\r
-            input.readBytes(rxPackets);\r
-            portStatsBuilder.setRxPackets(new BigInteger(rxPackets));\r
-            \r
-            byte[] txPackets = new byte[Long.SIZE/Byte.SIZE];\r
-            input.readBytes(txPackets);\r
-            portStatsBuilder.setTxPackets(new BigInteger(txPackets));\r
-            \r
-            byte[] rxBytes = new byte[Long.SIZE/Byte.SIZE];\r
-            input.readBytes(rxBytes);\r
-            portStatsBuilder.setRxBytes(new BigInteger(rxBytes));\r
-            \r
-            byte[] txBytes = new byte[Long.SIZE/Byte.SIZE];\r
-            input.readBytes(txBytes);\r
-            portStatsBuilder.setTxBytes(new BigInteger(txBytes));\r
-            \r
-            byte[] rxDropped = new byte[Long.SIZE/Byte.SIZE];\r
-            input.readBytes(rxDropped);\r
-            portStatsBuilder.setRxDropped(new BigInteger(rxDropped));\r
-            \r
-            byte[] txDropped = new byte[Long.SIZE/Byte.SIZE];\r
-            input.readBytes(txDropped);\r
-            portStatsBuilder.setTxDropped(new BigInteger(txDropped));\r
-            \r
-            byte[] rxErrors = new byte[Long.SIZE/Byte.SIZE];\r
-            input.readBytes(rxErrors);\r
-            portStatsBuilder.setRxErrors(new BigInteger(rxErrors));\r
-            \r
-            byte[] txErrors = new byte[Long.SIZE/Byte.SIZE];\r
-            input.readBytes(txErrors);\r
-            portStatsBuilder.setTxErrors(new BigInteger(txErrors));\r
-            \r
-            byte[] rxFrameErr = new byte[Long.SIZE/Byte.SIZE];\r
-            input.readBytes(rxFrameErr);\r
-            portStatsBuilder.setRxFrameErr(new BigInteger(rxFrameErr));\r
-            \r
-            byte[] rxOverErr = new byte[Long.SIZE/Byte.SIZE];\r
-            input.readBytes(rxOverErr);\r
-            portStatsBuilder.setRxOverErr(new BigInteger(rxOverErr));\r
-            \r
-            byte[] rxCrcErr = new byte[Long.SIZE/Byte.SIZE];\r
-            input.readBytes(rxCrcErr);\r
-            portStatsBuilder.setRxCrcErr(new BigInteger(rxCrcErr));\r
-            \r
-            byte[] collisions = new byte[Long.SIZE/Byte.SIZE];\r
-            input.readBytes(collisions);\r
-            portStatsBuilder.setCollisions(new BigInteger(collisions));\r
-            \r
-        }\r
-        builder.setPortStats(new ArrayList<>(portStatsList));\r
-        portStatsList.clear();\r
-        return builder.build();\r
-    }\r
-    \r
-    private static MultipartReplyQueue setQueue(ByteBuf input) {\r
-        final byte PADDING_IN_QUEUE_HEADER = 2;\r
-        MultipartReplyQueueBuilder builder = new MultipartReplyQueueBuilder();\r
-        QueueStatsBuilder queueStatsBuilder = new QueueStatsBuilder();\r
-        List<QueueStats> queueStatsList = new ArrayList<>();\r
-        \r
-        while (input.readableBytes() > 0) {\r
-            queueStatsBuilder.setPortNo((long) input.readUnsignedShort());\r
-            input.skipBytes(PADDING_IN_QUEUE_HEADER);\r
-            queueStatsBuilder.setQueueId(input.readUnsignedInt());\r
-\r
-            byte[] txBytes = new byte[Long.SIZE/Byte.SIZE];\r
-            input.readBytes(txBytes);\r
-            queueStatsBuilder.setTxBytes(new BigInteger(txBytes));\r
-\r
-            byte[] txPackets = new byte[Long.SIZE/Byte.SIZE];\r
-            input.readBytes(txPackets);\r
-            queueStatsBuilder.setTxPackets(new BigInteger(txPackets));\r
-\r
-            byte[] txErrors = new byte[Long.SIZE/Byte.SIZE];\r
-            input.readBytes(txErrors);\r
-            queueStatsBuilder.setTxErrors(new BigInteger(txErrors));\r
-\r
-            queueStatsList.add(queueStatsBuilder.build());\r
-        }\r
-        builder.setQueueStats(new ArrayList<>(queueStatsList));\r
-        queueStatsList.clear();\r
-        return builder.build();\r
-    }\r
-    \r
-    private static MultipartReplyExperimenter setExperimenter(ByteBuf input) {\r
-        MultipartReplyExperimenterBuilder builder = new MultipartReplyExperimenterBuilder();\r
-        builder.setExperimenter(input.readUnsignedInt());\r
-        byte[] data = new byte[Long.SIZE/Byte.SIZE];\r
-        input.readBytes(data);\r
-        builder.setData(data);\r
-        return builder.build();\r
-    }\r
-}\r
+/*
+ * Copyright (c) 2013 Pantheon Technologies s.r.o. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.openflowjava.protocol.impl.deserialization.factories;
+
+import io.netty.buffer.ByteBuf;
+
+import java.math.BigInteger;
+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.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;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyAggregateCaseBuilder;
+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.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;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyPortStatsCaseBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyQueueCase;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyQueueCaseBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyTableCase;
+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.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;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.port.stats._case.MultipartReplyPortStatsBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.port.stats._case.multipart.reply.port.stats.PortStats;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.port.stats._case.multipart.reply.port.stats.PortStatsBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.queue._case.MultipartReplyQueueBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.queue._case.multipart.reply.queue.QueueStats;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.queue._case.multipart.reply.queue.QueueStatsBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.table._case.MultipartReplyTableBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.table._case.multipart.reply.table.TableStats;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.table._case.multipart.reply.table.TableStatsBuilder;
+
+/**
+ * Translates StatsReply messages (OpenFlow v1.0)
+ * @author michal.polkorab
+ */
+public class OF10StatsReplyMessageFactory implements OFDeserializer<MultipartReplyMessage>,
+        DeserializerRegistryInjector {
+
+    private static final int DESC_STR_LEN = 256;
+    private static final int SERIAL_NUM_LEN = 32;
+    private static final byte PADDING_IN_FLOW_STATS_HEADER = 1;
+    private static final byte PADDING_IN_FLOW_STATS_HEADER_02 = 6;
+    private static final byte PADDING_IN_AGGREGATE_HEADER = 4;
+    private static final byte PADDING_IN_TABLE_HEADER = 3;
+    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 final byte LENGTH_OF_FLOW_STATS = 88;
+    private static final int TABLE_STATS_LENGTH = 64;
+    private DeserializerRegistry registry;
+
+    @Override
+    public MultipartReplyMessage deserialize(ByteBuf rawMessage) {
+        MultipartReplyMessageBuilder builder = new MultipartReplyMessageBuilder();
+        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 (MultipartType.forValue(type)) {
+        case OFPMPDESC:  builder.setMultipartReplyBody(setDesc(rawMessage));
+            break;
+        case OFPMPFLOW:  builder.setMultipartReplyBody(setFlow(rawMessage));
+            break;
+        case OFPMPAGGREGATE:  builder.setMultipartReplyBody(setAggregate(rawMessage));
+            break;
+        case OFPMPTABLE:  builder.setMultipartReplyBody(setTable(rawMessage));
+            break;
+        case OFPMPPORTSTATS:  builder.setMultipartReplyBody(setPortStats(rawMessage));
+            break;
+        case OFPMPQUEUE:  builder.setMultipartReplyBody(setQueue(rawMessage));
+            break;
+        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();
+        byte[] mfrDescBytes = new byte[DESC_STR_LEN];
+        input.readBytes(mfrDescBytes);
+        String mfrDesc = new String(mfrDescBytes);
+        descBuilder.setMfrDesc(mfrDesc.trim());
+        byte[] hwDescBytes = new byte[DESC_STR_LEN];
+        input.readBytes(hwDescBytes);
+        String hwDesc = new String(hwDescBytes);
+        descBuilder.setHwDesc(hwDesc.trim());
+        byte[] swDescBytes = new byte[DESC_STR_LEN];
+        input.readBytes(swDescBytes);
+        String swDesc = new String(swDescBytes);
+        descBuilder.setSwDesc(swDesc.trim());
+        byte[] serialNumBytes = new byte[SERIAL_NUM_LEN];
+        input.readBytes(serialNumBytes);
+        String serialNum = new String(serialNumBytes);
+        descBuilder.setSerialNum(serialNum.trim());
+        byte[] dpDescBytes = new byte[DESC_STR_LEN];
+        input.readBytes(dpDescBytes);
+        String dpDesc = new String(dpDescBytes);
+        descBuilder.setDpDesc(dpDesc.trim());
+        caseBuilder.setMultipartReplyDesc(descBuilder.build());
+        return caseBuilder.build();
+    }
+
+    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();
+            int length = input.readUnsignedShort();
+            flowStatsBuilder.setTableId(input.readUnsignedByte());
+            input.skipBytes(PADDING_IN_FLOW_STATS_HEADER);
+            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[EncodeConstants.SIZE_OF_LONG_IN_BYTES];
+            input.readBytes(cookie);
+            flowStatsBuilder.setCookie(new BigInteger(1, cookie));
+            byte[] packetCount = new byte[EncodeConstants.SIZE_OF_LONG_IN_BYTES];
+            input.readBytes(packetCount);
+            flowStatsBuilder.setPacketCount(new BigInteger(1, packetCount));
+            byte[] byteCount = new byte[EncodeConstants.SIZE_OF_LONG_IN_BYTES];
+            input.readBytes(byteCount);
+            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[EncodeConstants.SIZE_OF_LONG_IN_BYTES];
+        input.readBytes(packetCount);
+        builder.setPacketCount(new BigInteger(1, packetCount));
+        byte[] byteCount = new byte[EncodeConstants.SIZE_OF_LONG_IN_BYTES];
+        input.readBytes(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<>();
+        // 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(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[EncodeConstants.SIZE_OF_LONG_IN_BYTES];
+            input.readBytes(lookupCount);
+            tableStatsBuilder.setLookupCount(new BigInteger(1, lookupCount));
+            byte[] matchedCount = new byte[EncodeConstants.SIZE_OF_LONG_IN_BYTES];
+            input.readBytes(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();
+        List<PortStats> portStatsList = new ArrayList<>();
+        while (input.readableBytes() > 0) {
+            PortStatsBuilder portStatsBuilder = new PortStatsBuilder();
+            portStatsBuilder.setPortNo((long) input.readUnsignedShort());
+            input.skipBytes(PADDING_IN_PORT_STATS_HEADER);
+            byte[] rxPackets = new byte[EncodeConstants.SIZE_OF_LONG_IN_BYTES];
+            input.readBytes(rxPackets);
+            portStatsBuilder.setRxPackets(new BigInteger(1, rxPackets));
+            byte[] txPackets = new byte[EncodeConstants.SIZE_OF_LONG_IN_BYTES];
+            input.readBytes(txPackets);
+            portStatsBuilder.setTxPackets(new BigInteger(1, txPackets));
+            byte[] rxBytes = new byte[EncodeConstants.SIZE_OF_LONG_IN_BYTES];
+            input.readBytes(rxBytes);
+            portStatsBuilder.setRxBytes(new BigInteger(1, rxBytes));
+            byte[] txBytes = new byte[EncodeConstants.SIZE_OF_LONG_IN_BYTES];
+            input.readBytes(txBytes);
+            portStatsBuilder.setTxBytes(new BigInteger(1, txBytes));
+            byte[] rxDropped = new byte[EncodeConstants.SIZE_OF_LONG_IN_BYTES];
+            input.readBytes(rxDropped);
+            portStatsBuilder.setRxDropped(new BigInteger(1, rxDropped));
+            byte[] txDropped = new byte[EncodeConstants.SIZE_OF_LONG_IN_BYTES];
+            input.readBytes(txDropped);
+            portStatsBuilder.setTxDropped(new BigInteger(1, txDropped));
+            byte[] rxErrors = new byte[EncodeConstants.SIZE_OF_LONG_IN_BYTES];
+            input.readBytes(rxErrors);
+            portStatsBuilder.setRxErrors(new BigInteger(1, rxErrors));
+            byte[] txErrors = new byte[EncodeConstants.SIZE_OF_LONG_IN_BYTES];
+            input.readBytes(txErrors);
+            portStatsBuilder.setTxErrors(new BigInteger(1, txErrors));
+            byte[] rxFrameErr = new byte[EncodeConstants.SIZE_OF_LONG_IN_BYTES];
+            input.readBytes(rxFrameErr);
+            portStatsBuilder.setRxFrameErr(new BigInteger(1, rxFrameErr));
+            byte[] rxOverErr = new byte[EncodeConstants.SIZE_OF_LONG_IN_BYTES];
+            input.readBytes(rxOverErr);
+            portStatsBuilder.setRxOverErr(new BigInteger(1, rxOverErr));
+            byte[] rxCrcErr = new byte[EncodeConstants.SIZE_OF_LONG_IN_BYTES];
+            input.readBytes(rxCrcErr);
+            portStatsBuilder.setRxCrcErr(new BigInteger(1, rxCrcErr));
+            byte[] collisions = new byte[EncodeConstants.SIZE_OF_LONG_IN_BYTES];
+            input.readBytes(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();
+        List<QueueStats> queueStatsList = new ArrayList<>();
+        while (input.readableBytes() > 0) {
+            QueueStatsBuilder queueStatsBuilder = new QueueStatsBuilder();
+            queueStatsBuilder.setPortNo((long) input.readUnsignedShort());
+            input.skipBytes(PADDING_IN_QUEUE_HEADER);
+            queueStatsBuilder.setQueueId(input.readUnsignedInt());
+            byte[] txBytes = new byte[EncodeConstants.SIZE_OF_LONG_IN_BYTES];
+            input.readBytes(txBytes);
+            queueStatsBuilder.setTxBytes(new BigInteger(1, txBytes));
+            byte[] txPackets = new byte[EncodeConstants.SIZE_OF_LONG_IN_BYTES];
+            input.readBytes(txPackets);
+            queueStatsBuilder.setTxPackets(new BigInteger(1, txPackets));
+            byte[] txErrors = new byte[EncodeConstants.SIZE_OF_LONG_IN_BYTES];
+            input.readBytes(txErrors);
+            queueStatsBuilder.setTxErrors(new BigInteger(1, txErrors));
+            queueStatsList.add(queueStatsBuilder.build());
+        }
+        builder.setQueueStats(queueStatsList);
+        caseBuilder.setMultipartReplyQueue(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;
+    }
+}