Added a mechanism to configure the following timeout values.
Those are needed for the Internet2 deployment.
* FlowRuleManager Timeout per Flow Operation (default to 500ms)
This can be set in the following configuration file and variable:
tools/package/etc/org.onosproject.net.flow.impl.FlowRuleManager.cfg
timeoutPerFlowOpMsec = 500
* IntentManager Timeout per Intent Operation (default to 500ms)
This can be set in the following configuration file and variable:
tools/package/etc/org.onosproject.net.intent.impl.IntentManager.cfg
timeoutPerIntentOpMsec = 500
For the Intentet2 deployment the above two parameters should be
configured to 15000 (i.e., 15 seconds).
The reason is because of recent modifications to the Internet2 firewall:
it could take up to 10s for the reported FlowStats to reflect added
FlowMods.
Also, sometimes a single FlowAdd FLOW_MOD operation
with the Internet2 firewall in the middle could take close to 1s to
complete.
* Added sample configuration files:
tools/package/etc/samples/org.onosproject.*.cfg
Those sample configuration files should be copied to the following
directory so they can be used:
tools/package/etc/
Change-Id: I699d93d4210fd7033234fd71be9b64c1f1d86117
diff --git a/core/net/src/main/java/org/onosproject/net/flow/impl/FlowRuleManager.java b/core/net/src/main/java/org/onosproject/net/flow/impl/FlowRuleManager.java
index 0f543d0..c56eab5 100644
--- a/core/net/src/main/java/org/onosproject/net/flow/impl/FlowRuleManager.java
+++ b/core/net/src/main/java/org/onosproject/net/flow/impl/FlowRuleManager.java
@@ -25,6 +25,8 @@
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.Reference;
import org.apache.felix.scr.annotations.ReferenceCardinality;
import org.apache.felix.scr.annotations.Service;
@@ -53,8 +55,10 @@
import org.onosproject.net.flow.FlowRuleStoreDelegate;
import org.onosproject.net.provider.AbstractProviderRegistry;
import org.onosproject.net.provider.AbstractProviderService;
+import org.osgi.service.component.ComponentContext;
import org.slf4j.Logger;
+import java.util.Dictionary;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
@@ -68,6 +72,7 @@
import java.util.concurrent.TimeoutException;
import java.util.concurrent.atomic.AtomicReference;
import static com.google.common.base.Preconditions.checkNotNull;
+import static com.google.common.base.Strings.isNullOrEmpty;
import static org.onlab.util.Tools.namedThreads;
import static org.slf4j.LoggerFactory.getLogger;
@@ -82,6 +87,8 @@
enum BatchState { STARTED, FINISHED, CANCELLED };
+ private static final int DEFAULT_TIMEOUT_PER_FLOW_OP_MSEC = 500; // ms
+
public static final String FLOW_RULE_NULL = "FlowRule cannot be null";
private final Logger log = getLogger(getClass());
@@ -101,8 +108,16 @@
@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
protected DeviceService deviceService;
+ @Property(name = "timeoutPerFlowOpMsec", intValue = DEFAULT_TIMEOUT_PER_FLOW_OP_MSEC,
+ label = "Configure Timeout per Flow Operation; " +
+ "default is 500 msec")
+ private int timeoutPerFlowOpMsec = DEFAULT_TIMEOUT_PER_FLOW_OP_MSEC;
+
+
@Activate
- public void activate() {
+ public void activate(ComponentContext context) {
+ readComponentConfiguration(context);
+
futureService =
Executors.newFixedThreadPool(32, namedThreads("provider-future-listeners-%d"));
store.setDelegate(delegate);
@@ -119,6 +134,54 @@
log.info("Stopped");
}
+ @Modified
+ public void modified(ComponentContext context) {
+ readComponentConfiguration(context);
+ }
+
+ /**
+ * Extracts properties from the component configuration context.
+ *
+ * @param context the component context
+ */
+ private void readComponentConfiguration(ComponentContext context) {
+ if (context == null) {
+ return; // Nothing to do
+ }
+ Dictionary<?, ?> properties = context.getProperties();
+
+ Integer timeoutPerFlowOpMsecConfigured =
+ getIntegerProperty(properties, "timeoutPerFlowOpMsec");
+ if (timeoutPerFlowOpMsecConfigured == null) {
+ log.info("Timeout per Flow Operation is not configured, " +
+ "using current value of {} ms", timeoutPerFlowOpMsec);
+ } else {
+ timeoutPerFlowOpMsec = timeoutPerFlowOpMsecConfigured;
+ log.info("Configured. Timeout per Flow Operation is " +
+ "configured to {} ms", timeoutPerFlowOpMsec);
+ }
+ }
+
+ /**
+ * Get Integer property from the propertyName
+ * Return null if propertyName is not found.
+ *
+ * @param properties properties to be looked up
+ * @param propertyName the name of the property to look up
+ * @return value when the propertyName is defined or return null
+ */
+ private static Integer getIntegerProperty(Dictionary<?, ?> properties,
+ String propertyName) {
+ Integer value = null;
+ try {
+ String s = (String) properties.get(propertyName);
+ value = isNullOrEmpty(s) ? null : Integer.parseInt(s.trim());
+ } catch (NumberFormatException | ClassCastException e) {
+ value = null;
+ }
+ return value;
+ }
+
@Override
public int getFlowRuleCount() {
return store.getFlowRuleCount();
@@ -378,9 +441,6 @@
// Store delegate to re-post events emitted from the store.
private class InternalStoreDelegate implements FlowRuleStoreDelegate {
- // FIXME set appropriate default and make it configurable
- private static final int TIMEOUT_PER_OP = 500; // ms
-
// TODO: Right now we only dispatch events at individual flowEntry level.
// It may be more efficient for also dispatch events as a batch.
@Override
@@ -408,7 +468,8 @@
public void run() {
CompletedBatchOperation res;
try {
- res = result.get(TIMEOUT_PER_OP * batchOperation.size(), TimeUnit.MILLISECONDS);
+ res = result.get(timeoutPerFlowOpMsec * batchOperation.size(),
+ TimeUnit.MILLISECONDS);
store.batchOperationComplete(FlowRuleBatchEvent.completed(request, res));
} catch (TimeoutException | InterruptedException | ExecutionException e) {
log.warn("Something went wrong with the batch operation {}",
diff --git a/core/net/src/main/java/org/onosproject/net/intent/impl/IntentManager.java b/core/net/src/main/java/org/onosproject/net/intent/impl/IntentManager.java
index 3a1d4f2..da4a4b7 100644
--- a/core/net/src/main/java/org/onosproject/net/intent/impl/IntentManager.java
+++ b/core/net/src/main/java/org/onosproject/net/intent/impl/IntentManager.java
@@ -22,6 +22,8 @@
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.Reference;
import org.apache.felix.scr.annotations.ReferenceCardinality;
import org.apache.felix.scr.annotations.Service;
@@ -50,10 +52,12 @@
import org.onosproject.net.intent.IntentStore;
import org.onosproject.net.intent.BatchWrite;
import org.onosproject.net.intent.IntentStoreDelegate;
+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.EnumSet;
import java.util.List;
import java.util.Map;
@@ -67,6 +71,7 @@
import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkNotNull;
+import static com.google.common.base.Strings.isNullOrEmpty;
import static java.util.concurrent.Executors.newFixedThreadPool;
import static org.onosproject.net.intent.IntentState.*;
import static org.onlab.util.Tools.namedThreads;
@@ -79,6 +84,9 @@
@Service
public class IntentManager
implements IntentService, IntentExtensionService {
+
+ private static final int DEFAULT_TIMEOUT_PER_INTENT_OP_MSEC = 500; // ms
+
private static final Logger log = getLogger(IntentManager.class);
public static final String INTENT_NULL = "Intent cannot be null";
@@ -119,6 +127,10 @@
@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
protected FlowRuleService flowRuleService;
+ @Property(name = "timeoutPerIntentOpMsec", intValue = DEFAULT_TIMEOUT_PER_INTENT_OP_MSEC,
+ label = "Configure Timeout per Intent Operation; " +
+ "default is 500 msec")
+ private int timeoutPerIntentOpMsec = DEFAULT_TIMEOUT_PER_INTENT_OP_MSEC;
private ExecutorService executor;
@@ -128,7 +140,9 @@
private IdGenerator idGenerator;
@Activate
- public void activate() {
+ public void activate(ComponentContext context) {
+ readComponentConfiguration(context);
+
store.setDelegate(delegate);
trackerService.setDelegate(topoDelegate);
batchService.setDelegate(batchDelegate);
@@ -150,6 +164,54 @@
log.info("Stopped");
}
+ @Modified
+ public void modified(ComponentContext context) {
+ readComponentConfiguration(context);
+ }
+
+ /**
+ * Extracts properties from the component configuration context.
+ *
+ * @param context the component context
+ */
+ private void readComponentConfiguration(ComponentContext context) {
+ if (context == null) {
+ return; // Nothing to do
+ }
+ Dictionary<?, ?> properties = context.getProperties();
+
+ Integer timeoutPerIntentOpMsecConfigured =
+ getIntegerProperty(properties, "timeoutPerIntentOpMsec");
+ if (timeoutPerIntentOpMsecConfigured == null) {
+ log.info("Timeout per Intent Operation is not configured, " +
+ "using current value of {} ms", timeoutPerIntentOpMsec);
+ } else {
+ timeoutPerIntentOpMsec = timeoutPerIntentOpMsecConfigured;
+ log.info("Configured. Timeout per Intent Operation is " +
+ "configured to {} ms", timeoutPerIntentOpMsec);
+ }
+ }
+
+ /**
+ * Get Integer property from the propertyName
+ * Return null if propertyName is not found.
+ *
+ * @param properties properties to be looked up
+ * @param propertyName the name of the property to look up
+ * @return value when the propertyName is defined or return null
+ */
+ private static Integer getIntegerProperty(Dictionary<?, ?> properties,
+ String propertyName) {
+ Integer value = null;
+ try {
+ String s = (String) properties.get(propertyName);
+ value = isNullOrEmpty(s) ? null : Integer.parseInt(s.trim());
+ } catch (NumberFormatException | ClassCastException e) {
+ value = null;
+ }
+ return value;
+ }
+
@Override
public void submit(Intent intent) {
checkNotNull(intent, INTENT_NULL);
@@ -744,7 +806,6 @@
private class IntentInstallMonitor implements Runnable {
// TODO make this configurable
- private static final int TIMEOUT_PER_OP = 500; // ms
private static final int MAX_ATTEMPTS = 3;
private final IntentOperations ops;
@@ -764,7 +825,7 @@
private void resetTimeoutLimit() {
// FIXME compute reasonable timeouts
this.endTime = System.currentTimeMillis()
- + ops.operations().size() * TIMEOUT_PER_OP;
+ + ops.operations().size() * timeoutPerIntentOpMsec;
}
private void buildIntentUpdates() {
diff --git a/core/net/src/test/java/org/onosproject/net/flow/impl/FlowRuleManagerTest.java b/core/net/src/test/java/org/onosproject/net/flow/impl/FlowRuleManagerTest.java
index 974af66..dffc072 100644
--- a/core/net/src/test/java/org/onosproject/net/flow/impl/FlowRuleManagerTest.java
+++ b/core/net/src/test/java/org/onosproject/net/flow/impl/FlowRuleManagerTest.java
@@ -106,7 +106,7 @@
service = mgr;
registry = mgr;
- mgr.activate();
+ mgr.activate(null);
mgr.addListener(listener);
provider = new TestProvider(PID);
providerService = registry.register(provider);
diff --git a/core/net/src/test/java/org/onosproject/net/intent/impl/IntentManagerTest.java b/core/net/src/test/java/org/onosproject/net/intent/impl/IntentManagerTest.java
index fe509dd..88d3f8b 100644
--- a/core/net/src/test/java/org/onosproject/net/intent/impl/IntentManagerTest.java
+++ b/core/net/src/test/java/org/onosproject/net/intent/impl/IntentManagerTest.java
@@ -285,7 +285,7 @@
service = manager;
extensionService = manager;
- manager.activate();
+ manager.activate(null);
service.addListener(listener);
extensionService.registerCompiler(MockIntent.class, compiler);
extensionService.registerInstaller(MockInstallableIntent.class, installer);
diff --git a/tools/package/etc/samples/org.onosproject.net.flow.impl.FlowRuleManager.cfg b/tools/package/etc/samples/org.onosproject.net.flow.impl.FlowRuleManager.cfg
new file mode 100644
index 0000000..613833c
--- /dev/null
+++ b/tools/package/etc/samples/org.onosproject.net.flow.impl.FlowRuleManager.cfg
@@ -0,0 +1,9 @@
+#
+# Sample configuration for the ONOS FlowRuleManager.
+#
+
+#
+# Timeout per Flow Operation (in milliseconds).
+# Default is 500 msec
+#
+# timeoutPerFlowOpMsec = 500
diff --git a/tools/package/etc/samples/org.onosproject.net.intent.impl.IntentManager.cfg b/tools/package/etc/samples/org.onosproject.net.intent.impl.IntentManager.cfg
new file mode 100644
index 0000000..4d771c0
--- /dev/null
+++ b/tools/package/etc/samples/org.onosproject.net.intent.impl.IntentManager.cfg
@@ -0,0 +1,9 @@
+#
+# Sample configuration for the ONOS IntentManager.
+#
+
+#
+# Timeout per Intent Operation (in milliseconds).
+# Default is 500 msec
+#
+# timeoutPerIntentOpMsec = 500