Pavlin Radoslavov

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
...@@ -25,6 +25,8 @@ import com.google.common.collect.Sets; ...@@ -25,6 +25,8 @@ import com.google.common.collect.Sets;
25 import org.apache.felix.scr.annotations.Activate; 25 import org.apache.felix.scr.annotations.Activate;
26 import org.apache.felix.scr.annotations.Component; 26 import org.apache.felix.scr.annotations.Component;
27 import org.apache.felix.scr.annotations.Deactivate; 27 import org.apache.felix.scr.annotations.Deactivate;
28 +import org.apache.felix.scr.annotations.Modified;
29 +import org.apache.felix.scr.annotations.Property;
28 import org.apache.felix.scr.annotations.Reference; 30 import org.apache.felix.scr.annotations.Reference;
29 import org.apache.felix.scr.annotations.ReferenceCardinality; 31 import org.apache.felix.scr.annotations.ReferenceCardinality;
30 import org.apache.felix.scr.annotations.Service; 32 import org.apache.felix.scr.annotations.Service;
...@@ -53,8 +55,10 @@ import org.onosproject.net.flow.FlowRuleStore; ...@@ -53,8 +55,10 @@ import org.onosproject.net.flow.FlowRuleStore;
53 import org.onosproject.net.flow.FlowRuleStoreDelegate; 55 import org.onosproject.net.flow.FlowRuleStoreDelegate;
54 import org.onosproject.net.provider.AbstractProviderRegistry; 56 import org.onosproject.net.provider.AbstractProviderRegistry;
55 import org.onosproject.net.provider.AbstractProviderService; 57 import org.onosproject.net.provider.AbstractProviderService;
58 +import org.osgi.service.component.ComponentContext;
56 import org.slf4j.Logger; 59 import org.slf4j.Logger;
57 60
61 +import java.util.Dictionary;
58 import java.util.HashSet; 62 import java.util.HashSet;
59 import java.util.List; 63 import java.util.List;
60 import java.util.Map; 64 import java.util.Map;
...@@ -68,6 +72,7 @@ import java.util.concurrent.TimeUnit; ...@@ -68,6 +72,7 @@ import java.util.concurrent.TimeUnit;
68 import java.util.concurrent.TimeoutException; 72 import java.util.concurrent.TimeoutException;
69 import java.util.concurrent.atomic.AtomicReference; 73 import java.util.concurrent.atomic.AtomicReference;
70 import static com.google.common.base.Preconditions.checkNotNull; 74 import static com.google.common.base.Preconditions.checkNotNull;
75 +import static com.google.common.base.Strings.isNullOrEmpty;
71 import static org.onlab.util.Tools.namedThreads; 76 import static org.onlab.util.Tools.namedThreads;
72 import static org.slf4j.LoggerFactory.getLogger; 77 import static org.slf4j.LoggerFactory.getLogger;
73 78
...@@ -82,6 +87,8 @@ public class FlowRuleManager ...@@ -82,6 +87,8 @@ public class FlowRuleManager
82 87
83 enum BatchState { STARTED, FINISHED, CANCELLED }; 88 enum BatchState { STARTED, FINISHED, CANCELLED };
84 89
90 + private static final int DEFAULT_TIMEOUT_PER_FLOW_OP_MSEC = 500; // ms
91 +
85 public static final String FLOW_RULE_NULL = "FlowRule cannot be null"; 92 public static final String FLOW_RULE_NULL = "FlowRule cannot be null";
86 private final Logger log = getLogger(getClass()); 93 private final Logger log = getLogger(getClass());
87 94
...@@ -101,8 +108,16 @@ public class FlowRuleManager ...@@ -101,8 +108,16 @@ public class FlowRuleManager
101 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) 108 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
102 protected DeviceService deviceService; 109 protected DeviceService deviceService;
103 110
111 + @Property(name = "timeoutPerFlowOpMsec", intValue = DEFAULT_TIMEOUT_PER_FLOW_OP_MSEC,
112 + label = "Configure Timeout per Flow Operation; " +
113 + "default is 500 msec")
114 + private int timeoutPerFlowOpMsec = DEFAULT_TIMEOUT_PER_FLOW_OP_MSEC;
115 +
116 +
104 @Activate 117 @Activate
105 - public void activate() { 118 + public void activate(ComponentContext context) {
119 + readComponentConfiguration(context);
120 +
106 futureService = 121 futureService =
107 Executors.newFixedThreadPool(32, namedThreads("provider-future-listeners-%d")); 122 Executors.newFixedThreadPool(32, namedThreads("provider-future-listeners-%d"));
108 store.setDelegate(delegate); 123 store.setDelegate(delegate);
...@@ -119,6 +134,54 @@ public class FlowRuleManager ...@@ -119,6 +134,54 @@ public class FlowRuleManager
119 log.info("Stopped"); 134 log.info("Stopped");
120 } 135 }
121 136
137 + @Modified
138 + public void modified(ComponentContext context) {
139 + readComponentConfiguration(context);
140 + }
141 +
142 + /**
143 + * Extracts properties from the component configuration context.
144 + *
145 + * @param context the component context
146 + */
147 + private void readComponentConfiguration(ComponentContext context) {
148 + if (context == null) {
149 + return; // Nothing to do
150 + }
151 + Dictionary<?, ?> properties = context.getProperties();
152 +
153 + Integer timeoutPerFlowOpMsecConfigured =
154 + getIntegerProperty(properties, "timeoutPerFlowOpMsec");
155 + if (timeoutPerFlowOpMsecConfigured == null) {
156 + log.info("Timeout per Flow Operation is not configured, " +
157 + "using current value of {} ms", timeoutPerFlowOpMsec);
158 + } else {
159 + timeoutPerFlowOpMsec = timeoutPerFlowOpMsecConfigured;
160 + log.info("Configured. Timeout per Flow Operation is " +
161 + "configured to {} ms", timeoutPerFlowOpMsec);
162 + }
163 + }
164 +
165 + /**
166 + * Get Integer property from the propertyName
167 + * Return null if propertyName is not found.
168 + *
169 + * @param properties properties to be looked up
170 + * @param propertyName the name of the property to look up
171 + * @return value when the propertyName is defined or return null
172 + */
173 + private static Integer getIntegerProperty(Dictionary<?, ?> properties,
174 + String propertyName) {
175 + Integer value = null;
176 + try {
177 + String s = (String) properties.get(propertyName);
178 + value = isNullOrEmpty(s) ? null : Integer.parseInt(s.trim());
179 + } catch (NumberFormatException | ClassCastException e) {
180 + value = null;
181 + }
182 + return value;
183 + }
184 +
122 @Override 185 @Override
123 public int getFlowRuleCount() { 186 public int getFlowRuleCount() {
124 return store.getFlowRuleCount(); 187 return store.getFlowRuleCount();
...@@ -378,9 +441,6 @@ public class FlowRuleManager ...@@ -378,9 +441,6 @@ public class FlowRuleManager
378 // Store delegate to re-post events emitted from the store. 441 // Store delegate to re-post events emitted from the store.
379 private class InternalStoreDelegate implements FlowRuleStoreDelegate { 442 private class InternalStoreDelegate implements FlowRuleStoreDelegate {
380 443
381 - // FIXME set appropriate default and make it configurable
382 - private static final int TIMEOUT_PER_OP = 500; // ms
383 -
384 // TODO: Right now we only dispatch events at individual flowEntry level. 444 // TODO: Right now we only dispatch events at individual flowEntry level.
385 // It may be more efficient for also dispatch events as a batch. 445 // It may be more efficient for also dispatch events as a batch.
386 @Override 446 @Override
...@@ -408,7 +468,8 @@ public class FlowRuleManager ...@@ -408,7 +468,8 @@ public class FlowRuleManager
408 public void run() { 468 public void run() {
409 CompletedBatchOperation res; 469 CompletedBatchOperation res;
410 try { 470 try {
411 - res = result.get(TIMEOUT_PER_OP * batchOperation.size(), TimeUnit.MILLISECONDS); 471 + res = result.get(timeoutPerFlowOpMsec * batchOperation.size(),
472 + TimeUnit.MILLISECONDS);
412 store.batchOperationComplete(FlowRuleBatchEvent.completed(request, res)); 473 store.batchOperationComplete(FlowRuleBatchEvent.completed(request, res));
413 } catch (TimeoutException | InterruptedException | ExecutionException e) { 474 } catch (TimeoutException | InterruptedException | ExecutionException e) {
414 log.warn("Something went wrong with the batch operation {}", 475 log.warn("Something went wrong with the batch operation {}",
......
...@@ -22,6 +22,8 @@ import com.google.common.collect.Maps; ...@@ -22,6 +22,8 @@ import com.google.common.collect.Maps;
22 import org.apache.felix.scr.annotations.Activate; 22 import org.apache.felix.scr.annotations.Activate;
23 import org.apache.felix.scr.annotations.Component; 23 import org.apache.felix.scr.annotations.Component;
24 import org.apache.felix.scr.annotations.Deactivate; 24 import org.apache.felix.scr.annotations.Deactivate;
25 +import org.apache.felix.scr.annotations.Modified;
26 +import org.apache.felix.scr.annotations.Property;
25 import org.apache.felix.scr.annotations.Reference; 27 import org.apache.felix.scr.annotations.Reference;
26 import org.apache.felix.scr.annotations.ReferenceCardinality; 28 import org.apache.felix.scr.annotations.ReferenceCardinality;
27 import org.apache.felix.scr.annotations.Service; 29 import org.apache.felix.scr.annotations.Service;
...@@ -50,10 +52,12 @@ import org.onosproject.net.intent.IntentState; ...@@ -50,10 +52,12 @@ import org.onosproject.net.intent.IntentState;
50 import org.onosproject.net.intent.IntentStore; 52 import org.onosproject.net.intent.IntentStore;
51 import org.onosproject.net.intent.BatchWrite; 53 import org.onosproject.net.intent.BatchWrite;
52 import org.onosproject.net.intent.IntentStoreDelegate; 54 import org.onosproject.net.intent.IntentStoreDelegate;
55 +import org.osgi.service.component.ComponentContext;
53 import org.slf4j.Logger; 56 import org.slf4j.Logger;
54 57
55 import java.util.ArrayList; 58 import java.util.ArrayList;
56 import java.util.Collections; 59 import java.util.Collections;
60 +import java.util.Dictionary;
57 import java.util.EnumSet; 61 import java.util.EnumSet;
58 import java.util.List; 62 import java.util.List;
59 import java.util.Map; 63 import java.util.Map;
...@@ -67,6 +71,7 @@ import java.util.concurrent.TimeoutException; ...@@ -67,6 +71,7 @@ import java.util.concurrent.TimeoutException;
67 71
68 import static com.google.common.base.Preconditions.checkArgument; 72 import static com.google.common.base.Preconditions.checkArgument;
69 import static com.google.common.base.Preconditions.checkNotNull; 73 import static com.google.common.base.Preconditions.checkNotNull;
74 +import static com.google.common.base.Strings.isNullOrEmpty;
70 import static java.util.concurrent.Executors.newFixedThreadPool; 75 import static java.util.concurrent.Executors.newFixedThreadPool;
71 import static org.onosproject.net.intent.IntentState.*; 76 import static org.onosproject.net.intent.IntentState.*;
72 import static org.onlab.util.Tools.namedThreads; 77 import static org.onlab.util.Tools.namedThreads;
...@@ -79,6 +84,9 @@ import static org.slf4j.LoggerFactory.getLogger; ...@@ -79,6 +84,9 @@ import static org.slf4j.LoggerFactory.getLogger;
79 @Service 84 @Service
80 public class IntentManager 85 public class IntentManager
81 implements IntentService, IntentExtensionService { 86 implements IntentService, IntentExtensionService {
87 +
88 + private static final int DEFAULT_TIMEOUT_PER_INTENT_OP_MSEC = 500; // ms
89 +
82 private static final Logger log = getLogger(IntentManager.class); 90 private static final Logger log = getLogger(IntentManager.class);
83 91
84 public static final String INTENT_NULL = "Intent cannot be null"; 92 public static final String INTENT_NULL = "Intent cannot be null";
...@@ -119,6 +127,10 @@ public class IntentManager ...@@ -119,6 +127,10 @@ public class IntentManager
119 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) 127 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
120 protected FlowRuleService flowRuleService; 128 protected FlowRuleService flowRuleService;
121 129
130 + @Property(name = "timeoutPerIntentOpMsec", intValue = DEFAULT_TIMEOUT_PER_INTENT_OP_MSEC,
131 + label = "Configure Timeout per Intent Operation; " +
132 + "default is 500 msec")
133 + private int timeoutPerIntentOpMsec = DEFAULT_TIMEOUT_PER_INTENT_OP_MSEC;
122 134
123 private ExecutorService executor; 135 private ExecutorService executor;
124 136
...@@ -128,7 +140,9 @@ public class IntentManager ...@@ -128,7 +140,9 @@ public class IntentManager
128 private IdGenerator idGenerator; 140 private IdGenerator idGenerator;
129 141
130 @Activate 142 @Activate
131 - public void activate() { 143 + public void activate(ComponentContext context) {
144 + readComponentConfiguration(context);
145 +
132 store.setDelegate(delegate); 146 store.setDelegate(delegate);
133 trackerService.setDelegate(topoDelegate); 147 trackerService.setDelegate(topoDelegate);
134 batchService.setDelegate(batchDelegate); 148 batchService.setDelegate(batchDelegate);
...@@ -150,6 +164,54 @@ public class IntentManager ...@@ -150,6 +164,54 @@ public class IntentManager
150 log.info("Stopped"); 164 log.info("Stopped");
151 } 165 }
152 166
167 + @Modified
168 + public void modified(ComponentContext context) {
169 + readComponentConfiguration(context);
170 + }
171 +
172 + /**
173 + * Extracts properties from the component configuration context.
174 + *
175 + * @param context the component context
176 + */
177 + private void readComponentConfiguration(ComponentContext context) {
178 + if (context == null) {
179 + return; // Nothing to do
180 + }
181 + Dictionary<?, ?> properties = context.getProperties();
182 +
183 + Integer timeoutPerIntentOpMsecConfigured =
184 + getIntegerProperty(properties, "timeoutPerIntentOpMsec");
185 + if (timeoutPerIntentOpMsecConfigured == null) {
186 + log.info("Timeout per Intent Operation is not configured, " +
187 + "using current value of {} ms", timeoutPerIntentOpMsec);
188 + } else {
189 + timeoutPerIntentOpMsec = timeoutPerIntentOpMsecConfigured;
190 + log.info("Configured. Timeout per Intent Operation is " +
191 + "configured to {} ms", timeoutPerIntentOpMsec);
192 + }
193 + }
194 +
195 + /**
196 + * Get Integer property from the propertyName
197 + * Return null if propertyName is not found.
198 + *
199 + * @param properties properties to be looked up
200 + * @param propertyName the name of the property to look up
201 + * @return value when the propertyName is defined or return null
202 + */
203 + private static Integer getIntegerProperty(Dictionary<?, ?> properties,
204 + String propertyName) {
205 + Integer value = null;
206 + try {
207 + String s = (String) properties.get(propertyName);
208 + value = isNullOrEmpty(s) ? null : Integer.parseInt(s.trim());
209 + } catch (NumberFormatException | ClassCastException e) {
210 + value = null;
211 + }
212 + return value;
213 + }
214 +
153 @Override 215 @Override
154 public void submit(Intent intent) { 216 public void submit(Intent intent) {
155 checkNotNull(intent, INTENT_NULL); 217 checkNotNull(intent, INTENT_NULL);
...@@ -744,7 +806,6 @@ public class IntentManager ...@@ -744,7 +806,6 @@ public class IntentManager
744 private class IntentInstallMonitor implements Runnable { 806 private class IntentInstallMonitor implements Runnable {
745 807
746 // TODO make this configurable 808 // TODO make this configurable
747 - private static final int TIMEOUT_PER_OP = 500; // ms
748 private static final int MAX_ATTEMPTS = 3; 809 private static final int MAX_ATTEMPTS = 3;
749 810
750 private final IntentOperations ops; 811 private final IntentOperations ops;
...@@ -764,7 +825,7 @@ public class IntentManager ...@@ -764,7 +825,7 @@ public class IntentManager
764 private void resetTimeoutLimit() { 825 private void resetTimeoutLimit() {
765 // FIXME compute reasonable timeouts 826 // FIXME compute reasonable timeouts
766 this.endTime = System.currentTimeMillis() 827 this.endTime = System.currentTimeMillis()
767 - + ops.operations().size() * TIMEOUT_PER_OP; 828 + + ops.operations().size() * timeoutPerIntentOpMsec;
768 } 829 }
769 830
770 private void buildIntentUpdates() { 831 private void buildIntentUpdates() {
......
...@@ -106,7 +106,7 @@ public class FlowRuleManagerTest { ...@@ -106,7 +106,7 @@ public class FlowRuleManagerTest {
106 service = mgr; 106 service = mgr;
107 registry = mgr; 107 registry = mgr;
108 108
109 - mgr.activate(); 109 + mgr.activate(null);
110 mgr.addListener(listener); 110 mgr.addListener(listener);
111 provider = new TestProvider(PID); 111 provider = new TestProvider(PID);
112 providerService = registry.register(provider); 112 providerService = registry.register(provider);
......
...@@ -285,7 +285,7 @@ public class IntentManagerTest { ...@@ -285,7 +285,7 @@ public class IntentManagerTest {
285 service = manager; 285 service = manager;
286 extensionService = manager; 286 extensionService = manager;
287 287
288 - manager.activate(); 288 + manager.activate(null);
289 service.addListener(listener); 289 service.addListener(listener);
290 extensionService.registerCompiler(MockIntent.class, compiler); 290 extensionService.registerCompiler(MockIntent.class, compiler);
291 extensionService.registerInstaller(MockInstallableIntent.class, installer); 291 extensionService.registerInstaller(MockInstallableIntent.class, installer);
......
1 +#
2 +# Sample configuration for the ONOS FlowRuleManager.
3 +#
4 +
5 +#
6 +# Timeout per Flow Operation (in milliseconds).
7 +# Default is 500 msec
8 +#
9 +# timeoutPerFlowOpMsec = 500
1 +#
2 +# Sample configuration for the ONOS IntentManager.
3 +#
4 +
5 +#
6 +# Timeout per Intent Operation (in milliseconds).
7 +# Default is 500 msec
8 +#
9 +# timeoutPerIntentOpMsec = 500