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