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