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.utils.concurrent.ListenableFutures;
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).checkedGet();
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).checkedGet();
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).checkedGet();
316 Optional<EgressElementCountersRequestConfig> eecrcOpt =
317 tx.read(LogicalDatastoreType.CONFIGURATION, CountersServiceUtils.EECRC_IDENTIFIER).checkedGet();
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).checkedGet();
328 Optional<CounterRequests> egressRequestOpt =
329 tx.read(LogicalDatastoreType.CONFIGURATION, egressPath).checkedGet();
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 ReadOnlyTransaction 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();
405 GetElementCountersByHandlerOutputBuilder gecbhob = new GetElementCountersByHandlerOutputBuilder();
406 gecbhob.setCounterResult(counters);
407 return RpcResultBuilder.success(gecbhob.build()).buildFuture();
411 public void handleInterfaceRemoval(String interfaceId) {
412 CheckedFuture<Optional<IngressElementCountersRequestConfig>, ReadFailedException> iecrc;
413 CheckedFuture<Optional<EgressElementCountersRequestConfig>, ReadFailedException> eecrc;
414 try (ReadOnlyTransaction tx = db.newReadOnlyTransaction()) {
415 iecrc = tx.read(LogicalDatastoreType.CONFIGURATION, CountersServiceUtils.IECRC_IDENTIFIER);
416 eecrc = tx.read(LogicalDatastoreType.CONFIGURATION, CountersServiceUtils.EECRC_IDENTIFIER);
420 Optional<IngressElementCountersRequestConfig> iecrcOpt = iecrc.get();
421 Optional<EgressElementCountersRequestConfig> eecrcOpt = eecrc.get();
422 if (!iecrcOpt.isPresent() || !eecrcOpt.isPresent()) {
423 LOG.warn("Couldn't read element counters config data from DB");
424 statisticsCounters.failedReadingCounterDataFromConfig();
427 removeAllElementCounterRequestsOnPort(interfaceId, iecrcOpt.get().getCounterRequests());
428 removeAllElementCounterRequestsOnPort(interfaceId, eecrcOpt.get().getCounterRequests());
429 } catch (InterruptedException | ExecutionException e) {
430 LOG.warn("failed to get counter request data from DB");
431 statisticsCounters.failedGettingCounterResultsPortRemoval();
437 public ListenableFuture<RpcResult<CleanAllElementCounterRequestsOutput>> cleanAllElementCounterRequests(
438 CleanAllElementCounterRequestsInput input) {
439 ReadOnlyTransaction tx = db.newReadOnlyTransaction();
440 CheckedFuture<Optional<IngressElementCountersRequestConfig>, ReadFailedException> iecrc =
441 tx.read(LogicalDatastoreType.CONFIGURATION, CountersServiceUtils.IECRC_IDENTIFIER);
442 CheckedFuture<Optional<EgressElementCountersRequestConfig>, ReadFailedException> eecrc =
443 tx.read(LogicalDatastoreType.CONFIGURATION, CountersServiceUtils.EECRC_IDENTIFIER);
445 Optional<IngressElementCountersRequestConfig> iecrcOpt = iecrc.get();
446 Optional<EgressElementCountersRequestConfig> eecrcOpt = eecrc.get();
447 if (!iecrcOpt.isPresent() || !eecrcOpt.isPresent()) {
448 LOG.warn("Couldn't read element counters config data from DB");
449 statisticsCounters.failedReadingCounterDataFromConfig();
450 return RpcResultBuilder.<CleanAllElementCounterRequestsOutput>failed()
451 .withError(ErrorType.APPLICATION, "Couldn't read element counters config data from DB")
454 Set<String> idsToRelease = new HashSet<>();
455 if (input.getPortId() != null && !input.getPortId().isEmpty()) {
457 .addAll(getAllPortRequestsUniqueIds(input.getPortId(), iecrcOpt.get().getCounterRequests()));
459 .addAll(getAllPortRequestsUniqueIds(input.getPortId(), eecrcOpt.get().getCounterRequests()));
460 removeAllElementCounterRequestsOnPort(input.getPortId(), iecrcOpt.get().getCounterRequests());
461 removeAllElementCounterRequestsOnPort(input.getPortId(), eecrcOpt.get().getCounterRequests());
463 idsToRelease.addAll(getAllRquestsUniqueIds(iecrcOpt.get().getCounterRequests()));
464 idsToRelease.addAll(getAllRquestsUniqueIds(eecrcOpt.get().getCounterRequests()));
465 removeAllElementCounterRequests(iecrcOpt.get().getCounterRequests());
466 removeAllElementCounterRequests(eecrcOpt.get().getCounterRequests());
468 releaseIds(idsToRelease);
469 } catch (InterruptedException | ExecutionException e) {
470 LOG.warn("failed to get counter request data from DB");
471 return RpcResultBuilder.<CleanAllElementCounterRequestsOutput>failed()
472 .withError(ErrorType.APPLICATION, "failed to get counter request data from DB").buildFuture();
475 return RpcResultBuilder.<CleanAllElementCounterRequestsOutput>success().buildFuture();
478 private Set<String> getAllPortRequestsUniqueIds(String interfaceId, List<CounterRequests> counterRequests) {
479 Set<String> result = new HashSet<>();
480 for (CounterRequests counterRequest : counterRequests) {
481 if (counterRequest.getPortId().equals(interfaceId)) {
482 result.add(counterRequest.getGeneratedUniqueId());
488 private Set<String> getAllRquestsUniqueIds(List<CounterRequests> counterRequests) {
489 Set<String> result = new HashSet<>();
490 for (CounterRequests counterRequest : counterRequests) {
491 result.add(counterRequest.getGeneratedUniqueId());
496 private void releaseIds(Set<String> ids) {
497 for (String id : ids) {
502 private void removeAllElementCounterRequestsOnPort(String interfaceId, List<CounterRequests> counterRequests) {
503 unbindCountersServiceIfBound(interfaceId, ElementCountersDirection.INGRESS);
504 unbindCountersServiceIfBound(interfaceId, ElementCountersDirection.EGRESS);
505 if (counterRequests != null) {
506 for (CounterRequests counterRequest : counterRequests) {
507 if (interfaceId.equals(counterRequest.getPortId())) {
508 countersRequestCleanup(counterRequest);
514 private void removeAllElementCounterRequests(List<CounterRequests> counterRequests) {
515 for (CounterRequests counterRequest : counterRequests) {
516 unbindCountersServiceIfBound(counterRequest.getPortId(), ElementCountersDirection.INGRESS);
517 unbindCountersServiceIfBound(counterRequest.getPortId(), ElementCountersDirection.EGRESS);
518 countersRequestCleanup(counterRequest);
522 private void countersRequestCleanup(CounterRequests counterRequest) {
523 ElementCountersDirection direction = ElementCountersDirection.valueOf(counterRequest.getTrafficDirection());
524 deleteCounterSpecificRules(counterRequest.getPortId(), counterRequest.getLportTag(), counterRequest.getDpn(),
525 direction, counterRequest.getFilters());
526 deleteCounterRequest(counterRequest, direction);
529 private void deleteCounterSpecificRules(String portId, int lportTag, BigInteger dpn,
530 ElementCountersDirection direction, Filters filters) {
531 List<ElementCountersRequest> ecrList = createElementCounterRequest(portId, lportTag, dpn, direction, filters);
532 for (ElementCountersRequest ecr : ecrList) {
533 if (ElementCountersDirection.INGRESS.equals(ecr.getDirection())) {
534 IngressCountersServiceImpl icsi = new IngressCountersServiceImpl(db, interfaceManager, mdsalApiManager);
535 icsi.deleteCounterRules(ecr);
536 } else if (ElementCountersDirection.EGRESS.equals(ecr.getDirection())) {
537 EgressCountersServiceImpl ecsi = new EgressCountersServiceImpl(db, interfaceManager, mdsalApiManager);
538 ecsi.deleteCounterRules(ecr);
543 private void deleteCounterRequest(CounterRequests counterRequest, ElementCountersDirection direction) {
544 ListenableFutures.addErrorLogging(
545 txRunner.callWithNewWriteOnlyTransactionAndSubmit(tx -> {
546 if (ElementCountersDirection.INGRESS.equals(direction)) {
547 tx.delete(LogicalDatastoreType.CONFIGURATION, InstanceIdentifier
548 .builder(IngressElementCountersRequestConfig.class)
549 .child(CounterRequests.class,
550 new CounterRequestsKey(counterRequest.key().getRequestId()))
552 } else if (ElementCountersDirection.EGRESS.equals(direction)) {
553 tx.delete(LogicalDatastoreType.CONFIGURATION, InstanceIdentifier
554 .builder(EgressElementCountersRequestConfig.class)
555 .child(CounterRequests.class,
556 new CounterRequestsKey(counterRequest.key().getRequestId()))
559 }), LOG, "Error deleting counter");
562 private CounterResultDataStructure createElementCountersResult(CounterRequests counterRequest) {
563 ElementCountersRequest ecr =
564 createElementCounterRequest(counterRequest.getPortId(), counterRequest.getLportTag(),
565 counterRequest.getDpn(), ElementCountersDirection.valueOf(counterRequest.getTrafficDirection()),
566 counterRequest.getFilters()).iterator().next();
567 BigInteger dpId = getDpn(ecr.getPortId());
568 InterfaceInfo interfaceInfo = interfaceManager.getInterfaceInfo(ecr.getPortId());
569 if (interfaceInfo == null) {
572 int lportTag = interfaceInfo.getInterfaceTag();
573 List<MatchInfoBase> matches = CountersServiceUtils.getCounterFlowMatch(ecr, lportTag,
574 ElementCountersDirection.valueOf(counterRequest.getTrafficDirection()));
575 Match match = MDSALUtil.buildMatches(matches);
576 return counterRetriever.getSwitchFlowCountersDirect(dpId, match);
579 private void initializeCountrsConfigDataSrore() {
580 ListenableFutures.addErrorLogging(
581 txRunner.callWithNewReadWriteTransactionAndSubmit(transaction -> {
582 Optional<IngressElementCountersRequestConfig> iecrcOpt =
583 transaction.read(LogicalDatastoreType.CONFIGURATION,
584 CountersServiceUtils.IECRC_IDENTIFIER).checkedGet();
585 Optional<EgressElementCountersRequestConfig> eecrcOpt =
586 transaction.read(LogicalDatastoreType.CONFIGURATION,
587 CountersServiceUtils.EECRC_IDENTIFIER).checkedGet();
588 if (!iecrcOpt.isPresent()) {
589 creatIngressEelementCountersContainerInConfig(transaction,
590 CountersServiceUtils.IECRC_IDENTIFIER);
592 if (!eecrcOpt.isPresent()) {
593 creatEgressEelementCountersContainerInConfig(transaction,
594 CountersServiceUtils.EECRC_IDENTIFIER);
596 }), LOG, "Failed to create counters in config datastore");
599 private void handleReleaseTransaction(WriteTransaction transaction, ReleaseElementCountersRequestHandlerInput input,
600 InstanceIdentifier<CounterRequests> path, Optional<CounterRequests> requestData,
601 List<CounterRequests> counterRequests) {
602 transaction.delete(LogicalDatastoreType.CONFIGURATION, path);
603 CounterRequests counterRequest = requestData.get();
604 if (shouldUnbindCountersService(counterRequest.getPortId(), counterRequest.key().getRequestId(),
606 unbindCountersServiceIfBound(counterRequest.getPortId(),
607 ElementCountersDirection.valueOf(counterRequest.getTrafficDirection()));
609 if (!isIdenticalCounterRequestExist(input.getHandler(), counterRequest.getPortId(),
610 counterRequest.getTrafficDirection(), counterRequest.getFilters(), counterRequests)) {
611 deleteCounterSpecificRules(counterRequest.getPortId(), counterRequest.getLportTag(),
612 counterRequest.getDpn(), ElementCountersDirection.valueOf(counterRequest.getTrafficDirection()),
613 counterRequest.getFilters());
617 private boolean getNodeConnectorResult(List<CounterResult> counters, BigInteger dpId, String portNumber) {
618 CounterResultDataStructure counterResultDS =
619 counterRetriever.getNodeConnectorCountersDirect(new NodeId(CountersUtils.getNodeId(dpId)),
620 new NodeConnectorId(CountersUtils.getNodeConnectorId(dpId, portNumber)));
621 if (counterResultDS == null) {
625 CounterResultBuilder crb = new CounterResultBuilder();
626 String resultId = CountersUtils.getNodeConnectorId(dpId, portNumber);
629 createGroups(counters, counterResultDS, crb, resultId);
631 return !counters.isEmpty();
634 private boolean getNodeResult(List<CounterResult> counters, BigInteger dpId) {
635 InstanceIdentifier<Node> nodeInstanceIdentifier = InstanceIdentifier.builder(Nodes.class)
636 .child(Node.class, new NodeKey(new NodeId(CountersUtils.getNodeId(dpId)))).build();
637 Optional<Node> nodeOptional = MDSALUtil.read(db, LogicalDatastoreType.OPERATIONAL, nodeInstanceIdentifier);
638 if (!nodeOptional.isPresent()) {
642 Node node = nodeOptional.get();
643 CounterResultDataStructure counterResultDS = counterRetriever.getNodeCountersDirect(node);
644 if (counterResultDS == null) {
648 createCounterResults(counters, counterResultDS);
650 return !counters.isEmpty();
653 private boolean getNodeAggregatedResult(List<CounterResult> aggregatedCounters, BigInteger dpId) {
654 InstanceIdentifier<Node> nodeInstanceIdentifier = InstanceIdentifier.builder(Nodes.class)
655 .child(Node.class, new NodeKey(new NodeId(CountersUtils.getNodeId(dpId)))).build();
656 Optional<Node> nodeOptional = MDSALUtil.read(db, LogicalDatastoreType.OPERATIONAL, nodeInstanceIdentifier);
657 if (!nodeOptional.isPresent()) {
661 Node node = nodeOptional.get();
662 CounterResultDataStructure counters = counterRetriever.getNodeCountersDirect(node);
663 if (counters == null || counters.isEmpty()) {
667 CounterResultDataStructure aggregatedResultsDS =
668 CountersUtils.aggregateCounters(counters, CountersUtils.getNodeId(dpId));
669 createCounterResults(aggregatedCounters, aggregatedResultsDS);
670 return !aggregatedCounters.isEmpty();
674 private void createCounterResults(List<CounterResult> counters, CounterResultDataStructure counterResultDS) {
675 for (String counterResultId : counterResultDS.getResults().keySet()) {
676 CounterResultBuilder crb = new CounterResultBuilder();
677 crb.setId(counterResultId);
678 createGroups(counters, counterResultDS, crb, counterResultId);
682 private void createCounterResults(List<CounterResult> counters, CounterResultDataStructure counterResultDS,
684 for (String counterResultId : counterResultDS.getResults().keySet()) {
685 CounterResultBuilder crb = new CounterResultBuilder();
687 createGroups(counters, counterResultDS, crb, counterResultId);
691 private void createGroups(List<CounterResult> counters, CounterResultDataStructure counterResultDS,
692 CounterResultBuilder crb, String resultId) {
693 List<Groups> groups = new ArrayList<>();
694 Map<String, Map<String, BigInteger>> counterGroups = counterResultDS.getGroups(resultId);
695 if (counterGroups != null && !counterGroups.isEmpty()) {
696 for (Entry<String, Map<String, BigInteger>> entry : counterGroups.entrySet()) {
697 String groupName = entry.getKey();
698 groups.add(createGroupsResult(groupName, entry.getValue()));
700 crb.setGroups(groups);
701 counters.add(crb.build());
705 private Groups createGroupsResult(String groupName, Map<String, BigInteger> countersMap) {
706 GroupsBuilder gb = new GroupsBuilder();
707 gb.setName(groupName);
709 Map<String, Counters> counters = new HashMap<>();
710 List<Counters> countersList = new ArrayList<>();
711 for (String counterName : countersMap.keySet()) {
712 addCountersToMap(countersMap, counters, counterName);
714 for (Counters counter : counters.values()) {
715 countersList.add(counter);
718 gb.setCounters(countersList);
722 private Counters buildCounter(String counterName, BigInteger value, Counters prevCounter) {
723 BigInteger prevValue = BigInteger.ZERO;
724 if (prevCounter != null) {
725 prevValue = prevCounter.getValue();
727 CountersBuilder cb = new CountersBuilder();
728 cb.setName(counterName);
729 cb.setValue(value.add(prevValue));
733 private void addCountersToMap(Map<String, BigInteger> result, Map<String, Counters> counters, String counterName) {
734 counters.put(counterName, buildCounter(counterName, result.get(counterName), counters.get(counterName)));
737 private void addElementCounterRequest(List<ElementCountersRequest> ecrList, String portId, int lportTag,
738 BigInteger dpn, ElementCountersDirection direction, Filters filters) {
739 ElementCountersRequest ecr = new ElementCountersRequest(portId);
740 ecr.setLportTag(lportTag);
742 ecr.setElementCountersDirection(direction);
743 if (filters.getIpFilter() != null) {
744 String ip = filters.getIpFilter().getIp();
746 ecr.addFilterToFilterGroup(CountersUtils.ELEMENT_COUNTERS_IP_FILTER_GROUP_NAME,
747 CountersUtils.IP_FILTER_NAME, ip);
751 boolean isTcpPortExist = false;
752 if (filters.getTcpFilter() != null && filters.getTcpFilter().isOn()) {
753 TcpFilter tcpFilter = filters.getTcpFilter();
754 int srcPort = tcpFilter.getSrcPort();
755 int dstPort = tcpFilter.getDstPort();
757 isTcpPortExist = true;
758 ecr.addFilterToFilterGroup(CountersUtils.ELEMENT_COUNTERS_TCP_FILTER_GROUP_NAME,
759 CountersUtils.TCP_SRC_PORT_FILTER_NAME, String.valueOf(srcPort));
762 isTcpPortExist = true;
763 ecr.addFilterToFilterGroup(CountersUtils.ELEMENT_COUNTERS_TCP_FILTER_GROUP_NAME,
764 CountersUtils.TCP_DST_PORT_FILTER_NAME, String.valueOf(dstPort));
766 if (!isTcpPortExist) {
767 ecr.addFilterToFilterGroup(CountersUtils.ELEMENT_COUNTERS_TCP_FILTER_GROUP_NAME,
768 CountersUtils.TCP_FILTER_NAME, "");
771 } else if (filters.getUdpFilter() != null && filters.getUdpFilter().isOn()) {
772 UdpFilter udpFilter = filters.getUdpFilter();
773 int srcPort = udpFilter.getSrcPort();
774 int dstPort = udpFilter.getDstPort();
776 isTcpPortExist = true;
777 ecr.addFilterToFilterGroup(CountersUtils.ELEMENT_COUNTERS_UDP_FILTER_GROUP_NAME,
778 CountersUtils.UDP_SRC_PORT_FILTER_NAME, String.valueOf(srcPort));
781 isTcpPortExist = true;
782 ecr.addFilterToFilterGroup(CountersUtils.ELEMENT_COUNTERS_UDP_FILTER_GROUP_NAME,
783 CountersUtils.UDP_DST_PORT_FILTER_NAME, String.valueOf(dstPort));
785 if (!isTcpPortExist) {
786 ecr.addFilterToFilterGroup(CountersUtils.ELEMENT_COUNTERS_UDP_FILTER_GROUP_NAME,
787 CountersUtils.UDP_FILTER_NAME, "");
791 if (!ecr.getFilters().isEmpty()) {
796 @SuppressFBWarnings("SLF4J_FORMAT_SHOULD_BE_CONST")
797 private void logElementCounterRequests(List<ElementCountersRequest> ecrList) {
798 for (ElementCountersRequest counterRequest : ecrList) {
799 LOG.debug(counterRequest.toString());
803 private void bindCountersServiceIfUnbound(String interfaceId, ElementCountersDirection direction) {
804 if (ElementCountersDirection.INGRESS.equals(direction) && !interfaceManager.isServiceBoundOnInterfaceForIngress(
805 CountersServiceUtils.INGRESS_COUNTERS_SERVICE_INDEX, interfaceId)) {
806 IngressCountersServiceImpl icsi = new IngressCountersServiceImpl(db, interfaceManager, mdsalApiManager);
807 icsi.bindService(interfaceId);
808 statisticsCounters.ingressCountersServiceBind();
809 } else if (ElementCountersDirection.EGRESS.equals(direction) && !interfaceManager
810 .isServiceBoundOnInterfaceForEgress(CountersServiceUtils.EGRESS_COUNTERS_SERVICE_INDEX, interfaceId)) {
811 EgressCountersServiceImpl ecsi = new EgressCountersServiceImpl(db, interfaceManager, mdsalApiManager);
812 ecsi.bindService(interfaceId);
813 statisticsCounters.egressCountersServiceBind();
817 private void unbindCountersServiceIfBound(String interfaceId, ElementCountersDirection direction) {
818 if (ElementCountersDirection.INGRESS.equals(direction) && interfaceManager.isServiceBoundOnInterfaceForIngress(
819 CountersServiceUtils.INGRESS_COUNTERS_SERVICE_INDEX, interfaceId)) {
820 IngressCountersServiceImpl icsi = new IngressCountersServiceImpl(db, interfaceManager, mdsalApiManager);
821 icsi.unBindService(interfaceId);
822 statisticsCounters.ingressCountersServiceUnbind();
823 } else if (ElementCountersDirection.EGRESS.equals(direction) && interfaceManager
824 .isServiceBoundOnInterfaceForEgress(CountersServiceUtils.EGRESS_COUNTERS_SERVICE_INDEX, interfaceId)) {
825 EgressCountersServiceImpl ecsi = new EgressCountersServiceImpl(db, interfaceManager, mdsalApiManager);
826 ecsi.unBindService(interfaceId);
827 statisticsCounters.egressCountersServiceUnbind();
831 private boolean shouldUnbindCountersService(String portId, String requesId, List<CounterRequests> counterRequests) {
832 for (CounterRequests counterRequest : counterRequests) {
833 if (portId.equals(counterRequest.getPortId()) && !requesId.equals(counterRequest.key().getRequestId())) {
840 private void installCounterSpecificRules(String portId, int lportTag, BigInteger dpn,
841 ElementCountersDirection direction, Filters filters) {
842 List<ElementCountersRequest> ecrList = createElementCounterRequest(portId, lportTag, dpn, direction, filters);
843 for (ElementCountersRequest ecr : ecrList) {
844 if (ElementCountersDirection.INGRESS.equals(ecr.getDirection())) {
845 IngressCountersServiceImpl icsi = new IngressCountersServiceImpl(db, interfaceManager, mdsalApiManager);
846 icsi.installCounterRules(ecr);
847 } else if (ElementCountersDirection.EGRESS.equals(ecr.getDirection())) {
848 EgressCountersServiceImpl ecsi = new EgressCountersServiceImpl(db, interfaceManager, mdsalApiManager);
849 ecsi.installCounterRules(ecr);
854 private boolean areFiltersEqual(Filters filterGroup1, Filters filterGroup2) {
855 if (filterGroup1 == null && filterGroup2 == null) {
858 if (filterGroup1 == null || filterGroup2 == null) {
862 return filterGroup1.toString().equals(filterGroup2.toString());
865 private void putIngressElementCounterRequestInConfig(AcquireElementCountersRequestHandlerInput input,
866 ElementCountersDirection direcion, ReadWriteTransaction transaction, String requestKey,
867 InstanceIdentifier<IngressElementCountersRequestConfig> ecrcIdentifier,
868 Optional<IngressElementCountersRequestConfig> iecrcOpt, String generatedUniqueId) {
869 IngressElementCountersRequestConfig requestConfig = iecrcOpt.get();
870 CounterRequestsBuilder crb = new CounterRequestsBuilder();
871 crb.setRequestId(requestKey);
872 crb.withKey(new CounterRequestsKey(requestKey));
873 crb.setFilters(input.getOutgoingTraffic().getFilters());
874 crb.setPortId(input.getPortId());
875 crb.setLportTag(getLportTag(input.getPortId()));
876 crb.setDpn(getDpn(input.getPortId()));
877 crb.setTrafficDirection(direcion.toString());
878 crb.setGeneratedUniqueId(generatedUniqueId);
879 List<CounterRequests> counterRequests = requestConfig.getCounterRequests();
880 counterRequests.add(crb.build());
882 IngressElementCountersRequestConfigBuilder ecrcb = new IngressElementCountersRequestConfigBuilder();
883 ecrcb.setCounterRequests(counterRequests);
884 requestConfig = ecrcb.build();
885 transaction.put(LogicalDatastoreType.CONFIGURATION, ecrcIdentifier, requestConfig,
886 WriteTransaction.CREATE_MISSING_PARENTS);
889 private void putEgressElementCounterRequestInConfig(AcquireElementCountersRequestHandlerInput input,
890 ElementCountersDirection direcion, ReadWriteTransaction transaction, String requestKey,
891 InstanceIdentifier<EgressElementCountersRequestConfig> ecrcIdentifier,
892 Optional<EgressElementCountersRequestConfig> eecrcOpt, String generatedUniqueId) {
893 EgressElementCountersRequestConfig requestConfig = eecrcOpt.get();
894 CounterRequestsBuilder crb = new CounterRequestsBuilder();
895 crb.setRequestId(requestKey);
896 crb.withKey(new CounterRequestsKey(requestKey));
897 crb.setFilters(input.getIncomingTraffic().getFilters());
898 crb.setPortId(input.getPortId());
899 crb.setLportTag(getLportTag(input.getPortId()));
900 crb.setDpn(getDpn(input.getPortId()));
901 crb.setTrafficDirection(direcion.toString());
902 crb.setGeneratedUniqueId(generatedUniqueId);
903 List<CounterRequests> counterRequests = requestConfig.getCounterRequests();
904 counterRequests.add(crb.build());
906 EgressElementCountersRequestConfigBuilder ecrcb = new EgressElementCountersRequestConfigBuilder();
907 ecrcb.setCounterRequests(counterRequests);
908 requestConfig = ecrcb.build();
909 transaction.put(LogicalDatastoreType.CONFIGURATION, ecrcIdentifier, requestConfig,
910 WriteTransaction.CREATE_MISSING_PARENTS);
913 private void creatIngressEelementCountersContainerInConfig(ReadWriteTransaction transaction,
914 InstanceIdentifier<IngressElementCountersRequestConfig> ecrcIdentifier) {
915 IngressElementCountersRequestConfigBuilder iecrcb = new IngressElementCountersRequestConfigBuilder();
916 List<CounterRequests> counterRequests = new ArrayList<>();
917 iecrcb.setCounterRequests(counterRequests);
918 IngressElementCountersRequestConfig iecrc = iecrcb.build();
919 transaction.put(LogicalDatastoreType.CONFIGURATION, ecrcIdentifier, iecrc,
920 WriteTransaction.CREATE_MISSING_PARENTS);
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,
930 WriteTransaction.CREATE_MISSING_PARENTS);
933 private Integer allocateId(String idKey) {
935 AllocateIdInput getIdInput = new AllocateIdInputBuilder().setPoolName(CountersServiceUtils.COUNTERS_PULL_NAME)
936 .setIdKey(idKey).build();
938 Future<RpcResult<AllocateIdOutput>> result = idManagerService.allocateId(getIdInput);
939 RpcResult<AllocateIdOutput> rpcResult = result.get();
940 if (rpcResult.isSuccessful()) {
941 return rpcResult.getResult().getIdValue().intValue();
943 LOG.warn("RPC Call to Get Unique Id returned with Errors {}", rpcResult.getErrors());
945 } catch (InterruptedException | ExecutionException e) {
946 LOG.warn("Exception when getting Unique Id", e);
951 private void createIdPool() {
952 if (checkPoolExists()) {
955 CreateIdPoolInput createPool = new CreateIdPoolInputBuilder()
956 .setPoolName(CountersServiceUtils.COUNTERS_PULL_NAME).setLow(CountersServiceUtils.COUNTERS_PULL_START)
957 .setHigh(CountersServiceUtils.COUNTERS_PULL_START + CountersServiceUtils.COUNTERS_PULL_END).build();
958 ListenableFuture<RpcResult<CreateIdPoolOutput>> result = idManagerService.createIdPool(createPool);
959 Futures.addCallback(result, new FutureCallback<RpcResult<CreateIdPoolOutput>>() {
962 public void onFailure(Throwable error) {
963 LOG.error("Failed to create idPool for Aliveness Monitor Service", error);
967 public void onSuccess(@Nonnull RpcResult<CreateIdPoolOutput> rpcResult) {
968 if (rpcResult.isSuccessful()) {
969 LOG.debug("Created IdPool for tap");
971 LOG.error("RPC to create Idpool failed {}", rpcResult.getErrors());
974 }, MoreExecutors.directExecutor());
977 private void releaseId(String idKey) {
978 ReleaseIdInput idInput = new ReleaseIdInputBuilder().setPoolName(CountersServiceUtils.COUNTERS_PULL_NAME)
979 .setIdKey(idKey).build();
981 RpcResult<ReleaseIdOutput> rpcResult = idManagerService.releaseId(idInput).get();
982 if (!rpcResult.isSuccessful()) {
983 LOG.warn("RPC Call to release Id with Key {} returned with Errors {}", idKey, rpcResult.getErrors());
985 } catch (InterruptedException | ExecutionException e) {
986 LOG.warn("Exception when releasing Id for key {}", idKey, e);
990 private boolean checkPoolExists() {
991 ReadOnlyTransaction roTransaction = db.newReadOnlyTransaction();
992 InstanceIdentifier<IdPool> path = InstanceIdentifier.create(IdPools.class).child(IdPool.class,
993 new IdPoolKey(CountersServiceUtils.COUNTERS_PULL_NAME));
994 CheckedFuture<Optional<IdPool>, ReadFailedException> pool =
995 roTransaction.read(LogicalDatastoreType.CONFIGURATION, path);
997 Optional<IdPool> poolOpt = pool.get();
998 if (poolOpt.isPresent()) {
1001 } catch (InterruptedException | ExecutionException e) {
1007 private boolean isIdenticalCounterRequestExist(String portId, String dirction, Filters filters,
1008 List<CounterRequests> counterRequests) {
1009 if (counterRequests.isEmpty()) {
1013 for (CounterRequests counterRequest : counterRequests) {
1014 if (portId.equals(counterRequest.getPortId()) && dirction.equals(counterRequest.getTrafficDirection())) {
1015 if (areFiltersEqual(filters, counterRequest.getFilters())) {
1023 private boolean isIdenticalCounterRequestExist(String requesId, String portId, String dirction, Filters filters,
1024 List<CounterRequests> counterRequests) {
1025 if (counterRequests.isEmpty()) {
1029 for (CounterRequests counterRequest : counterRequests) {
1030 if (portId.equals(counterRequest.getPortId()) && dirction.equals(counterRequest.getTrafficDirection())
1031 && !counterRequest.key().getRequestId().equals(requesId)) {
1032 if (areFiltersEqual(filters, counterRequest.getFilters())) {
1040 private int getLportTag(String interfaceId) {
1041 return interfaceManager.getInterfaceInfo(interfaceId).getInterfaceTag();
1044 private BigInteger getDpn(String interfaceId) {
1045 return interfaceManager.getDpnForInterface(interfaceId);
1048 private List<ElementCountersRequest> createElementCounterRequest(String portId, int lportTag, BigInteger dpn,
1049 ElementCountersDirection direcrtion, Filters filters) {
1050 List<ElementCountersRequest> ecrList = new ArrayList<>();
1051 LOG.debug("getting element counters for port {}", portId);
1052 addElementCounterRequest(ecrList, portId, lportTag, dpn, direcrtion, filters);
1054 logElementCounterRequests(ecrList);