e63cb54b8685174fafc7367bbe76bc130104a107
[controller.git] / opendaylight / md-sal / compatibility / sal-compatibility / src / main / java / org / opendaylight / controller / sal / compatibility / adsal / FlowStatisticsAdapter.java
1 /*
2  * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
3  *
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
7  */
8 package org.opendaylight.controller.sal.compatibility.adsal;
9
10 import java.math.BigInteger;
11 import java.util.ArrayList;
12 import java.util.List;
13 import java.util.concurrent.Future;
14
15 import org.opendaylight.controller.sal.binding.api.NotificationProviderService;
16 import org.opendaylight.controller.sal.compatibility.FromSalConversionsUtils;
17 import org.opendaylight.controller.sal.compatibility.InventoryMapping;
18 import org.opendaylight.controller.sal.compatibility.NodeMapping;
19 import org.opendaylight.controller.sal.compatibility.ToSalConversionsUtils;
20 import org.opendaylight.controller.sal.core.ConstructionException;
21 import org.opendaylight.controller.sal.core.Node;
22 import org.opendaylight.controller.sal.flowprogrammer.Flow;
23 import org.opendaylight.controller.sal.reader.FlowOnNode;
24 import org.opendaylight.controller.sal.reader.IReadService;
25 import org.opendaylight.controller.sal.reader.IReadServiceListener;
26 import org.opendaylight.controller.sal.reader.NodeConnectorStatistics;
27 import org.opendaylight.controller.sal.reader.NodeDescription;
28 import org.opendaylight.controller.sal.reader.NodeTableStatistics;
29 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev100924.Counter32;
30 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev100924.Counter64;
31 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.FlowsStatisticsUpdateBuilder;
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.GetAggregateFlowStatisticsFromFlowTableForAllFlowsInput;
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.GetAggregateFlowStatisticsFromFlowTableForAllFlowsOutput;
34 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.GetAggregateFlowStatisticsFromFlowTableForGivenMatchInput;
35 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.GetAggregateFlowStatisticsFromFlowTableForGivenMatchOutput;
36 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.GetAllFlowStatisticsFromFlowTableInput;
37 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.GetAllFlowStatisticsFromFlowTableOutput;
38 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.GetAllFlowStatisticsFromFlowTableOutputBuilder;
39 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.GetAllFlowsStatisticsFromAllFlowTablesInput;
40 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.GetAllFlowsStatisticsFromAllFlowTablesOutput;
41 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.GetAllFlowsStatisticsFromAllFlowTablesOutputBuilder;
42 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.GetFlowStatisticsFromFlowTableInput;
43 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.GetFlowStatisticsFromFlowTableOutput;
44 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.GetFlowStatisticsFromFlowTableOutputBuilder;
45 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.OpendaylightFlowStatisticsService;
46 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.flow.and.statistics.map.list.FlowAndStatisticsMapList;
47 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.flow.and.statistics.map.list.FlowAndStatisticsMapListBuilder;
48 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.table.statistics.rev131215.FlowTableStatisticsUpdateBuilder;
49 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.table.statistics.rev131215.flow.table.and.statistics.map.FlowTableAndStatisticsMap;
50 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.table.statistics.rev131215.flow.table.and.statistics.map.FlowTableAndStatisticsMapBuilder;
51 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.transaction.rev131103.TransactionId;
52 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.statistics.types.rev130925.duration.DurationBuilder;
53 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.statistics.types.rev130925.node.connector.statistics.Bytes;
54 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.statistics.types.rev130925.node.connector.statistics.BytesBuilder;
55 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.statistics.types.rev130925.node.connector.statistics.Packets;
56 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.statistics.types.rev130925.node.connector.statistics.PacketsBuilder;
57 import org.opendaylight.yang.gen.v1.urn.opendaylight.port.statistics.rev131214.NodeConnectorStatisticsUpdateBuilder;
58 import org.opendaylight.yang.gen.v1.urn.opendaylight.port.statistics.rev131214.node.connector.statistics.and.port.number.map.NodeConnectorStatisticsAndPortNumberMap;
59 import org.opendaylight.yang.gen.v1.urn.opendaylight.port.statistics.rev131214.node.connector.statistics.and.port.number.map.NodeConnectorStatisticsAndPortNumberMapBuilder;
60 import org.opendaylight.yang.gen.v1.urn.opendaylight.table.types.rev131026.TableId;
61 import org.opendaylight.yangtools.yang.common.RpcResult;
62 import org.opendaylight.yangtools.yang.common.RpcResultBuilder;
63 import org.slf4j.Logger;
64 import org.slf4j.LoggerFactory;
65
66 import com.google.common.util.concurrent.Futures;
67 import com.google.common.util.concurrent.ListenableFuture;
68
69 public class FlowStatisticsAdapter implements OpendaylightFlowStatisticsService, IReadServiceListener{
70
71     private static final Logger LOG = LoggerFactory.getLogger(FlowStatisticsAdapter.class);
72     private IReadService readDelegate;
73     private NotificationProviderService notifier;
74
75     @Override
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.
80         return null;
81     }
82
83     @Override
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.
88         return null;
89     }
90
91     @Override
92     public ListenableFuture<RpcResult<GetAllFlowStatisticsFromFlowTableOutput>> getAllFlowStatisticsFromFlowTable(
93             GetAllFlowStatisticsFromFlowTableInput input) {
94         GetAllFlowStatisticsFromFlowTableOutput rpcResultType = null;
95         boolean rpcResultBool = false;
96
97         try {
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();
104
105             rpcResultBool = true;
106         } catch (ConstructionException e) {
107             LOG.error(e.getMessage());
108         }
109
110         return Futures.immediateFuture(RpcResultBuilder.<GetAllFlowStatisticsFromFlowTableOutput>
111                                                 status(rpcResultBool).withResult(rpcResultType).build());
112     }
113
114     /**
115      * Essentially this API will return the same result as getAllFlowStatisticsFromFlowTable
116      */
117     @Override
118     public ListenableFuture<RpcResult<GetAllFlowsStatisticsFromAllFlowTablesOutput>> getAllFlowsStatisticsFromAllFlowTables(
119             GetAllFlowsStatisticsFromAllFlowTablesInput input) {
120
121         GetAllFlowsStatisticsFromAllFlowTablesOutput rpcResultType = null;
122         boolean rpcResultBool = false;
123
124         try {
125             Node adNode = NodeMapping.toADNode(input.getNode());
126             List<FlowOnNode> flowsOnNode = readDelegate.readAllFlows(adNode);
127             List<FlowAndStatisticsMapList> flowsStatistics = toOdFlowsStatistics(flowsOnNode);
128             GetAllFlowsStatisticsFromAllFlowTablesOutputBuilder builder = new GetAllFlowsStatisticsFromAllFlowTablesOutputBuilder();
129             builder.setTransactionId(new TransactionId(new BigInteger("0")));
130             rpcResultType = builder.setFlowAndStatisticsMapList(flowsStatistics).build();
131
132             rpcResultBool = true;
133         } catch (ConstructionException e) {
134             LOG.error(e.getMessage());
135         }
136
137         return Futures.immediateFuture(RpcResultBuilder.<GetAllFlowsStatisticsFromAllFlowTablesOutput>
138                                                status(rpcResultBool).withResult(rpcResultType).build());
139     }
140
141     @Override
142     public ListenableFuture<RpcResult<GetFlowStatisticsFromFlowTableOutput>> getFlowStatisticsFromFlowTable(
143             GetFlowStatisticsFromFlowTableInput input) {
144         GetFlowStatisticsFromFlowTableOutput rpcResultType = null;
145         boolean rpcResultBool = false;
146
147         try {
148             Node node = NodeMapping.toADNode(input.getNode());
149             Flow flow = ToSalConversionsUtils.toFlow(input, null);
150             FlowOnNode readFlow = readDelegate.readFlow(node, flow);
151             List<FlowAndStatisticsMapList> flowOnNodeToFlowStatistics = new ArrayList<FlowAndStatisticsMapList>();
152             flowOnNodeToFlowStatistics.add(toOdFlowStatistics(readFlow));
153             rpcResultType = new GetFlowStatisticsFromFlowTableOutputBuilder().setFlowAndStatisticsMapList(flowOnNodeToFlowStatistics).build();
154             rpcResultBool = true;
155         } catch (ConstructionException e) {
156             LOG.error(e.getMessage());
157         }
158
159         return Futures.immediateFuture(RpcResultBuilder.<GetFlowStatisticsFromFlowTableOutput>
160                                               status(rpcResultBool).withResult(rpcResultType).build());
161     }
162
163     @Override
164     public void nodeFlowStatisticsUpdated(Node node, List<FlowOnNode> flowStatsList) {
165         List<FlowAndStatisticsMapList> flowStatistics = toOdFlowsStatistics(flowStatsList);
166         FlowsStatisticsUpdateBuilder flowsStatisticsUpdateBuilder = new FlowsStatisticsUpdateBuilder();
167         flowsStatisticsUpdateBuilder.setFlowAndStatisticsMapList(flowStatistics);
168         flowsStatisticsUpdateBuilder.setMoreReplies(false);
169         flowsStatisticsUpdateBuilder.setTransactionId(null);
170         flowsStatisticsUpdateBuilder.setId(InventoryMapping.toNodeKey(node).getId());
171         notifier.publish(flowsStatisticsUpdateBuilder.build());
172     }
173
174     @Override
175     public void nodeConnectorStatisticsUpdated(Node node, List<NodeConnectorStatistics> ncStatsList) {
176         NodeConnectorStatisticsUpdateBuilder nodeConnectorStatisticsUpdateBuilder = new NodeConnectorStatisticsUpdateBuilder();
177         List<NodeConnectorStatisticsAndPortNumberMap> nodeConnectorStatistics = toOdNodeConnectorStatistics(ncStatsList);
178
179         nodeConnectorStatisticsUpdateBuilder.setNodeConnectorStatisticsAndPortNumberMap(nodeConnectorStatistics);
180         nodeConnectorStatisticsUpdateBuilder.setMoreReplies(false);
181         nodeConnectorStatisticsUpdateBuilder.setTransactionId(null);
182         nodeConnectorStatisticsUpdateBuilder.setId(InventoryMapping.toNodeKey(node).getId());
183         notifier.publish(nodeConnectorStatisticsUpdateBuilder.build());
184     }
185
186     @Override
187     public void nodeTableStatisticsUpdated(Node node, List<NodeTableStatistics> tableStatsList) {
188
189         FlowTableStatisticsUpdateBuilder flowTableStatisticsUpdateBuilder = new FlowTableStatisticsUpdateBuilder();
190
191         List<FlowTableAndStatisticsMap>  flowTableStatistics = toOdFlowTableStatistics(tableStatsList);
192         flowTableStatisticsUpdateBuilder.setFlowTableAndStatisticsMap(flowTableStatistics);
193         flowTableStatisticsUpdateBuilder.setMoreReplies(false);
194         flowTableStatisticsUpdateBuilder.setTransactionId(null);
195         flowTableStatisticsUpdateBuilder.setId(InventoryMapping.toNodeKey(node).getId());
196         notifier.publish(flowTableStatisticsUpdateBuilder.build());
197 }
198
199         @Override
200     public void descriptionStatisticsUpdated(Node node, NodeDescription nodeDescription) {
201             // TODO which *StatisticsUpdated interface should be used?
202
203     }
204
205     private List<FlowAndStatisticsMapList> toOdFlowsStatistics(List<FlowOnNode> flowsOnNode) {
206         List<FlowAndStatisticsMapList> flowsStatistics = new ArrayList<>();
207         for (FlowOnNode flowOnNode : flowsOnNode) {
208             flowsStatistics.add(toOdFlowStatistics(flowOnNode));
209         }
210         return flowsStatistics;
211     }
212
213     private FlowAndStatisticsMapList toOdFlowStatistics(FlowOnNode flowOnNode) {
214         FlowAndStatisticsMapListBuilder builder = new FlowAndStatisticsMapListBuilder();
215
216         builder.setByteCount(toCounter64(flowOnNode.getByteCount()));
217         builder.setPacketCount(toCounter64(flowOnNode.getPacketCount()));
218         builder.setDuration(extractDuration(flowOnNode));
219         builder.setMatch(FromSalConversionsUtils.toMatch(flowOnNode.getFlow().getMatch()));
220         builder.setPriority((int)flowOnNode.getFlow().getPriority());
221         builder.setHardTimeout((int)flowOnNode.getFlow().getHardTimeout());
222         builder.setIdleTimeout((int)flowOnNode.getFlow().getIdleTimeout());
223         //TODO: actions to instruction conversion
224         builder.setInstructions(null);
225         return builder.build();
226     }
227
228     private org.opendaylight.yang.gen.v1.urn.opendaylight.model.statistics.types.rev130925.duration.Duration extractDuration(FlowOnNode flowOnNode) {
229         DurationBuilder builder = new DurationBuilder();
230         builder.setNanosecond(new Counter32((long)flowOnNode.getDurationNanoseconds()));
231         builder.setSecond(new Counter32((long)flowOnNode.getDurationSeconds()));
232         return builder.build();
233     }
234
235     private Counter64 toCounter64(long num) {
236         String byteCountStr = String.valueOf(num);
237         BigInteger byteCountBigInt = new BigInteger(byteCountStr);
238         return new Counter64(byteCountBigInt);
239     }
240
241     private List<FlowTableAndStatisticsMap> toOdFlowTableStatistics(List<NodeTableStatistics> tableStatsList) {
242
243         List<FlowTableAndStatisticsMap> flowTableStatsMap = new ArrayList<FlowTableAndStatisticsMap>();
244         for (NodeTableStatistics nodeTableStatistics : tableStatsList) {
245             FlowTableAndStatisticsMapBuilder flowTableAndStatisticsMapBuilder = new FlowTableAndStatisticsMapBuilder();
246             flowTableAndStatisticsMapBuilder.setActiveFlows(new Counter32((long) nodeTableStatistics.getActiveCount()));
247             flowTableAndStatisticsMapBuilder.setPacketsLookedUp(toCounter64(nodeTableStatistics.getLookupCount()));
248             flowTableAndStatisticsMapBuilder.setPacketsMatched(toCounter64(nodeTableStatistics.getMatchedCount()));
249             flowTableAndStatisticsMapBuilder.setActiveFlows(new Counter32((long) nodeTableStatistics.getActiveCount()));
250             flowTableAndStatisticsMapBuilder.setTableId(new TableId((short)nodeTableStatistics.getNodeTable().getID()));
251             flowTableStatsMap.add(flowTableAndStatisticsMapBuilder.build());
252         }
253
254         return flowTableStatsMap;
255     }
256
257     private List<NodeConnectorStatisticsAndPortNumberMap> toOdNodeConnectorStatistics(
258             List<NodeConnectorStatistics> ncStatsList) {
259         List<NodeConnectorStatisticsAndPortNumberMap> nodeConnectorStatisticsList = new ArrayList<NodeConnectorStatisticsAndPortNumberMap>();
260         for(NodeConnectorStatistics ofNodeConnectorStatistics : ncStatsList){
261             NodeConnectorStatisticsAndPortNumberMapBuilder nodeConnectorStatisticsAndPortNumberMapBuilder = new NodeConnectorStatisticsAndPortNumberMapBuilder();
262
263             nodeConnectorStatisticsAndPortNumberMapBuilder.setBytes(extractBytes(ofNodeConnectorStatistics));
264             nodeConnectorStatisticsAndPortNumberMapBuilder.setCollisionCount(toBI(ofNodeConnectorStatistics.getCollisionCount()));
265             nodeConnectorStatisticsAndPortNumberMapBuilder.setDuration(null);
266             nodeConnectorStatisticsAndPortNumberMapBuilder.setPackets(extractPackets(ofNodeConnectorStatistics));
267             nodeConnectorStatisticsAndPortNumberMapBuilder.setReceiveCrcError(toBI(ofNodeConnectorStatistics.getReceiveCRCErrorCount()));
268             nodeConnectorStatisticsAndPortNumberMapBuilder.setReceiveDrops(toBI(ofNodeConnectorStatistics.getReceiveDropCount()));
269             nodeConnectorStatisticsAndPortNumberMapBuilder.setReceiveErrors(toBI(ofNodeConnectorStatistics.getReceiveErrorCount()));
270             nodeConnectorStatisticsAndPortNumberMapBuilder.setReceiveFrameError(toBI(ofNodeConnectorStatistics.getReceiveFrameErrorCount()));
271             nodeConnectorStatisticsAndPortNumberMapBuilder.setReceiveOverRunError(toBI(ofNodeConnectorStatistics.getReceiveOverRunErrorCount()));
272             nodeConnectorStatisticsAndPortNumberMapBuilder.setTransmitDrops(toBI(ofNodeConnectorStatistics.getTransmitDropCount()));
273             nodeConnectorStatisticsAndPortNumberMapBuilder.setTransmitErrors(toBI(ofNodeConnectorStatistics.getTransmitErrorCount()));
274             nodeConnectorStatisticsList.add(nodeConnectorStatisticsAndPortNumberMapBuilder.build());
275         }
276
277         return nodeConnectorStatisticsList;
278     }
279
280     private BigInteger toBI(long num) {
281         String numStr = String.valueOf(num);
282         return new BigInteger(numStr);
283     }
284
285     private Packets extractPackets(NodeConnectorStatistics nodeConnectorStatistics) {
286         long receivePacketCount = nodeConnectorStatistics.getReceivePacketCount();
287         long transmitPacketCount = nodeConnectorStatistics.getTransmitPacketCount();
288
289         PacketsBuilder builder = new PacketsBuilder();
290         builder.setReceived(toBI(receivePacketCount));
291         builder.setTransmitted(toBI(transmitPacketCount));
292
293         return builder.build();
294     }
295
296     private Bytes extractBytes(NodeConnectorStatistics nodeConnectorStatistics) {
297         long transmitByteCount = nodeConnectorStatistics.getTransmitByteCount();
298         long receiveByteCount = nodeConnectorStatistics.getReceiveByteCount();
299
300         BytesBuilder builder = new BytesBuilder();
301         builder.setReceived(toBI(receiveByteCount));
302         builder.setTransmitted(toBI(transmitByteCount));
303
304         return builder.build();
305     }
306
307 }