2 * Copyright (c) 2017 HPE, Inc. and others. All rights reserved.
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
8 package org.opendaylight.netvirt.statistics;
10 import com.google.common.base.Optional;
11 import com.google.common.util.concurrent.CheckedFuture;
12 import com.google.common.util.concurrent.FutureCallback;
13 import com.google.common.util.concurrent.Futures;
14 import com.google.common.util.concurrent.ListenableFuture;
15 import com.google.common.util.concurrent.MoreExecutors;
16 import com.google.common.util.concurrent.SettableFuture;
17 import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
18 import java.math.BigInteger;
19 import java.util.ArrayList;
20 import java.util.HashMap;
21 import java.util.HashSet;
22 import java.util.List;
24 import java.util.Map.Entry;
26 import java.util.UUID;
27 import java.util.concurrent.ExecutionException;
28 import java.util.concurrent.Future;
29 import javax.annotation.Nonnull;
30 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
31 import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction;
32 import org.opendaylight.controller.md.sal.binding.api.ReadWriteTransaction;
33 import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
34 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
35 import org.opendaylight.controller.md.sal.common.api.data.ReadFailedException;
36 import org.opendaylight.genius.infra.ManagedNewTransactionRunner;
37 import org.opendaylight.genius.infra.ManagedNewTransactionRunnerImpl;
38 import org.opendaylight.genius.interfacemanager.globals.InterfaceInfo;
39 import org.opendaylight.genius.interfacemanager.interfaces.IInterfaceManager;
40 import org.opendaylight.genius.mdsalutil.MDSALUtil;
41 import org.opendaylight.genius.mdsalutil.MatchInfoBase;
42 import org.opendaylight.genius.mdsalutil.interfaces.IMdsalApiManager;
43 import org.opendaylight.infrautils.counters.api.OccurenceCounter;
44 import org.opendaylight.infrautils.utils.concurrent.ListenableFutures;
45 import org.opendaylight.netvirt.statistics.api.ICountersInterfaceChangeHandler;
46 import org.opendaylight.netvirt.vpnmanager.api.InterfaceUtils;
47 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface;
48 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.Match;
49 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.AllocateIdInput;
50 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.AllocateIdInputBuilder;
51 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.AllocateIdOutput;
52 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.CreateIdPoolInput;
53 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.CreateIdPoolInputBuilder;
54 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.CreateIdPoolOutput;
55 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.IdManagerService;
56 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.IdPools;
57 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.ReleaseIdInput;
58 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.ReleaseIdInputBuilder;
59 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.ReleaseIdOutput;
60 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.id.pools.IdPool;
61 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.id.pools.IdPoolKey;
62 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorId;
63 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId;
64 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.Nodes;
65 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
66 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeKey;
67 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.statistics.rev170120.AcquireElementCountersRequestHandlerInput;
68 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.statistics.rev170120.AcquireElementCountersRequestHandlerOutput;
69 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.statistics.rev170120.AcquireElementCountersRequestHandlerOutputBuilder;
70 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.statistics.rev170120.CleanAllElementCounterRequestsInput;
71 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.statistics.rev170120.CleanAllElementCounterRequestsOutput;
72 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.statistics.rev170120.EgressElementCountersRequestConfig;
73 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.statistics.rev170120.EgressElementCountersRequestConfigBuilder;
74 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.statistics.rev170120.GetElementCountersByHandlerInput;
75 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.statistics.rev170120.GetElementCountersByHandlerOutput;
76 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.statistics.rev170120.GetElementCountersByHandlerOutputBuilder;
77 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.statistics.rev170120.GetNodeAggregatedCountersInput;
78 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.statistics.rev170120.GetNodeAggregatedCountersOutput;
79 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.statistics.rev170120.GetNodeAggregatedCountersOutputBuilder;
80 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.statistics.rev170120.GetNodeConnectorCountersInput;
81 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.statistics.rev170120.GetNodeConnectorCountersOutput;
82 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.statistics.rev170120.GetNodeConnectorCountersOutputBuilder;
83 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.statistics.rev170120.GetNodeCountersInput;
84 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.statistics.rev170120.GetNodeCountersOutput;
85 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.statistics.rev170120.GetNodeCountersOutputBuilder;
86 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.statistics.rev170120.IngressElementCountersRequestConfig;
87 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.statistics.rev170120.IngressElementCountersRequestConfigBuilder;
88 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.statistics.rev170120.ReleaseElementCountersRequestHandlerInput;
89 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.statistics.rev170120.ReleaseElementCountersRequestHandlerOutput;
90 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.statistics.rev170120.StatisticsService;
91 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.statistics.rev170120.counterrequestsconfig.CounterRequests;
92 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.statistics.rev170120.counterrequestsconfig.CounterRequestsBuilder;
93 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.statistics.rev170120.counterrequestsconfig.CounterRequestsKey;
94 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.statistics.rev170120.elementrequestdata.Filters;
95 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.statistics.rev170120.elementrequestdata.filters.TcpFilter;
96 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.statistics.rev170120.elementrequestdata.filters.UdpFilter;
97 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.statistics.rev170120.result.CounterResult;
98 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.statistics.rev170120.result.CounterResultBuilder;
99 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.statistics.rev170120.result.counterresult.Groups;
100 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.statistics.rev170120.result.counterresult.GroupsBuilder;
101 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.statistics.rev170120.result.counterresult.groups.Counters;
102 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.statistics.rev170120.result.counterresult.groups.CountersBuilder;
103 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
104 import org.opendaylight.yangtools.yang.common.RpcError.ErrorType;
105 import org.opendaylight.yangtools.yang.common.RpcResult;
106 import org.opendaylight.yangtools.yang.common.RpcResultBuilder;
107 import org.slf4j.Logger;
108 import org.slf4j.LoggerFactory;
110 public class StatisticsImpl implements StatisticsService, ICountersInterfaceChangeHandler {
111 private static final Logger LOG = LoggerFactory.getLogger(StatisticsImpl.class);
112 private final DataBroker db;
113 private final ManagedNewTransactionRunner txRunner;
114 private final CounterRetriever counterRetriever;
115 private final IInterfaceManager interfaceManager;
116 private final IMdsalApiManager mdsalApiManager;
117 private final IdManagerService idManagerService;
119 public StatisticsImpl(DataBroker db, CounterRetriever counterRetriever, IInterfaceManager interfaceManager,
120 IMdsalApiManager mdsalApiManager, IdManagerService idManagerService) {
122 this.txRunner = new ManagedNewTransactionRunnerImpl(db);
123 this.counterRetriever = counterRetriever;
124 this.interfaceManager = interfaceManager;
125 this.mdsalApiManager = mdsalApiManager;
126 this.idManagerService = idManagerService;
127 initializeCountrsConfigDataSrore();
131 @SuppressWarnings("checkstyle:illegalCatch")
132 public ListenableFuture<RpcResult<GetNodeCountersOutput>> getNodeCounters(GetNodeCountersInput input) {
133 BigInteger dpId = input.getNodeId();
134 LOG.trace("getting node counters for node {}", dpId);
135 GetNodeCountersOutputBuilder gncob = new GetNodeCountersOutputBuilder();
137 List<CounterResult> counterResults = new ArrayList<>();
139 if (!getNodeResult(counterResults, dpId)) {
140 StatisticsPluginImplCounters.failed_getting_node_counters.inc();
141 return RpcResultBuilder.<GetNodeCountersOutput>failed()
142 .withError(ErrorType.APPLICATION, "failed to get node counters for node: " + dpId)
145 } catch (RuntimeException e) {
146 LOG.warn("failed to get counter result for node {}", dpId, e);
147 return RpcResultBuilder.<GetNodeCountersOutput>failed()
148 .withError(ErrorType.APPLICATION, "failed to get node counters for node: " + dpId).buildFuture();
151 gncob.setCounterResult(counterResults);
152 return RpcResultBuilder.success(gncob.build()).buildFuture();
156 @SuppressWarnings("checkstyle:illegalCatch")
157 public ListenableFuture<RpcResult<GetNodeAggregatedCountersOutput>> getNodeAggregatedCounters(
158 GetNodeAggregatedCountersInput input) {
159 BigInteger dpId = input.getNodeId();
160 LOG.trace("getting aggregated node counters for node {}", dpId);
161 GetNodeAggregatedCountersOutputBuilder gnacob = new GetNodeAggregatedCountersOutputBuilder();
163 List<CounterResult> aggregatedCounterResults = new ArrayList<>();
165 if (!getNodeAggregatedResult(aggregatedCounterResults, dpId)) {
166 StatisticsPluginImplCounters.failed_getting_aggregated_node_counters.inc();
167 return RpcResultBuilder.<GetNodeAggregatedCountersOutput>failed()
168 .withError(ErrorType.APPLICATION, "failed to get node aggregated counters for node " + dpId)
171 } catch (Exception e) {
172 LOG.warn("failed to get counter result for node {}", dpId, e);
173 return RpcResultBuilder.<GetNodeAggregatedCountersOutput>failed()
174 .withError(ErrorType.APPLICATION, "failed to get node aggregated counters for node " + dpId)
178 gnacob.setCounterResult(aggregatedCounterResults);
179 return RpcResultBuilder.success(gnacob.build()).buildFuture();
183 @SuppressWarnings("checkstyle:illegalCatch")
184 public ListenableFuture<RpcResult<GetNodeConnectorCountersOutput>> getNodeConnectorCounters(
185 GetNodeConnectorCountersInput input) {
186 String portId = input.getPortId();
187 LOG.trace("getting port counters of port {}", portId);
189 Interface interfaceState = InterfaceUtils.getInterfaceStateFromOperDS(db, portId);
190 if (interfaceState == null) {
191 LOG.warn("trying to get counters for non exist port {}", portId);
192 return RpcResultBuilder.<GetNodeConnectorCountersOutput>failed().buildFuture();
195 BigInteger dpId = InterfaceUtils.getDpIdFromInterface(interfaceState);
196 if (interfaceState.getLowerLayerIf() == null || interfaceState.getLowerLayerIf().isEmpty()) {
197 LOG.warn("Lower layer if wasn't found for port {}", portId);
198 return RpcResultBuilder.<GetNodeConnectorCountersOutput>failed().buildFuture();
201 String portNumber = interfaceState.getLowerLayerIf().get(0);
202 portNumber = portNumber.split(":")[2];
203 List<CounterResult> counterResults = new ArrayList<>();
206 if (!getNodeConnectorResult(counterResults, dpId, portNumber)) {
207 StatisticsPluginImplCounters.failed_getting_node_connector_counters.inc();
208 return RpcResultBuilder.<GetNodeConnectorCountersOutput>failed()
209 .withError(ErrorType.APPLICATION, "failed to get port counters").buildFuture();
211 } catch (RuntimeException e) {
212 LOG.warn("failed to get counter result for port {}", portId, e);
215 GetNodeConnectorCountersOutputBuilder gpcob = new GetNodeConnectorCountersOutputBuilder();
216 gpcob.setCounterResult(counterResults);
217 return RpcResultBuilder.success(gpcob.build()).buildFuture();
221 public ListenableFuture<RpcResult<AcquireElementCountersRequestHandlerOutput>> acquireElementCountersRequestHandler(
222 AcquireElementCountersRequestHandlerInput input) {
223 AcquireElementCountersRequestHandlerOutputBuilder aecrhob =
224 new AcquireElementCountersRequestHandlerOutputBuilder();
225 UUID randomNumber = UUID.randomUUID();
226 Integer intRequestKey = allocateId(randomNumber.toString());
227 if (intRequestKey == null) {
228 LOG.warn("failed generating unique request identifier");
229 StatisticsPluginImplCounters.failed_generating_unique_request_id.inc();
230 return RpcResultBuilder.<AcquireElementCountersRequestHandlerOutput>failed()
231 .withError(ErrorType.APPLICATION, "failed generating unique request identifier").buildFuture();
233 String requestKey = String.valueOf(intRequestKey);
234 SettableFuture<RpcResult<AcquireElementCountersRequestHandlerOutput>> result = SettableFuture.create();
236 ListenableFutures.addErrorLogging(
237 txRunner.callWithNewReadWriteTransactionAndSubmit(transaction -> {
238 if (input.getIncomingTraffic() != null) {
239 Optional<EgressElementCountersRequestConfig> eecrcOpt =
240 transaction.read(LogicalDatastoreType.CONFIGURATION,
241 CountersServiceUtils.EECRC_IDENTIFIER).checkedGet();
242 if (!eecrcOpt.isPresent()) {
243 LOG.warn("failed creating incoming traffic counter request data container in DB");
244 StatisticsPluginImplCounters.failed_creating_egress_counter_data_config.inc();
245 result.setFuture(RpcResultBuilder.<AcquireElementCountersRequestHandlerOutput>failed()
246 .withError(ErrorType.APPLICATION,
247 "failed creating egress counter request data container in DB")
251 if (!isIdenticalCounterRequestExist(input.getPortId(), ElementCountersDirection.EGRESS.toString(),
252 input.getIncomingTraffic().getFilters(), eecrcOpt.get().getCounterRequests())) {
253 installCounterSpecificRules(input.getPortId(), getLportTag(input.getPortId()),
254 getDpn(input.getPortId()), ElementCountersDirection.EGRESS,
255 input.getIncomingTraffic().getFilters());
257 putEgressElementCounterRequestInConfig(input, ElementCountersDirection.EGRESS, transaction,
258 requestKey, CountersServiceUtils.EECRC_IDENTIFIER, eecrcOpt, randomNumber.toString());
260 aecrhob.setIncomingTrafficHandler(requestKey);
262 bindCountersServiceIfUnbound(input.getPortId(), ElementCountersDirection.EGRESS);
265 if (input.getOutgoingTraffic() != null) {
266 Optional<IngressElementCountersRequestConfig> iecrcOpt =
267 transaction.read(LogicalDatastoreType.CONFIGURATION,
268 CountersServiceUtils.IECRC_IDENTIFIER).checkedGet();
269 if (!iecrcOpt.isPresent()) {
270 LOG.warn("failed creating outgoing traffc counter request data container in DB");
271 StatisticsPluginImplCounters.failed_creating_ingress_counter_data_config.inc();
272 result.setFuture(RpcResultBuilder.<AcquireElementCountersRequestHandlerOutput>failed()
273 .withError(ErrorType.APPLICATION,
274 "failed creating ingress counter request data container in DB")
278 if (!isIdenticalCounterRequestExist(input.getPortId(), ElementCountersDirection.INGRESS.toString(),
279 input.getOutgoingTraffic().getFilters(), iecrcOpt.get().getCounterRequests())) {
280 installCounterSpecificRules(input.getPortId(), getLportTag(input.getPortId()),
281 getDpn(input.getPortId()), ElementCountersDirection.INGRESS,
282 input.getOutgoingTraffic().getFilters());
284 putIngressElementCounterRequestInConfig(input, ElementCountersDirection.INGRESS, transaction,
285 requestKey, CountersServiceUtils.IECRC_IDENTIFIER, iecrcOpt, randomNumber.toString());
287 aecrhob.setIncomingTrafficHandler(requestKey);
289 bindCountersServiceIfUnbound(input.getPortId(), ElementCountersDirection.INGRESS);
291 result.setFuture(RpcResultBuilder.success(aecrhob.build()).buildFuture());
293 }), LOG, "Error acquiring element counters");
299 public ListenableFuture<RpcResult<ReleaseElementCountersRequestHandlerOutput>> releaseElementCountersRequestHandler(
300 ReleaseElementCountersRequestHandlerInput input) {
301 InstanceIdentifier<CounterRequests> ingressPath =
302 InstanceIdentifier.builder(IngressElementCountersRequestConfig.class)
303 .child(CounterRequests.class, new CounterRequestsKey(input.getHandler())).build();
304 InstanceIdentifier<CounterRequests> egressPath =
305 InstanceIdentifier.builder(EgressElementCountersRequestConfig.class)
306 .child(CounterRequests.class, new CounterRequestsKey(input.getHandler())).build();
308 SettableFuture<RpcResult<ReleaseElementCountersRequestHandlerOutput>> result = SettableFuture.create();
309 ListenableFutures.addErrorLogging(txRunner.callWithNewReadWriteTransactionAndSubmit(tx -> {
310 Optional<IngressElementCountersRequestConfig> iecrcOpt =
311 tx.read(LogicalDatastoreType.CONFIGURATION, CountersServiceUtils.IECRC_IDENTIFIER).checkedGet();
312 Optional<EgressElementCountersRequestConfig> eecrcOpt =
313 tx.read(LogicalDatastoreType.CONFIGURATION, CountersServiceUtils.EECRC_IDENTIFIER).checkedGet();
314 if (!iecrcOpt.isPresent() || !eecrcOpt.isPresent()) {
315 LOG.warn("Couldn't read element counters config data from DB");
316 StatisticsPluginImplCounters.failed_reading_counter_data_from_config.inc();
317 result.setFuture(RpcResultBuilder.<ReleaseElementCountersRequestHandlerOutput>failed()
318 .withError(ErrorType.APPLICATION, "Couldn't read element counters config data from DB")
322 Optional<CounterRequests> ingressRequestOpt =
323 tx.read(LogicalDatastoreType.CONFIGURATION, ingressPath).checkedGet();
324 Optional<CounterRequests> egressRequestOpt =
325 tx.read(LogicalDatastoreType.CONFIGURATION, egressPath).checkedGet();
326 if (!ingressRequestOpt.isPresent() && !egressRequestOpt.isPresent()) {
327 LOG.warn("Handler does not exists");
328 StatisticsPluginImplCounters.unknown_request_handler.inc();
329 result.setFuture(RpcResultBuilder.<ReleaseElementCountersRequestHandlerOutput>failed()
330 .withError(ErrorType.APPLICATION, "Handler does not exists").buildFuture());
333 String generatedKey = null;
334 if (ingressRequestOpt.isPresent()) {
335 handleReleaseTransaction(tx, input, ingressPath, ingressRequestOpt,
336 iecrcOpt.get().getCounterRequests());
337 generatedKey = ingressRequestOpt.get().getGeneratedUniqueId();
339 if (egressRequestOpt.isPresent()) {
340 handleReleaseTransaction(tx, input, egressPath, egressRequestOpt, eecrcOpt.get().getCounterRequests());
341 generatedKey = egressRequestOpt.get().getGeneratedUniqueId();
343 releaseId(generatedKey);
344 result.setFuture(RpcResultBuilder.<ReleaseElementCountersRequestHandlerOutput>success().buildFuture());
345 }), LOG, "Error releasing element counters");
351 public ListenableFuture<RpcResult<GetElementCountersByHandlerOutput>> getElementCountersByHandler(
352 GetElementCountersByHandlerInput input) {
353 InstanceIdentifier<CounterRequests> ingressPath =
354 InstanceIdentifier.builder(IngressElementCountersRequestConfig.class)
355 .child(CounterRequests.class, new CounterRequestsKey(input.getHandler())).build();
356 InstanceIdentifier<CounterRequests> egressPath =
357 InstanceIdentifier.builder(EgressElementCountersRequestConfig.class)
358 .child(CounterRequests.class, new CounterRequestsKey(input.getHandler())).build();
360 ReadOnlyTransaction tx = db.newReadOnlyTransaction();
361 CheckedFuture<Optional<CounterRequests>, ReadFailedException> ingressRequestData =
362 tx.read(LogicalDatastoreType.CONFIGURATION, ingressPath);
363 CheckedFuture<Optional<CounterRequests>, ReadFailedException> egressRequestData =
364 tx.read(LogicalDatastoreType.CONFIGURATION, egressPath);
365 List<CounterResult> counters = new ArrayList<>();
368 if (!ingressRequestData.get().isPresent() && !egressRequestData.get().isPresent()) {
369 LOG.warn("Handler does not exists");
370 return RpcResultBuilder.<GetElementCountersByHandlerOutput>failed()
371 .withError(ErrorType.APPLICATION, "Handler does not exists").buildFuture();
373 if (ingressRequestData.get().isPresent()) {
374 CounterRequests ingressCounterRequest = ingressRequestData.get().get();
375 CounterResultDataStructure ingressCounterResultDS = createElementCountersResult(ingressCounterRequest);
376 if (ingressCounterResultDS == null) {
377 LOG.warn("Unable to get counter results");
378 StatisticsPluginImplCounters.failed_getting_counter_results.inc();
379 return RpcResultBuilder.<GetElementCountersByHandlerOutput>failed()
380 .withError(ErrorType.APPLICATION, "Unable to get counter results").buildFuture();
382 createCounterResults(counters, ingressCounterResultDS, CountersServiceUtils.INGRESS_COUNTER_RESULT_ID);
384 if (egressRequestData.get().isPresent()) {
385 CounterRequests egressCounterRequest = egressRequestData.get().get();
386 CounterResultDataStructure egressCounterResultDS = createElementCountersResult(egressCounterRequest);
387 if (egressCounterResultDS == null) {
388 LOG.warn("Unable to get counter results");
389 StatisticsPluginImplCounters.failed_getting_counter_results.inc();
390 return RpcResultBuilder.<GetElementCountersByHandlerOutput>failed()
391 .withError(ErrorType.APPLICATION, "Unable to get counter results").buildFuture();
393 createCounterResults(counters, egressCounterResultDS, CountersServiceUtils.EGRESS_COUNTER_RESULT_ID);
395 } catch (InterruptedException | ExecutionException e) {
396 LOG.warn("failed to get counter request data from DB");
397 return RpcResultBuilder.<GetElementCountersByHandlerOutput>failed()
398 .withError(ErrorType.APPLICATION, "failed to get counter request data from DB").buildFuture();
401 GetElementCountersByHandlerOutputBuilder gecbhob = new GetElementCountersByHandlerOutputBuilder();
402 gecbhob.setCounterResult(counters);
403 return RpcResultBuilder.success(gecbhob.build()).buildFuture();
407 public void handleInterfaceRemoval(String interfaceId) {
408 CheckedFuture<Optional<IngressElementCountersRequestConfig>, ReadFailedException> iecrc;
409 CheckedFuture<Optional<EgressElementCountersRequestConfig>, ReadFailedException> eecrc;
410 try (ReadOnlyTransaction tx = db.newReadOnlyTransaction()) {
411 iecrc = tx.read(LogicalDatastoreType.CONFIGURATION, CountersServiceUtils.IECRC_IDENTIFIER);
412 eecrc = tx.read(LogicalDatastoreType.CONFIGURATION, CountersServiceUtils.EECRC_IDENTIFIER);
416 Optional<IngressElementCountersRequestConfig> iecrcOpt = iecrc.get();
417 Optional<EgressElementCountersRequestConfig> eecrcOpt = eecrc.get();
418 if (!iecrcOpt.isPresent() || !eecrcOpt.isPresent()) {
419 LOG.warn("Couldn't read element counters config data from DB");
420 StatisticsPluginImplCounters.failed_reading_counter_data_from_config.inc();
423 removeAllElementCounterRequestsOnPort(interfaceId, iecrcOpt.get().getCounterRequests());
424 removeAllElementCounterRequestsOnPort(interfaceId, eecrcOpt.get().getCounterRequests());
425 } catch (InterruptedException | ExecutionException e) {
426 LOG.warn("failed to get counter request data from DB");
427 StatisticsPluginImplCounters.failed_getting_counter_results_port_removal.inc();
433 public ListenableFuture<RpcResult<CleanAllElementCounterRequestsOutput>> cleanAllElementCounterRequests(
434 CleanAllElementCounterRequestsInput input) {
435 ReadOnlyTransaction tx = db.newReadOnlyTransaction();
436 CheckedFuture<Optional<IngressElementCountersRequestConfig>, ReadFailedException> iecrc =
437 tx.read(LogicalDatastoreType.CONFIGURATION, CountersServiceUtils.IECRC_IDENTIFIER);
438 CheckedFuture<Optional<EgressElementCountersRequestConfig>, ReadFailedException> eecrc =
439 tx.read(LogicalDatastoreType.CONFIGURATION, CountersServiceUtils.EECRC_IDENTIFIER);
441 Optional<IngressElementCountersRequestConfig> iecrcOpt = iecrc.get();
442 Optional<EgressElementCountersRequestConfig> eecrcOpt = eecrc.get();
443 if (!iecrcOpt.isPresent() || !eecrcOpt.isPresent()) {
444 LOG.warn("Couldn't read element counters config data from DB");
445 StatisticsPluginImplCounters.failed_reading_counter_data_from_config.inc();
446 return RpcResultBuilder.<CleanAllElementCounterRequestsOutput>failed()
447 .withError(ErrorType.APPLICATION, "Couldn't read element counters config data from DB")
450 Set<String> idsToRelease = new HashSet<>();
451 if (input.getPortId() != null && !input.getPortId().isEmpty()) {
453 .addAll(getAllPortRequestsUniqueIds(input.getPortId(), iecrcOpt.get().getCounterRequests()));
455 .addAll(getAllPortRequestsUniqueIds(input.getPortId(), eecrcOpt.get().getCounterRequests()));
456 removeAllElementCounterRequestsOnPort(input.getPortId(), iecrcOpt.get().getCounterRequests());
457 removeAllElementCounterRequestsOnPort(input.getPortId(), eecrcOpt.get().getCounterRequests());
459 idsToRelease.addAll(getAllRquestsUniqueIds(iecrcOpt.get().getCounterRequests()));
460 idsToRelease.addAll(getAllRquestsUniqueIds(eecrcOpt.get().getCounterRequests()));
461 removeAllElementCounterRequests(iecrcOpt.get().getCounterRequests());
462 removeAllElementCounterRequests(eecrcOpt.get().getCounterRequests());
464 releaseIds(idsToRelease);
465 } catch (InterruptedException | ExecutionException e) {
466 LOG.warn("failed to get counter request data from DB");
467 return RpcResultBuilder.<CleanAllElementCounterRequestsOutput>failed()
468 .withError(ErrorType.APPLICATION, "failed to get counter request data from DB").buildFuture();
471 return RpcResultBuilder.<CleanAllElementCounterRequestsOutput>success().buildFuture();
474 private Set<String> getAllPortRequestsUniqueIds(String interfaceId, List<CounterRequests> counterRequests) {
475 Set<String> result = new HashSet<>();
476 for (CounterRequests counterRequest : counterRequests) {
477 if (counterRequest.getPortId().equals(interfaceId)) {
478 result.add(counterRequest.getGeneratedUniqueId());
484 private Set<String> getAllRquestsUniqueIds(List<CounterRequests> counterRequests) {
485 Set<String> result = new HashSet<>();
486 for (CounterRequests counterRequest : counterRequests) {
487 result.add(counterRequest.getGeneratedUniqueId());
492 private void releaseIds(Set<String> ids) {
493 for (String id : ids) {
498 private void removeAllElementCounterRequestsOnPort(String interfaceId, List<CounterRequests> counterRequests) {
499 unbindCountersServiceIfBound(interfaceId, ElementCountersDirection.INGRESS);
500 unbindCountersServiceIfBound(interfaceId, ElementCountersDirection.EGRESS);
501 if (counterRequests != null) {
502 for (CounterRequests counterRequest : counterRequests) {
503 if (interfaceId.equals(counterRequest.getPortId())) {
504 countersRequestCleanup(counterRequest);
510 private void removeAllElementCounterRequests(List<CounterRequests> counterRequests) {
511 for (CounterRequests counterRequest : counterRequests) {
512 unbindCountersServiceIfBound(counterRequest.getPortId(), ElementCountersDirection.INGRESS);
513 unbindCountersServiceIfBound(counterRequest.getPortId(), ElementCountersDirection.EGRESS);
514 countersRequestCleanup(counterRequest);
518 private void countersRequestCleanup(CounterRequests counterRequest) {
519 ElementCountersDirection direction = ElementCountersDirection.valueOf(counterRequest.getTrafficDirection());
520 deleteCounterSpecificRules(counterRequest.getPortId(), counterRequest.getLportTag(), counterRequest.getDpn(),
521 direction, counterRequest.getFilters());
522 deleteCounterRequest(counterRequest, direction);
525 private void deleteCounterSpecificRules(String portId, int lportTag, BigInteger dpn,
526 ElementCountersDirection direction, Filters filters) {
527 List<ElementCountersRequest> ecrList = createElementCounterRequest(portId, lportTag, dpn, direction, filters);
528 for (ElementCountersRequest ecr : ecrList) {
529 if (ElementCountersDirection.INGRESS.equals(ecr.getDirection())) {
530 IngressCountersServiceImpl icsi = new IngressCountersServiceImpl(db, interfaceManager, mdsalApiManager);
531 icsi.deleteCounterRules(ecr);
532 } else if (ElementCountersDirection.EGRESS.equals(ecr.getDirection())) {
533 EgressCountersServiceImpl ecsi = new EgressCountersServiceImpl(db, interfaceManager, mdsalApiManager);
534 ecsi.deleteCounterRules(ecr);
539 private void deleteCounterRequest(CounterRequests counterRequest, ElementCountersDirection direction) {
540 ListenableFutures.addErrorLogging(
541 txRunner.callWithNewWriteOnlyTransactionAndSubmit(tx -> {
542 if (ElementCountersDirection.INGRESS.equals(direction)) {
543 tx.delete(LogicalDatastoreType.CONFIGURATION, InstanceIdentifier
544 .builder(IngressElementCountersRequestConfig.class)
545 .child(CounterRequests.class,
546 new CounterRequestsKey(counterRequest.key().getRequestId()))
548 } else if (ElementCountersDirection.EGRESS.equals(direction)) {
549 tx.delete(LogicalDatastoreType.CONFIGURATION, InstanceIdentifier
550 .builder(EgressElementCountersRequestConfig.class)
551 .child(CounterRequests.class,
552 new CounterRequestsKey(counterRequest.key().getRequestId()))
555 }), LOG, "Error deleting counter");
558 private CounterResultDataStructure createElementCountersResult(CounterRequests counterRequest) {
559 ElementCountersRequest ecr =
560 createElementCounterRequest(counterRequest.getPortId(), counterRequest.getLportTag(),
561 counterRequest.getDpn(), ElementCountersDirection.valueOf(counterRequest.getTrafficDirection()),
562 counterRequest.getFilters()).iterator().next();
563 BigInteger dpId = getDpn(ecr.getPortId());
564 InterfaceInfo interfaceInfo = interfaceManager.getInterfaceInfo(ecr.getPortId());
565 if (interfaceInfo == null) {
568 int lportTag = interfaceInfo.getInterfaceTag();
569 List<MatchInfoBase> matches = CountersServiceUtils.getCounterFlowMatch(ecr, lportTag,
570 ElementCountersDirection.valueOf(counterRequest.getTrafficDirection()));
571 Match match = MDSALUtil.buildMatches(matches);
572 return counterRetriever.getSwitchFlowCountersDirect(dpId, match);
575 private void initializeCountrsConfigDataSrore() {
576 ListenableFutures.addErrorLogging(
577 txRunner.callWithNewReadWriteTransactionAndSubmit(transaction -> {
578 Optional<IngressElementCountersRequestConfig> iecrcOpt =
579 transaction.read(LogicalDatastoreType.CONFIGURATION,
580 CountersServiceUtils.IECRC_IDENTIFIER).checkedGet();
581 Optional<EgressElementCountersRequestConfig> eecrcOpt =
582 transaction.read(LogicalDatastoreType.CONFIGURATION,
583 CountersServiceUtils.EECRC_IDENTIFIER).checkedGet();
584 if (!iecrcOpt.isPresent()) {
585 creatIngressEelementCountersContainerInConfig(transaction,
586 CountersServiceUtils.IECRC_IDENTIFIER);
588 if (!eecrcOpt.isPresent()) {
589 creatEgressEelementCountersContainerInConfig(transaction,
590 CountersServiceUtils.EECRC_IDENTIFIER);
592 }), LOG, "Failed to create counters in config datastore");
595 private void handleReleaseTransaction(WriteTransaction transaction, ReleaseElementCountersRequestHandlerInput input,
596 InstanceIdentifier<CounterRequests> path, Optional<CounterRequests> requestData,
597 List<CounterRequests> counterRequests) {
598 transaction.delete(LogicalDatastoreType.CONFIGURATION, path);
599 CounterRequests counterRequest = requestData.get();
600 if (shouldUnbindCountersService(counterRequest.getPortId(), counterRequest.key().getRequestId(),
602 unbindCountersServiceIfBound(counterRequest.getPortId(),
603 ElementCountersDirection.valueOf(counterRequest.getTrafficDirection()));
605 if (!isIdenticalCounterRequestExist(input.getHandler(), counterRequest.getPortId(),
606 counterRequest.getTrafficDirection(), counterRequest.getFilters(), counterRequests)) {
607 deleteCounterSpecificRules(counterRequest.getPortId(), counterRequest.getLportTag(),
608 counterRequest.getDpn(), ElementCountersDirection.valueOf(counterRequest.getTrafficDirection()),
609 counterRequest.getFilters());
613 private boolean getNodeConnectorResult(List<CounterResult> counters, BigInteger dpId, String portNumber) {
614 CounterResultDataStructure counterResultDS =
615 counterRetriever.getNodeConnectorCountersDirect(new NodeId(CountersUtils.getNodeId(dpId)),
616 new NodeConnectorId(CountersUtils.getNodeConnectorId(dpId, portNumber)));
617 if (counterResultDS == null) {
621 CounterResultBuilder crb = new CounterResultBuilder();
622 String resultId = CountersUtils.getNodeConnectorId(dpId, portNumber);
625 createGroups(counters, counterResultDS, crb, resultId);
627 return !counters.isEmpty();
630 private boolean getNodeResult(List<CounterResult> counters, BigInteger dpId) {
631 InstanceIdentifier<Node> nodeInstanceIdentifier = InstanceIdentifier.builder(Nodes.class)
632 .child(Node.class, new NodeKey(new NodeId(CountersUtils.getNodeId(dpId)))).build();
633 Optional<Node> nodeOptional = MDSALUtil.read(db, LogicalDatastoreType.OPERATIONAL, nodeInstanceIdentifier);
634 if (!nodeOptional.isPresent()) {
638 Node node = nodeOptional.get();
639 CounterResultDataStructure counterResultDS = counterRetriever.getNodeCountersDirect(node);
640 if (counterResultDS == null) {
644 createCounterResults(counters, counterResultDS);
646 return !counters.isEmpty();
649 private boolean getNodeAggregatedResult(List<CounterResult> aggregatedCounters, BigInteger dpId) {
650 InstanceIdentifier<Node> nodeInstanceIdentifier = InstanceIdentifier.builder(Nodes.class)
651 .child(Node.class, new NodeKey(new NodeId(CountersUtils.getNodeId(dpId)))).build();
652 Optional<Node> nodeOptional = MDSALUtil.read(db, LogicalDatastoreType.OPERATIONAL, nodeInstanceIdentifier);
653 if (!nodeOptional.isPresent()) {
657 Node node = nodeOptional.get();
658 CounterResultDataStructure counters = counterRetriever.getNodeCountersDirect(node);
659 if (counters == null || counters.isEmpty()) {
663 CounterResultDataStructure aggregatedResultsDS =
664 CountersUtils.aggregateCounters(counters, CountersUtils.getNodeId(dpId));
665 createCounterResults(aggregatedCounters, aggregatedResultsDS);
666 return !aggregatedCounters.isEmpty();
670 private void createCounterResults(List<CounterResult> counters, CounterResultDataStructure counterResultDS) {
671 for (String counterResultId : counterResultDS.getResults().keySet()) {
672 CounterResultBuilder crb = new CounterResultBuilder();
673 crb.setId(counterResultId);
674 createGroups(counters, counterResultDS, crb, counterResultId);
678 private void createCounterResults(List<CounterResult> counters, CounterResultDataStructure counterResultDS,
680 for (String counterResultId : counterResultDS.getResults().keySet()) {
681 CounterResultBuilder crb = new CounterResultBuilder();
683 createGroups(counters, counterResultDS, crb, counterResultId);
687 private void createGroups(List<CounterResult> counters, CounterResultDataStructure counterResultDS,
688 CounterResultBuilder crb, String resultId) {
689 List<Groups> groups = new ArrayList<>();
690 Map<String, Map<String, BigInteger>> counterGroups = counterResultDS.getGroups(resultId);
691 if (counterGroups != null && !counterGroups.isEmpty()) {
692 for (Entry<String, Map<String, BigInteger>> entry : counterGroups.entrySet()) {
693 String groupName = entry.getKey();
694 groups.add(createGroupsResult(groupName, entry.getValue()));
696 crb.setGroups(groups);
697 counters.add(crb.build());
701 private Groups createGroupsResult(String groupName, Map<String, BigInteger> countersMap) {
702 GroupsBuilder gb = new GroupsBuilder();
703 gb.setName(groupName);
705 Map<String, Counters> counters = new HashMap<>();
706 List<Counters> countersList = new ArrayList<>();
707 for (String counterName : countersMap.keySet()) {
708 addCountersToMap(countersMap, counters, counterName);
710 for (Counters counter : counters.values()) {
711 countersList.add(counter);
714 gb.setCounters(countersList);
718 private Counters buildCounter(String counterName, BigInteger value, Counters prevCounter) {
719 BigInteger prevValue = BigInteger.ZERO;
720 if (prevCounter != null) {
721 prevValue = prevCounter.getValue();
723 CountersBuilder cb = new CountersBuilder();
724 cb.setName(counterName);
725 cb.setValue(value.add(prevValue));
729 private void addCountersToMap(Map<String, BigInteger> result, Map<String, Counters> counters, String counterName) {
730 counters.put(counterName, buildCounter(counterName, result.get(counterName), counters.get(counterName)));
733 private void addElementCounterRequest(List<ElementCountersRequest> ecrList, String portId, int lportTag,
734 BigInteger dpn, ElementCountersDirection direction, Filters filters) {
735 ElementCountersRequest ecr = new ElementCountersRequest(portId);
736 ecr.setLportTag(lportTag);
738 ecr.setElementCountersDirection(direction);
739 if (filters.getIpFilter() != null) {
740 String ip = filters.getIpFilter().getIp();
742 ecr.addFilterToFilterGroup(CountersUtils.ELEMENT_COUNTERS_IP_FILTER_GROUP_NAME,
743 CountersUtils.IP_FILTER_NAME, ip);
747 boolean isTcpPortExist = false;
748 if (filters.getTcpFilter() != null && filters.getTcpFilter().isOn()) {
749 TcpFilter tcpFilter = filters.getTcpFilter();
750 int srcPort = tcpFilter.getSrcPort();
751 int dstPort = tcpFilter.getDstPort();
753 isTcpPortExist = true;
754 ecr.addFilterToFilterGroup(CountersUtils.ELEMENT_COUNTERS_TCP_FILTER_GROUP_NAME,
755 CountersUtils.TCP_SRC_PORT_FILTER_NAME, String.valueOf(srcPort));
758 isTcpPortExist = true;
759 ecr.addFilterToFilterGroup(CountersUtils.ELEMENT_COUNTERS_TCP_FILTER_GROUP_NAME,
760 CountersUtils.TCP_DST_PORT_FILTER_NAME, String.valueOf(dstPort));
762 if (!isTcpPortExist) {
763 ecr.addFilterToFilterGroup(CountersUtils.ELEMENT_COUNTERS_TCP_FILTER_GROUP_NAME,
764 CountersUtils.TCP_FILTER_NAME, "");
767 } else if (filters.getUdpFilter() != null && filters.getUdpFilter().isOn()) {
768 UdpFilter udpFilter = filters.getUdpFilter();
769 int srcPort = udpFilter.getSrcPort();
770 int dstPort = udpFilter.getDstPort();
772 isTcpPortExist = true;
773 ecr.addFilterToFilterGroup(CountersUtils.ELEMENT_COUNTERS_UDP_FILTER_GROUP_NAME,
774 CountersUtils.UDP_SRC_PORT_FILTER_NAME, String.valueOf(srcPort));
777 isTcpPortExist = true;
778 ecr.addFilterToFilterGroup(CountersUtils.ELEMENT_COUNTERS_UDP_FILTER_GROUP_NAME,
779 CountersUtils.UDP_DST_PORT_FILTER_NAME, String.valueOf(dstPort));
781 if (!isTcpPortExist) {
782 ecr.addFilterToFilterGroup(CountersUtils.ELEMENT_COUNTERS_UDP_FILTER_GROUP_NAME,
783 CountersUtils.UDP_FILTER_NAME, "");
787 if (!ecr.getFilters().isEmpty()) {
792 @SuppressFBWarnings("SLF4J_FORMAT_SHOULD_BE_CONST")
793 private void logElementCounterRequests(List<ElementCountersRequest> ecrList) {
794 for (ElementCountersRequest counterRequest : ecrList) {
795 LOG.debug(counterRequest.toString());
799 private void bindCountersServiceIfUnbound(String interfaceId, ElementCountersDirection direction) {
800 if (ElementCountersDirection.INGRESS.equals(direction) && !interfaceManager.isServiceBoundOnInterfaceForIngress(
801 CountersServiceUtils.INGRESS_COUNTERS_SERVICE_INDEX, interfaceId)) {
802 IngressCountersServiceImpl icsi = new IngressCountersServiceImpl(db, interfaceManager, mdsalApiManager);
803 icsi.bindService(interfaceId);
804 StatisticsPluginImplCounters.ingress_counters_service_bind.inc();
805 } else if (ElementCountersDirection.EGRESS.equals(direction) && !interfaceManager
806 .isServiceBoundOnInterfaceForEgress(CountersServiceUtils.EGRESS_COUNTERS_SERVICE_INDEX, interfaceId)) {
807 EgressCountersServiceImpl ecsi = new EgressCountersServiceImpl(db, interfaceManager, mdsalApiManager);
808 ecsi.bindService(interfaceId);
809 StatisticsPluginImplCounters.egress_counters_service_bind.inc();
813 private void unbindCountersServiceIfBound(String interfaceId, ElementCountersDirection direction) {
814 if (ElementCountersDirection.INGRESS.equals(direction) && interfaceManager.isServiceBoundOnInterfaceForIngress(
815 CountersServiceUtils.INGRESS_COUNTERS_SERVICE_INDEX, interfaceId)) {
816 IngressCountersServiceImpl icsi = new IngressCountersServiceImpl(db, interfaceManager, mdsalApiManager);
817 icsi.unBindService(interfaceId);
818 StatisticsPluginImplCounters.ingress_counters_service_unbind.inc();
819 } else if (ElementCountersDirection.EGRESS.equals(direction) && interfaceManager
820 .isServiceBoundOnInterfaceForEgress(CountersServiceUtils.EGRESS_COUNTERS_SERVICE_INDEX, interfaceId)) {
821 EgressCountersServiceImpl ecsi = new EgressCountersServiceImpl(db, interfaceManager, mdsalApiManager);
822 ecsi.unBindService(interfaceId);
823 StatisticsPluginImplCounters.egress_counters_service_unbind.inc();
827 private boolean shouldUnbindCountersService(String portId, String requesId, List<CounterRequests> counterRequests) {
828 for (CounterRequests counterRequest : counterRequests) {
829 if (portId.equals(counterRequest.getPortId()) && !requesId.equals(counterRequest.key().getRequestId())) {
836 private void installCounterSpecificRules(String portId, int lportTag, BigInteger dpn,
837 ElementCountersDirection direction, Filters filters) {
838 List<ElementCountersRequest> ecrList = createElementCounterRequest(portId, lportTag, dpn, direction, filters);
839 for (ElementCountersRequest ecr : ecrList) {
840 if (ElementCountersDirection.INGRESS.equals(ecr.getDirection())) {
841 IngressCountersServiceImpl icsi = new IngressCountersServiceImpl(db, interfaceManager, mdsalApiManager);
842 icsi.installCounterRules(ecr);
843 } else if (ElementCountersDirection.EGRESS.equals(ecr.getDirection())) {
844 EgressCountersServiceImpl ecsi = new EgressCountersServiceImpl(db, interfaceManager, mdsalApiManager);
845 ecsi.installCounterRules(ecr);
850 private boolean areFiltersEqual(Filters filterGroup1, Filters filterGroup2) {
851 if (filterGroup1 == null && filterGroup2 == null) {
854 if (filterGroup1 == null || filterGroup2 == null) {
858 return filterGroup1.toString().equals(filterGroup2.toString());
861 private void putIngressElementCounterRequestInConfig(AcquireElementCountersRequestHandlerInput input,
862 ElementCountersDirection direcion, ReadWriteTransaction transaction, String requestKey,
863 InstanceIdentifier<IngressElementCountersRequestConfig> ecrcIdentifier,
864 Optional<IngressElementCountersRequestConfig> iecrcOpt, String generatedUniqueId) {
865 IngressElementCountersRequestConfig requestConfig = iecrcOpt.get();
866 CounterRequestsBuilder crb = new CounterRequestsBuilder();
867 crb.setRequestId(requestKey);
868 crb.withKey(new CounterRequestsKey(requestKey));
869 crb.setFilters(input.getOutgoingTraffic().getFilters());
870 crb.setPortId(input.getPortId());
871 crb.setLportTag(getLportTag(input.getPortId()));
872 crb.setDpn(getDpn(input.getPortId()));
873 crb.setTrafficDirection(direcion.toString());
874 crb.setGeneratedUniqueId(generatedUniqueId);
875 List<CounterRequests> counterRequests = requestConfig.getCounterRequests();
876 counterRequests.add(crb.build());
878 IngressElementCountersRequestConfigBuilder ecrcb = new IngressElementCountersRequestConfigBuilder();
879 ecrcb.setCounterRequests(counterRequests);
880 requestConfig = ecrcb.build();
881 transaction.put(LogicalDatastoreType.CONFIGURATION, ecrcIdentifier, requestConfig,
882 WriteTransaction.CREATE_MISSING_PARENTS);
885 private void putEgressElementCounterRequestInConfig(AcquireElementCountersRequestHandlerInput input,
886 ElementCountersDirection direcion, ReadWriteTransaction transaction, String requestKey,
887 InstanceIdentifier<EgressElementCountersRequestConfig> ecrcIdentifier,
888 Optional<EgressElementCountersRequestConfig> eecrcOpt, String generatedUniqueId) {
889 EgressElementCountersRequestConfig requestConfig = eecrcOpt.get();
890 CounterRequestsBuilder crb = new CounterRequestsBuilder();
891 crb.setRequestId(requestKey);
892 crb.withKey(new CounterRequestsKey(requestKey));
893 crb.setFilters(input.getIncomingTraffic().getFilters());
894 crb.setPortId(input.getPortId());
895 crb.setLportTag(getLportTag(input.getPortId()));
896 crb.setDpn(getDpn(input.getPortId()));
897 crb.setTrafficDirection(direcion.toString());
898 crb.setGeneratedUniqueId(generatedUniqueId);
899 List<CounterRequests> counterRequests = requestConfig.getCounterRequests();
900 counterRequests.add(crb.build());
902 EgressElementCountersRequestConfigBuilder ecrcb = new EgressElementCountersRequestConfigBuilder();
903 ecrcb.setCounterRequests(counterRequests);
904 requestConfig = ecrcb.build();
905 transaction.put(LogicalDatastoreType.CONFIGURATION, ecrcIdentifier, requestConfig,
906 WriteTransaction.CREATE_MISSING_PARENTS);
909 private void creatIngressEelementCountersContainerInConfig(ReadWriteTransaction transaction,
910 InstanceIdentifier<IngressElementCountersRequestConfig> ecrcIdentifier) {
911 IngressElementCountersRequestConfigBuilder iecrcb = new IngressElementCountersRequestConfigBuilder();
912 List<CounterRequests> counterRequests = new ArrayList<>();
913 iecrcb.setCounterRequests(counterRequests);
914 IngressElementCountersRequestConfig iecrc = iecrcb.build();
915 transaction.put(LogicalDatastoreType.CONFIGURATION, ecrcIdentifier, iecrc,
916 WriteTransaction.CREATE_MISSING_PARENTS);
919 private void creatEgressEelementCountersContainerInConfig(ReadWriteTransaction transaction,
920 InstanceIdentifier<EgressElementCountersRequestConfig> ecrcIdentifier) {
921 EgressElementCountersRequestConfigBuilder eecrcb = new EgressElementCountersRequestConfigBuilder();
922 List<CounterRequests> counterRequests = new ArrayList<>();
923 eecrcb.setCounterRequests(counterRequests);
924 EgressElementCountersRequestConfig eecrc = eecrcb.build();
925 transaction.put(LogicalDatastoreType.CONFIGURATION, ecrcIdentifier, eecrc,
926 WriteTransaction.CREATE_MISSING_PARENTS);
929 private Integer allocateId(String idKey) {
931 AllocateIdInput getIdInput = new AllocateIdInputBuilder().setPoolName(CountersServiceUtils.COUNTERS_PULL_NAME)
932 .setIdKey(idKey).build();
934 Future<RpcResult<AllocateIdOutput>> result = idManagerService.allocateId(getIdInput);
935 RpcResult<AllocateIdOutput> rpcResult = result.get();
936 if (rpcResult.isSuccessful()) {
937 return rpcResult.getResult().getIdValue().intValue();
939 LOG.warn("RPC Call to Get Unique Id returned with Errors {}", rpcResult.getErrors());
941 } catch (InterruptedException | ExecutionException e) {
942 LOG.warn("Exception when getting Unique Id", e);
947 private void createIdPool() {
948 if (checkPoolExists()) {
951 CreateIdPoolInput createPool = new CreateIdPoolInputBuilder()
952 .setPoolName(CountersServiceUtils.COUNTERS_PULL_NAME).setLow(CountersServiceUtils.COUNTERS_PULL_START)
953 .setHigh(CountersServiceUtils.COUNTERS_PULL_START + CountersServiceUtils.COUNTERS_PULL_END).build();
954 ListenableFuture<RpcResult<CreateIdPoolOutput>> result = idManagerService.createIdPool(createPool);
955 Futures.addCallback(result, new FutureCallback<RpcResult<CreateIdPoolOutput>>() {
958 public void onFailure(Throwable error) {
959 LOG.error("Failed to create idPool for Aliveness Monitor Service", error);
963 public void onSuccess(@Nonnull RpcResult<CreateIdPoolOutput> rpcResult) {
964 if (rpcResult.isSuccessful()) {
965 LOG.debug("Created IdPool for tap");
967 LOG.error("RPC to create Idpool failed {}", rpcResult.getErrors());
970 }, MoreExecutors.directExecutor());
973 private void releaseId(String idKey) {
974 ReleaseIdInput idInput = new ReleaseIdInputBuilder().setPoolName(CountersServiceUtils.COUNTERS_PULL_NAME)
975 .setIdKey(idKey).build();
977 RpcResult<ReleaseIdOutput> rpcResult = idManagerService.releaseId(idInput).get();
978 if (!rpcResult.isSuccessful()) {
979 LOG.warn("RPC Call to release Id with Key {} returned with Errors {}", idKey, rpcResult.getErrors());
981 } catch (InterruptedException | ExecutionException e) {
982 LOG.warn("Exception when releasing Id for key {}", idKey, e);
986 private boolean checkPoolExists() {
987 ReadOnlyTransaction roTransaction = db.newReadOnlyTransaction();
988 InstanceIdentifier<IdPool> path = InstanceIdentifier.create(IdPools.class).child(IdPool.class,
989 new IdPoolKey(CountersServiceUtils.COUNTERS_PULL_NAME));
990 CheckedFuture<Optional<IdPool>, ReadFailedException> pool =
991 roTransaction.read(LogicalDatastoreType.CONFIGURATION, path);
993 Optional<IdPool> poolOpt = pool.get();
994 if (poolOpt.isPresent()) {
997 } catch (InterruptedException | ExecutionException e) {
1003 private boolean isIdenticalCounterRequestExist(String portId, String dirction, Filters filters,
1004 List<CounterRequests> counterRequests) {
1005 if (counterRequests.isEmpty()) {
1009 for (CounterRequests counterRequest : counterRequests) {
1010 if (portId.equals(counterRequest.getPortId()) && dirction.equals(counterRequest.getTrafficDirection())) {
1011 if (areFiltersEqual(filters, counterRequest.getFilters())) {
1019 private boolean isIdenticalCounterRequestExist(String requesId, String portId, String dirction, Filters filters,
1020 List<CounterRequests> counterRequests) {
1021 if (counterRequests.isEmpty()) {
1025 for (CounterRequests counterRequest : counterRequests) {
1026 if (portId.equals(counterRequest.getPortId()) && dirction.equals(counterRequest.getTrafficDirection())
1027 && !counterRequest.key().getRequestId().equals(requesId)) {
1028 if (areFiltersEqual(filters, counterRequest.getFilters())) {
1036 private int getLportTag(String interfaceId) {
1037 return interfaceManager.getInterfaceInfo(interfaceId).getInterfaceTag();
1040 private BigInteger getDpn(String interfaceId) {
1041 return interfaceManager.getDpnForInterface(interfaceId);
1044 private List<ElementCountersRequest> createElementCounterRequest(String portId, int lportTag, BigInteger dpn,
1045 ElementCountersDirection direcrtion, Filters filters) {
1046 List<ElementCountersRequest> ecrList = new ArrayList<>();
1047 LOG.debug("getting element counters for port {}", portId);
1048 addElementCounterRequest(ecrList, portId, lportTag, dpn, direcrtion, filters);
1050 logElementCounterRequests(ecrList);
1055 enum StatisticsPluginImplCounters {
1056 failed_getting_node_counters, //
1057 failed_getting_node_connector_counters, //
1058 failed_getting_aggregated_node_counters, //
1059 failed_generating_unique_request_id, //
1060 unknown_request_handler, //
1061 failed_creating_ingress_counter_data_config, //
1062 failed_creating_egress_counter_data_config, //
1063 failed_reading_counter_data_from_config, //
1064 failed_getting_counter_results, //
1065 failed_creating_counters_config, //
1066 failed_getting_counter_results_port_removal, //
1067 ingress_counters_service_bind, //
1068 egress_counters_service_bind, //
1069 ingress_counters_service_unbind, //
1070 egress_counters_service_unbind, //
1072 private final OccurenceCounter counter;
1074 StatisticsPluginImplCounters() {
1075 counter = new OccurenceCounter(getClass().getEnclosingClass().getSimpleName(), name(), "");