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