BUG-4118: Li:backward compatibility - rpcs - transformers 67/26667/4
authorMichal Rehak <mirehak@cisco.com>
Tue, 8 Sep 2015 19:15:44 +0000 (21:15 +0200)
committerMichal Rehak <mirehak@cisco.com>
Fri, 27 Nov 2015 13:41:02 +0000 (14:41 +0100)
 - added general stats to notificatin transformers
 - added abstract service providing transaction aware result
   and async notification

Change-Id: If902096e1bd1041aa9ae1d5e23cd45fcc5eef5ea
Signed-off-by: Michal Rehak <mirehak@cisco.com>
openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/statistics/services/compatibility/AbstractCompatibleStatService.java [new file with mode: 0644]
openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/statistics/services/compatibility/FlowStatisticsToNotificationTransformer.java [new file with mode: 0644]
openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/statistics/services/compatibility/GroupStatisticsToNotificationTransformer.java [new file with mode: 0644]
openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/statistics/services/compatibility/MeterStatisticsToNotificationTransformer.java [new file with mode: 0644]
openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/statistics/services/compatibility/NodeConnectorStatisticsToNotificationTransformer.java [new file with mode: 0644]
openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/statistics/services/compatibility/QueueStatisticsToNotificationTransformer.java [new file with mode: 0644]

diff --git a/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/statistics/services/compatibility/AbstractCompatibleStatService.java b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/statistics/services/compatibility/AbstractCompatibleStatService.java
new file mode 100644 (file)
index 0000000..47eb568
--- /dev/null
@@ -0,0 +1,86 @@
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.openflowplugin.impl.statistics.services.compatibility;
+
+import com.google.common.util.concurrent.FutureCallback;
+import com.google.common.util.concurrent.Futures;
+import com.google.common.util.concurrent.ListenableFuture;
+import java.math.BigInteger;
+import java.util.List;
+import java.util.concurrent.atomic.AtomicLong;
+import javax.annotation.Nullable;
+import org.opendaylight.controller.md.sal.binding.api.NotificationPublishService;
+import org.opendaylight.openflowplugin.api.openflow.device.DeviceContext;
+import org.opendaylight.openflowplugin.api.openflow.device.RequestContextStack;
+import org.opendaylight.openflowplugin.api.openflow.md.util.OpenflowVersion;
+import org.opendaylight.openflowplugin.api.openflow.statistics.compatibility.BackwardCompatibleAtomicService;
+import org.opendaylight.openflowplugin.impl.services.AbstractMultipartService;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.transaction.rev150304.TransactionId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.MultipartReply;
+import org.opendaylight.yangtools.yang.binding.Notification;
+import org.opendaylight.yangtools.yang.common.RpcResult;
+import org.opendaylight.yangtools.yang.common.RpcResultBuilder;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * pulled up common functionality of notification emitting stats services (backward compatibility relic)
+ */
+public abstract class AbstractCompatibleStatService<I, O, N extends Notification> extends AbstractMultipartService<I> implements BackwardCompatibleAtomicService<I, O> {
+
+    private static final Logger LOG = LoggerFactory.getLogger(AbstractCompatibleStatService.class);
+
+    private final AtomicLong compatibilityXidSeed;
+    private final OpenflowVersion ofVersion;
+
+    public AbstractCompatibleStatService(RequestContextStack requestContextStack, DeviceContext deviceContext, AtomicLong compatibilityXidSeed) {
+        super(requestContextStack, deviceContext);
+        this.compatibilityXidSeed = compatibilityXidSeed;
+        ofVersion = OpenflowVersion.get(getDeviceContext().getDeviceState().getVersion());
+    }
+
+    public OpenflowVersion getOfVersion() {
+        return ofVersion;
+    }
+
+    @Override
+    public ListenableFuture<RpcResult<O>> handleAndNotify(final I input, final NotificationPublishService notificationPublishService) {
+        // prepare emulated xid
+        final long emulatedXid = compatibilityXidSeed.incrementAndGet();
+        final TransactionId emulatedTxId = new TransactionId(BigInteger.valueOf(emulatedXid));
+
+        // do real processing
+        final ListenableFuture<RpcResult<List<MultipartReply>>> rpcResultListenableFuture = handleServiceCall(input);
+
+        // hook notification publishing
+        Futures.addCallback(rpcResultListenableFuture, new FutureCallback<RpcResult<List<MultipartReply>>>() {
+            @Override
+            public void onSuccess(@Nullable RpcResult<List<MultipartReply>> result) {
+                if (result != null && result.isSuccessful()) {
+                    // transform rpc result (raw multipart) to notification
+                    final N flowNotification = transformToNotification(result.getResult(), emulatedTxId);
+                    notificationPublishService.offerNotification(flowNotification);
+                } else {
+                    LOG.debug("compatibility callback failed - NOT emitting notification: {}", input.getClass().getSimpleName());
+                }
+            }
+
+            @Override
+            public void onFailure(Throwable t) {
+                LOG.debug("compatibility callback crashed - NOT emitting notification: {}", input.getClass().getSimpleName(), t);
+            }
+        });
+
+        return RpcResultBuilder.<O>success(buildTxCapableResult(emulatedTxId)).buildFuture();
+    }
+
+    public abstract O buildTxCapableResult(TransactionId emulatedTxId);
+
+    public abstract N transformToNotification(List<MultipartReply> result, TransactionId emulatedTxId);
+}
diff --git a/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/statistics/services/compatibility/FlowStatisticsToNotificationTransformer.java b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/statistics/services/compatibility/FlowStatisticsToNotificationTransformer.java
new file mode 100644 (file)
index 0000000..7f28f25
--- /dev/null
@@ -0,0 +1,64 @@
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.openflowplugin.impl.statistics.services.compatibility;
+
+import com.google.common.base.Preconditions;
+import java.util.ArrayList;
+import java.util.List;
+import org.opendaylight.openflowplugin.api.openflow.device.DeviceContext;
+import org.opendaylight.openflowplugin.api.openflow.md.util.OpenflowVersion;
+import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.FlowStatsResponseConvertor;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.FlowsStatisticsUpdate;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.FlowsStatisticsUpdateBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.flow.and.statistics.map.list.FlowAndStatisticsMapList;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.transaction.rev150304.TransactionId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.MultipartType;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.MultipartReply;
+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.multipart.reply.flow._case.MultipartReplyFlow;
+
+/**
+ * pulled out flow stats to notification transformation
+ */
+public class FlowStatisticsToNotificationTransformer {
+
+    private static FlowStatsResponseConvertor flowStatsConvertor = new FlowStatsResponseConvertor();
+
+    /**
+     * @param mpResult      raw multipart response from device
+     * @param deviceContext device context
+     * @param ofVersion device version
+     * @param emulatedTxId
+     * @return notification containing flow stats
+     */
+    public static FlowsStatisticsUpdate transformToNotification(final List<MultipartReply> mpResult,
+                                                                final DeviceContext deviceContext,
+                                                                final OpenflowVersion ofVersion,
+                                                                final TransactionId emulatedTxId) {
+        final FlowsStatisticsUpdateBuilder notification = new FlowsStatisticsUpdateBuilder();
+        final List<FlowAndStatisticsMapList> statsList = new ArrayList<>();
+        notification.setFlowAndStatisticsMapList(statsList);
+        notification.setMoreReplies(Boolean.FALSE);
+        notification.setTransactionId(emulatedTxId);
+
+        for (MultipartReply mpRawReply : mpResult) {
+            Preconditions.checkArgument(MultipartType.OFPMPFLOW.equals(mpRawReply.getType()));
+
+            MultipartReplyFlowCase caseBody = (MultipartReplyFlowCase) mpRawReply.getMultipartReplyBody();
+            MultipartReplyFlow replyBody = caseBody.getMultipartReplyFlow();
+            List<FlowAndStatisticsMapList> outStatsItem = flowStatsConvertor.toSALFlowStatsList(
+                    replyBody.getFlowStats(),
+                    deviceContext.getDeviceState().getFeatures().getDatapathId(),
+                    ofVersion);
+            statsList.addAll(outStatsItem);
+        }
+
+        return notification.build();
+    }
+}
diff --git a/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/statistics/services/compatibility/GroupStatisticsToNotificationTransformer.java b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/statistics/services/compatibility/GroupStatisticsToNotificationTransformer.java
new file mode 100644 (file)
index 0000000..0a4b7ec
--- /dev/null
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.openflowplugin.impl.statistics.services.compatibility;
+
+import java.util.ArrayList;
+import java.util.List;
+import org.opendaylight.openflowplugin.api.openflow.device.DeviceContext;
+import org.opendaylight.openflowplugin.api.openflow.md.util.OpenflowVersion;
+import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.GroupStatsResponseConvertor;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.transaction.rev150304.TransactionId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.GroupStatisticsUpdated;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.GroupStatisticsUpdatedBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.group.statistics.reply.GroupStats;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.MultipartReply;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyGroupCase;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.group._case.MultipartReplyGroup;
+
+/**
+ * pulled out group stats to notification transformation
+ */
+public class GroupStatisticsToNotificationTransformer {
+
+    private static GroupStatsResponseConvertor groupStatsConvertor = new GroupStatsResponseConvertor();
+
+    /**
+     * @param mpReplyList   raw multipart response from device
+     * @param deviceContext device context
+     * @param ofVersion     device version
+     * @param emulatedTxId
+     * @return notification containing flow stats
+     */
+    public static GroupStatisticsUpdated transformToNotification(final List<MultipartReply> mpReplyList,
+                                                                 final DeviceContext deviceContext,
+                                                                 final OpenflowVersion ofVersion,
+                                                                 final TransactionId emulatedTxId) {
+
+        GroupStatisticsUpdatedBuilder notification = new GroupStatisticsUpdatedBuilder();
+        notification.setId(deviceContext.getDeviceState().getNodeId());
+        notification.setMoreReplies(Boolean.FALSE);
+        notification.setTransactionId(emulatedTxId);
+
+        notification.setGroupStats(new ArrayList<GroupStats>());
+
+        for (MultipartReply mpReply : mpReplyList) {
+            MultipartReplyGroupCase caseBody = (MultipartReplyGroupCase) mpReply.getMultipartReplyBody();
+            MultipartReplyGroup replyBody = caseBody.getMultipartReplyGroup();
+            notification.getGroupStats().addAll(groupStatsConvertor.toSALGroupStatsList(replyBody.getGroupStats()));
+        }
+        return notification.build();
+    }
+}
diff --git a/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/statistics/services/compatibility/MeterStatisticsToNotificationTransformer.java b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/statistics/services/compatibility/MeterStatisticsToNotificationTransformer.java
new file mode 100644 (file)
index 0000000..e642506
--- /dev/null
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.openflowplugin.impl.statistics.services.compatibility;
+
+import java.util.ArrayList;
+import java.util.List;
+import org.opendaylight.openflowplugin.api.openflow.device.DeviceContext;
+import org.opendaylight.openflowplugin.api.openflow.md.util.OpenflowVersion;
+import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.MeterStatsResponseConvertor;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.transaction.rev150304.TransactionId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.MeterStatisticsUpdated;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.MeterStatisticsUpdatedBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.types.rev130918.meter.statistics.reply.MeterStats;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.MultipartReply;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyMeterCase;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.meter._case.MultipartReplyMeter;
+
+/**
+ * pulled out meter stats to notification transformation
+ */
+public class MeterStatisticsToNotificationTransformer {
+
+    private static MeterStatsResponseConvertor meterStatsConvertor = new MeterStatsResponseConvertor();
+
+    /**
+     * @param mpReplyList   raw multipart response from device
+     * @param deviceContext device context
+     * @param ofVersion     device version
+     * @param emulatedTxId
+     * @return notification containing flow stats
+     */
+    public static MeterStatisticsUpdated transformToNotification(final List<MultipartReply> mpReplyList,
+                                                                 final DeviceContext deviceContext,
+                                                                 final OpenflowVersion ofVersion,
+                                                                 final TransactionId emulatedTxId) {
+
+        MeterStatisticsUpdatedBuilder notification = new MeterStatisticsUpdatedBuilder();
+        notification.setId(deviceContext.getDeviceState().getNodeId());
+        notification.setMoreReplies(Boolean.FALSE);
+        notification.setTransactionId(emulatedTxId);
+
+        notification.setMeterStats(new ArrayList<MeterStats>());
+        for (MultipartReply mpReply : mpReplyList) {
+            MultipartReplyMeterCase caseBody = (MultipartReplyMeterCase) mpReply.getMultipartReplyBody();
+            MultipartReplyMeter replyBody = caseBody.getMultipartReplyMeter();
+            notification.getMeterStats().addAll(meterStatsConvertor.toSALMeterStatsList(replyBody.getMeterStats()));
+        }
+
+        return notification.build();
+    }
+}
diff --git a/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/statistics/services/compatibility/NodeConnectorStatisticsToNotificationTransformer.java b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/statistics/services/compatibility/NodeConnectorStatisticsToNotificationTransformer.java
new file mode 100644 (file)
index 0000000..3649a25
--- /dev/null
@@ -0,0 +1,106 @@
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.openflowplugin.impl.statistics.services.compatibility;
+
+import com.google.common.annotations.VisibleForTesting;
+import java.util.ArrayList;
+import java.util.List;
+import org.opendaylight.openflowplugin.api.openflow.device.DeviceContext;
+import org.opendaylight.openflowplugin.api.openflow.md.util.OpenflowVersion;
+import org.opendaylight.openflowplugin.openflow.md.util.InventoryDataServiceUtil;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev100924.Counter32;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.transaction.rev150304.TransactionId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.model.statistics.types.rev130925.duration.DurationBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.model.statistics.types.rev130925.node.connector.statistics.BytesBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.model.statistics.types.rev130925.node.connector.statistics.PacketsBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.MultipartReply;
+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.multipart.reply.port.stats._case.MultipartReplyPortStats;
+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.port.statistics.rev131214.NodeConnectorStatisticsUpdate;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.port.statistics.rev131214.NodeConnectorStatisticsUpdateBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.port.statistics.rev131214.node.connector.statistics.and.port.number.map.NodeConnectorStatisticsAndPortNumberMap;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.port.statistics.rev131214.node.connector.statistics.and.port.number.map.NodeConnectorStatisticsAndPortNumberMapBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.port.statistics.rev131214.node.connector.statistics.and.port.number.map.NodeConnectorStatisticsAndPortNumberMapKey;
+
+/**
+ * pulled out port stats to notification transformation
+ */
+public class NodeConnectorStatisticsToNotificationTransformer {
+
+    /**
+     * @param mpReplyList   raw multipart response from device
+     * @param deviceContext device context
+     * @param ofVersion     device version
+     * @param emulatedTxId
+     * @return notification containing flow stats
+     */
+    public static NodeConnectorStatisticsUpdate transformToNotification(final List<MultipartReply> mpReplyList,
+                                                                        final DeviceContext deviceContext,
+                                                                        final OpenflowVersion ofVersion,
+                                                                        final TransactionId emulatedTxId) {
+
+        NodeConnectorStatisticsUpdateBuilder notification = new NodeConnectorStatisticsUpdateBuilder();
+        notification.setId(deviceContext.getDeviceState().getNodeId());
+        notification.setMoreReplies(Boolean.FALSE);
+        notification.setTransactionId(emulatedTxId);
+
+        notification.setNodeConnectorStatisticsAndPortNumberMap(new ArrayList<NodeConnectorStatisticsAndPortNumberMap>());
+        for (MultipartReply mpReply : mpReplyList) {
+            MultipartReplyPortStatsCase caseBody = (MultipartReplyPortStatsCase) mpReply.getMultipartReplyBody();
+
+            MultipartReplyPortStats replyBody = caseBody.getMultipartReplyPortStats();
+            for (PortStats portStats : replyBody.getPortStats()) {
+                NodeConnectorStatisticsAndPortNumberMapBuilder statsBuilder =
+                        processSingleNodeConnectorStats(deviceContext, ofVersion, portStats);
+                notification.getNodeConnectorStatisticsAndPortNumberMap().add(statsBuilder.build());
+            }
+        }
+        return notification.build();
+    }
+
+    @VisibleForTesting
+    static NodeConnectorStatisticsAndPortNumberMapBuilder processSingleNodeConnectorStats(DeviceContext deviceContext, OpenflowVersion ofVersion, PortStats portStats) {
+        NodeConnectorStatisticsAndPortNumberMapBuilder statsBuilder =
+                new NodeConnectorStatisticsAndPortNumberMapBuilder();
+        statsBuilder.setNodeConnectorId(
+                InventoryDataServiceUtil.nodeConnectorIdfromDatapathPortNo(
+                        deviceContext.getDeviceState().getFeatures().getDatapathId(),
+                        portStats.getPortNo(), ofVersion));
+
+        BytesBuilder bytesBuilder = new BytesBuilder();
+        bytesBuilder.setReceived(portStats.getRxBytes());
+        bytesBuilder.setTransmitted(portStats.getTxBytes());
+        statsBuilder.setBytes(bytesBuilder.build());
+
+        PacketsBuilder packetsBuilder = new PacketsBuilder();
+        packetsBuilder.setReceived(portStats.getRxPackets());
+        packetsBuilder.setTransmitted(portStats.getTxPackets());
+        statsBuilder.setPackets(packetsBuilder.build());
+
+        DurationBuilder durationBuilder = new DurationBuilder();
+        if (portStats.getDurationSec() != null) {
+            durationBuilder.setSecond(new Counter32(portStats.getDurationSec()));
+        }
+        if (portStats.getDurationNsec() != null) {
+            durationBuilder.setNanosecond(new Counter32(portStats.getDurationNsec()));
+        }
+        statsBuilder.setDuration(durationBuilder.build());
+        statsBuilder.setCollisionCount(portStats.getCollisions());
+        statsBuilder.setKey(new NodeConnectorStatisticsAndPortNumberMapKey(statsBuilder.getNodeConnectorId()));
+        statsBuilder.setReceiveCrcError(portStats.getRxCrcErr());
+        statsBuilder.setReceiveDrops(portStats.getRxDropped());
+        statsBuilder.setReceiveErrors(portStats.getRxErrors());
+        statsBuilder.setReceiveFrameError(portStats.getRxFrameErr());
+        statsBuilder.setReceiveOverRunError(portStats.getRxOverErr());
+        statsBuilder.setTransmitDrops(portStats.getTxDropped());
+        statsBuilder.setTransmitErrors(portStats.getTxErrors());
+        return statsBuilder;
+    }
+}
diff --git a/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/statistics/services/compatibility/QueueStatisticsToNotificationTransformer.java b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/statistics/services/compatibility/QueueStatisticsToNotificationTransformer.java
new file mode 100644 (file)
index 0000000..5ac509a
--- /dev/null
@@ -0,0 +1,84 @@
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.openflowplugin.impl.statistics.services.compatibility;
+
+import java.util.ArrayList;
+import java.util.List;
+import org.opendaylight.openflowplugin.api.openflow.device.DeviceContext;
+import org.opendaylight.openflowplugin.api.openflow.md.util.OpenflowVersion;
+import org.opendaylight.openflowplugin.openflow.md.util.InventoryDataServiceUtil;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev100924.Counter32;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev100924.Counter64;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.transaction.rev150304.TransactionId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.queue.rev130925.QueueId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.model.statistics.types.rev130925.duration.DurationBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.MultipartReply;
+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.multipart.reply.queue._case.MultipartReplyQueue;
+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.queue.statistics.rev131216.QueueStatisticsUpdate;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.queue.statistics.rev131216.QueueStatisticsUpdateBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.queue.statistics.rev131216.queue.id.and.statistics.map.QueueIdAndStatisticsMap;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.queue.statistics.rev131216.queue.id.and.statistics.map.QueueIdAndStatisticsMapBuilder;
+
+/**
+ * pulled out queue stats to notification transformation
+ */
+public class QueueStatisticsToNotificationTransformer {
+
+    /**
+     * @param mpReplyList   raw multipart response from device
+     * @param deviceContext device context
+     * @param ofVersion     device version
+     * @param emulatedTxId
+     * @return notification containing flow stats
+     */
+    public static QueueStatisticsUpdate transformToNotification(final List<MultipartReply> mpReplyList,
+                                                                final DeviceContext deviceContext,
+                                                                final OpenflowVersion ofVersion,
+                                                                final TransactionId emulatedTxId) {
+
+        QueueStatisticsUpdateBuilder notification = new QueueStatisticsUpdateBuilder();
+        notification.setId(deviceContext.getDeviceState().getNodeId());
+        notification.setMoreReplies(Boolean.FALSE);
+        notification.setTransactionId(emulatedTxId);
+
+        notification.setQueueIdAndStatisticsMap(new ArrayList<QueueIdAndStatisticsMap>());
+        for (MultipartReply mpReply : mpReplyList) {
+
+            MultipartReplyQueueCase caseBody = (MultipartReplyQueueCase) mpReply.getMultipartReplyBody();
+            MultipartReplyQueue replyBody = caseBody.getMultipartReplyQueue();
+
+            for (QueueStats queueStats : replyBody.getQueueStats()) {
+
+                QueueIdAndStatisticsMapBuilder statsBuilder =
+                        new QueueIdAndStatisticsMapBuilder();
+                statsBuilder.setNodeConnectorId(
+                        InventoryDataServiceUtil.nodeConnectorIdfromDatapathPortNo(
+                                deviceContext.getDeviceState().getFeatures().getDatapathId(),
+                                queueStats.getPortNo(), ofVersion));
+                statsBuilder.setTransmissionErrors(new Counter64(queueStats.getTxErrors()));
+                statsBuilder.setTransmittedBytes(new Counter64(queueStats.getTxBytes()));
+                statsBuilder.setTransmittedPackets(new Counter64(queueStats.getTxPackets()));
+
+                DurationBuilder durationBuilder = new DurationBuilder();
+                durationBuilder.setSecond(new Counter32(queueStats.getDurationSec()));
+                durationBuilder.setNanosecond(new Counter32(queueStats.getDurationNsec()));
+                statsBuilder.setDuration(durationBuilder.build());
+
+                statsBuilder.setQueueId(new QueueId(queueStats.getQueueId()));
+
+                notification.getQueueIdAndStatisticsMap().add(statsBuilder.build());
+            }
+        }
+        return notification.build();
+    }
+
+
+}