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