2 * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
4 * This program and the accompanying materials are made available under the
5 * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6 * and is available at http://www.eclipse.org/legal/epl-v10.html
8 package org.opendaylight.controller.sal.compatibility.adsal;
10 import java.math.BigInteger;
11 import java.util.ArrayList;
12 import java.util.List;
13 import java.util.concurrent.Future;
15 import org.opendaylight.controller.sal.binding.api.NotificationProviderService;
16 import org.opendaylight.controller.sal.common.util.Rpcs;
17 import org.opendaylight.controller.sal.compatibility.FromSalConversionsUtils;
18 import org.opendaylight.controller.sal.compatibility.InventoryMapping;
19 import org.opendaylight.controller.sal.compatibility.NodeMapping;
20 import org.opendaylight.controller.sal.compatibility.ToSalConversionsUtils;
21 import org.opendaylight.controller.sal.core.ConstructionException;
22 import org.opendaylight.controller.sal.core.Node;
23 import org.opendaylight.controller.sal.flowprogrammer.Flow;
24 import org.opendaylight.controller.sal.reader.FlowOnNode;
25 import org.opendaylight.controller.sal.reader.IReadService;
26 import org.opendaylight.controller.sal.reader.IReadServiceListener;
27 import org.opendaylight.controller.sal.reader.NodeConnectorStatistics;
28 import org.opendaylight.controller.sal.reader.NodeDescription;
29 import org.opendaylight.controller.sal.reader.NodeTableStatistics;
30 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev100924.Counter32;
31 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev100924.Counter64;
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.FlowsStatisticsUpdateBuilder;
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.GetAggregateFlowStatisticsFromFlowTableForAllFlowsInput;
34 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.GetAggregateFlowStatisticsFromFlowTableForAllFlowsOutput;
35 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.GetAggregateFlowStatisticsFromFlowTableForGivenMatchInput;
36 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.GetAggregateFlowStatisticsFromFlowTableForGivenMatchOutput;
37 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.GetAllFlowStatisticsFromFlowTableInput;
38 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.GetAllFlowStatisticsFromFlowTableOutput;
39 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.GetAllFlowStatisticsFromFlowTableOutputBuilder;
40 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.GetAllFlowsStatisticsFromAllFlowTablesInput;
41 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.GetAllFlowsStatisticsFromAllFlowTablesOutput;
42 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.GetAllFlowsStatisticsFromAllFlowTablesOutputBuilder;
43 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.GetFlowStatisticsFromFlowTableInput;
44 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.GetFlowStatisticsFromFlowTableOutput;
45 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.GetFlowStatisticsFromFlowTableOutputBuilder;
46 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.OpendaylightFlowStatisticsService;
47 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.flow.and.statistics.map.list.FlowAndStatisticsMapList;
48 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.flow.and.statistics.map.list.FlowAndStatisticsMapListBuilder;
49 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.table.statistics.rev131215.FlowTableStatisticsUpdateBuilder;
50 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.table.statistics.rev131215.flow.table.and.statistics.map.FlowTableAndStatisticsMap;
51 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.table.statistics.rev131215.flow.table.and.statistics.map.FlowTableAndStatisticsMapBuilder;
52 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.transaction.rev131103.TransactionId;
53 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.statistics.types.rev130925.duration.DurationBuilder;
54 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.statistics.types.rev130925.node.connector.statistics.Bytes;
55 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.statistics.types.rev130925.node.connector.statistics.BytesBuilder;
56 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.statistics.types.rev130925.node.connector.statistics.Packets;
57 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.statistics.types.rev130925.node.connector.statistics.PacketsBuilder;
58 import org.opendaylight.yang.gen.v1.urn.opendaylight.port.statistics.rev131214.NodeConnectorStatisticsUpdateBuilder;
59 import org.opendaylight.yang.gen.v1.urn.opendaylight.port.statistics.rev131214.node.connector.statistics.and.port.number.map.NodeConnectorStatisticsAndPortNumberMap;
60 import org.opendaylight.yang.gen.v1.urn.opendaylight.port.statistics.rev131214.node.connector.statistics.and.port.number.map.NodeConnectorStatisticsAndPortNumberMapBuilder;
61 import org.opendaylight.yang.gen.v1.urn.opendaylight.table.types.rev131026.TableId;
62 import org.opendaylight.yangtools.yang.common.RpcResult;
63 import org.slf4j.Logger;
64 import org.slf4j.LoggerFactory;
66 import com.google.common.util.concurrent.Futures;
67 import com.google.common.util.concurrent.ListenableFuture;
69 public class FlowStatisticsAdapter implements OpendaylightFlowStatisticsService, IReadServiceListener{
71 private static final Logger LOG = LoggerFactory.getLogger(FlowStatisticsAdapter.class);
72 private IReadService readDelegate;
73 private NotificationProviderService notifier;
76 public Future<RpcResult<GetAggregateFlowStatisticsFromFlowTableForAllFlowsOutput>> getAggregateFlowStatisticsFromFlowTableForAllFlows(
77 GetAggregateFlowStatisticsFromFlowTableForAllFlowsInput input) {
78 //TODO: No supported API exist in AD-SAL, it can either be implemented by fetching all the stats of the flows and
79 // generating aggregate flow statistics out of those individual flow stats.
84 public Future<RpcResult<GetAggregateFlowStatisticsFromFlowTableForGivenMatchOutput>> getAggregateFlowStatisticsFromFlowTableForGivenMatch(
85 GetAggregateFlowStatisticsFromFlowTableForGivenMatchInput input) {
86 //TODO: No supported API exist in AD-SAL, it can either be implemented by fetching all the stats of the flows and
87 // generating aggregate flow statistics out of those individual flow stats.
92 public ListenableFuture<RpcResult<GetAllFlowStatisticsFromFlowTableOutput>> getAllFlowStatisticsFromFlowTable(
93 GetAllFlowStatisticsFromFlowTableInput input) {
94 GetAllFlowStatisticsFromFlowTableOutput rpcResultType = null;
95 boolean rpcResultBool = false;
98 Node adNode = NodeMapping.toADNode(input.getNode());
99 List<FlowOnNode> flowsOnNode = readDelegate.readAllFlows(adNode);
100 List<FlowAndStatisticsMapList> flowsStatistics = toOdFlowsStatistics(flowsOnNode);
101 GetAllFlowStatisticsFromFlowTableOutputBuilder builder = new GetAllFlowStatisticsFromFlowTableOutputBuilder();
102 builder.setTransactionId(new TransactionId(new BigInteger("0")));
103 rpcResultType = builder.setFlowAndStatisticsMapList(flowsStatistics).build();
105 rpcResultBool = true;
106 } catch (ConstructionException e) {
107 LOG.error(e.getMessage());
110 return Futures.immediateFuture(Rpcs.getRpcResult(rpcResultBool, rpcResultType, null));
114 * Essentially this API will return the same result as getAllFlowStatisticsFromFlowTable
117 public ListenableFuture<RpcResult<GetAllFlowsStatisticsFromAllFlowTablesOutput>> getAllFlowsStatisticsFromAllFlowTables(
118 GetAllFlowsStatisticsFromAllFlowTablesInput input) {
120 GetAllFlowsStatisticsFromAllFlowTablesOutput rpcResultType = null;
121 boolean rpcResultBool = false;
124 Node adNode = NodeMapping.toADNode(input.getNode());
125 List<FlowOnNode> flowsOnNode = readDelegate.readAllFlows(adNode);
126 List<FlowAndStatisticsMapList> flowsStatistics = toOdFlowsStatistics(flowsOnNode);
127 GetAllFlowsStatisticsFromAllFlowTablesOutputBuilder builder = new GetAllFlowsStatisticsFromAllFlowTablesOutputBuilder();
128 builder.setTransactionId(new TransactionId(new BigInteger("0")));
129 rpcResultType = builder.setFlowAndStatisticsMapList(flowsStatistics).build();
131 rpcResultBool = true;
132 } catch (ConstructionException e) {
133 LOG.error(e.getMessage());
136 return Futures.immediateFuture(Rpcs.getRpcResult(rpcResultBool, rpcResultType, null));
140 public ListenableFuture<RpcResult<GetFlowStatisticsFromFlowTableOutput>> getFlowStatisticsFromFlowTable(
141 GetFlowStatisticsFromFlowTableInput input) {
142 GetFlowStatisticsFromFlowTableOutput rpcResultType = null;
143 boolean rpcResultBool = false;
146 Node node = NodeMapping.toADNode(input.getNode());
147 Flow flow = ToSalConversionsUtils.toFlow(input, null);
148 FlowOnNode readFlow = readDelegate.readFlow(node, flow);
149 List<FlowAndStatisticsMapList> flowOnNodeToFlowStatistics = new ArrayList<FlowAndStatisticsMapList>();
150 flowOnNodeToFlowStatistics.add(toOdFlowStatistics(readFlow));
151 rpcResultType = new GetFlowStatisticsFromFlowTableOutputBuilder().setFlowAndStatisticsMapList(flowOnNodeToFlowStatistics).build();
152 rpcResultBool = true;
153 } catch (ConstructionException e) {
154 LOG.error(e.getMessage());
157 return Futures.immediateFuture(Rpcs.getRpcResult(rpcResultBool, rpcResultType, null));
161 public void nodeFlowStatisticsUpdated(Node node, List<FlowOnNode> flowStatsList) {
162 List<FlowAndStatisticsMapList> flowStatistics = toOdFlowsStatistics(flowStatsList);
163 FlowsStatisticsUpdateBuilder flowsStatisticsUpdateBuilder = new FlowsStatisticsUpdateBuilder();
164 flowsStatisticsUpdateBuilder.setFlowAndStatisticsMapList(flowStatistics);
165 flowsStatisticsUpdateBuilder.setMoreReplies(false);
166 flowsStatisticsUpdateBuilder.setTransactionId(null);
167 flowsStatisticsUpdateBuilder.setId(InventoryMapping.toNodeKey(node).getId());
168 notifier.publish(flowsStatisticsUpdateBuilder.build());
172 public void nodeConnectorStatisticsUpdated(Node node, List<NodeConnectorStatistics> ncStatsList) {
173 NodeConnectorStatisticsUpdateBuilder nodeConnectorStatisticsUpdateBuilder = new NodeConnectorStatisticsUpdateBuilder();
174 List<NodeConnectorStatisticsAndPortNumberMap> nodeConnectorStatistics = toOdNodeConnectorStatistics(ncStatsList);
176 nodeConnectorStatisticsUpdateBuilder.setNodeConnectorStatisticsAndPortNumberMap(nodeConnectorStatistics);
177 nodeConnectorStatisticsUpdateBuilder.setMoreReplies(false);
178 nodeConnectorStatisticsUpdateBuilder.setTransactionId(null);
179 nodeConnectorStatisticsUpdateBuilder.setId(InventoryMapping.toNodeKey(node).getId());
180 notifier.publish(nodeConnectorStatisticsUpdateBuilder.build());
184 public void nodeTableStatisticsUpdated(Node node, List<NodeTableStatistics> tableStatsList) {
186 FlowTableStatisticsUpdateBuilder flowTableStatisticsUpdateBuilder = new FlowTableStatisticsUpdateBuilder();
188 List<FlowTableAndStatisticsMap> flowTableStatistics = toOdFlowTableStatistics(tableStatsList);
189 flowTableStatisticsUpdateBuilder.setFlowTableAndStatisticsMap(flowTableStatistics);
190 flowTableStatisticsUpdateBuilder.setMoreReplies(false);
191 flowTableStatisticsUpdateBuilder.setTransactionId(null);
192 flowTableStatisticsUpdateBuilder.setId(InventoryMapping.toNodeKey(node).getId());
193 notifier.publish(flowTableStatisticsUpdateBuilder.build());
197 public void descriptionStatisticsUpdated(Node node, NodeDescription nodeDescription) {
198 // TODO which *StatisticsUpdated interface should be used?
202 private List<FlowAndStatisticsMapList> toOdFlowsStatistics(List<FlowOnNode> flowsOnNode) {
203 List<FlowAndStatisticsMapList> flowsStatistics = new ArrayList<>();
204 for (FlowOnNode flowOnNode : flowsOnNode) {
205 flowsStatistics.add(toOdFlowStatistics(flowOnNode));
207 return flowsStatistics;
210 private FlowAndStatisticsMapList toOdFlowStatistics(FlowOnNode flowOnNode) {
211 FlowAndStatisticsMapListBuilder builder = new FlowAndStatisticsMapListBuilder();
213 builder.setByteCount(toCounter64(flowOnNode.getByteCount()));
214 builder.setPacketCount(toCounter64(flowOnNode.getPacketCount()));
215 builder.setDuration(extractDuration(flowOnNode));
216 builder.setMatch(FromSalConversionsUtils.toMatch(flowOnNode.getFlow().getMatch()));
217 builder.setPriority((int)flowOnNode.getFlow().getPriority());
218 builder.setHardTimeout((int)flowOnNode.getFlow().getHardTimeout());
219 builder.setIdleTimeout((int)flowOnNode.getFlow().getIdleTimeout());
220 //TODO: actions to instruction conversion
221 builder.setInstructions(null);
222 return builder.build();
225 private org.opendaylight.yang.gen.v1.urn.opendaylight.model.statistics.types.rev130925.duration.Duration extractDuration(FlowOnNode flowOnNode) {
226 DurationBuilder builder = new DurationBuilder();
227 builder.setNanosecond(new Counter32((long)flowOnNode.getDurationNanoseconds()));
228 builder.setSecond(new Counter32((long)flowOnNode.getDurationSeconds()));
229 return builder.build();
232 private Counter64 toCounter64(long num) {
233 String byteCountStr = String.valueOf(num);
234 BigInteger byteCountBigInt = new BigInteger(byteCountStr);
235 return new Counter64(byteCountBigInt);
238 private List<FlowTableAndStatisticsMap> toOdFlowTableStatistics(List<NodeTableStatistics> tableStatsList) {
240 List<FlowTableAndStatisticsMap> flowTableStatsMap = new ArrayList<FlowTableAndStatisticsMap>();
241 for (NodeTableStatistics nodeTableStatistics : tableStatsList) {
242 FlowTableAndStatisticsMapBuilder flowTableAndStatisticsMapBuilder = new FlowTableAndStatisticsMapBuilder();
243 flowTableAndStatisticsMapBuilder.setActiveFlows(new Counter32((long) nodeTableStatistics.getActiveCount()));
244 flowTableAndStatisticsMapBuilder.setPacketsLookedUp(toCounter64(nodeTableStatistics.getLookupCount()));
245 flowTableAndStatisticsMapBuilder.setPacketsMatched(toCounter64(nodeTableStatistics.getMatchedCount()));
246 flowTableAndStatisticsMapBuilder.setActiveFlows(new Counter32((long) nodeTableStatistics.getActiveCount()));
247 flowTableAndStatisticsMapBuilder.setTableId(new TableId((short)nodeTableStatistics.getNodeTable().getID()));
248 flowTableStatsMap.add(flowTableAndStatisticsMapBuilder.build());
251 return flowTableStatsMap;
254 private List<NodeConnectorStatisticsAndPortNumberMap> toOdNodeConnectorStatistics(
255 List<NodeConnectorStatistics> ncStatsList) {
256 List<NodeConnectorStatisticsAndPortNumberMap> nodeConnectorStatisticsList = new ArrayList<NodeConnectorStatisticsAndPortNumberMap>();
257 for(NodeConnectorStatistics ofNodeConnectorStatistics : ncStatsList){
258 NodeConnectorStatisticsAndPortNumberMapBuilder nodeConnectorStatisticsAndPortNumberMapBuilder = new NodeConnectorStatisticsAndPortNumberMapBuilder();
260 nodeConnectorStatisticsAndPortNumberMapBuilder.setBytes(extractBytes(ofNodeConnectorStatistics));
261 nodeConnectorStatisticsAndPortNumberMapBuilder.setCollisionCount(toBI(ofNodeConnectorStatistics.getCollisionCount()));
262 nodeConnectorStatisticsAndPortNumberMapBuilder.setDuration(null);
263 nodeConnectorStatisticsAndPortNumberMapBuilder.setPackets(extractPackets(ofNodeConnectorStatistics));
264 nodeConnectorStatisticsAndPortNumberMapBuilder.setReceiveCrcError(toBI(ofNodeConnectorStatistics.getReceiveCRCErrorCount()));
265 nodeConnectorStatisticsAndPortNumberMapBuilder.setReceiveDrops(toBI(ofNodeConnectorStatistics.getReceiveDropCount()));
266 nodeConnectorStatisticsAndPortNumberMapBuilder.setReceiveErrors(toBI(ofNodeConnectorStatistics.getReceiveErrorCount()));
267 nodeConnectorStatisticsAndPortNumberMapBuilder.setReceiveFrameError(toBI(ofNodeConnectorStatistics.getReceiveFrameErrorCount()));
268 nodeConnectorStatisticsAndPortNumberMapBuilder.setReceiveOverRunError(toBI(ofNodeConnectorStatistics.getReceiveOverRunErrorCount()));
269 nodeConnectorStatisticsAndPortNumberMapBuilder.setTransmitDrops(toBI(ofNodeConnectorStatistics.getTransmitDropCount()));
270 nodeConnectorStatisticsAndPortNumberMapBuilder.setTransmitErrors(toBI(ofNodeConnectorStatistics.getTransmitErrorCount()));
271 nodeConnectorStatisticsList.add(nodeConnectorStatisticsAndPortNumberMapBuilder.build());
274 return nodeConnectorStatisticsList;
277 private BigInteger toBI(long num) {
278 String numStr = String.valueOf(num);
279 return new BigInteger(numStr);
282 private Packets extractPackets(NodeConnectorStatistics nodeConnectorStatistics) {
283 long receivePacketCount = nodeConnectorStatistics.getReceivePacketCount();
284 long transmitPacketCount = nodeConnectorStatistics.getTransmitPacketCount();
286 PacketsBuilder builder = new PacketsBuilder();
287 builder.setReceived(toBI(receivePacketCount));
288 builder.setTransmitted(toBI(transmitPacketCount));
290 return builder.build();
293 private Bytes extractBytes(NodeConnectorStatistics nodeConnectorStatistics) {
294 long transmitByteCount = nodeConnectorStatistics.getTransmitByteCount();
295 long receiveByteCount = nodeConnectorStatistics.getReceiveByteCount();
297 BytesBuilder builder = new BytesBuilder();
298 builder.setReceived(toBI(receiveByteCount));
299 builder.setTransmitted(toBI(transmitByteCount));
301 return builder.build();