Remove unused parameters
[netvirt.git] / statistics / impl / src / main / java / org / opendaylight / netvirt / statistics / CounterRetriever.java
1 /*
2  * Copyright (c) 2017 HPE, 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.netvirt.statistics;
9
10 import java.math.BigInteger;
11 import java.util.ArrayList;
12 import java.util.List;
13 import java.util.UUID;
14 import java.util.concurrent.CompletableFuture;
15 import java.util.concurrent.ExecutionException;
16 import java.util.concurrent.Future;
17 import java.util.concurrent.TimeUnit;
18 import java.util.concurrent.TimeoutException;
19 import javax.annotation.PostConstruct;
20 import javax.annotation.PreDestroy;
21 import javax.inject.Inject;
22 import javax.inject.Singleton;
23 import org.opendaylight.infrautils.counters.api.OccurenceCounter;
24 import org.opendaylight.yang.gen.v1.urn.opendaylight.direct.statistics.rev160511.GetFlowStatisticsInputBuilder;
25 import org.opendaylight.yang.gen.v1.urn.opendaylight.direct.statistics.rev160511.GetFlowStatisticsOutput;
26 import org.opendaylight.yang.gen.v1.urn.opendaylight.direct.statistics.rev160511.GetNodeConnectorStatisticsInput;
27 import org.opendaylight.yang.gen.v1.urn.opendaylight.direct.statistics.rev160511.GetNodeConnectorStatisticsInputBuilder;
28 import org.opendaylight.yang.gen.v1.urn.opendaylight.direct.statistics.rev160511.GetNodeConnectorStatisticsOutput;
29 import org.opendaylight.yang.gen.v1.urn.opendaylight.direct.statistics.rev160511.OpendaylightDirectStatisticsService;
30 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.flow.and.statistics.map.list.FlowAndStatisticsMapList;
31 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.Match;
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorId;
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId;
34 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeRef;
35 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.Nodes;
36 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnector;
37 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
38 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeKey;
39 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.statistics.config.rev170326.StatisticsConfig;
40 import org.opendaylight.yang.gen.v1.urn.opendaylight.port.statistics.rev131214.node.connector.statistics.and.port.number.map.NodeConnectorStatisticsAndPortNumberMap;
41 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
42 import org.opendaylight.yangtools.yang.common.RpcResult;
43 import org.slf4j.Logger;
44 import org.slf4j.LoggerFactory;
45
46 @Singleton
47 public class CounterRetriever {
48     protected static final Logger LOG = LoggerFactory.getLogger(CounterRetriever.class);
49     private final OpendaylightDirectStatisticsService odlDirectStatsService;
50     private final long nodeResultTimeout;
51     private final Counters counters = new Counters();
52
53     @Inject
54     public CounterRetriever(final StatisticsConfig statisticsConfig,
55             final OpendaylightDirectStatisticsService odlDirectStatsService) {
56         this.odlDirectStatsService = odlDirectStatsService;
57         nodeResultTimeout = statisticsConfig.getNodeCounterResultTimeout();
58     }
59
60     @PreDestroy
61     public void destroy() {
62         LOG.info("{} close", getClass().getSimpleName());
63     }
64
65     @PostConstruct
66     public void init() {
67         LOG.info("{} start", getClass().getSimpleName());
68     }
69
70     public CounterResultDataStructure getNodeConnectorCountersDirect(NodeId nodeId, NodeConnectorId nodeConnectorId) {
71         GetNodeConnectorStatisticsInput gncsi = getNodeConnectorStatisticsInputBuilder(nodeId, nodeConnectorId);
72
73         Future<RpcResult<GetNodeConnectorStatisticsOutput>> rpcResultFuture =
74                 odlDirectStatsService.getNodeConnectorStatistics(gncsi);
75         RpcResult<GetNodeConnectorStatisticsOutput> rpcResult = null;
76         try {
77             rpcResult = rpcResultFuture.get();
78         } catch (InterruptedException | ExecutionException e) {
79             counters.failedGettingNodeConnectorCounters.inc();
80             LOG.warn("Unable to retrieve node connector counters for port {}", nodeConnectorId);
81             return null;
82         }
83
84         if (rpcResult != null && rpcResult.isSuccessful() && rpcResult.getResult() != null) {
85             GetNodeConnectorStatisticsOutput nodeConnectorStatsOutput = rpcResult.getResult();
86             return createNodeConnectorResultMapDirect(nodeConnectorStatsOutput, nodeConnectorId);
87         } else {
88             counters.failedGettingRpcResultForNodeConnectorCounters.inc();
89             LOG.warn("Unable to retrieve node connector counters for port {}", nodeConnectorId);
90             return null;
91         }
92     }
93
94     public CounterResultDataStructure getNodeCountersDirect(Node node) {
95         List<CounterResultDataStructure> countersResults = new ArrayList<>();
96         List<CompletableFuture<NodeConnectorStatisticsSupplierOutput>> futureList = new ArrayList<>();
97         for (NodeConnector nodeConnector : node.getNodeConnector()) {
98             GetNodeConnectorStatisticsInput gncsi =
99                     getNodeConnectorStatisticsInputBuilder(node.getId(), nodeConnector.getId());
100             futureList.add(CompletableFuture.supplyAsync(
101                     new NodeConnectorStatisticsSupplier(odlDirectStatsService, gncsi, nodeConnector.getId())));
102         }
103         try {
104             CompletableFuture<Void> allOf = CompletableFuture.allOf(futureList.toArray(new CompletableFuture[0]));
105             allOf.get(nodeResultTimeout, TimeUnit.SECONDS);
106             for (int i = 0; i < futureList.size(); i++) {
107                 CompletableFuture<NodeConnectorStatisticsSupplierOutput> completableCurrentResult = futureList.get(i);
108                 if (completableCurrentResult == null) {
109                     LOG.warn("Unable to retrieve node counters");
110                     counters.failedGettingNodeCounters.inc();
111                     return null;
112                 }
113                 RpcResult<GetNodeConnectorStatisticsOutput> currentResult =
114                         completableCurrentResult.get().getNodeConnectorStatisticsOutput();
115                 if (currentResult != null && currentResult.isSuccessful() && currentResult.getResult() != null) {
116                     GetNodeConnectorStatisticsOutput nodeConnectorStatsOutput = currentResult.getResult();
117                     countersResults.add(createNodeConnectorResultMapDirect(nodeConnectorStatsOutput,
118                             completableCurrentResult.get().getNodeConnectrId()));
119                 } else {
120                     counters.failedGettingNodeCounters.inc();
121                     LOG.warn("Unable to retrieve node counters");
122                     return null;
123                 }
124             }
125         } catch (InterruptedException | ExecutionException | TimeoutException e) {
126             counters.failedGettingNodeCounters.inc();
127             LOG.warn("Unable to retrieve node counters");
128             return null;
129         }
130
131         return mergeCountersResults(countersResults);
132     }
133
134     private CounterResultDataStructure mergeCountersResults(List<CounterResultDataStructure> countersResults) {
135         CounterResultDataStructure crds = new CounterResultDataStructure();
136         for (CounterResultDataStructure currentCrds : countersResults) {
137             for (String resultId : currentCrds.getResults().keySet()) {
138                 crds.addCounterResult(resultId, currentCrds.getResults().get(resultId));
139             }
140         }
141         return crds;
142     }
143
144     private GetNodeConnectorStatisticsInput getNodeConnectorStatisticsInputBuilder(NodeId nodeId,
145             NodeConnectorId nodeConnectorId) {
146         NodeRef nodeRef = new NodeRef(
147                 InstanceIdentifier.builder(Nodes.class).child(Node.class, new NodeKey(nodeId)).toInstance());
148         GetNodeConnectorStatisticsInputBuilder nodeConnectorBuilder =
149                 new GetNodeConnectorStatisticsInputBuilder().setNode(nodeRef).setNodeConnectorId(nodeConnectorId);
150         GetNodeConnectorStatisticsInput gncsi = nodeConnectorBuilder.build();
151         return gncsi;
152     }
153
154     private CounterResultDataStructure createNodeConnectorResultMapDirect(
155             GetNodeConnectorStatisticsOutput nodeConnectorStatsOutput, NodeConnectorId nodeConnectorId) {
156         List<NodeConnectorStatisticsAndPortNumberMap> nodeConnectorUpdates =
157                 nodeConnectorStatsOutput.getNodeConnectorStatisticsAndPortNumberMap();
158         if (nodeConnectorUpdates == null || nodeConnectorUpdates.isEmpty()) {
159             counters.failedGettingResultMapForNodeConnectorCounters.inc();
160             LOG.warn("Unable to retrieve statistics info for node connector");
161             return null;
162         }
163
164         CounterResultDataStructure crds = new CounterResultDataStructure();
165         for (NodeConnectorStatisticsAndPortNumberMap nodeConnectorUpdate : nodeConnectorUpdates) {
166             if (nodeConnectorUpdate.getNodeConnectorId() == null) {
167                 continue;
168             }
169             String resultId = nodeConnectorId.getValue();
170             crds.addCounterResult(resultId);
171             if (nodeConnectorUpdate.getBytes() != null) {
172                 crds.addCounterToGroup(resultId, CountersUtils.BYTES_GROUP_NAME,
173                         CountersUtils.BYTES_RECEIVED_COUNTER_NAME, nodeConnectorUpdate.getBytes().getReceived());
174                 crds.addCounterToGroup(resultId, CountersUtils.BYTES_GROUP_NAME,
175                         CountersUtils.BYTES_TRANSMITTED_COUNTER_NAME, nodeConnectorUpdate.getBytes().getTransmitted());
176             }
177             if (nodeConnectorUpdate.getPackets() != null) {
178                 crds.addCounterToGroup(resultId, CountersUtils.PACKETS_GROUP_NAME,
179                         CountersUtils.PACKETS_RECEIVED_COUNTER_NAME, nodeConnectorUpdate.getPackets().getReceived());
180                 crds.addCounterToGroup(resultId, CountersUtils.PACKETS_GROUP_NAME,
181                         CountersUtils.PACKETS_TRANSMITTED_COUNTER_NAME,
182                         nodeConnectorUpdate.getPackets().getTransmitted());
183             }
184             if (nodeConnectorUpdate.getDuration() != null) {
185                 crds.addCounterToGroup(resultId, CountersUtils.DURATION_GROUP_NAME,
186                         CountersUtils.DURATION_SECOND_COUNTER_NAME,
187                         big(nodeConnectorUpdate.getDuration().getSecond().getValue()));
188                 crds.addCounterToGroup(resultId, CountersUtils.DURATION_GROUP_NAME,
189                         CountersUtils.DURATION_NANO_SECOND_COUNTER_NAME,
190                         big(nodeConnectorUpdate.getDuration().getNanosecond().getValue()));
191             }
192         }
193
194         return crds;
195     }
196
197     public CounterResultDataStructure getSwitchFlowCountersDirect(BigInteger dpId, Match match) {
198         NodeRef nodeRef = new NodeRef(InstanceIdentifier.builder(Nodes.class)
199                 .child(Node.class, new NodeKey(new NodeId(CountersUtils.getNodeId(dpId)))).toInstance());
200         GetFlowStatisticsInputBuilder gfsib = new GetFlowStatisticsInputBuilder();
201         gfsib.setNode(nodeRef);
202         gfsib.setMatch(match);
203         gfsib.setStoreStats(false);
204
205         Future<RpcResult<GetFlowStatisticsOutput>> rpcResultFuture =
206                 odlDirectStatsService.getFlowStatistics(gfsib.build());
207         RpcResult<GetFlowStatisticsOutput> rpcResult = null;
208         try {
209             rpcResult = rpcResultFuture.get();
210         } catch (InterruptedException | ExecutionException e) {
211             counters.failedGettingFlowCounters.inc();
212             LOG.warn("Unable to retrieve flow counters for match {}", match);
213             return null;
214         }
215
216         if (rpcResult != null && rpcResult.isSuccessful() && rpcResult.getResult() != null) {
217             GetFlowStatisticsOutput flowStatsOutput = rpcResult.getResult();
218             return createSwitchFlowResultMapDirect(flowStatsOutput);
219         } else {
220             counters.failedGettingFlowCounters.inc();
221             LOG.warn("Unable to retrieve flow counters for match {}", match);
222             return null;
223         }
224     }
225
226     private CounterResultDataStructure createSwitchFlowResultMapDirect(GetFlowStatisticsOutput flowStatsOutput) {
227         List<FlowAndStatisticsMapList> flowUpdates = flowStatsOutput.getFlowAndStatisticsMapList();
228         if (flowUpdates == null || flowUpdates.isEmpty()) {
229             LOG.warn("Unable to retrieve flows statistics info");
230             return null;
231         }
232
233         CounterResultDataStructure crds = new CounterResultDataStructure();
234         for (FlowAndStatisticsMapList flowUpdate : flowUpdates) {
235             String resultId = flowUpdate.getTableId().toString() + CountersUtils.OF_DELIMITER + UUID.randomUUID();
236             crds.addCounterResult(resultId);
237             if (flowUpdate.getByteCount() != null) {
238                 crds.addCounterToGroup(resultId, CountersUtils.BYTES_GROUP_NAME, CountersUtils.BYTE_COUNTER_NAME,
239                         flowUpdate.getByteCount().getValue());
240             }
241             if (flowUpdate.getPacketCount() != null) {
242                 crds.addCounterToGroup(resultId, CountersUtils.PACKETS_GROUP_NAME, CountersUtils.PACKET_COUNTER_NAME,
243                         flowUpdate.getPacketCount().getValue());
244             }
245             if (flowUpdate.getDuration() != null) {
246                 crds.addCounterToGroup(resultId, CountersUtils.DURATION_GROUP_NAME,
247                         CountersUtils.DURATION_SECOND_COUNTER_NAME,
248                         big(flowUpdate.getDuration().getSecond().getValue()));
249                 crds.addCounterToGroup(resultId, CountersUtils.DURATION_GROUP_NAME,
250                         CountersUtils.DURATION_NANO_SECOND_COUNTER_NAME,
251                         big(flowUpdate.getDuration().getNanosecond().getValue()));
252             }
253         }
254         return crds;
255     }
256
257     private BigInteger big(Long longValue) {
258         return BigInteger.valueOf(longValue);
259     }
260
261     private static class Counters {
262         OccurenceCounter failedGettingNodeConnectorCounters = new OccurenceCounter(
263                 getClass().getEnclosingClass().getSimpleName(), "failed_getting_node_connector_counters", "");
264
265         OccurenceCounter failedGettingRpcResultForNodeConnectorCounters = new OccurenceCounter(
266                 getClass().getEnclosingClass().getSimpleName(),
267                 "failed_getting_rpc_result_for_node_connector_counters", "");
268
269         OccurenceCounter failedGettingNodeCounters = new OccurenceCounter(
270                 getClass().getEnclosingClass().getSimpleName(), "failed_getting_node_counters", "");
271
272         OccurenceCounter failedGettingResultMapForNodeConnectorCounters = new OccurenceCounter(
273                 getClass().getEnclosingClass().getSimpleName(),
274                 "failed_getting_result_map_for_node_connector_counters", "");
275
276         OccurenceCounter failedGettingFlowCounters = new OccurenceCounter(
277                 getClass().getEnclosingClass().getSimpleName(), "failed_getting_flow_counters", "");
278     }
279 }