sangyun-han
Committed by Gerrit Code Review

Add configurable method to SimpleFlowRuleStore

- Add @Modified annotation
- Delete TODO annotation

Change-Id: Ida2855c23105f68cfa2f2b7bb4ec3f384a2de838
......@@ -27,8 +27,11 @@ import com.google.common.util.concurrent.SettableFuture;
import org.apache.felix.scr.annotations.Activate;
import org.apache.felix.scr.annotations.Component;
import org.apache.felix.scr.annotations.Deactivate;
import org.apache.felix.scr.annotations.Modified;
import org.apache.felix.scr.annotations.Property;
import org.apache.felix.scr.annotations.Service;
import org.onlab.util.NewConcurrentHashMap;
import org.onlab.util.Tools;
import org.onosproject.net.DeviceId;
import org.onosproject.net.flow.CompletedBatchOperation;
import org.onosproject.net.flow.DefaultFlowEntry;
......@@ -48,10 +51,12 @@ import org.onosproject.net.flow.FlowRuleStoreDelegate;
import org.onosproject.net.flow.StoredFlowEntry;
import org.onosproject.net.flow.TableStatisticsEntry;
import org.onosproject.store.AbstractStore;
import org.osgi.service.component.ComponentContext;
import org.slf4j.Logger;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Dictionary;
import java.util.List;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
......@@ -87,8 +92,10 @@ public class SimpleFlowRuleStore
private final AtomicInteger localBatchIdGen = new AtomicInteger();
// TODO: make this configurable
private int pendingFutureTimeoutMinutes = 5;
private static final int DEFAULT_PENDING_FUTURE_TIMEOUT_MINUTES = 5;
@Property(name = "pendingFutureTimeoutMinutes", intValue = DEFAULT_PENDING_FUTURE_TIMEOUT_MINUTES,
label = "Expiration time after an entry is created that it should be automatically removed")
private int pendingFutureTimeoutMinutes = DEFAULT_PENDING_FUTURE_TIMEOUT_MINUTES;
private Cache<Integer, SettableFuture<CompletedBatchOperation>> pendingFutures =
CacheBuilder.newBuilder()
......@@ -108,6 +115,21 @@ public class SimpleFlowRuleStore
log.info("Stopped");
}
@Modified
public void modified(ComponentContext context) {
readComponentConfiguration(context);
// Reset Cache and copy all.
Cache<Integer, SettableFuture<CompletedBatchOperation>> prevFutures = pendingFutures;
pendingFutures = CacheBuilder.newBuilder()
.expireAfterWrite(pendingFutureTimeoutMinutes, TimeUnit.MINUTES)
.removalListener(new TimeoutFuture())
.build();
pendingFutures.putAll(prevFutures.asMap());
}
@Override
public int getFlowRuleCount() {
......@@ -120,6 +142,27 @@ public class SimpleFlowRuleStore
return sum;
}
/**
* Extracts properties from the component configuration context.
*
* @param context the component context
*/
private void readComponentConfiguration(ComponentContext context) {
Dictionary<?, ?> properties = context.getProperties();
Integer newPendingFutureTimeoutMinutes =
Tools.getIntegerProperty(properties, "pendingFutureTimeoutMinutes");
if (newPendingFutureTimeoutMinutes == null) {
pendingFutureTimeoutMinutes = DEFAULT_PENDING_FUTURE_TIMEOUT_MINUTES;
log.info("Pending future timeout is not configured, " +
"using current value of {}", pendingFutureTimeoutMinutes);
} else {
pendingFutureTimeoutMinutes = newPendingFutureTimeoutMinutes;
log.info("Configured. Pending future timeout is configured to {}",
pendingFutureTimeoutMinutes);
}
}
private static NewConcurrentHashMap<FlowId, List<StoredFlowEntry>> lazyEmptyFlowTable() {
return NewConcurrentHashMap.<FlowId, List<StoredFlowEntry>>ifNeeded();
}
......@@ -332,19 +375,6 @@ public class SimpleFlowRuleStore
notifyDelegate(event);
}
private static final class TimeoutFuture
implements RemovalListener<Integer, SettableFuture<CompletedBatchOperation>> {
@Override
public void onRemoval(RemovalNotification<Integer, SettableFuture<CompletedBatchOperation>> notification) {
// wrapping in ExecutionException to support Future.get
if (notification.wasEvicted()) {
notification.getValue()
.setException(new ExecutionException("Timed out",
new TimeoutException()));
}
}
}
@Override
public FlowRuleEvent updateTableStatistics(DeviceId deviceId,
List<TableStatisticsEntry> tableStats) {
......@@ -360,4 +390,17 @@ public class SimpleFlowRuleStore
}
return ImmutableList.copyOf(tableStats);
}
private static final class TimeoutFuture
implements RemovalListener<Integer, SettableFuture<CompletedBatchOperation>> {
@Override
public void onRemoval(RemovalNotification<Integer, SettableFuture<CompletedBatchOperation>> notification) {
// wrapping in ExecutionException to support Future.get
if (notification.wasEvicted()) {
notification.getValue()
.setException(new ExecutionException("Timed out",
new TimeoutException()));
}
}
}
}
......
......@@ -148,7 +148,6 @@ public class OpenFlowDeviceProvider extends AbstractProvider implements DevicePr
private final InternalDeviceProvider listener = new InternalDeviceProvider();
// TODO: We need to make the poll interval configurable.
static final int POLL_INTERVAL = 5;
@Property(name = "PortStatsPollFrequency", intValue = POLL_INTERVAL,
label = "Frequency (in seconds) for polling switch Port statistics")
......