--- /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.DataBrokerService;
+import org.opendaylight.controller.sal.binding.api.data.DataChangeListener;
+import org.opendaylight.yangtools.concepts.ListenerRegistration;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.base.Preconditions;
+
+abstract class AbstractListeningStatsTracker<I, K> extends AbstractStatsTracker<I, K> implements AutoCloseable, DataChangeListener {
+ private static final Logger logger = LoggerFactory.getLogger(AbstractListeningStatsTracker.class);
+ private ListenerRegistration<?> reg;
+
+ protected AbstractListeningStatsTracker(FlowCapableContext context, long lifetimeNanos) {
+ super(context, lifetimeNanos);
+ }
+
+ protected abstract InstanceIdentifier<?> listenPath();
+ protected abstract String statName();
+
+ public void start(final DataBrokerService dbs) {
+ Preconditions.checkState(reg == null);
+
+ reg = dbs.registerDataChangeListener(listenPath(), this);
+ logger.debug("{} Statistics tracker for node {} started", statName(), getNodeIdentifier());
+ }
+
+ @Override
+ public final void close() {
+ if (reg != null) {
+ try {
+ reg.close();
+ } catch (Exception e) {
+ logger.warn("Failed to stop {} Statistics tracker for node {}", statName(), getNodeIdentifier(), e);
+ }
+ reg = null;
+ }
+ }
+}
import java.util.Map.Entry;
import java.util.concurrent.Future;
+import org.opendaylight.controller.md.statistics.manager.MultipartMessageManager.StatsRequestType;
import org.opendaylight.controller.sal.binding.api.data.DataModificationTransaction;
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 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 =
return context.getNodeIdentifier();
}
- protected static final <T extends TransactionAware> ListenableFuture<TransactionId> requestHelper(Future<RpcResult<T>> future) {
- return Futures.transform(JdkFutureAdapters.listenInPoolThread(future), FUNCTION);
+ protected final <T extends TransactionAware> void requestHelper(Future<RpcResult<T>> future, StatsRequestType type) {
+ context.registerTransaction(Futures.transform(JdkFutureAdapters.listenInPoolThread(future), FUNCTION), type);
+ }
+
+ protected final DataModificationTransaction startTransaction() {
+ return context.startDataModification();
}
protected abstract void cleanupSingleStat(DataModificationTransaction trans, K item);
public final synchronized void updateStats(List<I> list) {
final Long expiryTime = System.nanoTime() + lifetimeNanos;
- final DataModificationTransaction trans = context.startDataModification();
+ final DataModificationTransaction trans = startTransaction();
for (final I item : list) {
trackedItems.put(updateSingleStat(trans, item), expiryTime);
*/
package org.opendaylight.controller.md.statistics.manager;
+import org.opendaylight.controller.md.statistics.manager.MultipartMessageManager.StatsRequestType;
import org.opendaylight.controller.sal.binding.api.data.DataModificationTransaction;
+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 com.google.common.util.concurrent.ListenableFuture;
+
/**
* Interface exposed to AbstractStatsTracker by its parent NodeStatisticsHandler.
* While we could simply exist without this interface, its purpose is to document
InstanceIdentifier<Node> getNodeIdentifier();
NodeRef getNodeRef();
DataModificationTransaction startDataModification();
+ void registerTransaction(ListenableFuture<TransactionId> future, StatsRequestType type);
+ void registerTableTransaction(ListenableFuture<TransactionId> future, Short tableId);
}
*/
package org.opendaylight.controller.md.statistics.manager;
+import java.util.Map.Entry;
+
+import org.opendaylight.controller.md.sal.common.api.data.DataChangeEvent;
+import org.opendaylight.controller.md.statistics.manager.MultipartMessageManager.StatsRequestType;
+import org.opendaylight.controller.sal.binding.api.data.DataBrokerService;
import org.opendaylight.controller.sal.binding.api.data.DataModificationTransaction;
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.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.flow.transaction.rev131103.TransactionId;
import org.opendaylight.yang.gen.v1.urn.opendaylight.model.statistics.types.rev130925.GenericStatistics;
+import org.opendaylight.yangtools.yang.binding.DataObject;
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> {
+final class FlowStatsTracker extends AbstractListeningStatsTracker<FlowAndStatisticsMapList, FlowStatsEntry> {
private static final Logger logger = LoggerFactory.getLogger(FlowStatsTracker.class);
private final OpendaylightFlowStatisticsService flowStatsService;
private int unaccountedFlowsCounter = 1;
FlowStatsTracker(OpendaylightFlowStatisticsService flowStatsService, final FlowCapableContext context, long lifetimeNanos) {
super(context, lifetimeNanos);
- this.flowStatsService = Preconditions.checkNotNull(flowStatsService);
+ this.flowStatsService = flowStatsService;
}
@Override
return flowStatsEntry;
}
- public ListenableFuture<TransactionId> requestAllFlowsAllTables() {
- final GetAllFlowsStatisticsFromAllFlowTablesInputBuilder input = new GetAllFlowsStatisticsFromAllFlowTablesInputBuilder();
- input.setNode(getNodeRef());
+ @Override
+ protected InstanceIdentifier<?> listenPath() {
+ return getNodeIdentifierBuilder().augmentation(FlowCapableNode.class).child(Table.class).child(Flow.class).build();
+ }
- return requestHelper(flowStatsService.getAllFlowsStatisticsFromAllFlowTables(input.build()));
+ @Override
+ protected String statName() {
+ return "Flow";
}
- public ListenableFuture<TransactionId> requestAggregateFlows(final TableKey key) {
- GetAggregateFlowStatisticsFromFlowTableForAllFlowsInputBuilder input =
- new GetAggregateFlowStatisticsFromFlowTableForAllFlowsInputBuilder();
+ public void requestAllFlowsAllTables() {
+ if (flowStatsService != null) {
+ final GetAllFlowsStatisticsFromAllFlowTablesInputBuilder input = new GetAllFlowsStatisticsFromAllFlowTablesInputBuilder();
+ input.setNode(getNodeRef());
- 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()));
+ requestHelper(flowStatsService.getAllFlowsStatisticsFromAllFlowTables(input.build()), StatsRequestType.ALL_FLOW);
+ }
}
- public ListenableFuture<TransactionId> requestFlow(final Flow flow) {
- final GetFlowStatisticsFromFlowTableInputBuilder input =
- new GetFlowStatisticsFromFlowTableInputBuilder(flow);
- input.setNode(getNodeRef());
+ public void requestAggregateFlows(final TableKey key) {
+ if (flowStatsService != null) {
+ GetAggregateFlowStatisticsFromFlowTableForAllFlowsInputBuilder input =
+ new GetAggregateFlowStatisticsFromFlowTableForAllFlowsInputBuilder();
+
+ input.setNode(getNodeRef());
+ input.setTableId(new org.opendaylight.yang.gen.v1.urn.opendaylight.table.types.rev131026.TableId(key.getId()));
+ requestHelper(flowStatsService.getAggregateFlowStatisticsFromFlowTableForAllFlows(input.build()), StatsRequestType.ALL_FLOW);
+ }
+ }
+
+ public void requestFlow(final Flow flow) {
+ if (flowStatsService != null) {
+ final GetFlowStatisticsFromFlowTableInputBuilder input =
+ new GetFlowStatisticsFromFlowTableInputBuilder(flow);
+ input.setNode(getNodeRef());
+
+ requestHelper(flowStatsService.getFlowStatisticsFromFlowTable(input.build()), StatsRequestType.ALL_FLOW);
+ }
+ }
+
+ @Override
+ public void onDataChanged(DataChangeEvent<InstanceIdentifier<?>, DataObject> change) {
+ for (Entry<InstanceIdentifier<?>, DataObject> e : change.getCreatedConfigurationData().entrySet()) {
+ if (Flow.class.equals(e.getKey().getTargetType())) {
+ final Flow flow = (Flow) e.getValue();
+ logger.debug("Key {} triggered request for flow {}", e.getKey(), flow);
+ requestFlow(flow);
+ } else {
+ logger.debug("Ignoring key {}", e.getKey());
+ }
+ }
+
+ final DataModificationTransaction trans = startTransaction();
+ for (InstanceIdentifier<?> key : change.getRemovedConfigurationData()) {
+ if (Flow.class.equals(key.getTargetType())) {
+ @SuppressWarnings("unchecked")
+ final InstanceIdentifier<Flow> flow = (InstanceIdentifier<Flow>)key;
+ final InstanceIdentifier<?> del = InstanceIdentifier.builder(flow)
+ .augmentation(FlowStatisticsData.class).build();
+ logger.debug("Key {} triggered remove of augmentation {}", key, del);
+
+ trans.removeOperationalData(del);
+ }
+ }
+ trans.commit();
+ }
+
+ @Override
+ public void start(final DataBrokerService dbs) {
+ if (flowStatsService == null) {
+ logger.debug("No Flow Statistics service, not subscribing to flows on node {}", getNodeIdentifier());
+ return;
+ }
- return requestHelper(flowStatsService.getFlowStatisticsFromFlowTable(input.build()));
+ super.start(dbs);
}
}
import java.util.Set;
import java.util.concurrent.ConcurrentSkipListSet;
+import org.opendaylight.controller.md.statistics.manager.MultipartMessageManager.StatsRequestType;
import org.opendaylight.controller.sal.binding.api.data.DataModificationTransaction;
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.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.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);
FlowTableStatsTracker(OpendaylightFlowTableStatisticsService flowTableStatsService, final FlowCapableContext context, long lifetimeNanos) {
super(context, lifetimeNanos);
- this.flowTableStatsService = Preconditions.checkNotNull(flowTableStatsService);
+ this.flowTableStatsService = flowTableStatsService;
}
Set<TableKey> getTables() {
return item;
}
- public ListenableFuture<TransactionId> request() {
- final GetFlowTablesStatisticsInputBuilder input = new GetFlowTablesStatisticsInputBuilder();
- input.setNode(getNodeRef());
+ public void request() {
+ if (flowTableStatsService != null) {
+ final GetFlowTablesStatisticsInputBuilder input = new GetFlowTablesStatisticsInputBuilder();
+ input.setNode(getNodeRef());
- return requestHelper(flowTableStatsService.getFlowTablesStatistics(input.build()));
+ requestHelper(flowTableStatsService.getFlowTablesStatistics(input.build()), StatsRequestType.ALL_FLOW);
+ }
}
}
*/
package org.opendaylight.controller.md.statistics.manager;
+import org.opendaylight.controller.md.sal.common.api.data.DataChangeEvent;
+import org.opendaylight.controller.md.statistics.manager.MultipartMessageManager.StatsRequestType;
+import org.opendaylight.controller.sal.binding.api.data.DataBrokerService;
import org.opendaylight.controller.sal.binding.api.data.DataModificationTransaction;
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.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.yangtools.yang.binding.DataObject;
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 GroupDescStatsTracker extends AbstractStatsTracker<GroupDescStats, GroupDescStats> {
+final class GroupDescStatsTracker extends AbstractListeningStatsTracker<GroupDescStats, GroupDescStats> {
+ private static final Logger logger = LoggerFactory.getLogger(GroupDescStatsTracker.class);
private final OpendaylightGroupStatisticsService groupStatsService;
public GroupDescStatsTracker(OpendaylightGroupStatisticsService groupStatsService, final FlowCapableContext context, final long lifetimeNanos) {
super(context, lifetimeNanos);
- this.groupStatsService = Preconditions.checkNotNull(groupStatsService);
+ this.groupStatsService = groupStatsService;
}
@Override
trans.removeOperationalData(groupRef);
}
- public ListenableFuture<TransactionId> request() {
- final GetGroupDescriptionInputBuilder input = new GetGroupDescriptionInputBuilder();
- input.setNode(getNodeRef());
+ @Override
+ protected InstanceIdentifier<?> listenPath() {
+ return getNodeIdentifierBuilder().augmentation(FlowCapableNode.class).child(Group.class).build();
+ }
+
+ @Override
+ protected String statName() {
+ return "Group Descriptor";
+ }
+
+ public void request() {
+ if (groupStatsService != null) {
+ final GetGroupDescriptionInputBuilder input = new GetGroupDescriptionInputBuilder();
+ input.setNode(getNodeRef());
+
+ requestHelper(groupStatsService.getGroupDescription(input.build()), StatsRequestType.GROUP_DESC);
+ }
+ }
+
+ @Override
+ public void onDataChanged(DataChangeEvent<InstanceIdentifier<?>, DataObject> change) {
+ for (InstanceIdentifier<?> key : change.getCreatedConfigurationData().keySet()) {
+ if (Group.class.equals(key.getTargetType())) {
+ logger.debug("Key {} triggered request", key);
+ request();
+ } else {
+ logger.debug("Ignoring key {}", key);
+ }
+ }
+
+ final DataModificationTransaction trans = startTransaction();
+ for (InstanceIdentifier<?> key : change.getRemovedConfigurationData()) {
+ if (Group.class.equals(key.getTargetType())) {
+ @SuppressWarnings("unchecked")
+ InstanceIdentifier<Group> group = (InstanceIdentifier<Group>)key;
+ InstanceIdentifier<?> del = InstanceIdentifier.builder(group).augmentation(NodeGroupDescStats.class).toInstance();
+ logger.debug("Key {} triggered remove of augmentation {}", key, del);
+
+ trans.removeOperationalData(del);
+ }
+ }
+ trans.commit();
+ }
+
+ @Override
+ public void start(final DataBrokerService dbs) {
+ if (groupStatsService == null) {
+ logger.debug("No Group Statistics service, not subscribing to groups on node {}", getNodeIdentifier());
+ return;
+ }
- return requestHelper(groupStatsService.getGroupDescription(input.build()));
+ super.start(dbs);
}
}
*/
package org.opendaylight.controller.md.statistics.manager;
+import org.opendaylight.controller.md.sal.common.api.data.DataChangeEvent;
+import org.opendaylight.controller.md.statistics.manager.MultipartMessageManager.StatsRequestType;
+import org.opendaylight.controller.sal.binding.api.data.DataBrokerService;
import org.opendaylight.controller.sal.binding.api.data.DataModificationTransaction;
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.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.yangtools.yang.binding.DataObject;
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 GroupStatsTracker extends AbstractStatsTracker<GroupStats, GroupStats> {
+final class GroupStatsTracker extends AbstractListeningStatsTracker<GroupStats, GroupStats> {
+ private static final Logger logger = LoggerFactory.getLogger(GroupStatsTracker.class);
private final OpendaylightGroupStatisticsService groupStatsService;
GroupStatsTracker(OpendaylightGroupStatisticsService groupStatsService, FlowCapableContext context, long lifetimeNanos) {
return item;
}
- public ListenableFuture<TransactionId> request() {
+ @Override
+ protected InstanceIdentifier<?> listenPath() {
+ return getNodeIdentifierBuilder().augmentation(FlowCapableNode.class).child(Group.class).build();
+ }
+
+ @Override
+ protected String statName() {
+ return "Group";
+ }
+
+ public void request() {
final GetAllGroupStatisticsInputBuilder input = new GetAllGroupStatisticsInputBuilder();
input.setNode(getNodeRef());
- return requestHelper(groupStatsService.getAllGroupStatistics(input.build()));
+ requestHelper(groupStatsService.getAllGroupStatistics(input.build()), StatsRequestType.ALL_GROUP);
+ }
+
+ @Override
+ public void onDataChanged(DataChangeEvent<InstanceIdentifier<?>, DataObject> change) {
+ final DataModificationTransaction trans = startTransaction();
+ for (InstanceIdentifier<?> key : change.getRemovedConfigurationData()) {
+ if (Group.class.equals(key.getTargetType())) {
+ @SuppressWarnings("unchecked")
+ InstanceIdentifier<Group> group = (InstanceIdentifier<Group>)key;
+ InstanceIdentifier<?> del = InstanceIdentifier.builder(group).augmentation(NodeGroupStatistics.class).toInstance();
+ logger.debug("Key {} triggered remove of augmentation {}", key, del);
+
+ trans.removeOperationalData(del);
+ }
+ }
+ trans.commit();
+ }
+
+ @Override
+ public void start(final DataBrokerService dbs) {
+ if (groupStatsService == null) {
+ logger.debug("No Group Statistics service, not subscribing to groups on node {}", getNodeIdentifier());
+ return;
+ }
+
+ super.start(dbs);
}
}
*/
package org.opendaylight.controller.md.statistics.manager;
+import org.opendaylight.controller.md.sal.common.api.data.DataChangeEvent;
+import org.opendaylight.controller.md.statistics.manager.MultipartMessageManager.StatsRequestType;
+import org.opendaylight.controller.sal.binding.api.data.DataBrokerService;
import org.opendaylight.controller.sal.binding.api.data.DataModificationTransaction;
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.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.DataObject;
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 MeterConfigStatsTracker extends AbstractStatsTracker<MeterConfigStats, MeterConfigStats> {
+final class MeterConfigStatsTracker extends AbstractListeningStatsTracker<MeterConfigStats, MeterConfigStats> {
+ private static final Logger logger = LoggerFactory.getLogger(MeterConfigStatsTracker.class);
private final OpendaylightMeterStatisticsService meterStatsService;
protected MeterConfigStatsTracker(OpendaylightMeterStatisticsService meterStatsService, final FlowCapableContext context, long lifetimeNanos) {
super(context, lifetimeNanos);
- this.meterStatsService = Preconditions.checkNotNull(meterStatsService);
+ this.meterStatsService = meterStatsService;
}
@Override
return item;
}
- public ListenableFuture<TransactionId> request() {
- GetAllMeterConfigStatisticsInputBuilder input = new GetAllMeterConfigStatisticsInputBuilder();
- input.setNode(getNodeRef());
+ public void request() {
+ if (meterStatsService != null) {
+ GetAllMeterConfigStatisticsInputBuilder input = new GetAllMeterConfigStatisticsInputBuilder();
+ input.setNode(getNodeRef());
+
+ requestHelper(meterStatsService.getAllMeterConfigStatistics(input.build()), StatsRequestType.METER_CONFIG);
+ }
+ }
+
+ @Override
+ public void onDataChanged(DataChangeEvent<InstanceIdentifier<?>, DataObject> change) {
+ final DataModificationTransaction trans = startTransaction();
+
+ for (InstanceIdentifier<?> key : change.getRemovedConfigurationData()) {
+ if (Meter.class.equals(key.getTargetType())) {
+ @SuppressWarnings("unchecked")
+ InstanceIdentifier<Meter> meter = (InstanceIdentifier<Meter>)key;
+
+ InstanceIdentifier<?> nodeMeterStatisticsAugmentation =
+ InstanceIdentifier.builder(meter).augmentation(NodeMeterConfigStats.class).toInstance();
+ trans.removeOperationalData(nodeMeterStatisticsAugmentation);
+ }
+ }
+
+ trans.commit();
+ }
+
+ @Override
+ protected InstanceIdentifier<?> listenPath() {
+ return getNodeIdentifierBuilder().augmentation(FlowCapableNode.class).child(Meter.class).build();
+ }
+
+ @Override
+ protected String statName() {
+ return "Meter Config";
+ }
+
+ @Override
+ public void start(final DataBrokerService dbs) {
+ if (meterStatsService == null) {
+ logger.debug("No Meter Statistics service, not subscribing to meter on node {}", getNodeIdentifier());
+ return;
+ }
- return requestHelper(meterStatsService.getAllMeterConfigStatistics(input.build()));
+ super.start(dbs);
}
}
*/
package org.opendaylight.controller.md.statistics.manager;
+import org.opendaylight.controller.md.sal.common.api.data.DataChangeEvent;
+import org.opendaylight.controller.md.statistics.manager.MultipartMessageManager.StatsRequestType;
+import org.opendaylight.controller.sal.binding.api.data.DataBrokerService;
import org.opendaylight.controller.sal.binding.api.data.DataModificationTransaction;
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.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.DataObject;
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 MeterStatsTracker extends AbstractStatsTracker<MeterStats, MeterStats> {
+final class MeterStatsTracker extends AbstractListeningStatsTracker<MeterStats, MeterStats> {
+ private static final Logger logger = LoggerFactory.getLogger(MeterStatsTracker.class);
private final OpendaylightMeterStatisticsService meterStatsService;
MeterStatsTracker(OpendaylightMeterStatisticsService meterStatsService, final FlowCapableContext context, long lifetimeNanos) {
super(context, lifetimeNanos);
- this.meterStatsService = Preconditions.checkNotNull(meterStatsService);
+ this.meterStatsService = meterStatsService;
}
@Override
return item;
}
- public ListenableFuture<TransactionId> request() {
- GetAllMeterStatisticsInputBuilder input = new GetAllMeterStatisticsInputBuilder();
- input.setNode(getNodeRef());
+ public void request() {
+ if (meterStatsService != null) {
+ GetAllMeterStatisticsInputBuilder input = new GetAllMeterStatisticsInputBuilder();
+ input.setNode(getNodeRef());
+
+ requestHelper(meterStatsService.getAllMeterStatistics(input.build()), StatsRequestType.ALL_METER);
+ }
+ }
+
+ @Override
+ public void onDataChanged(DataChangeEvent<InstanceIdentifier<?>, DataObject> change) {
+ for (InstanceIdentifier<?> key : change.getCreatedConfigurationData().keySet()) {
+ if (Meter.class.equals(key.getTargetType())) {
+ request();
+ }
+ }
+
+ final DataModificationTransaction trans = startTransaction();
+ for (InstanceIdentifier<?> key : change.getRemovedConfigurationData()) {
+ if (Meter.class.equals(key.getTargetType())) {
+ @SuppressWarnings("unchecked")
+ InstanceIdentifier<Meter> meter = (InstanceIdentifier<Meter>)key;
+
+ InstanceIdentifier<?> nodeMeterStatisticsAugmentation =
+ InstanceIdentifier.builder(meter).augmentation(NodeMeterStatistics.class).toInstance();
+ trans.removeOperationalData(nodeMeterStatisticsAugmentation);
+ }
+ }
+ trans.commit();
+ }
+
+ @Override
+ protected InstanceIdentifier<?> listenPath() {
+ return getNodeIdentifierBuilder().augmentation(FlowCapableNode.class).child(Meter.class).build();
+ }
+
+ @Override
+ protected String statName() {
+ return "Meter";
+ }
+
+ @Override
+ public void start(final DataBrokerService dbs) {
+ if (meterStatsService == null) {
+ logger.debug("No Meter Statistics service, not subscribing to meters on node {}", getNodeIdentifier());
+ return;
+ }
- return requestHelper(meterStatsService.getAllMeterStatistics(input.build()));
+ super.start(dbs);
}
}
*/
package org.opendaylight.controller.md.statistics.manager;
+import org.opendaylight.controller.md.statistics.manager.MultipartMessageManager.StatsRequestType;
import org.opendaylight.controller.sal.binding.api.data.DataModificationTransaction;
-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.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(final OpendaylightPortStatisticsService portStatsService, final FlowCapableContext context, long lifetimeNanos) {
super(context, lifetimeNanos);
- this.portStatsService = Preconditions.checkNotNull(portStatsService);
+ this.portStatsService = portStatsService;
}
@Override
return item;
}
- public ListenableFuture<TransactionId> request() {
- final GetAllNodeConnectorsStatisticsInputBuilder input = new GetAllNodeConnectorsStatisticsInputBuilder();
- input.setNode(getNodeRef());
+ public void request() {
+ if (portStatsService != null) {
+ final GetAllNodeConnectorsStatisticsInputBuilder input = new GetAllNodeConnectorsStatisticsInputBuilder();
+ input.setNode(getNodeRef());
- return requestHelper(portStatsService.getAllNodeConnectorsStatistics(input.build()));
+ requestHelper(portStatsService.getAllNodeConnectorsStatistics(input.build()), StatsRequestType.ALL_PORT);
+ }
}
}
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.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.OpendaylightFlowStatisticsService;
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.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.group.types.rev131018.GroupFeatures;
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.group.statistics.reply.GroupStats;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorId;
import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeRef;
import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.Nodes;
import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
final long lifetimeNanos = TimeUnit.MILLISECONDS.toNanos(StatisticsProvider.STATS_COLLECTION_MILLIS * NUMBER_OF_WAIT_CYCLES);
- 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;
- }
+ flowStats = new FlowStatsTracker(flowStatsService, this, lifetimeNanos);
+ flowTableStats = new FlowTableStatsTracker(flowTableStatsService, this, lifetimeNanos);
+ groupDescStats = new GroupDescStatsTracker(groupStatsService, this, lifetimeNanos);
+ groupStats = new GroupStatsTracker(groupStatsService, this, lifetimeNanos);
+ meterConfigStats = new MeterConfigStatsTracker(meterStatsService, this, lifetimeNanos);
+ meterStats = new MeterStatsTracker(meterStatsService, this, lifetimeNanos);
+ nodeConnectorStats = new NodeConnectorStatsTracker(portStatsService, this, lifetimeNanos);
+ queueStats = new QueueStatsTracker(queueStatsService, this, lifetimeNanos);
}
public NodeKey getTargetNodeKey() {
public synchronized void requestPeriodicStatistics() {
logger.debug("Send requests for statistics collection to node : {}", targetNodeKey);
- 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());
- }
-
- registerTransaction(flowStats.requestAllFlowsAllTables(), StatsRequestType.ALL_FLOW);
- }
+ flowTableStats.request();
- if (nodeConnectorStats != null) {
- registerTransaction(nodeConnectorStats.request(), StatsRequestType.ALL_PORT);
+ // 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);
+ flowStats.requestAggregateFlows(key);
}
- 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);
- }
+ flowStats.requestAllFlowsAllTables();
+ nodeConnectorStats.request();
+ groupStats.request();
+ groupDescStats.request();
+ meterStats.request();
+ meterConfigStats.request();
+ queueStats.request();
}
public synchronized void start() {
+ flowStats.start(dps);
+ groupDescStats.start(dps);
+ groupStats.start(dps);
+ meterConfigStats.start(dps);
+ meterStats.start(dps);
+ queueStats.start(dps);
+
requestPeriodicStatistics();
}
@Override
public synchronized void close() {
- // FIXME: cleanup any resources we hold (registrations, etc.)
- logger.debug("Statistics handler for {} shut down", targetNodeKey.getId());
- }
-
- synchronized void sendFlowStatsFromTableRequest(Flow flow) {
- if (flowStats == null) {
- logger.debug("No Flow statistics service, not sending a request");
- return;
- }
-
- registerTransaction(flowStats.requestFlow(flow), StatsRequestType.ALL_FLOW);
- }
-
- synchronized void sendGroupDescriptionRequest() {
- if (groupStats == null) {
- logger.debug("No Group Descriptor statistics service, not sending a request");
- return;
- }
-
- registerTransaction(groupDescStats.request(), StatsRequestType.GROUP_DESC);
- }
+ flowStats.close();
+ groupDescStats.close();
+ groupStats.close();
+ meterConfigStats.close();
+ meterStats.close();
+ queueStats.close();
- synchronized void sendMeterConfigStatisticsRequest() {
- if (meterConfigStats == null) {
- logger.debug("No Meter Config statistics service, not sending a request");
- return;
- }
-
- registerTransaction(meterConfigStats.request(), StatsRequestType.METER_CONFIG);
- }
-
- synchronized void sendQueueStatsFromGivenNodeConnector(NodeConnectorId nodeConnectorId, QueueId queueId) {
- if (queueStats == null) {
- logger.debug("No Queue statistics service, not sending a request");
- return;
- }
-
- registerTransaction(queueStats.request(nodeConnectorId, queueId), StatsRequestType.ALL_QUEUE_STATS);
+ logger.debug("Statistics handler for {} shut down", targetNodeKey.getId());
}
- private void registerTransaction(final ListenableFuture<TransactionId> future, final StatsRequestType type) {
+ @Override
+ public void registerTransaction(final ListenableFuture<TransactionId> future, final StatsRequestType type) {
Futures.addCallback(future, new FutureCallback<TransactionId>() {
@Override
public void onSuccess(TransactionId result) {
});
}
- private void registerTableTransaction(final ListenableFuture<TransactionId> future, final Short id) {
+ @Override
+ public void registerTableTransaction(final ListenableFuture<TransactionId> future, final Short id) {
Futures.addCallback(future, new FutureCallback<TransactionId>() {
@Override
public void onSuccess(TransactionId result) {
*/
package org.opendaylight.controller.md.statistics.manager;
+import java.util.Map.Entry;
+
+import org.opendaylight.controller.md.sal.common.api.data.DataChangeEvent;
+import org.opendaylight.controller.md.statistics.manager.MultipartMessageManager.StatsRequestType;
+import org.opendaylight.controller.sal.binding.api.data.DataBrokerService;
import org.opendaylight.controller.sal.binding.api.data.DataModificationTransaction;
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.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.DataObject;
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> {
+final class QueueStatsTracker extends AbstractListeningStatsTracker<QueueIdAndStatisticsMap, QueueStatsEntry> {
private static final Logger logger = LoggerFactory.getLogger(QueueStatsTracker.class);
private final OpendaylightQueueStatisticsService queueStatsService;
QueueStatsTracker(OpendaylightQueueStatisticsService queueStatsService, final FlowCapableContext context, long lifetimeNanos) {
super(context, lifetimeNanos);
- this.queueStatsService = Preconditions.checkNotNull(queueStatsService);
+ this.queueStatsService = queueStatsService;
}
@Override
return queueEntry;
}
- public ListenableFuture<TransactionId> request() {
- GetAllQueuesStatisticsFromAllPortsInputBuilder input = new GetAllQueuesStatisticsFromAllPortsInputBuilder();
- input.setNode(getNodeRef());
+ public void request() {
+ if (queueStatsService != null) {
+ GetAllQueuesStatisticsFromAllPortsInputBuilder input = new GetAllQueuesStatisticsFromAllPortsInputBuilder();
+ input.setNode(getNodeRef());
+
+ requestHelper(queueStatsService.getAllQueuesStatisticsFromAllPorts(input.build()), StatsRequestType.ALL_QUEUE_STATS);
+ }
+ }
+
+ public void request(NodeConnectorId nodeConnectorId, QueueId queueId) {
+ if (queueStatsService != null) {
+ GetQueueStatisticsFromGivenPortInputBuilder input = new GetQueueStatisticsFromGivenPortInputBuilder();
+
+ input.setNode(getNodeRef());
+ input.setNodeConnectorId(nodeConnectorId);
+ input.setQueueId(queueId);
- return requestHelper(queueStatsService.getAllQueuesStatisticsFromAllPorts(input.build()));
+ requestHelper(queueStatsService.getQueueStatisticsFromGivenPort(input.build()), StatsRequestType.ALL_QUEUE_STATS);
+ }
}
- public ListenableFuture<TransactionId> request(NodeConnectorId nodeConnectorId, QueueId queueId) {
- GetQueueStatisticsFromGivenPortInputBuilder input = new GetQueueStatisticsFromGivenPortInputBuilder();
+ @Override
+ public void onDataChanged(DataChangeEvent<InstanceIdentifier<?>, DataObject> change) {
+ for (Entry<InstanceIdentifier<?>, DataObject> e : change.getCreatedConfigurationData().entrySet()) {
+ if (Queue.class.equals(e.getKey().getTargetType())) {
+ final Queue queue = (Queue) e.getValue();
+ final NodeConnectorKey key = e.getKey().firstKeyOf(NodeConnector.class, NodeConnectorKey.class);
+ logger.debug("Key {} triggered request for connector {} queue {}", key.getId(), queue.getQueueId());
+ request(key.getId(), queue.getQueueId());
+ } else {
+ logger.debug("Ignoring key {}", e.getKey());
+ }
+ }
+
+ final DataModificationTransaction trans = startTransaction();
+ for (InstanceIdentifier<?> key : change.getRemovedConfigurationData()) {
+ if (Queue.class.equals(key.getTargetType())) {
+ @SuppressWarnings("unchecked")
+ final InstanceIdentifier<Queue> queue = (InstanceIdentifier<Queue>)key;
+ final InstanceIdentifier<?> del = InstanceIdentifier.builder(queue)
+ .augmentation(FlowCapableNodeConnectorQueueStatisticsData.class).build();
+ logger.debug("Key {} triggered remove of augmentation {}", key, del);
+
+ trans.removeOperationalData(del);
+ }
+ }
+ trans.commit();
+ }
- input.setNode(getNodeRef());
- input.setNodeConnectorId(nodeConnectorId);
- input.setQueueId(queueId);
+ @Override
+ protected InstanceIdentifier<?> listenPath() {
+ return getNodeIdentifierBuilder().child(NodeConnector.class)
+ .augmentation(FlowCapableNodeConnector.class).child(Queue.class).build();
+ }
+
+ @Override
+ protected String statName() {
+ return "Queue";
+ }
+
+ @Override
+ public void start(final DataBrokerService dbs) {
+ if (queueStatsService == null) {
+ logger.debug("No Queue Statistics service, not subscribing to queues on node {}", getNodeIdentifier());
+ return;
+ }
- return requestHelper(queueStatsService.getQueueStatisticsFromGivenPort(input.build()));
+ super.start(dbs);
}
}
import org.opendaylight.controller.sal.binding.api.AbstractBindingAwareProvider;
import org.opendaylight.controller.sal.binding.api.BindingAwareBroker.ProviderContext;
import org.opendaylight.controller.sal.binding.api.NotificationProviderService;
-import org.opendaylight.controller.sal.binding.api.data.DataBrokerService;
import org.opendaylight.controller.sal.binding.api.data.DataProviderService;
import org.osgi.framework.BundleContext;
@Override
public void onSessionInitiated(ProviderContext session) {
- final DataBrokerService dbs = session.getSALService(DataBrokerService.class);
final DataProviderService dps = session.getSALService(DataProviderService.class);
final NotificationProviderService nps = session.getSALService(NotificationProviderService.class);
statsProvider = new StatisticsProvider(dps);
- statsProvider.start(dbs, nps, session);
+ statsProvider.start(nps, session);
}
@Override
import org.opendaylight.controller.sal.binding.api.NotificationProviderService;
import org.opendaylight.controller.sal.binding.api.RpcConsumerRegistry;
-import org.opendaylight.controller.sal.binding.api.data.DataBrokerService;
import org.opendaylight.controller.sal.binding.api.data.DataChangeListener;
-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.FlowCapableNodeConnector;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.meters.Meter;
-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.Flow;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.OpendaylightFlowStatisticsService;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.table.statistics.rev131215.OpendaylightFlowTableStatisticsService;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.port.rev130925.queues.Queue;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.queue.rev130925.QueueId;
import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.OpendaylightGroupStatisticsService;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.groups.Group;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorId;
import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId;
import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.Nodes;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnector;
import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeKey;
import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.OpendaylightMeterStatisticsService;
import org.opendaylight.yang.gen.v1.urn.opendaylight.queue.statistics.rev131216.OpendaylightQueueStatisticsService;
import org.opendaylight.yangtools.concepts.ListenerRegistration;
import org.opendaylight.yangtools.concepts.Registration;
-import org.opendaylight.yangtools.yang.binding.DataObject;
import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
import org.opendaylight.yangtools.yang.binding.NotificationListener;
import org.slf4j.Logger;
private OpendaylightQueueStatisticsService queueStatsService;
- private StatisticsUpdateHandler statsUpdateHandler;
-
public StatisticsProvider(final DataProviderService dataService) {
this.dps = Preconditions.checkNotNull(dataService);
}
private ListenerRegistration<DataChangeListener> flowCapableTrackerRegistration;
- public void start(final DataBrokerService dbs, final NotificationProviderService nps, final RpcConsumerRegistry rpcRegistry) {
+ public void start(final NotificationProviderService nps, final RpcConsumerRegistry rpcRegistry) {
// Get Group/Meter statistics service instances
groupStatsService = rpcRegistry.getRpcService(OpendaylightGroupStatisticsService.class);
final InstanceIdentifier<FlowCapableNode> fcnId = InstanceIdentifier.builder(Nodes.class)
.child(Node.class).augmentation(FlowCapableNode.class).build();
spLogger.debug("Registering FlowCapable tracker to {}", fcnId);
- this.flowCapableTrackerRegistration = dbs.registerDataChangeListener(fcnId,
+ this.flowCapableTrackerRegistration = dps.registerDataChangeListener(fcnId,
new FlowCapableTracker(this, fcnId));
- statsUpdateHandler = new StatisticsUpdateHandler(StatisticsProvider.this);
- registerDataStoreUpdateListener(dbs);
-
timer.schedule(new TimerTask() {
@Override
public void run() {
spLogger.info("Statistics Provider started.");
}
- private void registerDataStoreUpdateListener(DataBrokerService dbs) {
- // FIXME: the below should be broken out into StatisticsUpdateHandler
-
- //Register for flow updates
- InstanceIdentifier<? extends DataObject> pathFlow = InstanceIdentifier.builder(Nodes.class).child(Node.class)
- .augmentation(FlowCapableNode.class)
- .child(Table.class)
- .child(Flow.class).toInstance();
- dbs.registerDataChangeListener(pathFlow, statsUpdateHandler);
-
- //Register for meter updates
- InstanceIdentifier<? extends DataObject> pathMeter = InstanceIdentifier.builder(Nodes.class).child(Node.class)
- .augmentation(FlowCapableNode.class)
- .child(Meter.class).toInstance();
-
- dbs.registerDataChangeListener(pathMeter, statsUpdateHandler);
-
- //Register for group updates
- InstanceIdentifier<? extends DataObject> pathGroup = InstanceIdentifier.builder(Nodes.class).child(Node.class)
- .augmentation(FlowCapableNode.class)
- .child(Group.class).toInstance();
- dbs.registerDataChangeListener(pathGroup, statsUpdateHandler);
-
- //Register for queue updates
- InstanceIdentifier<? extends DataObject> pathQueue = InstanceIdentifier.builder(Nodes.class).child(Node.class)
- .child(NodeConnector.class)
- .augmentation(FlowCapableNodeConnector.class)
- .child(Queue.class).toInstance();
- dbs.registerDataChangeListener(pathQueue, statsUpdateHandler);
- }
-
- protected DataModificationTransaction startChange() {
- return dps.beginTransaction();
- }
-
- public void sendFlowStatsFromTableRequest(NodeKey node, Flow flow) {
- final NodeStatisticsHandler h = getStatisticsHandler(node.getId());
- if (h != null) {
- h.sendFlowStatsFromTableRequest(flow);
- }
- }
-
- public void sendGroupDescriptionRequest(NodeKey node) {
- final NodeStatisticsHandler h = getStatisticsHandler(node.getId());
- if (h != null) {
- h.sendGroupDescriptionRequest();
- }
- }
-
- 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) {
- final NodeStatisticsHandler h = getStatisticsHandler(node.getId());
- if (h != null) {
- h.sendQueueStatsFromGivenNodeConnector(nodeConnectorId, queueId);
- }
- }
-
/**
* Get the handler for a particular node.
*
+++ /dev/null
-/*
- * Copyright IBM Corporation, 2013. 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 java.util.Map;
-import java.util.Set;
-
-import org.opendaylight.controller.md.sal.common.api.data.DataChangeEvent;
-import org.opendaylight.controller.sal.binding.api.data.DataChangeListener;
-import org.opendaylight.controller.sal.binding.api.data.DataModificationTransaction;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.meters.Meter;
-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.FlowStatisticsData;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.port.rev130925.queues.Queue;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.NodeGroupDescStats;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.NodeGroupStatistics;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.groups.Group;
-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.inventory.rev130819.nodes.NodeKey;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.NodeMeterConfigStats;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.NodeMeterStatistics;
-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;
-
-/**
- * Following are two main responsibilities of the class
- * 1) Listen for the create changes in config data store for tree nodes (Flow,Group,Meter,Queue)
- * and send statistics request to the switch to fetch the statistics
- *
- * 2)Listen for the remove changes in config data store for tree nodes (Flow,Group,Meter,Queue)
- * and remove the relative statistics data from operational data store.
- *
- * @author avishnoi@in.ibm.com
- *
- */
-public class StatisticsUpdateHandler implements DataChangeListener {
- private final StatisticsProvider statisticsManager;
-
- public StatisticsUpdateHandler(final StatisticsProvider manager){
- this.statisticsManager = manager;
- }
-
- @SuppressWarnings("unchecked")
- @Override
- public void onDataChanged(DataChangeEvent<InstanceIdentifier<?>, DataObject> change) {
- Map<InstanceIdentifier<?>, DataObject> additions = change.getCreatedConfigurationData();
- for (InstanceIdentifier<? extends DataObject> dataObjectInstance : additions.keySet()) {
- DataObject dataObject = additions.get(dataObjectInstance);
- NodeKey nodeII = dataObjectInstance.firstKeyOf(Node.class, NodeKey.class);
- if(dataObject instanceof Flow){
- Flow flow = (Flow) dataObject;
- this.statisticsManager.sendFlowStatsFromTableRequest(nodeII, flow);
- }
- if(dataObject instanceof Meter){
- this.statisticsManager.sendMeterConfigStatisticsRequest(nodeII);
- }
- if(dataObject instanceof Group){
- this.statisticsManager.sendGroupDescriptionRequest(nodeII);
- }
- if(dataObject instanceof Queue){
- Queue queue = (Queue) dataObject;
- InstanceIdentifier<NodeConnector> nodeConnectorII = dataObjectInstance.firstIdentifierOf(NodeConnector.class);
- NodeConnectorKey nodeConnectorKey = InstanceIdentifier.keyOf(nodeConnectorII);
- this.statisticsManager.sendQueueStatsFromGivenNodeConnector(nodeII, nodeConnectorKey.getId(), queue.getQueueId());
- }
- }
-
- DataModificationTransaction it = this.statisticsManager.startChange();
- Set<InstanceIdentifier<? extends DataObject>> removals = change.getRemovedConfigurationData();
- for (InstanceIdentifier<? extends DataObject> dataObjectInstance : removals) {
- DataObject dataObject = change.getOriginalConfigurationData().get(dataObjectInstance);
-
- if(dataObject instanceof Flow){
- InstanceIdentifier<Flow> flowII = (InstanceIdentifier<Flow>)dataObjectInstance;
- InstanceIdentifier<?> flowAugmentation =
- InstanceIdentifier.builder(flowII).augmentation(FlowStatisticsData.class).toInstance();
- it.removeOperationalData(flowAugmentation);
- }
- if(dataObject instanceof Meter){
- InstanceIdentifier<Meter> meterII = (InstanceIdentifier<Meter>)dataObjectInstance;
-
- InstanceIdentifier<?> nodeMeterConfigStatsAugmentation =
- InstanceIdentifier.builder(meterII).augmentation(NodeMeterConfigStats.class).toInstance();
- it.removeOperationalData(nodeMeterConfigStatsAugmentation);
-
- InstanceIdentifier<?> nodeMeterStatisticsAugmentation =
- InstanceIdentifier.builder(meterII).augmentation(NodeMeterStatistics.class).toInstance();
- it.removeOperationalData(nodeMeterStatisticsAugmentation);
- }
-
- if(dataObject instanceof Group){
- InstanceIdentifier<Group> groupII = (InstanceIdentifier<Group>)dataObjectInstance;
-
- InstanceIdentifier<?> nodeGroupDescStatsAugmentation =
- InstanceIdentifier.builder(groupII).augmentation(NodeGroupDescStats.class).toInstance();
- it.removeOperationalData(nodeGroupDescStatsAugmentation);
-
- InstanceIdentifier<?> nodeGroupStatisticsAugmentation =
- InstanceIdentifier.builder(groupII).augmentation(NodeGroupStatistics.class).toInstance();
- it.removeOperationalData(nodeGroupStatisticsAugmentation);
- }
-
- if(dataObject instanceof Queue){
- InstanceIdentifier<Queue> queueII = (InstanceIdentifier<Queue>)dataObjectInstance;
-
- InstanceIdentifier<?> nodeConnectorQueueStatisticsDataAugmentation =
- InstanceIdentifier.builder(queueII).augmentation(FlowCapableNodeConnectorQueueStatisticsData.class).toInstance();
- it.removeOperationalData(nodeConnectorQueueStatisticsDataAugmentation);
- }
- }
- it.commit();
- }
-}