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.util.concurrent.CheckedFuture;
11 import com.google.common.util.concurrent.FutureCallback;
12 import com.google.common.util.concurrent.Futures;
13 import com.google.common.util.concurrent.ListenableFuture;
14 import com.google.common.util.concurrent.MoreExecutors;
15 import com.google.common.util.concurrent.SettableFuture;
16 import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
17 import java.math.BigInteger;
18 import java.util.ArrayList;
19 import java.util.HashMap;
20 import java.util.HashSet;
21 import java.util.List;
23 import java.util.Map.Entry;
24 import java.util.Optional;
26 import java.util.UUID;
27 import java.util.concurrent.ExecutionException;
28 import java.util.concurrent.Future;
29 import org.eclipse.jdt.annotation.NonNull;
30 import org.opendaylight.genius.infra.ManagedNewTransactionRunner;
31 import org.opendaylight.genius.infra.ManagedNewTransactionRunnerImpl;
32 import org.opendaylight.genius.interfacemanager.globals.InterfaceInfo;
33 import org.opendaylight.genius.interfacemanager.interfaces.IInterfaceManager;
34 import org.opendaylight.genius.mdsalutil.MDSALUtil;
35 import org.opendaylight.genius.mdsalutil.MatchInfoBase;
36 import org.opendaylight.genius.mdsalutil.interfaces.IMdsalApiManager;
37 import org.opendaylight.infrautils.utils.concurrent.ListenableFutures;
38 import org.opendaylight.mdsal.binding.api.DataBroker;
39 import org.opendaylight.mdsal.binding.api.ReadTransaction;
40 import org.opendaylight.mdsal.binding.api.ReadWriteTransaction;
41 import org.opendaylight.mdsal.binding.api.WriteTransaction;
42 import org.opendaylight.mdsal.common.api.LogicalDatastoreType;
43 import org.opendaylight.mdsal.common.api.ReadFailedException;
44 import org.opendaylight.netvirt.statistics.api.ICountersInterfaceChangeHandler;
45 import org.opendaylight.netvirt.vpnmanager.api.InterfaceUtils;
46 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface;
47 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.Match;
48 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.AllocateIdInput;
49 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.AllocateIdInputBuilder;
50 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.AllocateIdOutput;
51 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.CreateIdPoolInput;
52 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.CreateIdPoolInputBuilder;
53 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.CreateIdPoolOutput;
54 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.IdManagerService;
55 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.IdPools;
56 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.ReleaseIdInput;
57 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.ReleaseIdInputBuilder;
58 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.ReleaseIdOutput;
59 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.id.pools.IdPool;
60 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.id.pools.IdPoolKey;
61 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorId;
62 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId;
63 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.Nodes;
64 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
65 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeKey;
66 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.statistics.rev170120.AcquireElementCountersRequestHandlerInput;
67 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.statistics.rev170120.AcquireElementCountersRequestHandlerOutput;
68 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.statistics.rev170120.AcquireElementCountersRequestHandlerOutputBuilder;
69 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.statistics.rev170120.CleanAllElementCounterRequestsInput;
70 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.statistics.rev170120.CleanAllElementCounterRequestsOutput;
71 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.statistics.rev170120.EgressElementCountersRequestConfig;
72 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.statistics.rev170120.EgressElementCountersRequestConfigBuilder;
73 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.statistics.rev170120.GetElementCountersByHandlerInput;
74 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.statistics.rev170120.GetElementCountersByHandlerOutput;
75 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.statistics.rev170120.GetElementCountersByHandlerOutputBuilder;
76 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.statistics.rev170120.GetNodeAggregatedCountersInput;
77 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.statistics.rev170120.GetNodeAggregatedCountersOutput;
78 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.statistics.rev170120.GetNodeAggregatedCountersOutputBuilder;
79 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.statistics.rev170120.GetNodeConnectorCountersInput;
80 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.statistics.rev170120.GetNodeConnectorCountersOutput;
81 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.statistics.rev170120.GetNodeConnectorCountersOutputBuilder;
82 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.statistics.rev170120.GetNodeCountersInput;
83 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.statistics.rev170120.GetNodeCountersOutput;
84 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.statistics.rev170120.GetNodeCountersOutputBuilder;
85 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.statistics.rev170120.IngressElementCountersRequestConfig;
86 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.statistics.rev170120.IngressElementCountersRequestConfigBuilder;
87 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.statistics.rev170120.ReleaseElementCountersRequestHandlerInput;
88 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.statistics.rev170120.ReleaseElementCountersRequestHandlerOutput;
89 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.statistics.rev170120.StatisticsService;
90 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.statistics.rev170120.counterrequestsconfig.CounterRequests;
91 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.statistics.rev170120.counterrequestsconfig.CounterRequestsBuilder;
92 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.statistics.rev170120.counterrequestsconfig.CounterRequestsKey;
93 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.statistics.rev170120.elementrequestdata.Filters;
94 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.statistics.rev170120.elementrequestdata.filters.TcpFilter;
95 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.statistics.rev170120.elementrequestdata.filters.UdpFilter;
96 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.statistics.rev170120.result.CounterResult;
97 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.statistics.rev170120.result.CounterResultBuilder;
98 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.statistics.rev170120.result.counterresult.Groups;
99 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.statistics.rev170120.result.counterresult.GroupsBuilder;
100 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.statistics.rev170120.result.counterresult.groups.Counters;
101 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.statistics.rev170120.result.counterresult.groups.CountersBuilder;
102 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
103 import org.opendaylight.yangtools.yang.common.RpcError.ErrorType;
104 import org.opendaylight.yangtools.yang.common.RpcResult;
105 import org.opendaylight.yangtools.yang.common.RpcResultBuilder;
106 import org.slf4j.Logger;
107 import org.slf4j.LoggerFactory;
109 public class StatisticsImpl implements StatisticsService, ICountersInterfaceChangeHandler {
110 private static final Logger LOG = LoggerFactory.getLogger(StatisticsImpl.class);
111 private final DataBroker db;
112 private final ManagedNewTransactionRunner txRunner;
113 private final CounterRetriever counterRetriever;
114 private final IInterfaceManager interfaceManager;
115 private final IMdsalApiManager mdsalApiManager;
116 private final IdManagerService idManagerService;
117 private final StatisticsCounters statisticsCounters;
119 public StatisticsImpl(DataBroker db, CounterRetriever counterRetriever, IInterfaceManager interfaceManager,
120 IMdsalApiManager mdsalApiManager, IdManagerService idManagerService,
121 StatisticsCounters statisticsCounters) {
123 this.txRunner = new ManagedNewTransactionRunnerImpl(db);
124 this.counterRetriever = counterRetriever;
125 this.interfaceManager = interfaceManager;
126 this.mdsalApiManager = mdsalApiManager;
127 this.idManagerService = idManagerService;
128 this.statisticsCounters = statisticsCounters;
129 initializeCountrsConfigDataSrore();
133 @SuppressWarnings("checkstyle:illegalCatch")
134 public ListenableFuture<RpcResult<GetNodeCountersOutput>> getNodeCounters(GetNodeCountersInput input) {
135 BigInteger dpId = input.getNodeId();
136 LOG.trace("getting node counters for node {}", dpId);
137 GetNodeCountersOutputBuilder gncob = new GetNodeCountersOutputBuilder();
139 List<CounterResult> counterResults = new ArrayList<>();
141 if (!getNodeResult(counterResults, dpId)) {
142 statisticsCounters.failedGettingNodeCounters();
143 return RpcResultBuilder.<GetNodeCountersOutput>failed()
144 .withError(ErrorType.APPLICATION, "failed to get node counters for node: " + dpId)
147 } catch (RuntimeException e) {
148 LOG.warn("failed to get counter result for node {}", dpId, e);
149 return RpcResultBuilder.<GetNodeCountersOutput>failed()
150 .withError(ErrorType.APPLICATION, "failed to get node counters for node: " + dpId).buildFuture();
153 gncob.setCounterResult(counterResults);
154 return RpcResultBuilder.success(gncob.build()).buildFuture();
158 @SuppressWarnings("checkstyle:illegalCatch")
159 public ListenableFuture<RpcResult<GetNodeAggregatedCountersOutput>> getNodeAggregatedCounters(
160 GetNodeAggregatedCountersInput input) {
161 BigInteger dpId = input.getNodeId();
162 LOG.trace("getting aggregated node counters for node {}", dpId);
163 GetNodeAggregatedCountersOutputBuilder gnacob = new GetNodeAggregatedCountersOutputBuilder();
165 List<CounterResult> aggregatedCounterResults = new ArrayList<>();
167 if (!getNodeAggregatedResult(aggregatedCounterResults, dpId)) {
168 statisticsCounters.failedGettingAggregatedNodeCounters();
169 return RpcResultBuilder.<GetNodeAggregatedCountersOutput>failed()
170 .withError(ErrorType.APPLICATION, "failed to get node aggregated counters for node " + dpId)
173 } catch (Exception e) {
174 LOG.warn("failed to get counter result for node {}", dpId, e);
175 return RpcResultBuilder.<GetNodeAggregatedCountersOutput>failed()
176 .withError(ErrorType.APPLICATION, "failed to get node aggregated counters for node " + dpId)
180 gnacob.setCounterResult(aggregatedCounterResults);
181 return RpcResultBuilder.success(gnacob.build()).buildFuture();
185 @SuppressWarnings("checkstyle:illegalCatch")
186 public ListenableFuture<RpcResult<GetNodeConnectorCountersOutput>> getNodeConnectorCounters(
187 GetNodeConnectorCountersInput input) {
188 String portId = input.getPortId();
189 LOG.trace("getting port counters of port {}", portId);
191 Interface interfaceState = InterfaceUtils.getInterfaceStateFromOperDS(db, portId);
192 if (interfaceState == null) {
193 LOG.warn("trying to get counters for non exist port {}", portId);
194 return RpcResultBuilder.<GetNodeConnectorCountersOutput>failed().buildFuture();
197 BigInteger dpId = InterfaceUtils.getDpIdFromInterface(interfaceState);
198 if (interfaceState.getLowerLayerIf() == null || interfaceState.getLowerLayerIf().isEmpty()) {
199 LOG.warn("Lower layer if wasn't found for port {}", portId);
200 return RpcResultBuilder.<GetNodeConnectorCountersOutput>failed().buildFuture();
203 String portNumber = interfaceState.getLowerLayerIf().get(0);
204 portNumber = portNumber.split(":")[2];
205 List<CounterResult> counterResults = new ArrayList<>();
208 if (!getNodeConnectorResult(counterResults, dpId, portNumber)) {
209 statisticsCounters.failedGettingNodeConnectorCounters();
210 return RpcResultBuilder.<GetNodeConnectorCountersOutput>failed()
211 .withError(ErrorType.APPLICATION, "failed to get port counters").buildFuture();
213 } catch (RuntimeException e) {
214 LOG.warn("failed to get counter result for port {}", portId, e);
217 GetNodeConnectorCountersOutputBuilder gpcob = new GetNodeConnectorCountersOutputBuilder();
218 gpcob.setCounterResult(counterResults);
219 return RpcResultBuilder.success(gpcob.build()).buildFuture();
223 public ListenableFuture<RpcResult<AcquireElementCountersRequestHandlerOutput>> acquireElementCountersRequestHandler(
224 AcquireElementCountersRequestHandlerInput input) {
225 AcquireElementCountersRequestHandlerOutputBuilder aecrhob =
226 new AcquireElementCountersRequestHandlerOutputBuilder();
227 UUID randomNumber = UUID.randomUUID();
228 Integer intRequestKey = allocateId(randomNumber.toString());
229 if (intRequestKey == null) {
230 LOG.warn("failed generating unique request identifier");
231 statisticsCounters.failedGeneratingUniqueRequestId();
232 return RpcResultBuilder.<AcquireElementCountersRequestHandlerOutput>failed()
233 .withError(ErrorType.APPLICATION, "failed generating unique request identifier").buildFuture();
235 String requestKey = String.valueOf(intRequestKey);
236 SettableFuture<RpcResult<AcquireElementCountersRequestHandlerOutput>> result = SettableFuture.create();
238 ListenableFutures.addErrorLogging(
239 txRunner.callWithNewReadWriteTransactionAndSubmit(transaction -> {
240 if (input.getIncomingTraffic() != null) {
241 Optional<EgressElementCountersRequestConfig> eecrcOpt =
242 transaction.read(LogicalDatastoreType.CONFIGURATION,
243 CountersServiceUtils.EECRC_IDENTIFIER).get();
244 if (!eecrcOpt.isPresent()) {
245 LOG.warn("failed creating incoming traffic counter request data container in DB");
246 statisticsCounters.failedCreatingEgressCounterDataConfig();
247 result.setFuture(RpcResultBuilder.<AcquireElementCountersRequestHandlerOutput>failed()
248 .withError(ErrorType.APPLICATION,
249 "failed creating egress counter request data container in DB")
253 if (!isIdenticalCounterRequestExist(input.getPortId(),
254 ElementCountersDirection.EGRESS.toString(),
255 input.getIncomingTraffic().getFilters(), eecrcOpt.get().getCounterRequests())) {
256 installCounterSpecificRules(input.getPortId(), getLportTag(input.getPortId()),
257 getDpn(input.getPortId()), ElementCountersDirection.EGRESS,
258 input.getIncomingTraffic().getFilters());
260 putEgressElementCounterRequestInConfig(input, ElementCountersDirection.EGRESS, transaction,
261 requestKey, CountersServiceUtils.EECRC_IDENTIFIER, eecrcOpt, randomNumber.toString());
263 aecrhob.setIncomingTrafficHandler(requestKey);
265 bindCountersServiceIfUnbound(input.getPortId(), ElementCountersDirection.EGRESS);
268 if (input.getOutgoingTraffic() != null) {
269 Optional<IngressElementCountersRequestConfig> iecrcOpt =
270 transaction.read(LogicalDatastoreType.CONFIGURATION,
271 CountersServiceUtils.IECRC_IDENTIFIER).get();
272 if (!iecrcOpt.isPresent()) {
273 LOG.warn("failed creating outgoing traffc counter request data container in DB");
274 statisticsCounters.failedCreatingIngressCounterDataConfig();
275 result.setFuture(RpcResultBuilder.<AcquireElementCountersRequestHandlerOutput>failed()
276 .withError(ErrorType.APPLICATION,
277 "failed creating ingress counter request data container in DB")
281 if (!isIdenticalCounterRequestExist(input.getPortId(),
282 ElementCountersDirection.INGRESS.toString(),
283 input.getOutgoingTraffic().getFilters(), iecrcOpt.get().getCounterRequests())) {
284 installCounterSpecificRules(input.getPortId(), getLportTag(input.getPortId()),
285 getDpn(input.getPortId()), ElementCountersDirection.INGRESS,
286 input.getOutgoingTraffic().getFilters());
288 putIngressElementCounterRequestInConfig(input, ElementCountersDirection.INGRESS, transaction,
289 requestKey, CountersServiceUtils.IECRC_IDENTIFIER, iecrcOpt, randomNumber.toString());
291 aecrhob.setIncomingTrafficHandler(requestKey);
293 bindCountersServiceIfUnbound(input.getPortId(), ElementCountersDirection.INGRESS);
295 result.setFuture(RpcResultBuilder.success(aecrhob.build()).buildFuture());
297 }), LOG, "Error acquiring element counters");
303 public ListenableFuture<RpcResult<ReleaseElementCountersRequestHandlerOutput>> releaseElementCountersRequestHandler(
304 ReleaseElementCountersRequestHandlerInput input) {
305 InstanceIdentifier<CounterRequests> ingressPath =
306 InstanceIdentifier.builder(IngressElementCountersRequestConfig.class)
307 .child(CounterRequests.class, new CounterRequestsKey(input.getHandler())).build();
308 InstanceIdentifier<CounterRequests> egressPath =
309 InstanceIdentifier.builder(EgressElementCountersRequestConfig.class)
310 .child(CounterRequests.class, new CounterRequestsKey(input.getHandler())).build();
312 SettableFuture<RpcResult<ReleaseElementCountersRequestHandlerOutput>> result = SettableFuture.create();
313 ListenableFutures.addErrorLogging(txRunner.callWithNewReadWriteTransactionAndSubmit(tx -> {
314 Optional<IngressElementCountersRequestConfig> iecrcOpt =
315 tx.read(LogicalDatastoreType.CONFIGURATION, CountersServiceUtils.IECRC_IDENTIFIER).get();
316 Optional<EgressElementCountersRequestConfig> eecrcOpt =
317 tx.read(LogicalDatastoreType.CONFIGURATION, CountersServiceUtils.EECRC_IDENTIFIER).get();
318 if (!iecrcOpt.isPresent() || !eecrcOpt.isPresent()) {
319 LOG.warn("Couldn't read element counters config data from DB");
320 statisticsCounters.failedReadingCounterDataFromConfig();
321 result.setFuture(RpcResultBuilder.<ReleaseElementCountersRequestHandlerOutput>failed()
322 .withError(ErrorType.APPLICATION, "Couldn't read element counters config data from DB")
326 Optional<CounterRequests> ingressRequestOpt =
327 tx.read(LogicalDatastoreType.CONFIGURATION, ingressPath).get();
328 Optional<CounterRequests> egressRequestOpt =
329 tx.read(LogicalDatastoreType.CONFIGURATION, egressPath).get();
330 if (!ingressRequestOpt.isPresent() && !egressRequestOpt.isPresent()) {
331 LOG.warn("Handler does not exists");
332 statisticsCounters.unknownRequestHandler();
333 result.setFuture(RpcResultBuilder.<ReleaseElementCountersRequestHandlerOutput>failed()
334 .withError(ErrorType.APPLICATION, "Handler does not exists").buildFuture());
337 String generatedKey = null;
338 if (ingressRequestOpt.isPresent()) {
339 handleReleaseTransaction(tx, input, ingressPath, ingressRequestOpt,
340 iecrcOpt.get().getCounterRequests());
341 generatedKey = ingressRequestOpt.get().getGeneratedUniqueId();
343 if (egressRequestOpt.isPresent()) {
344 handleReleaseTransaction(tx, input, egressPath, egressRequestOpt, eecrcOpt.get().getCounterRequests());
345 generatedKey = egressRequestOpt.get().getGeneratedUniqueId();
347 releaseId(generatedKey);
348 result.setFuture(RpcResultBuilder.<ReleaseElementCountersRequestHandlerOutput>success().buildFuture());
349 }), LOG, "Error releasing element counters");
355 public ListenableFuture<RpcResult<GetElementCountersByHandlerOutput>> getElementCountersByHandler(
356 GetElementCountersByHandlerInput input) {
357 InstanceIdentifier<CounterRequests> ingressPath =
358 InstanceIdentifier.builder(IngressElementCountersRequestConfig.class)
359 .child(CounterRequests.class, new CounterRequestsKey(input.getHandler())).build();
360 InstanceIdentifier<CounterRequests> egressPath =
361 InstanceIdentifier.builder(EgressElementCountersRequestConfig.class)
362 .child(CounterRequests.class, new CounterRequestsKey(input.getHandler())).build();
364 ReadTransaction tx = db.newReadOnlyTransaction();
365 CheckedFuture<Optional<CounterRequests>, ReadFailedException> ingressRequestData =
366 tx.read(LogicalDatastoreType.CONFIGURATION, ingressPath);
367 CheckedFuture<Optional<CounterRequests>, ReadFailedException> egressRequestData =
368 tx.read(LogicalDatastoreType.CONFIGURATION, egressPath);
369 List<CounterResult> counters = new ArrayList<>();
372 if (!ingressRequestData.get().isPresent() && !egressRequestData.get().isPresent()) {
373 LOG.warn("Handler does not exists");
374 return RpcResultBuilder.<GetElementCountersByHandlerOutput>failed()
375 .withError(ErrorType.APPLICATION, "Handler does not exists").buildFuture();
377 if (ingressRequestData.get().isPresent()) {
378 CounterRequests ingressCounterRequest = ingressRequestData.get().get();
379 CounterResultDataStructure ingressCounterResultDS = createElementCountersResult(ingressCounterRequest);
380 if (ingressCounterResultDS == null) {
381 LOG.warn("Unable to get counter results");
382 statisticsCounters.failedGettingCounterResults();
383 return RpcResultBuilder.<GetElementCountersByHandlerOutput>failed()
384 .withError(ErrorType.APPLICATION, "Unable to get counter results").buildFuture();
386 createCounterResults(counters, ingressCounterResultDS, CountersServiceUtils.INGRESS_COUNTER_RESULT_ID);
388 if (egressRequestData.get().isPresent()) {
389 CounterRequests egressCounterRequest = egressRequestData.get().get();
390 CounterResultDataStructure egressCounterResultDS = createElementCountersResult(egressCounterRequest);
391 if (egressCounterResultDS == null) {
392 LOG.warn("Unable to get counter results");
393 statisticsCounters.failedGettingCounterResults();
394 return RpcResultBuilder.<GetElementCountersByHandlerOutput>failed()
395 .withError(ErrorType.APPLICATION, "Unable to get counter results").buildFuture();
397 createCounterResults(counters, egressCounterResultDS, CountersServiceUtils.EGRESS_COUNTER_RESULT_ID);
399 } catch (InterruptedException | ExecutionException e) {
400 LOG.warn("failed to get counter request data from DB");
401 return RpcResultBuilder.<GetElementCountersByHandlerOutput>failed()
402 .withError(ErrorType.APPLICATION, "failed to get counter request data from DB").buildFuture();
407 GetElementCountersByHandlerOutputBuilder gecbhob = new GetElementCountersByHandlerOutputBuilder();
408 gecbhob.setCounterResult(counters);
409 return RpcResultBuilder.success(gecbhob.build()).buildFuture();
413 public void handleInterfaceRemoval(String interfaceId) {
414 CheckedFuture<Optional<IngressElementCountersRequestConfig>, ReadFailedException> iecrc;
415 CheckedFuture<Optional<EgressElementCountersRequestConfig>, ReadFailedException> eecrc;
416 try (ReadTransaction tx = db.newReadOnlyTransaction()) {
417 iecrc = tx.read(LogicalDatastoreType.CONFIGURATION, CountersServiceUtils.IECRC_IDENTIFIER);
418 eecrc = tx.read(LogicalDatastoreType.CONFIGURATION, CountersServiceUtils.EECRC_IDENTIFIER);
422 Optional<IngressElementCountersRequestConfig> iecrcOpt = iecrc.get();
423 Optional<EgressElementCountersRequestConfig> eecrcOpt = eecrc.get();
424 if (!iecrcOpt.isPresent() || !eecrcOpt.isPresent()) {
425 LOG.warn("Couldn't read element counters config data from DB");
426 statisticsCounters.failedReadingCounterDataFromConfig();
429 removeAllElementCounterRequestsOnPort(interfaceId, iecrcOpt.get().getCounterRequests());
430 removeAllElementCounterRequestsOnPort(interfaceId, eecrcOpt.get().getCounterRequests());
431 } catch (InterruptedException | ExecutionException e) {
432 LOG.warn("failed to get counter request data from DB");
433 statisticsCounters.failedGettingCounterResultsPortRemoval();
439 public ListenableFuture<RpcResult<CleanAllElementCounterRequestsOutput>> cleanAllElementCounterRequests(
440 CleanAllElementCounterRequestsInput input) {
441 ReadTransaction tx = db.newReadOnlyTransaction();
442 CheckedFuture<Optional<IngressElementCountersRequestConfig>, ReadFailedException> iecrc =
443 tx.read(LogicalDatastoreType.CONFIGURATION, CountersServiceUtils.IECRC_IDENTIFIER);
444 CheckedFuture<Optional<EgressElementCountersRequestConfig>, ReadFailedException> eecrc =
445 tx.read(LogicalDatastoreType.CONFIGURATION, CountersServiceUtils.EECRC_IDENTIFIER);
447 Optional<IngressElementCountersRequestConfig> iecrcOpt = iecrc.get();
448 Optional<EgressElementCountersRequestConfig> eecrcOpt = eecrc.get();
449 if (!iecrcOpt.isPresent() || !eecrcOpt.isPresent()) {
450 LOG.warn("Couldn't read element counters config data from DB");
451 statisticsCounters.failedReadingCounterDataFromConfig();
452 return RpcResultBuilder.<CleanAllElementCounterRequestsOutput>failed()
453 .withError(ErrorType.APPLICATION, "Couldn't read element counters config data from DB")
456 Set<String> idsToRelease = new HashSet<>();
457 if (input.getPortId() != null && !input.getPortId().isEmpty()) {
459 .addAll(getAllPortRequestsUniqueIds(input.getPortId(), iecrcOpt.get().getCounterRequests()));
461 .addAll(getAllPortRequestsUniqueIds(input.getPortId(), eecrcOpt.get().getCounterRequests()));
462 removeAllElementCounterRequestsOnPort(input.getPortId(), iecrcOpt.get().getCounterRequests());
463 removeAllElementCounterRequestsOnPort(input.getPortId(), eecrcOpt.get().getCounterRequests());
465 idsToRelease.addAll(getAllRquestsUniqueIds(iecrcOpt.get().getCounterRequests()));
466 idsToRelease.addAll(getAllRquestsUniqueIds(eecrcOpt.get().getCounterRequests()));
467 removeAllElementCounterRequests(iecrcOpt.get().getCounterRequests());
468 removeAllElementCounterRequests(eecrcOpt.get().getCounterRequests());
470 releaseIds(idsToRelease);
471 } catch (InterruptedException | ExecutionException e) {
472 LOG.warn("failed to get counter request data from DB");
473 return RpcResultBuilder.<CleanAllElementCounterRequestsOutput>failed()
474 .withError(ErrorType.APPLICATION, "failed to get counter request data from DB").buildFuture();
478 return RpcResultBuilder.<CleanAllElementCounterRequestsOutput>success().buildFuture();
481 private Set<String> getAllPortRequestsUniqueIds(String interfaceId, List<CounterRequests> counterRequests) {
482 Set<String> result = new HashSet<>();
483 for (CounterRequests counterRequest : counterRequests) {
484 if (counterRequest.getPortId().equals(interfaceId)) {
485 result.add(counterRequest.getGeneratedUniqueId());
491 private Set<String> getAllRquestsUniqueIds(List<CounterRequests> counterRequests) {
492 Set<String> result = new HashSet<>();
493 for (CounterRequests counterRequest : counterRequests) {
494 result.add(counterRequest.getGeneratedUniqueId());
499 private void releaseIds(Set<String> ids) {
500 for (String id : ids) {
505 private void removeAllElementCounterRequestsOnPort(String interfaceId, List<CounterRequests> counterRequests) {
506 unbindCountersServiceIfBound(interfaceId, ElementCountersDirection.INGRESS);
507 unbindCountersServiceIfBound(interfaceId, ElementCountersDirection.EGRESS);
508 if (counterRequests != null) {
509 for (CounterRequests counterRequest : counterRequests) {
510 if (interfaceId.equals(counterRequest.getPortId())) {
511 countersRequestCleanup(counterRequest);
517 private void removeAllElementCounterRequests(List<CounterRequests> counterRequests) {
518 for (CounterRequests counterRequest : counterRequests) {
519 unbindCountersServiceIfBound(counterRequest.getPortId(), ElementCountersDirection.INGRESS);
520 unbindCountersServiceIfBound(counterRequest.getPortId(), ElementCountersDirection.EGRESS);
521 countersRequestCleanup(counterRequest);
525 private void countersRequestCleanup(CounterRequests counterRequest) {
526 ElementCountersDirection direction = ElementCountersDirection.valueOf(counterRequest.getTrafficDirection());
527 deleteCounterSpecificRules(counterRequest.getPortId(), counterRequest.getLportTag(), counterRequest.getDpn(),
528 direction, counterRequest.getFilters());
529 deleteCounterRequest(counterRequest, direction);
532 private void deleteCounterSpecificRules(String portId, int lportTag, BigInteger dpn,
533 ElementCountersDirection direction, Filters filters) {
534 List<ElementCountersRequest> ecrList = createElementCounterRequest(portId, lportTag, dpn, direction, filters);
535 for (ElementCountersRequest ecr : ecrList) {
536 if (ElementCountersDirection.INGRESS.equals(ecr.getDirection())) {
537 IngressCountersServiceImpl icsi = new IngressCountersServiceImpl(db, interfaceManager, mdsalApiManager);
538 icsi.deleteCounterRules(ecr);
539 } else if (ElementCountersDirection.EGRESS.equals(ecr.getDirection())) {
540 EgressCountersServiceImpl ecsi = new EgressCountersServiceImpl(db, interfaceManager, mdsalApiManager);
541 ecsi.deleteCounterRules(ecr);
546 private void deleteCounterRequest(CounterRequests counterRequest, ElementCountersDirection direction) {
547 ListenableFutures.addErrorLogging(
548 txRunner.callWithNewWriteOnlyTransactionAndSubmit(tx -> {
549 if (ElementCountersDirection.INGRESS.equals(direction)) {
550 tx.delete(LogicalDatastoreType.CONFIGURATION, InstanceIdentifier
551 .builder(IngressElementCountersRequestConfig.class)
552 .child(CounterRequests.class,
553 new CounterRequestsKey(counterRequest.key().getRequestId()))
555 } else if (ElementCountersDirection.EGRESS.equals(direction)) {
556 tx.delete(LogicalDatastoreType.CONFIGURATION, InstanceIdentifier
557 .builder(EgressElementCountersRequestConfig.class)
558 .child(CounterRequests.class,
559 new CounterRequestsKey(counterRequest.key().getRequestId()))
562 }), LOG, "Error deleting counter");
565 private CounterResultDataStructure createElementCountersResult(CounterRequests counterRequest) {
566 ElementCountersRequest ecr =
567 createElementCounterRequest(counterRequest.getPortId(), counterRequest.getLportTag(),
568 counterRequest.getDpn(), ElementCountersDirection.valueOf(counterRequest.getTrafficDirection()),
569 counterRequest.getFilters()).iterator().next();
570 BigInteger dpId = getDpn(ecr.getPortId());
571 InterfaceInfo interfaceInfo = interfaceManager.getInterfaceInfo(ecr.getPortId());
572 if (interfaceInfo == null) {
575 int lportTag = interfaceInfo.getInterfaceTag();
576 List<MatchInfoBase> matches = CountersServiceUtils.getCounterFlowMatch(ecr, lportTag,
577 ElementCountersDirection.valueOf(counterRequest.getTrafficDirection()));
578 Match match = MDSALUtil.buildMatches(matches);
579 return counterRetriever.getSwitchFlowCountersDirect(dpId, match);
582 private void initializeCountrsConfigDataSrore() {
583 ListenableFutures.addErrorLogging(
584 txRunner.callWithNewReadWriteTransactionAndSubmit(transaction -> {
585 Optional<IngressElementCountersRequestConfig> iecrcOpt =
586 transaction.read(LogicalDatastoreType.CONFIGURATION,
587 CountersServiceUtils.IECRC_IDENTIFIER).get();
588 Optional<EgressElementCountersRequestConfig> eecrcOpt =
589 transaction.read(LogicalDatastoreType.CONFIGURATION,
590 CountersServiceUtils.EECRC_IDENTIFIER).get();
591 if (!iecrcOpt.isPresent()) {
592 creatIngressEelementCountersContainerInConfig(transaction,
593 CountersServiceUtils.IECRC_IDENTIFIER);
595 if (!eecrcOpt.isPresent()) {
596 creatEgressEelementCountersContainerInConfig(transaction,
597 CountersServiceUtils.EECRC_IDENTIFIER);
599 }), LOG, "Failed to create counters in config datastore");
602 private void handleReleaseTransaction(WriteTransaction transaction, ReleaseElementCountersRequestHandlerInput input,
603 InstanceIdentifier<CounterRequests> path, Optional<CounterRequests> requestData,
604 List<CounterRequests> counterRequests) {
605 transaction.delete(LogicalDatastoreType.CONFIGURATION, path);
606 CounterRequests counterRequest = requestData.get();
607 if (shouldUnbindCountersService(counterRequest.getPortId(), counterRequest.key().getRequestId(),
609 unbindCountersServiceIfBound(counterRequest.getPortId(),
610 ElementCountersDirection.valueOf(counterRequest.getTrafficDirection()));
612 if (!isIdenticalCounterRequestExist(input.getHandler(), counterRequest.getPortId(),
613 counterRequest.getTrafficDirection(), counterRequest.getFilters(), counterRequests)) {
614 deleteCounterSpecificRules(counterRequest.getPortId(), counterRequest.getLportTag(),
615 counterRequest.getDpn(), ElementCountersDirection.valueOf(counterRequest.getTrafficDirection()),
616 counterRequest.getFilters());
620 private boolean getNodeConnectorResult(List<CounterResult> counters, BigInteger dpId, String portNumber) {
621 CounterResultDataStructure counterResultDS =
622 counterRetriever.getNodeConnectorCountersDirect(new NodeId(CountersUtils.getNodeId(dpId)),
623 new NodeConnectorId(CountersUtils.getNodeConnectorId(dpId, portNumber)));
624 if (counterResultDS == null) {
628 CounterResultBuilder crb = new CounterResultBuilder();
629 String resultId = CountersUtils.getNodeConnectorId(dpId, portNumber);
632 createGroups(counters, counterResultDS, crb, resultId);
634 return !counters.isEmpty();
637 private boolean getNodeResult(List<CounterResult> counters, BigInteger dpId) {
638 InstanceIdentifier<Node> nodeInstanceIdentifier = InstanceIdentifier.builder(Nodes.class)
639 .child(Node.class, new NodeKey(new NodeId(CountersUtils.getNodeId(dpId)))).build();
640 Optional<Node> nodeOptional = MDSALUtil.read(db, LogicalDatastoreType.OPERATIONAL, nodeInstanceIdentifier);
641 if (!nodeOptional.isPresent()) {
645 Node node = nodeOptional.get();
646 CounterResultDataStructure counterResultDS = counterRetriever.getNodeCountersDirect(node);
647 if (counterResultDS == null) {
651 createCounterResults(counters, counterResultDS);
653 return !counters.isEmpty();
656 private boolean getNodeAggregatedResult(List<CounterResult> aggregatedCounters, BigInteger dpId) {
657 InstanceIdentifier<Node> nodeInstanceIdentifier = InstanceIdentifier.builder(Nodes.class)
658 .child(Node.class, new NodeKey(new NodeId(CountersUtils.getNodeId(dpId)))).build();
659 Optional<Node> nodeOptional = MDSALUtil.read(db, LogicalDatastoreType.OPERATIONAL, nodeInstanceIdentifier);
660 if (!nodeOptional.isPresent()) {
664 Node node = nodeOptional.get();
665 CounterResultDataStructure counters = counterRetriever.getNodeCountersDirect(node);
666 if (counters == null || counters.isEmpty()) {
670 CounterResultDataStructure aggregatedResultsDS =
671 CountersUtils.aggregateCounters(counters, CountersUtils.getNodeId(dpId));
672 createCounterResults(aggregatedCounters, aggregatedResultsDS);
673 return !aggregatedCounters.isEmpty();
677 private void createCounterResults(List<CounterResult> counters, CounterResultDataStructure counterResultDS) {
678 for (String counterResultId : counterResultDS.getResults().keySet()) {
679 CounterResultBuilder crb = new CounterResultBuilder();
680 crb.setId(counterResultId);
681 createGroups(counters, counterResultDS, crb, counterResultId);
685 private void createCounterResults(List<CounterResult> counters, CounterResultDataStructure counterResultDS,
687 for (String counterResultId : counterResultDS.getResults().keySet()) {
688 CounterResultBuilder crb = new CounterResultBuilder();
690 createGroups(counters, counterResultDS, crb, counterResultId);
694 private void createGroups(List<CounterResult> counters, CounterResultDataStructure counterResultDS,
695 CounterResultBuilder crb, String resultId) {
696 List<Groups> groups = new ArrayList<>();
697 Map<String, Map<String, BigInteger>> counterGroups = counterResultDS.getGroups(resultId);
698 if (counterGroups != null && !counterGroups.isEmpty()) {
699 for (Entry<String, Map<String, BigInteger>> entry : counterGroups.entrySet()) {
700 String groupName = entry.getKey();
701 groups.add(createGroupsResult(groupName, entry.getValue()));
703 crb.setGroups(groups);
704 counters.add(crb.build());
708 private Groups createGroupsResult(String groupName, Map<String, BigInteger> countersMap) {
709 GroupsBuilder gb = new GroupsBuilder();
710 gb.setName(groupName);
712 Map<String, Counters> counters = new HashMap<>();
713 List<Counters> countersList = new ArrayList<>();
714 for (String counterName : countersMap.keySet()) {
715 addCountersToMap(countersMap, counters, counterName);
717 for (Counters counter : counters.values()) {
718 countersList.add(counter);
721 gb.setCounters(countersList);
725 private Counters buildCounter(String counterName, BigInteger value, Counters prevCounter) {
726 BigInteger prevValue = BigInteger.ZERO;
727 if (prevCounter != null) {
728 prevValue = prevCounter.getValue();
730 CountersBuilder cb = new CountersBuilder();
731 cb.setName(counterName);
732 cb.setValue(value.add(prevValue));
736 private void addCountersToMap(Map<String, BigInteger> result, Map<String, Counters> counters, String counterName) {
737 counters.put(counterName, buildCounter(counterName, result.get(counterName), counters.get(counterName)));
740 private void addElementCounterRequest(List<ElementCountersRequest> ecrList, String portId, int lportTag,
741 BigInteger dpn, ElementCountersDirection direction, Filters filters) {
742 ElementCountersRequest ecr = new ElementCountersRequest(portId);
743 ecr.setLportTag(lportTag);
745 ecr.setElementCountersDirection(direction);
746 if (filters.getIpFilter() != null) {
747 String ip = filters.getIpFilter().getIp();
749 ecr.addFilterToFilterGroup(CountersUtils.ELEMENT_COUNTERS_IP_FILTER_GROUP_NAME,
750 CountersUtils.IP_FILTER_NAME, ip);
754 boolean isTcpPortExist = false;
755 if (filters.getTcpFilter() != null && filters.getTcpFilter().isOn()) {
756 TcpFilter tcpFilter = filters.getTcpFilter();
757 int srcPort = tcpFilter.getSrcPort();
758 int dstPort = tcpFilter.getDstPort();
760 isTcpPortExist = true;
761 ecr.addFilterToFilterGroup(CountersUtils.ELEMENT_COUNTERS_TCP_FILTER_GROUP_NAME,
762 CountersUtils.TCP_SRC_PORT_FILTER_NAME, String.valueOf(srcPort));
765 isTcpPortExist = true;
766 ecr.addFilterToFilterGroup(CountersUtils.ELEMENT_COUNTERS_TCP_FILTER_GROUP_NAME,
767 CountersUtils.TCP_DST_PORT_FILTER_NAME, String.valueOf(dstPort));
769 if (!isTcpPortExist) {
770 ecr.addFilterToFilterGroup(CountersUtils.ELEMENT_COUNTERS_TCP_FILTER_GROUP_NAME,
771 CountersUtils.TCP_FILTER_NAME, "");
774 } else if (filters.getUdpFilter() != null && filters.getUdpFilter().isOn()) {
775 UdpFilter udpFilter = filters.getUdpFilter();
776 int srcPort = udpFilter.getSrcPort();
777 int dstPort = udpFilter.getDstPort();
779 isTcpPortExist = true;
780 ecr.addFilterToFilterGroup(CountersUtils.ELEMENT_COUNTERS_UDP_FILTER_GROUP_NAME,
781 CountersUtils.UDP_SRC_PORT_FILTER_NAME, String.valueOf(srcPort));
784 isTcpPortExist = true;
785 ecr.addFilterToFilterGroup(CountersUtils.ELEMENT_COUNTERS_UDP_FILTER_GROUP_NAME,
786 CountersUtils.UDP_DST_PORT_FILTER_NAME, String.valueOf(dstPort));
788 if (!isTcpPortExist) {
789 ecr.addFilterToFilterGroup(CountersUtils.ELEMENT_COUNTERS_UDP_FILTER_GROUP_NAME,
790 CountersUtils.UDP_FILTER_NAME, "");
794 if (!ecr.getFilters().isEmpty()) {
799 @SuppressFBWarnings("SLF4J_FORMAT_SHOULD_BE_CONST")
800 private void logElementCounterRequests(List<ElementCountersRequest> ecrList) {
801 for (ElementCountersRequest counterRequest : ecrList) {
802 LOG.debug(counterRequest.toString());
806 private void bindCountersServiceIfUnbound(String interfaceId, ElementCountersDirection direction) {
807 if (ElementCountersDirection.INGRESS.equals(direction) && !interfaceManager.isServiceBoundOnInterfaceForIngress(
808 CountersServiceUtils.INGRESS_COUNTERS_SERVICE_INDEX, interfaceId)) {
809 IngressCountersServiceImpl icsi = new IngressCountersServiceImpl(db, interfaceManager, mdsalApiManager);
810 icsi.bindService(interfaceId);
811 statisticsCounters.ingressCountersServiceBind();
812 } else if (ElementCountersDirection.EGRESS.equals(direction) && !interfaceManager
813 .isServiceBoundOnInterfaceForEgress(CountersServiceUtils.EGRESS_COUNTERS_SERVICE_INDEX, interfaceId)) {
814 EgressCountersServiceImpl ecsi = new EgressCountersServiceImpl(db, interfaceManager, mdsalApiManager);
815 ecsi.bindService(interfaceId);
816 statisticsCounters.egressCountersServiceBind();
820 private void unbindCountersServiceIfBound(String interfaceId, ElementCountersDirection direction) {
821 if (ElementCountersDirection.INGRESS.equals(direction) && interfaceManager.isServiceBoundOnInterfaceForIngress(
822 CountersServiceUtils.INGRESS_COUNTERS_SERVICE_INDEX, interfaceId)) {
823 IngressCountersServiceImpl icsi = new IngressCountersServiceImpl(db, interfaceManager, mdsalApiManager);
824 icsi.unBindService(interfaceId);
825 statisticsCounters.ingressCountersServiceUnbind();
826 } else if (ElementCountersDirection.EGRESS.equals(direction) && interfaceManager
827 .isServiceBoundOnInterfaceForEgress(CountersServiceUtils.EGRESS_COUNTERS_SERVICE_INDEX, interfaceId)) {
828 EgressCountersServiceImpl ecsi = new EgressCountersServiceImpl(db, interfaceManager, mdsalApiManager);
829 ecsi.unBindService(interfaceId);
830 statisticsCounters.egressCountersServiceUnbind();
834 private boolean shouldUnbindCountersService(String portId, String requesId, List<CounterRequests> counterRequests) {
835 for (CounterRequests counterRequest : counterRequests) {
836 if (portId.equals(counterRequest.getPortId()) && !requesId.equals(counterRequest.key().getRequestId())) {
843 private void installCounterSpecificRules(String portId, int lportTag, BigInteger dpn,
844 ElementCountersDirection direction, Filters filters) {
845 List<ElementCountersRequest> ecrList = createElementCounterRequest(portId, lportTag, dpn, direction, filters);
846 for (ElementCountersRequest ecr : ecrList) {
847 if (ElementCountersDirection.INGRESS.equals(ecr.getDirection())) {
848 IngressCountersServiceImpl icsi = new IngressCountersServiceImpl(db, interfaceManager, mdsalApiManager);
849 icsi.installCounterRules(ecr);
850 } else if (ElementCountersDirection.EGRESS.equals(ecr.getDirection())) {
851 EgressCountersServiceImpl ecsi = new EgressCountersServiceImpl(db, interfaceManager, mdsalApiManager);
852 ecsi.installCounterRules(ecr);
857 private boolean areFiltersEqual(Filters filterGroup1, Filters filterGroup2) {
858 if (filterGroup1 == null && filterGroup2 == null) {
861 if (filterGroup1 == null || filterGroup2 == null) {
865 return filterGroup1.toString().equals(filterGroup2.toString());
868 private void putIngressElementCounterRequestInConfig(AcquireElementCountersRequestHandlerInput input,
869 ElementCountersDirection direcion, ReadWriteTransaction transaction, String requestKey,
870 InstanceIdentifier<IngressElementCountersRequestConfig> ecrcIdentifier,
871 Optional<IngressElementCountersRequestConfig> iecrcOpt, String generatedUniqueId) {
872 IngressElementCountersRequestConfig requestConfig = iecrcOpt.get();
873 CounterRequestsBuilder crb = new CounterRequestsBuilder();
874 crb.setRequestId(requestKey);
875 crb.withKey(new CounterRequestsKey(requestKey));
876 crb.setFilters(input.getOutgoingTraffic().getFilters());
877 crb.setPortId(input.getPortId());
878 crb.setLportTag(getLportTag(input.getPortId()));
879 crb.setDpn(getDpn(input.getPortId()));
880 crb.setTrafficDirection(direcion.toString());
881 crb.setGeneratedUniqueId(generatedUniqueId);
882 List<CounterRequests> counterRequests = requestConfig.getCounterRequests();
883 counterRequests.add(crb.build());
885 IngressElementCountersRequestConfigBuilder ecrcb = new IngressElementCountersRequestConfigBuilder();
886 ecrcb.setCounterRequests(counterRequests);
887 requestConfig = ecrcb.build();
888 transaction.mergeParentStructurePut(LogicalDatastoreType.CONFIGURATION, ecrcIdentifier, requestConfig);
891 private void putEgressElementCounterRequestInConfig(AcquireElementCountersRequestHandlerInput input,
892 ElementCountersDirection direcion, ReadWriteTransaction transaction, String requestKey,
893 InstanceIdentifier<EgressElementCountersRequestConfig> ecrcIdentifier,
894 Optional<EgressElementCountersRequestConfig> eecrcOpt, String generatedUniqueId) {
895 EgressElementCountersRequestConfig requestConfig = eecrcOpt.get();
896 CounterRequestsBuilder crb = new CounterRequestsBuilder();
897 crb.setRequestId(requestKey);
898 crb.withKey(new CounterRequestsKey(requestKey));
899 crb.setFilters(input.getIncomingTraffic().getFilters());
900 crb.setPortId(input.getPortId());
901 crb.setLportTag(getLportTag(input.getPortId()));
902 crb.setDpn(getDpn(input.getPortId()));
903 crb.setTrafficDirection(direcion.toString());
904 crb.setGeneratedUniqueId(generatedUniqueId);
905 List<CounterRequests> counterRequests = requestConfig.getCounterRequests();
906 counterRequests.add(crb.build());
908 EgressElementCountersRequestConfigBuilder ecrcb = new EgressElementCountersRequestConfigBuilder();
909 ecrcb.setCounterRequests(counterRequests);
910 requestConfig = ecrcb.build();
911 transaction.put(LogicalDatastoreType.CONFIGURATION, ecrcIdentifier, requestConfig);
914 private void creatIngressEelementCountersContainerInConfig(ReadWriteTransaction transaction,
915 InstanceIdentifier<IngressElementCountersRequestConfig> ecrcIdentifier) {
916 IngressElementCountersRequestConfigBuilder iecrcb = new IngressElementCountersRequestConfigBuilder();
917 List<CounterRequests> counterRequests = new ArrayList<>();
918 iecrcb.setCounterRequests(counterRequests);
919 IngressElementCountersRequestConfig iecrc = iecrcb.build();
920 transaction.put(LogicalDatastoreType.CONFIGURATION, ecrcIdentifier, iecrc);
923 private void creatEgressEelementCountersContainerInConfig(ReadWriteTransaction transaction,
924 InstanceIdentifier<EgressElementCountersRequestConfig> ecrcIdentifier) {
925 EgressElementCountersRequestConfigBuilder eecrcb = new EgressElementCountersRequestConfigBuilder();
926 List<CounterRequests> counterRequests = new ArrayList<>();
927 eecrcb.setCounterRequests(counterRequests);
928 EgressElementCountersRequestConfig eecrc = eecrcb.build();
929 transaction.put(LogicalDatastoreType.CONFIGURATION, ecrcIdentifier, eecrc);
932 private Integer allocateId(String idKey) {
934 AllocateIdInput getIdInput = new AllocateIdInputBuilder().setPoolName(CountersServiceUtils.COUNTERS_PULL_NAME)
935 .setIdKey(idKey).build();
937 Future<RpcResult<AllocateIdOutput>> result = idManagerService.allocateId(getIdInput);
938 RpcResult<AllocateIdOutput> rpcResult = result.get();
939 if (rpcResult.isSuccessful()) {
940 return rpcResult.getResult().getIdValue().intValue();
942 LOG.warn("RPC Call to Get Unique Id returned with Errors {}", rpcResult.getErrors());
944 } catch (InterruptedException | ExecutionException e) {
945 LOG.warn("Exception when getting Unique Id", e);
950 private void createIdPool() {
951 if (checkPoolExists()) {
954 CreateIdPoolInput createPool = new CreateIdPoolInputBuilder()
955 .setPoolName(CountersServiceUtils.COUNTERS_PULL_NAME).setLow(CountersServiceUtils.COUNTERS_PULL_START)
956 .setHigh(CountersServiceUtils.COUNTERS_PULL_START + CountersServiceUtils.COUNTERS_PULL_END).build();
957 ListenableFuture<RpcResult<CreateIdPoolOutput>> result = idManagerService.createIdPool(createPool);
958 Futures.addCallback(result, new FutureCallback<RpcResult<CreateIdPoolOutput>>() {
961 public void onFailure(Throwable error) {
962 LOG.error("Failed to create idPool for Aliveness Monitor Service", error);
966 public void onSuccess(@NonNull RpcResult<CreateIdPoolOutput> rpcResult) {
967 if (rpcResult.isSuccessful()) {
968 LOG.debug("Created IdPool for tap");
970 LOG.error("RPC to create Idpool failed {}", rpcResult.getErrors());
973 }, MoreExecutors.directExecutor());
976 private void releaseId(String idKey) {
977 ReleaseIdInput idInput = new ReleaseIdInputBuilder().setPoolName(CountersServiceUtils.COUNTERS_PULL_NAME)
978 .setIdKey(idKey).build();
980 RpcResult<ReleaseIdOutput> rpcResult = idManagerService.releaseId(idInput).get();
981 if (!rpcResult.isSuccessful()) {
982 LOG.warn("RPC Call to release Id with Key {} returned with Errors {}", idKey, rpcResult.getErrors());
984 } catch (InterruptedException | ExecutionException e) {
985 LOG.warn("Exception when releasing Id for key {}", idKey, e);
989 private boolean checkPoolExists() {
990 ReadTransaction roTransaction = db.newReadOnlyTransaction();
991 InstanceIdentifier<IdPool> path = InstanceIdentifier.create(IdPools.class).child(IdPool.class,
992 new IdPoolKey(CountersServiceUtils.COUNTERS_PULL_NAME));
993 CheckedFuture<Optional<IdPool>, ReadFailedException> pool =
994 roTransaction.read(LogicalDatastoreType.CONFIGURATION, path);
996 Optional<IdPool> poolOpt = pool.get();
997 if (poolOpt.isPresent()) {
1000 } catch (InterruptedException | ExecutionException e) {
1003 roTransaction.close();
1008 private boolean isIdenticalCounterRequestExist(String portId, String dirction, Filters filters,
1009 List<CounterRequests> counterRequests) {
1010 if (counterRequests.isEmpty()) {
1014 for (CounterRequests counterRequest : counterRequests) {
1015 if (portId.equals(counterRequest.getPortId()) && dirction.equals(counterRequest.getTrafficDirection())) {
1016 if (areFiltersEqual(filters, counterRequest.getFilters())) {
1024 private boolean isIdenticalCounterRequestExist(String requesId, String portId, String dirction, Filters filters,
1025 List<CounterRequests> counterRequests) {
1026 if (counterRequests.isEmpty()) {
1030 for (CounterRequests counterRequest : counterRequests) {
1031 if (portId.equals(counterRequest.getPortId()) && dirction.equals(counterRequest.getTrafficDirection())
1032 && !counterRequest.key().getRequestId().equals(requesId)) {
1033 if (areFiltersEqual(filters, counterRequest.getFilters())) {
1041 private int getLportTag(String interfaceId) {
1042 return interfaceManager.getInterfaceInfo(interfaceId).getInterfaceTag();
1045 private BigInteger getDpn(String interfaceId) {
1046 return interfaceManager.getDpnForInterface(interfaceId);
1049 private List<ElementCountersRequest> createElementCounterRequest(String portId, int lportTag, BigInteger dpn,
1050 ElementCountersDirection direcrtion, Filters filters) {
1051 List<ElementCountersRequest> ecrList = new ArrayList<>();
1052 LOG.debug("getting element counters for port {}", portId);
1053 addElementCounterRequest(ecrList, portId, lportTag, dpn, direcrtion, filters);
1055 logElementCounterRequests(ecrList);