X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?p=controller.git;a=blobdiff_plain;f=opendaylight%2Fmd-sal%2Fstatistics-manager%2Fsrc%2Fmain%2Fjava%2Forg%2Fopendaylight%2Fcontroller%2Fmd%2Fstatistics%2Fmanager%2FAbstractStatsTracker.java;h=e23ad0acdbe43a2603f458dd3a17b467116acd1b;hp=aa7720cf106844be6e440d0493b7bffbb24f244e;hb=20a6da0545abbfddde09a9ba423489f3032b40c9;hpb=1862f90478212a06a9534ed0674f27212972177f diff --git a/opendaylight/md-sal/statistics-manager/src/main/java/org/opendaylight/controller/md/statistics/manager/AbstractStatsTracker.java b/opendaylight/md-sal/statistics-manager/src/main/java/org/opendaylight/controller/md/statistics/manager/AbstractStatsTracker.java index aa7720cf10..e23ad0acdb 100644 --- a/opendaylight/md-sal/statistics-manager/src/main/java/org/opendaylight/controller/md/statistics/manager/AbstractStatsTracker.java +++ b/opendaylight/md-sal/statistics-manager/src/main/java/org/opendaylight/controller/md/statistics/manager/AbstractStatsTracker.java @@ -12,53 +12,115 @@ import java.util.Iterator; 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 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.JdkFutureAdapters; abstract class AbstractStatsTracker { + private static final Logger logger = LoggerFactory.getLogger(AbstractStatsTracker.class); + + private static final int WAIT_FOR_REQUEST_CYCLE = 2; + + private final FutureCallback> callback = + new FutureCallback>() { + @Override + public void onSuccess(RpcResult result) { + if (result.isSuccessful()) { + final TransactionId id = result.getResult().getTransactionId(); + if (id == null) { + final Throwable t = new UnsupportedOperationException("No protocol support"); + t.fillInStackTrace(); + onFailure(t); + } else { + context.registerTransaction(id); + } + } else { + logger.debug("Statistics request failed: {}", result.getErrors()); + + final Throwable t = new RPCFailedException("Failed to send statistics request", result.getErrors()); + t.fillInStackTrace(); + onFailure(t); + } + } + + @Override + public void onFailure(Throwable t) { + logger.debug("Failed to send statistics request", t); + } + }; + private final Map trackedItems = new HashMap<>(); - private final InstanceIdentifier nodeIdentifier; - private final DataProviderService dps; - private final long lifetimeNanos; - - protected AbstractStatsTracker(final InstanceIdentifier nodeIdentifier, final DataProviderService dps, long lifetimeNanos) { - this.nodeIdentifier = Preconditions.checkNotNull(nodeIdentifier); - this.dps = Preconditions.checkNotNull(dps); - this.lifetimeNanos = lifetimeNanos; + private final FlowCapableContext context; + private long requestCounter; + + protected AbstractStatsTracker(final FlowCapableContext context) { + this.context = Preconditions.checkNotNull(context); + this.requestCounter = 0; } protected final InstanceIdentifierBuilder getNodeIdentifierBuilder() { - return InstanceIdentifier.builder(nodeIdentifier); + return getNodeIdentifier().builder(); + } + + protected final NodeRef getNodeRef() { + return context.getNodeRef(); + } + + protected final InstanceIdentifier getNodeIdentifier() { + return context.getNodeIdentifier(); } - final synchronized void updateStats(List list) { - final Long expiryTime = System.nanoTime() + lifetimeNanos; - final DataModificationTransaction trans = dps.beginTransaction(); + protected final void requestHelper(Future> future) { + Futures.addCallback(JdkFutureAdapters.listenInPoolThread(future), callback); + } + + protected final DataModificationTransaction startTransaction() { + return context.startDataModification(); + } + + public final synchronized void increaseRequestCounter(){ + this.requestCounter++; + } + protected abstract void cleanupSingleStat(DataModificationTransaction trans, K item); + protected abstract K updateSingleStat(DataModificationTransaction trans, I item); + public abstract void request(); + + public final synchronized void updateStats(List list) { + + final DataModificationTransaction trans = startTransaction(); for (final I item : list) { - trackedItems.put(updateSingleStat(trans, item), expiryTime); + trackedItems.put(updateSingleStat(trans, item), requestCounter); } trans.commit(); } - - final synchronized void cleanup(final DataModificationTransaction trans, long now) { + /** + * Statistics will be cleaned up if not update in last two request cycles. + * @param trans + */ + public final synchronized void cleanup(final DataModificationTransaction trans) { for (Iterator> it = trackedItems.entrySet().iterator();it.hasNext();){ Entry e = it.next(); - if (now > e.getValue()) { + if (requestCounter >= e.getValue()+WAIT_FOR_REQUEST_CYCLE) { cleanupSingleStat(trans, e.getKey()); it.remove(); } } } - - protected abstract void cleanupSingleStat(DataModificationTransaction trans, K item); - protected abstract K updateSingleStat(DataModificationTransaction trans, I item); }