import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
+import java.util.concurrent.Future;
import org.opendaylight.controller.sal.binding.api.data.DataModificationTransaction;
-import org.opendaylight.controller.sal.binding.api.data.DataProviderService;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.transaction.rev131103.TransactionAware;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.transaction.rev131103.TransactionId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeRef;
import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
import org.opendaylight.yangtools.yang.binding.InstanceIdentifier.InstanceIdentifierBuilder;
+import org.opendaylight.yangtools.yang.common.RpcResult;
+import com.google.common.base.Function;
import com.google.common.base.Preconditions;
+import com.google.common.util.concurrent.Futures;
+import com.google.common.util.concurrent.JdkFutureAdapters;
+import com.google.common.util.concurrent.ListenableFuture;
abstract class AbstractStatsTracker<I, K> {
+ private static final Function<RpcResult<? extends TransactionAware>, TransactionId> FUNCTION =
+ new Function<RpcResult<? extends TransactionAware>, TransactionId>() {
+ @Override
+ public TransactionId apply(RpcResult<? extends TransactionAware> input) {
+ return input.getResult().getTransactionId();
+ }
+ };
+
private final Map<K, Long> trackedItems = new HashMap<>();
- private final InstanceIdentifier<Node> nodeIdentifier;
- private final DataProviderService dps;
+ private final FlowCapableContext context;
private final long lifetimeNanos;
- protected AbstractStatsTracker(final InstanceIdentifier<Node> nodeIdentifier, final DataProviderService dps, long lifetimeNanos) {
- this.nodeIdentifier = Preconditions.checkNotNull(nodeIdentifier);
- this.dps = Preconditions.checkNotNull(dps);
+ protected AbstractStatsTracker(final FlowCapableContext context, final long lifetimeNanos) {
+ this.context = Preconditions.checkNotNull(context);
this.lifetimeNanos = lifetimeNanos;
}
protected final InstanceIdentifierBuilder<Node> getNodeIdentifierBuilder() {
- return InstanceIdentifier.builder(nodeIdentifier);
+ return InstanceIdentifier.builder(getNodeIdentifier());
+ }
+
+ protected final NodeRef getNodeRef() {
+ return context.getNodeRef();
+ }
+
+ protected final InstanceIdentifier<Node> getNodeIdentifier() {
+ return context.getNodeIdentifier();
+ }
+
+ protected static final <T extends TransactionAware> ListenableFuture<TransactionId> requestHelper(Future<RpcResult<T>> future) {
+ return Futures.transform(JdkFutureAdapters.listenInPoolThread(future), FUNCTION);
}
- final synchronized void updateStats(List<I> list) {
+ protected abstract void cleanupSingleStat(DataModificationTransaction trans, K item);
+ protected abstract K updateSingleStat(DataModificationTransaction trans, I item);
+
+ public final synchronized void updateStats(List<I> list) {
final Long expiryTime = System.nanoTime() + lifetimeNanos;
- final DataModificationTransaction trans = dps.beginTransaction();
+ final DataModificationTransaction trans = context.startDataModification();
for (final I item : list) {
trackedItems.put(updateSingleStat(trans, item), expiryTime);
trans.commit();
}
-
- final synchronized void cleanup(final DataModificationTransaction trans, long now) {
+ public final synchronized void cleanup(final DataModificationTransaction trans, long now) {
for (Iterator<Entry<K, Long>> it = trackedItems.entrySet().iterator();it.hasNext();){
Entry<K, Long> e = it.next();
if (now > e.getValue()) {
}
}
}
-
- protected abstract void cleanupSingleStat(DataModificationTransaction trans, K item);
- protected abstract K updateSingleStat(DataModificationTransaction trans, I item);
}
--- /dev/null
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.controller.md.statistics.manager;
+
+import org.opendaylight.controller.sal.binding.api.data.DataModificationTransaction;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeRef;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+
+/**
+ * Interface exposed to AbstractStatsTracker by its parent NodeStatisticsHandler.
+ * While we could simply exist without this interface, its purpose is to document
+ * the contract between the two classes.
+ */
+interface FlowCapableContext {
+ InstanceIdentifier<Node> getNodeIdentifier();
+ NodeRef getNodeRef();
+ DataModificationTransaction startDataModification();
+}
package org.opendaylight.controller.md.statistics.manager;
import org.opendaylight.controller.sal.binding.api.data.DataModificationTransaction;
-import org.opendaylight.controller.sal.binding.api.data.DataProviderService;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowId;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.Table;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.FlowKey;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.FlowStatisticsData;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.FlowStatisticsDataBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.GetAggregateFlowStatisticsFromFlowTableForAllFlowsInputBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.GetAllFlowsStatisticsFromAllFlowTablesInputBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.GetFlowStatisticsFromFlowTableInputBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.OpendaylightFlowStatisticsService;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.flow.and.statistics.map.list.FlowAndStatisticsMapList;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.flow.and.statistics.map.list.FlowAndStatisticsMapListBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.flow.statistics.FlowStatisticsBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.transaction.rev131103.TransactionId;
import org.opendaylight.yang.gen.v1.urn.opendaylight.model.statistics.types.rev130925.GenericStatistics;
import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import com.google.common.base.Preconditions;
+import com.google.common.util.concurrent.ListenableFuture;
+
final class FlowStatsTracker extends AbstractStatsTracker<FlowAndStatisticsMapList, FlowStatsEntry> {
private static final Logger logger = LoggerFactory.getLogger(FlowStatsTracker.class);
+ private final OpendaylightFlowStatisticsService flowStatsService;
private int unaccountedFlowsCounter = 1;
- FlowStatsTracker(InstanceIdentifier<Node> nodeIdentifier, DataProviderService dps, long lifetimeNanos) {
- super(nodeIdentifier, dps, lifetimeNanos);
+ FlowStatsTracker(OpendaylightFlowStatisticsService flowStatsService, final FlowCapableContext context, long lifetimeNanos) {
+ super(context, lifetimeNanos);
+ this.flowStatsService = Preconditions.checkNotNull(flowStatsService);
}
@Override
trans.putOperationalData(flowRef, flowBuilder.build());
return flowStatsEntry;
}
+
+ public ListenableFuture<TransactionId> requestAllFlowsAllTables() {
+ final GetAllFlowsStatisticsFromAllFlowTablesInputBuilder input = new GetAllFlowsStatisticsFromAllFlowTablesInputBuilder();
+ input.setNode(getNodeRef());
+
+ return requestHelper(flowStatsService.getAllFlowsStatisticsFromAllFlowTables(input.build()));
+ }
+
+ public ListenableFuture<TransactionId> requestAggregateFlows(final TableKey key) {
+ GetAggregateFlowStatisticsFromFlowTableForAllFlowsInputBuilder input =
+ new GetAggregateFlowStatisticsFromFlowTableForAllFlowsInputBuilder();
+
+ input.setNode(getNodeRef());
+ input.setTableId(new org.opendaylight.yang.gen.v1.urn.opendaylight.table.types.rev131026.TableId(key.getId()));
+ return requestHelper(flowStatsService.getAggregateFlowStatisticsFromFlowTableForAllFlows(input.build()));
+ }
+
+ public ListenableFuture<TransactionId> requestFlow(final Flow flow) {
+ final GetFlowStatisticsFromFlowTableInputBuilder input =
+ new GetFlowStatisticsFromFlowTableInputBuilder(flow);
+ input.setNode(getNodeRef());
+
+ return requestHelper(flowStatsService.getFlowStatisticsFromFlowTable(input.build()));
+ }
}
import java.util.concurrent.ConcurrentSkipListSet;
import org.opendaylight.controller.sal.binding.api.data.DataModificationTransaction;
-import org.opendaylight.controller.sal.binding.api.data.DataProviderService;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.Table;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.TableBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.TableKey;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.table.statistics.rev131215.FlowTableStatisticsData;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.table.statistics.rev131215.FlowTableStatisticsDataBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.table.statistics.rev131215.GetFlowTablesStatisticsInputBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.table.statistics.rev131215.OpendaylightFlowTableStatisticsService;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.table.statistics.rev131215.flow.table.and.statistics.map.FlowTableAndStatisticsMap;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.table.statistics.rev131215.flow.table.statistics.FlowTableStatistics;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.table.statistics.rev131215.flow.table.statistics.FlowTableStatisticsBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.transaction.rev131103.TransactionId;
import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import com.google.common.base.Preconditions;
+import com.google.common.util.concurrent.ListenableFuture;
+
final class FlowTableStatsTracker extends AbstractStatsTracker<FlowTableAndStatisticsMap, FlowTableAndStatisticsMap> {
private final Set<TableKey> privateTables = new ConcurrentSkipListSet<>();
private final Set<TableKey> tables = Collections.unmodifiableSet(privateTables);
+ private final OpendaylightFlowTableStatisticsService flowTableStatsService;
- FlowTableStatsTracker(InstanceIdentifier<Node> nodeIdentifier, DataProviderService dps, long lifetimeNanos) {
- super(nodeIdentifier, dps, lifetimeNanos);
+ FlowTableStatsTracker(OpendaylightFlowTableStatisticsService flowTableStatsService, final FlowCapableContext context, long lifetimeNanos) {
+ super(context, lifetimeNanos);
+ this.flowTableStatsService = Preconditions.checkNotNull(flowTableStatsService);
}
Set<TableKey> getTables() {
trans.putOperationalData(tableRef, tableBuilder.build());
return item;
}
+
+ public ListenableFuture<TransactionId> request() {
+ final GetFlowTablesStatisticsInputBuilder input = new GetFlowTablesStatisticsInputBuilder();
+ input.setNode(getNodeRef());
+
+ return requestHelper(flowTableStatsService.getFlowTablesStatistics(input.build()));
+ }
}
package org.opendaylight.controller.md.statistics.manager;
import org.opendaylight.controller.sal.binding.api.data.DataModificationTransaction;
-import org.opendaylight.controller.sal.binding.api.data.DataProviderService;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.transaction.rev131103.TransactionId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.GetGroupDescriptionInputBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.NodeGroupDescStats;
import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.NodeGroupDescStatsBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.OpendaylightGroupStatisticsService;
import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.group.desc.GroupDescBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.group.desc.stats.reply.GroupDescStats;
import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.groups.Group;
import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.groups.GroupBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.groups.GroupKey;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import com.google.common.base.Preconditions;
+import com.google.common.util.concurrent.ListenableFuture;
+
final class GroupDescStatsTracker extends AbstractStatsTracker<GroupDescStats, GroupDescStats> {
- public GroupDescStatsTracker(final InstanceIdentifier<Node> targetNodeIdentifier, final DataProviderService dps, final long lifetimeNanos) {
- super(targetNodeIdentifier, dps, lifetimeNanos);
+ private final OpendaylightGroupStatisticsService groupStatsService;
+
+ public GroupDescStatsTracker(OpendaylightGroupStatisticsService groupStatsService, final FlowCapableContext context, final long lifetimeNanos) {
+ super(context, lifetimeNanos);
+ this.groupStatsService = Preconditions.checkNotNull(groupStatsService);
}
@Override
.child(Group.class, new GroupKey(item.getGroupId())).augmentation(NodeGroupDescStats.class).build();
trans.removeOperationalData(groupRef);
}
+
+ public ListenableFuture<TransactionId> request() {
+ final GetGroupDescriptionInputBuilder input = new GetGroupDescriptionInputBuilder();
+ input.setNode(getNodeRef());
+
+ return requestHelper(groupStatsService.getGroupDescription(input.build()));
+ }
}
package org.opendaylight.controller.md.statistics.manager;
import org.opendaylight.controller.sal.binding.api.data.DataModificationTransaction;
-import org.opendaylight.controller.sal.binding.api.data.DataProviderService;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.transaction.rev131103.TransactionId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.GetAllGroupStatisticsInputBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.NodeGroupStatistics;
import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.NodeGroupStatisticsBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.OpendaylightGroupStatisticsService;
import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.group.statistics.GroupStatisticsBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.group.statistics.reply.GroupStats;
import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.groups.Group;
import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.groups.GroupBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.groups.GroupKey;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import com.google.common.base.Preconditions;
+import com.google.common.util.concurrent.ListenableFuture;
+
final class GroupStatsTracker extends AbstractStatsTracker<GroupStats, GroupStats> {
+ private final OpendaylightGroupStatisticsService groupStatsService;
- GroupStatsTracker(InstanceIdentifier<Node> nodeIdentifier, DataProviderService dps, long lifetimeNanos) {
- super(nodeIdentifier, dps, lifetimeNanos);
+ GroupStatsTracker(OpendaylightGroupStatisticsService groupStatsService, FlowCapableContext context, long lifetimeNanos) {
+ super(context, lifetimeNanos);
+ this.groupStatsService = Preconditions.checkNotNull(groupStatsService);
}
@Override
return item;
}
+ public ListenableFuture<TransactionId> request() {
+ final GetAllGroupStatisticsInputBuilder input = new GetAllGroupStatisticsInputBuilder();
+ input.setNode(getNodeRef());
+
+ return requestHelper(groupStatsService.getAllGroupStatistics(input.build()));
+ }
}
package org.opendaylight.controller.md.statistics.manager;
import org.opendaylight.controller.sal.binding.api.data.DataModificationTransaction;
-import org.opendaylight.controller.sal.binding.api.data.DataProviderService;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.meters.Meter;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.meters.MeterBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.meters.MeterKey;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.transaction.rev131103.TransactionId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.GetAllMeterConfigStatisticsInputBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.NodeMeterConfigStats;
import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.NodeMeterConfigStatsBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.OpendaylightMeterStatisticsService;
import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.nodes.node.meter.MeterConfigStatsBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.types.rev130918.meter.config.stats.reply.MeterConfigStats;
import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import com.google.common.base.Preconditions;
+import com.google.common.util.concurrent.ListenableFuture;
+
final class MeterConfigStatsTracker extends AbstractStatsTracker<MeterConfigStats, MeterConfigStats> {
- protected MeterConfigStatsTracker(InstanceIdentifier<Node> nodeIdentifier, DataProviderService dps, long lifetimeNanos) {
- super(nodeIdentifier, dps, lifetimeNanos);
+ private final OpendaylightMeterStatisticsService meterStatsService;
+
+ protected MeterConfigStatsTracker(OpendaylightMeterStatisticsService meterStatsService, final FlowCapableContext context, long lifetimeNanos) {
+ super(context, lifetimeNanos);
+ this.meterStatsService = Preconditions.checkNotNull(meterStatsService);
}
@Override
return item;
}
+ public ListenableFuture<TransactionId> request() {
+ GetAllMeterConfigStatisticsInputBuilder input = new GetAllMeterConfigStatisticsInputBuilder();
+ input.setNode(getNodeRef());
+
+ return requestHelper(meterStatsService.getAllMeterConfigStatistics(input.build()));
+ }
}
package org.opendaylight.controller.md.statistics.manager;
import org.opendaylight.controller.sal.binding.api.data.DataModificationTransaction;
-import org.opendaylight.controller.sal.binding.api.data.DataProviderService;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.meters.Meter;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.meters.MeterBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.meters.MeterKey;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.transaction.rev131103.TransactionId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.GetAllMeterStatisticsInputBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.NodeMeterStatistics;
import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.NodeMeterStatisticsBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.OpendaylightMeterStatisticsService;
import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.nodes.node.meter.MeterStatisticsBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.types.rev130918.meter.statistics.reply.MeterStats;
import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import com.google.common.base.Preconditions;
+import com.google.common.util.concurrent.ListenableFuture;
+
final class MeterStatsTracker extends AbstractStatsTracker<MeterStats, MeterStats> {
+ private final OpendaylightMeterStatisticsService meterStatsService;
- MeterStatsTracker(InstanceIdentifier<Node> nodeIdentifier, DataProviderService dps, long lifetimeNanos) {
- super(nodeIdentifier, dps, lifetimeNanos);
+ MeterStatsTracker(OpendaylightMeterStatisticsService meterStatsService, final FlowCapableContext context, long lifetimeNanos) {
+ super(context, lifetimeNanos);
+ this.meterStatsService = Preconditions.checkNotNull(meterStatsService);
}
@Override
trans.putOperationalData(meterRef, meterBuilder.build());
return item;
}
+
+ public ListenableFuture<TransactionId> request() {
+ GetAllMeterStatisticsInputBuilder input = new GetAllMeterStatisticsInputBuilder();
+ input.setNode(getNodeRef());
+
+ return requestHelper(meterStatsService.getAllMeterStatistics(input.build()));
+ }
}
*/
package org.opendaylight.controller.md.statistics.manager;
-import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.TimeUnit;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.transaction.rev131103.TransactionAware;
* by Statistics Manager. Statistics Manager won't entertain any multipart
* response for which it didn't send the request.
*/
- private final Map<TxIdEntry,Long> txIdToRequestTypeMap = new HashMap<>();
+ private final Map<TxIdEntry,Long> txIdToRequestTypeMap = new ConcurrentHashMap<>();
/*
* Map to keep track of the request tx id for flow table statistics request.
* Because flow table statistics multi part response do not contains the table id.
*/
- private final Map<TxIdEntry,Short> txIdTotableIdMap = new HashMap<>();
+ private final Map<TxIdEntry,Short> txIdTotableIdMap = new ConcurrentHashMap<>();
private static final class TxIdEntry {
private final StatsRequestType requestType;
StatisticsProvider.STATS_COLLECTION_MILLIS*NUMBER_OF_WAIT_CYCLES);
}
- public enum StatsRequestType{
+ public enum StatsRequestType {
ALL_FLOW,
AGGR_FLOW,
ALL_PORT,
METER_CONFIG
}
- public void cleanStaleTransactionIds(){
+ public void cleanStaleTransactionIds() {
final long now = System.nanoTime();
for (Iterator<TxIdEntry> it = txIdToRequestTypeMap.keySet().iterator();it.hasNext();){
package org.opendaylight.controller.md.statistics.manager;
import org.opendaylight.controller.sal.binding.api.data.DataModificationTransaction;
-import org.opendaylight.controller.sal.binding.api.data.DataProviderService;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.transaction.rev131103.TransactionId;
import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnector;
import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnectorBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnectorKey;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
import org.opendaylight.yang.gen.v1.urn.opendaylight.port.statistics.rev131214.FlowCapableNodeConnectorStatisticsData;
import org.opendaylight.yang.gen.v1.urn.opendaylight.port.statistics.rev131214.FlowCapableNodeConnectorStatisticsDataBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.port.statistics.rev131214.GetAllNodeConnectorsStatisticsInputBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.port.statistics.rev131214.OpendaylightPortStatisticsService;
import org.opendaylight.yang.gen.v1.urn.opendaylight.port.statistics.rev131214.flow.capable.node.connector.statistics.FlowCapableNodeConnectorStatisticsBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.port.statistics.rev131214.node.connector.statistics.and.port.number.map.NodeConnectorStatisticsAndPortNumberMap;
import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import com.google.common.base.Preconditions;
+import com.google.common.util.concurrent.ListenableFuture;
+
final class NodeConnectorStatsTracker extends AbstractStatsTracker<NodeConnectorStatisticsAndPortNumberMap, NodeConnectorStatisticsAndPortNumberMap> {
private static final Logger logger = LoggerFactory.getLogger(NodeConnectorStatsTracker.class);
+ private final OpendaylightPortStatisticsService portStatsService;
- NodeConnectorStatsTracker(InstanceIdentifier<Node> nodeIdentifier, DataProviderService dps, long lifetimeNanos) {
- super(nodeIdentifier, dps, lifetimeNanos);
+ NodeConnectorStatsTracker(final OpendaylightPortStatisticsService portStatsService, final FlowCapableContext context, long lifetimeNanos) {
+ super(context, lifetimeNanos);
+ this.portStatsService = Preconditions.checkNotNull(portStatsService);
}
@Override
return item;
}
+
+ public ListenableFuture<TransactionId> request() {
+ final GetAllNodeConnectorsStatisticsInputBuilder input = new GetAllNodeConnectorsStatisticsInputBuilder();
+ input.setNode(getNodeRef());
+
+ return requestHelper(portStatsService.getAllNodeConnectorsStatistics(input.build()));
+ }
}
import java.util.Collection;
import java.util.List;
-import java.util.concurrent.ExecutionException;
-import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import org.opendaylight.controller.md.statistics.manager.MultipartMessageManager.StatsRequestType;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.Flow;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.AggregateFlowStatisticsData;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.AggregateFlowStatisticsDataBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.GetAggregateFlowStatisticsFromFlowTableForAllFlowsInputBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.GetAggregateFlowStatisticsFromFlowTableForAllFlowsOutput;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.GetAllFlowsStatisticsFromAllFlowTablesInputBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.GetAllFlowsStatisticsFromAllFlowTablesOutput;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.GetFlowStatisticsFromFlowTableInputBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.GetFlowStatisticsFromFlowTableOutput;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.OpendaylightFlowStatisticsService;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.aggregate.flow.statistics.AggregateFlowStatisticsBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.flow.and.statistics.map.list.FlowAndStatisticsMapList;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.table.statistics.rev131215.GetFlowTablesStatisticsInputBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.table.statistics.rev131215.GetFlowTablesStatisticsOutput;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.table.statistics.rev131215.OpendaylightFlowTableStatisticsService;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.table.statistics.rev131215.flow.table.and.statistics.map.FlowTableAndStatisticsMap;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.transaction.rev131103.TransactionAware;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.transaction.rev131103.TransactionId;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.queue.rev130925.QueueId;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.GetAllGroupStatisticsInputBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.GetAllGroupStatisticsOutput;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.GetGroupDescriptionInputBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.GetGroupDescriptionOutput;
import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.NodeGroupFeatures;
import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.NodeGroupFeaturesBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.OpendaylightGroupStatisticsService;
import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeKey;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.GetAllMeterConfigStatisticsInputBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.GetAllMeterConfigStatisticsOutput;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.GetAllMeterStatisticsInputBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.GetAllMeterStatisticsOutput;
import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.NodeMeterFeatures;
import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.NodeMeterFeaturesBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.OpendaylightMeterStatisticsService;
import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.types.rev130918.meter.config.stats.reply.MeterConfigStats;
import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.types.rev130918.meter.statistics.reply.MeterStats;
import org.opendaylight.yang.gen.v1.urn.opendaylight.model.statistics.types.rev130925.AggregateFlowStatistics;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.port.statistics.rev131214.GetAllNodeConnectorsStatisticsInputBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.port.statistics.rev131214.GetAllNodeConnectorsStatisticsOutput;
import org.opendaylight.yang.gen.v1.urn.opendaylight.port.statistics.rev131214.OpendaylightPortStatisticsService;
import org.opendaylight.yang.gen.v1.urn.opendaylight.port.statistics.rev131214.node.connector.statistics.and.port.number.map.NodeConnectorStatisticsAndPortNumberMap;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.queue.statistics.rev131216.GetAllQueuesStatisticsFromAllPortsInputBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.queue.statistics.rev131216.GetAllQueuesStatisticsFromAllPortsOutput;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.queue.statistics.rev131216.GetQueueStatisticsFromGivenPortInputBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.queue.statistics.rev131216.GetQueueStatisticsFromGivenPortOutput;
import org.opendaylight.yang.gen.v1.urn.opendaylight.queue.statistics.rev131216.OpendaylightQueueStatisticsService;
import org.opendaylight.yang.gen.v1.urn.opendaylight.queue.statistics.rev131216.queue.id.and.statistics.map.QueueIdAndStatisticsMap;
import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
-import org.opendaylight.yangtools.yang.common.RpcResult;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.google.common.base.Preconditions;
+import com.google.common.util.concurrent.FutureCallback;
+import com.google.common.util.concurrent.Futures;
+import com.google.common.util.concurrent.ListenableFuture;
/**
* This class handles the lifecycle of per-node statistics. It receives data
*
* @author avishnoi@in.ibm.com
*/
-public final class NodeStatisticsHandler implements AutoCloseable {
+public final class NodeStatisticsHandler implements AutoCloseable, FlowCapableContext {
private static final Logger logger = LoggerFactory.getLogger(NodeStatisticsHandler.class);
private static final int NUMBER_OF_WAIT_CYCLES = 2;
- private final OpendaylightFlowStatisticsService flowStatsService;
- private final OpendaylightFlowTableStatisticsService flowTableStatsService;
- private final OpendaylightGroupStatisticsService groupStatsService;
- private final OpendaylightMeterStatisticsService meterStatsService;
- private final OpendaylightPortStatisticsService portStatsService;
- private final OpendaylightQueueStatisticsService queueStatsService;
-
private final MultipartMessageManager msgManager = new MultipartMessageManager();
private final InstanceIdentifier<Node> targetNodeIdentifier;
private final FlowStatsTracker flowStats;
this.targetNodeIdentifier = InstanceIdentifier.builder(Nodes.class).child(Node.class, targetNodeKey).build();
this.targetNodeRef = new NodeRef(targetNodeIdentifier);
- this.flowStatsService = flowStatsService;
- this.flowTableStatsService = flowTableStatsService;
- this.groupStatsService = groupStatsService;
- this.meterStatsService = meterStatsService;
- this.portStatsService = portStatsService;
- this.queueStatsService = queueStatsService;
-
final long lifetimeNanos = TimeUnit.MILLISECONDS.toNanos(StatisticsProvider.STATS_COLLECTION_MILLIS * NUMBER_OF_WAIT_CYCLES);
- flowStats = new FlowStatsTracker(targetNodeIdentifier, dps, lifetimeNanos);
- flowTableStats = new FlowTableStatsTracker(targetNodeIdentifier, dps, lifetimeNanos);
- groupDescStats = new GroupDescStatsTracker(targetNodeIdentifier, dps, lifetimeNanos);
- groupStats = new GroupStatsTracker(targetNodeIdentifier, dps, lifetimeNanos);
- meterConfigStats = new MeterConfigStatsTracker(targetNodeIdentifier, dps, lifetimeNanos);
- meterStats = new MeterStatsTracker(targetNodeIdentifier, dps, lifetimeNanos);
- nodeConnectorStats = new NodeConnectorStatsTracker(targetNodeIdentifier, dps, lifetimeNanos);
- queueStats = new QueueStatsTracker(targetNodeIdentifier, dps, lifetimeNanos);
+
+ if (flowStatsService != null) {
+ flowStats = new FlowStatsTracker(flowStatsService, this, lifetimeNanos);
+ } else {
+ flowStats = null;
+ }
+ if (flowTableStatsService != null) {
+ flowTableStats = new FlowTableStatsTracker(flowTableStatsService, this, lifetimeNanos);
+ } else {
+ flowTableStats = null;
+ }
+
+ if (groupStatsService != null) {
+ groupDescStats = new GroupDescStatsTracker(groupStatsService, this, lifetimeNanos);
+ groupStats = new GroupStatsTracker(groupStatsService, this, lifetimeNanos);
+ } else {
+ groupDescStats = null;
+ groupStats = null;
+ }
+ if (meterStatsService != null) {
+ meterConfigStats = new MeterConfigStatsTracker(meterStatsService, this, lifetimeNanos);
+ meterStats = new MeterStatsTracker(meterStatsService, this, lifetimeNanos);
+ } else {
+ meterConfigStats = null;
+ meterStats = null;
+ }
+ if (portStatsService != null) {
+ nodeConnectorStats = new NodeConnectorStatsTracker(portStatsService, this, lifetimeNanos);
+ } else {
+ nodeConnectorStats = null;
+ }
+ if (queueStatsService != null) {
+ queueStats = new QueueStatsTracker(queueStatsService, this, lifetimeNanos);
+ } else {
+ queueStats = null;
+ }
}
public NodeKey getTargetNodeKey() {
return targetNodeKey;
}
- public Collection<TableKey> getKnownTables() {
- return flowTableStats.getTables();
- }
-
- public InstanceIdentifier<Node> getTargetNodeIdentifier() {
+ @Override
+ public InstanceIdentifier<Node> getNodeIdentifier() {
return targetNodeIdentifier;
}
- public NodeRef getTargetNodeRef() {
+ @Override
+ public NodeRef getNodeRef() {
return targetNodeRef;
}
+ @Override
+ public DataModificationTransaction startDataModification() {
+ return dps.beginTransaction();
+ }
+
public synchronized void updateGroupDescStats(TransactionAware transaction, Boolean more, List<GroupDescStats> list) {
if (msgManager.isExpectedTransaction(transaction, more)) {
groupDescStats.updateStats(list);
public synchronized void requestPeriodicStatistics() {
logger.debug("Send requests for statistics collection to node : {}", targetNodeKey);
- try{
- if(flowTableStatsService != null){
- final GetFlowTablesStatisticsInputBuilder input = new GetFlowTablesStatisticsInputBuilder();
- input.setNode(targetNodeRef);
-
- Future<RpcResult<GetFlowTablesStatisticsOutput>> response = flowTableStatsService.getFlowTablesStatistics(input.build());
- recordExpectedTransaction(response.get().getResult().getTransactionId(), StatsRequestType.ALL_FLOW_TABLE);
+ if (flowTableStats != null){
+ registerTransaction(flowTableStats.request(), StatsRequestType.ALL_FLOW);
+ }
+ if (flowStats != null){
+ // FIXME: it does not make sense to trigger this before sendAllFlowTablesStatisticsRequest()
+ // comes back -- we do not have any tables anyway.
+ final Collection<TableKey> tables = flowTableStats.getTables();
+ logger.debug("Node {} supports {} table(s)", targetNodeKey, tables.size());
+ for (final TableKey key : tables) {
+ logger.debug("Send aggregate stats request for flow table {} to node {}", key.getId(), targetNodeKey);
+ registerTableTransaction(flowStats.requestAggregateFlows(key), key.getId());
}
- if(flowStatsService != null){
- // FIXME: it does not make sense to trigger this before sendAllFlowTablesStatisticsRequest()
- // comes back -- we do not have any tables anyway.
- sendAggregateFlowsStatsFromAllTablesRequest();
- sendAllFlowsStatsFromAllTablesRequest();
- }
- if(portStatsService != null){
- sendAllNodeConnectorsStatisticsRequest();
- }
- if(groupStatsService != null){
- sendAllGroupStatisticsRequest();
- sendGroupDescriptionRequest();
- }
- if(meterStatsService != null){
- sendAllMeterStatisticsRequest();
- sendMeterConfigStatisticsRequest();
- }
- if(queueStatsService != null){
- sendAllQueueStatsFromAllNodeConnector();
- }
- } catch(Exception e) {
- logger.error("Exception occured while sending statistics requests", e);
+ registerTransaction(flowStats.requestAllFlowsAllTables(), StatsRequestType.ALL_FLOW);
+ }
+
+ if (nodeConnectorStats != null) {
+ registerTransaction(nodeConnectorStats.request(), StatsRequestType.ALL_PORT);
+ }
+
+ if (groupStats != null) {
+ registerTransaction(groupStats.request(), StatsRequestType.ALL_GROUP);
+ }
+ sendGroupDescriptionRequest();
+
+ if (meterStats != null) {
+ registerTransaction(meterStats.request(), StatsRequestType.ALL_METER);
+ }
+ sendMeterConfigStatisticsRequest();
+
+ if(queueStats != null) {
+ registerTransaction(queueStats.request(), StatsRequestType.ALL_QUEUE_STATS);
}
}
logger.debug("Statistics handler for {} shut down", targetNodeKey.getId());
}
- synchronized void sendFlowStatsFromTableRequest(Flow flow) throws InterruptedException, ExecutionException{
- final GetFlowStatisticsFromFlowTableInputBuilder input =
- new GetFlowStatisticsFromFlowTableInputBuilder(flow);
-
- input.setNode(targetNodeRef);
-
- Future<RpcResult<GetFlowStatisticsFromFlowTableOutput>> response =
- flowStatsService.getFlowStatisticsFromFlowTable(input.build());
-
- recordExpectedTransaction(response.get().getResult().getTransactionId(), StatsRequestType.ALL_FLOW);
- }
-
- synchronized void sendGroupDescriptionRequest() throws InterruptedException, ExecutionException{
- final GetGroupDescriptionInputBuilder input = new GetGroupDescriptionInputBuilder();
-
- input.setNode(targetNodeRef);
-
- Future<RpcResult<GetGroupDescriptionOutput>> response =
- groupStatsService.getGroupDescription(input.build());
-
- recordExpectedTransaction(response.get().getResult().getTransactionId(), StatsRequestType.GROUP_DESC);
- }
-
- synchronized void sendMeterConfigStatisticsRequest() throws InterruptedException, ExecutionException{
-
- GetAllMeterConfigStatisticsInputBuilder input = new GetAllMeterConfigStatisticsInputBuilder();
-
- input.setNode(targetNodeRef);
-
- Future<RpcResult<GetAllMeterConfigStatisticsOutput>> response =
- meterStatsService.getAllMeterConfigStatistics(input.build());
-
- recordExpectedTransaction(response.get().getResult().getTransactionId(), StatsRequestType.METER_CONFIG);
- }
-
- synchronized void sendQueueStatsFromGivenNodeConnector(NodeConnectorId nodeConnectorId, QueueId queueId) throws InterruptedException, ExecutionException {
- GetQueueStatisticsFromGivenPortInputBuilder input = new GetQueueStatisticsFromGivenPortInputBuilder();
-
- input.setNode(targetNodeRef);
- input.setNodeConnectorId(nodeConnectorId);
- input.setQueueId(queueId);
- Future<RpcResult<GetQueueStatisticsFromGivenPortOutput>> response =
- queueStatsService.getQueueStatisticsFromGivenPort(input.build());
-
- recordExpectedTransaction(response.get().getResult().getTransactionId(), StatsRequestType.ALL_QUEUE_STATS);;
- }
-
- private void sendAllMeterStatisticsRequest() throws InterruptedException, ExecutionException{
-
- GetAllMeterStatisticsInputBuilder input = new GetAllMeterStatisticsInputBuilder();
-
- input.setNode(targetNodeRef);
-
- Future<RpcResult<GetAllMeterStatisticsOutput>> response =
- meterStatsService.getAllMeterStatistics(input.build());
-
- recordExpectedTransaction(response.get().getResult().getTransactionId(), StatsRequestType.ALL_METER);
- }
-
- private void sendAllFlowsStatsFromAllTablesRequest() throws InterruptedException, ExecutionException{
- final GetAllFlowsStatisticsFromAllFlowTablesInputBuilder input = new GetAllFlowsStatisticsFromAllFlowTablesInputBuilder();
- input.setNode(targetNodeRef);
-
- Future<RpcResult<GetAllFlowsStatisticsFromAllFlowTablesOutput>> response = flowStatsService.getAllFlowsStatisticsFromAllFlowTables(input.build());
+ synchronized void sendFlowStatsFromTableRequest(Flow flow) {
+ if (flowStats == null) {
+ logger.debug("No Flow statistics service, not sending a request");
+ return;
+ }
- recordExpectedTransaction(response.get().getResult().getTransactionId(), StatsRequestType.ALL_FLOW);
+ registerTransaction(flowStats.requestFlow(flow), StatsRequestType.ALL_FLOW);
}
- private void sendAggregateFlowsStatsFromAllTablesRequest() throws InterruptedException, ExecutionException{
- final Collection<TableKey> tables = getKnownTables();
- logger.debug("Node {} supports {} table(s)", targetNodeKey, tables.size());
-
- for (TableKey key : tables) {
- sendAggregateFlowsStatsFromTableRequest(key.getId().shortValue());
+ synchronized void sendGroupDescriptionRequest() {
+ if (groupStats == null) {
+ logger.debug("No Group Descriptor statistics service, not sending a request");
+ return;
}
- }
- private void sendAggregateFlowsStatsFromTableRequest(Short tableId) throws InterruptedException, ExecutionException{
- logger.debug("Send aggregate stats request for flow table {} to node {}",tableId, targetNodeKey);
- GetAggregateFlowStatisticsFromFlowTableForAllFlowsInputBuilder input =
- new GetAggregateFlowStatisticsFromFlowTableForAllFlowsInputBuilder();
-
- input.setNode(new NodeRef(InstanceIdentifier.builder(Nodes.class).child(Node.class, targetNodeKey).toInstance()));
- input.setTableId(new org.opendaylight.yang.gen.v1.urn.opendaylight.table.types.rev131026.TableId(tableId));
- Future<RpcResult<GetAggregateFlowStatisticsFromFlowTableForAllFlowsOutput>> response =
- flowStatsService.getAggregateFlowStatisticsFromFlowTableForAllFlows(input.build());
-
- recordExpectedTableTransaction(response.get().getResult().getTransactionId(), tableId);
+ registerTransaction(groupDescStats.request(), StatsRequestType.GROUP_DESC);
}
- private void sendAllQueueStatsFromAllNodeConnector() throws InterruptedException, ExecutionException {
- GetAllQueuesStatisticsFromAllPortsInputBuilder input = new GetAllQueuesStatisticsFromAllPortsInputBuilder();
-
- input.setNode(targetNodeRef);
-
- Future<RpcResult<GetAllQueuesStatisticsFromAllPortsOutput>> response =
- queueStatsService.getAllQueuesStatisticsFromAllPorts(input.build());
+ synchronized void sendMeterConfigStatisticsRequest() {
+ if (meterConfigStats == null) {
+ logger.debug("No Meter Config statistics service, not sending a request");
+ return;
+ }
- recordExpectedTransaction(response.get().getResult().getTransactionId(), StatsRequestType.ALL_QUEUE_STATS);
+ registerTransaction(meterConfigStats.request(), StatsRequestType.METER_CONFIG);
}
- private void sendAllNodeConnectorsStatisticsRequest() throws InterruptedException, ExecutionException{
- final GetAllNodeConnectorsStatisticsInputBuilder input = new GetAllNodeConnectorsStatisticsInputBuilder();
-
- input.setNode(targetNodeRef);
+ synchronized void sendQueueStatsFromGivenNodeConnector(NodeConnectorId nodeConnectorId, QueueId queueId) {
+ if (queueStats == null) {
+ logger.debug("No Queue statistics service, not sending a request");
+ return;
+ }
- Future<RpcResult<GetAllNodeConnectorsStatisticsOutput>> response =
- portStatsService.getAllNodeConnectorsStatistics(input.build());
- recordExpectedTransaction(response.get().getResult().getTransactionId(), StatsRequestType.ALL_PORT);
+ registerTransaction(queueStats.request(nodeConnectorId, queueId), StatsRequestType.ALL_QUEUE_STATS);
}
- private void sendAllGroupStatisticsRequest() throws InterruptedException, ExecutionException{
- final GetAllGroupStatisticsInputBuilder input = new GetAllGroupStatisticsInputBuilder();
- input.setNode(targetNodeRef);
-
- Future<RpcResult<GetAllGroupStatisticsOutput>> response =
- groupStatsService.getAllGroupStatistics(input.build());
+ private void registerTransaction(final ListenableFuture<TransactionId> future, final StatsRequestType type) {
+ Futures.addCallback(future, new FutureCallback<TransactionId>() {
+ @Override
+ public void onSuccess(TransactionId result) {
+ msgManager.recordExpectedTransaction(result, type);
+ logger.debug("Transaction {} for node {} sent successfully", result, targetNodeKey);
+ }
- recordExpectedTransaction(response.get().getResult().getTransactionId(), StatsRequestType.ALL_GROUP);
+ @Override
+ public void onFailure(Throwable t) {
+ logger.warn("Failed to send statistics request for node {}", targetNodeKey, t);
+ }
+ });
}
- private void recordExpectedTransaction(TransactionId transactionId, StatsRequestType reqType) {
- msgManager.recordExpectedTransaction(transactionId, reqType);
- }
+ private void registerTableTransaction(final ListenableFuture<TransactionId> future, final Short id) {
+ Futures.addCallback(future, new FutureCallback<TransactionId>() {
+ @Override
+ public void onSuccess(TransactionId result) {
+ msgManager.recordExpectedTableTransaction(result, StatsRequestType.AGGR_FLOW, id);
+ logger.debug("Transaction {} for node {} table {} sent successfully", result, targetNodeKey, id);
+ }
- private void recordExpectedTableTransaction(TransactionId transactionId, Short tableId) {
- msgManager.recordExpectedTableTransaction(transactionId, StatsRequestType.AGGR_FLOW, tableId);
+ @Override
+ public void onFailure(Throwable t) {
+ logger.warn("Failed to send table statistics request for node {} table {}", targetNodeKey, id, t);
+ }
+ });
}
}
package org.opendaylight.controller.md.statistics.manager;
import org.opendaylight.controller.sal.binding.api.data.DataModificationTransaction;
-import org.opendaylight.controller.sal.binding.api.data.DataProviderService;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNodeConnector;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.transaction.rev131103.TransactionId;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.port.rev130925.queues.Queue;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.port.rev130925.queues.QueueBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.port.rev130925.queues.QueueKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.queue.rev130925.QueueId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorId;
import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnector;
import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnectorKey;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
import org.opendaylight.yang.gen.v1.urn.opendaylight.queue.statistics.rev131216.FlowCapableNodeConnectorQueueStatisticsData;
import org.opendaylight.yang.gen.v1.urn.opendaylight.queue.statistics.rev131216.FlowCapableNodeConnectorQueueStatisticsDataBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.queue.statistics.rev131216.GetAllQueuesStatisticsFromAllPortsInputBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.queue.statistics.rev131216.GetQueueStatisticsFromGivenPortInputBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.queue.statistics.rev131216.OpendaylightQueueStatisticsService;
import org.opendaylight.yang.gen.v1.urn.opendaylight.queue.statistics.rev131216.flow.capable.node.connector.queue.statistics.FlowCapableNodeConnectorQueueStatisticsBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.queue.statistics.rev131216.queue.id.and.statistics.map.QueueIdAndStatisticsMap;
import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import com.google.common.base.Preconditions;
+import com.google.common.util.concurrent.ListenableFuture;
+
final class QueueStatsTracker extends AbstractStatsTracker<QueueIdAndStatisticsMap, QueueStatsEntry> {
private static final Logger logger = LoggerFactory.getLogger(QueueStatsTracker.class);
+ private final OpendaylightQueueStatisticsService queueStatsService;
- QueueStatsTracker(InstanceIdentifier<Node> nodeIdentifier,
- DataProviderService dps, long lifetimeNanos) {
- super(nodeIdentifier, dps, lifetimeNanos);
+ QueueStatsTracker(OpendaylightQueueStatisticsService queueStatsService, final FlowCapableContext context, long lifetimeNanos) {
+ super(context, lifetimeNanos);
+ this.queueStatsService = Preconditions.checkNotNull(queueStatsService);
}
@Override
trans.putOperationalData(queueRef, queueBuilder.build());
return queueEntry;
}
+
+ public ListenableFuture<TransactionId> request() {
+ GetAllQueuesStatisticsFromAllPortsInputBuilder input = new GetAllQueuesStatisticsFromAllPortsInputBuilder();
+ input.setNode(getNodeRef());
+
+ return requestHelper(queueStatsService.getAllQueuesStatisticsFromAllPorts(input.build()));
+ }
+
+ public ListenableFuture<TransactionId> request(NodeConnectorId nodeConnectorId, QueueId queueId) {
+ GetQueueStatisticsFromGivenPortInputBuilder input = new GetQueueStatisticsFromGivenPortInputBuilder();
+
+ input.setNode(getNodeRef());
+ input.setNodeConnectorId(nodeConnectorId);
+ input.setQueueId(queueId);
+
+ return requestHelper(queueStatsService.getQueueStatisticsFromGivenPort(input.build()));
+ }
}
import java.util.TimerTask;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
-import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import org.opendaylight.controller.sal.binding.api.NotificationProviderService;
return dps.beginTransaction();
}
- public void sendFlowStatsFromTableRequest(NodeKey node, Flow flow) throws InterruptedException, ExecutionException {
+ public void sendFlowStatsFromTableRequest(NodeKey node, Flow flow) {
final NodeStatisticsHandler h = getStatisticsHandler(node.getId());
if (h != null) {
h.sendFlowStatsFromTableRequest(flow);
}
}
- public void sendGroupDescriptionRequest(NodeKey node) throws InterruptedException, ExecutionException{
+ public void sendGroupDescriptionRequest(NodeKey node) {
final NodeStatisticsHandler h = getStatisticsHandler(node.getId());
if (h != null) {
h.sendGroupDescriptionRequest();
}
}
- public void sendMeterConfigStatisticsRequest(NodeKey node) throws InterruptedException, ExecutionException {
+ public void sendMeterConfigStatisticsRequest(NodeKey node) {
final NodeStatisticsHandler h = getStatisticsHandler(node.getId());
if (h != null) {
h.sendMeterConfigStatisticsRequest();
}
}
- public void sendQueueStatsFromGivenNodeConnector(NodeKey node,NodeConnectorId nodeConnectorId, QueueId queueId) throws InterruptedException, ExecutionException {
+ public void sendQueueStatsFromGivenNodeConnector(NodeKey node,NodeConnectorId nodeConnectorId, QueueId queueId) {
final NodeStatisticsHandler h = getStatisticsHandler(node.getId());
if (h != null) {
h.sendQueueStatsFromGivenNodeConnector(nodeConnectorId, queueId);
import java.util.Map;
import java.util.Set;
-import java.util.concurrent.ExecutionException;
import org.opendaylight.controller.md.sal.common.api.data.DataChangeEvent;
import org.opendaylight.controller.sal.binding.api.data.DataChangeListener;
import org.opendaylight.yang.gen.v1.urn.opendaylight.queue.statistics.rev131216.FlowCapableNodeConnectorQueueStatisticsData;
import org.opendaylight.yangtools.yang.binding.DataObject;
import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
/**
* Following are two main responsibilities of the class
*
*/
public class StatisticsUpdateHandler implements DataChangeListener {
-
- private static final Logger suhLogger = LoggerFactory.getLogger(StatisticsUpdateHandler.class);
private final StatisticsProvider statisticsManager;
public StatisticsUpdateHandler(final StatisticsProvider manager){
NodeKey nodeII = dataObjectInstance.firstKeyOf(Node.class, NodeKey.class);
if(dataObject instanceof Flow){
Flow flow = (Flow) dataObject;
- try {
- this.statisticsManager.sendFlowStatsFromTableRequest(nodeII, flow);
- } catch (InterruptedException | ExecutionException e) {
- suhLogger.warn("Following exception occured while sending flow statistics request newly added flow: {}", e);
- }
+ this.statisticsManager.sendFlowStatsFromTableRequest(nodeII, flow);
}
if(dataObject instanceof Meter){
- try {
- this.statisticsManager.sendMeterConfigStatisticsRequest(nodeII);
- } catch (InterruptedException | ExecutionException e) {
- suhLogger.warn("Following exception occured while sending meter statistics request for newly added meter: {}", e);
- }
+ this.statisticsManager.sendMeterConfigStatisticsRequest(nodeII);
}
if(dataObject instanceof Group){
- try {
- this.statisticsManager.sendGroupDescriptionRequest(nodeII);
- } catch (InterruptedException | ExecutionException e) {
- suhLogger.warn("Following exception occured while sending group description request for newly added group: {}", e);
- }
+ this.statisticsManager.sendGroupDescriptionRequest(nodeII);
}
if(dataObject instanceof Queue){
Queue queue = (Queue) dataObject;
InstanceIdentifier<NodeConnector> nodeConnectorII = dataObjectInstance.firstIdentifierOf(NodeConnector.class);
NodeConnectorKey nodeConnectorKey = InstanceIdentifier.keyOf(nodeConnectorII);
- try {
- this.statisticsManager.sendQueueStatsFromGivenNodeConnector(nodeII,
- nodeConnectorKey.getId(), queue.getQueueId());
- } catch (InterruptedException | ExecutionException e) {
- suhLogger.warn("Following exception occured while sending queue statistics request for newly added group: {}", e);
- }
+ this.statisticsManager.sendQueueStatsFromGivenNodeConnector(nodeII, nodeConnectorKey.getId(), queue.getQueueId());
}
}