Cleanup in the SDN-IP related configuration files:
 * The (deployed) Interface addresses configuration file "addresses.json"
   from the apps/config application is expected to be found in the
   /opt/onos/config directory

 * The (deployed) SDN-IP configuration file "sdnip.json" is expected
   to be found in the /opt/onos/config directory

 * All configuration files (i.e., addresses.json and sdnip.json) should
   be stored in the tools/package/config directory before deployment
   (i.e., before running onos-config)

 * Removed the apps/config/src/main/resources/config.json sample configuration
   file, because it was incorrect, and replaced it with "addresses.json"
   file in the same directory

 * Updated the text in files tools/package/config/README and
   apps/sdnip/src/main/resources/config-examples/README

 * Minor code cleanup in SdnIpConfigReader.java and NetworkConfigReader.java

Change-Id: I8af75e62a94e4fb701e2c6a09cde93cd8461e255
diff --git a/apps/config/src/main/java/org/onlab/onos/config/NetworkConfigReader.java b/apps/config/src/main/java/org/onlab/onos/config/NetworkConfigReader.java
index f015e36..846e83c 100644
--- a/apps/config/src/main/java/org/onlab/onos/config/NetworkConfigReader.java
+++ b/apps/config/src/main/java/org/onlab/onos/config/NetworkConfigReader.java
@@ -50,7 +50,10 @@
 
     private final Logger log = getLogger(getClass());
 
-    private static final String DEFAULT_CONFIG_FILE = "config/addresses.json";
+    // Current working dir seems to be /opt/onos/apache-karaf-3.0.2
+    // TODO: Set the path to /opt/onos/config
+    private static final String CONFIG_DIR = "../config";
+    private static final String DEFAULT_CONFIG_FILE = "addresses.json";
     private String configFileName = DEFAULT_CONFIG_FILE;
 
     @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
@@ -60,52 +63,9 @@
     protected void activate() {
         log.info("Started network config reader");
 
-        log.info("Config file set to {}", configFileName);
-
         AddressConfiguration config = readNetworkConfig();
-
         if (config != null) {
-            for (AddressEntry entry : config.getAddresses()) {
-
-                ConnectPoint cp = new ConnectPoint(
-                        DeviceId.deviceId(dpidToUri(entry.getDpid())),
-                        PortNumber.portNumber(entry.getPortNumber()));
-
-                Set<InterfaceIpAddress> interfaceIpAddresses = new HashSet<>();
-
-                for (String strIp : entry.getIpAddresses()) {
-                    // Get the IP address and the subnet mask length
-                    try {
-                        String[] splits = strIp.split("/");
-                        if (splits.length != 2) {
-                            throw new IllegalArgumentException("Invalid IP address and prefix length format");
-                        }
-                        // NOTE: IpPrefix will mask-out the bits after the prefix length.
-                        IpPrefix subnet = IpPrefix.valueOf(strIp);
-                        IpAddress addr = IpAddress.valueOf(splits[0]);
-                        InterfaceIpAddress ia =
-                            new InterfaceIpAddress(addr, subnet);
-                        interfaceIpAddresses.add(ia);
-                    } catch (IllegalArgumentException e) {
-                        log.warn("Bad format for IP address in config: {}", strIp);
-                    }
-                }
-
-                MacAddress macAddress = null;
-                if (entry.getMacAddress() != null) {
-                    try {
-                        macAddress = MacAddress.valueOf(entry.getMacAddress());
-                    } catch (IllegalArgumentException e) {
-                        log.warn("Bad format for MAC address in config: {}",
-                                entry.getMacAddress());
-                    }
-                }
-
-                PortAddresses addresses = new PortAddresses(cp,
-                        interfaceIpAddresses, macAddress);
-
-                hostAdminService.bindAddressesToPort(addresses);
-            }
+            applyNetworkConfig(config);
         }
     }
 
@@ -114,12 +74,17 @@
         log.info("Stopped");
     }
 
+    /**
+     * Reads the network configuration.
+     *
+     * @return the network configuration on success, otherwise null
+     */
     private AddressConfiguration readNetworkConfig() {
-        File configFile = new File(configFileName);
-
+        File configFile = new File(CONFIG_DIR, configFileName);
         ObjectMapper mapper = new ObjectMapper();
 
         try {
+            log.info("Loading config: {}", configFile.getAbsolutePath());
             AddressConfiguration config =
                     mapper.readValue(configFile, AddressConfiguration.class);
 
@@ -127,12 +92,58 @@
         } catch (FileNotFoundException e) {
             log.warn("Configuration file not found: {}", configFileName);
         } catch (IOException e) {
-            log.error("Unable to read config from file:", e);
+            log.error("Error loading configuration", e);
         }
 
         return null;
     }
 
+    /**
+     * Applies the network configuration.
+     *
+     * @param config the network configuration to apply
+     */
+    private void applyNetworkConfig(AddressConfiguration config) {
+        for (AddressEntry entry : config.getAddresses()) {
+            ConnectPoint cp = new ConnectPoint(
+                        DeviceId.deviceId(dpidToUri(entry.getDpid())),
+                        PortNumber.portNumber(entry.getPortNumber()));
+
+            Set<InterfaceIpAddress> interfaceIpAddresses = new HashSet<>();
+            for (String strIp : entry.getIpAddresses()) {
+                // Get the IP address and the subnet mask length
+                try {
+                    String[] splits = strIp.split("/");
+                    if (splits.length != 2) {
+                        throw new IllegalArgumentException("Invalid IP address and prefix length format");
+                    }
+                    // NOTE: IpPrefix will mask-out the bits after the prefix length.
+                    IpPrefix subnet = IpPrefix.valueOf(strIp);
+                    IpAddress addr = IpAddress.valueOf(splits[0]);
+                    InterfaceIpAddress ia =
+                        new InterfaceIpAddress(addr, subnet);
+                    interfaceIpAddresses.add(ia);
+                } catch (IllegalArgumentException e) {
+                    log.warn("Bad format for IP address in config: {}", strIp);
+                }
+            }
+
+            MacAddress macAddress = null;
+            if (entry.getMacAddress() != null) {
+                try {
+                    macAddress = MacAddress.valueOf(entry.getMacAddress());
+                } catch (IllegalArgumentException e) {
+                    log.warn("Bad format for MAC address in config: {}",
+                             entry.getMacAddress());
+                }
+            }
+
+            PortAddresses addresses = new PortAddresses(cp,
+                        interfaceIpAddresses, macAddress);
+            hostAdminService.bindAddressesToPort(addresses);
+        }
+    }
+
     private static String dpidToUri(String dpid) {
         return "of:" + dpid.replace(":", "");
     }
diff --git a/apps/sdnip/src/main/resources/config-examples/addresses.json b/apps/config/src/main/resources/addresses.json
similarity index 100%
rename from apps/sdnip/src/main/resources/config-examples/addresses.json
rename to apps/config/src/main/resources/addresses.json
diff --git a/apps/config/src/main/resources/config.json b/apps/config/src/main/resources/config.json
deleted file mode 100644
index ca4be83..0000000
--- a/apps/config/src/main/resources/config.json
+++ /dev/null
@@ -1,21 +0,0 @@
-{
-    "interfaces" : [
-	{
-	    "dpid" : "00:00:00:00:00:00:01",
-	    "port" : "1",
-	    "ips" : ["192.168.10.101/24"],
-	    "mac" : "00:00:00:11:22:33"
-	},
-	{
-	    "dpid" : "00:00:00:00:00:00:02",
-	    "port" : "1",
-	    "ips" : ["192.168.20.101/24", "192.168.30.101/24"]
-	},
-	{
-	    "dpid" : "00:00:00:00:00:00:03",
-	    "port" : "1",
-	    "ips" : ["10.1.0.1/16"],
-	    "mac" : "00:00:00:00:00:01"
-	}
-    ]
-}
diff --git a/apps/sdnip/src/main/java/org/onlab/onos/sdnip/config/SdnIpConfigReader.java b/apps/sdnip/src/main/java/org/onlab/onos/sdnip/config/SdnIpConfigReader.java
index 2fcd1fe..7262c42 100644
--- a/apps/sdnip/src/main/java/org/onlab/onos/sdnip/config/SdnIpConfigReader.java
+++ b/apps/sdnip/src/main/java/org/onlab/onos/sdnip/config/SdnIpConfigReader.java
@@ -37,24 +37,31 @@
  */
 public class SdnIpConfigReader implements SdnIpConfigService {
 
-    private static final Logger log = LoggerFactory.getLogger(SdnIpConfigReader.class);
+    private final Logger log = LoggerFactory.getLogger(getClass());
 
-    private static final String DEFAULT_CONFIG_FILE = "config/sdnip.json";
+    // Current working dir seems to be /opt/onos/apache-karaf-3.0.2
+    // TODO: Set the path to /opt/onos/config
+    private static final String CONFIG_DIR = "../config";
+    private static final String DEFAULT_CONFIG_FILE = "sdnip.json";
     private String configFileName = DEFAULT_CONFIG_FILE;
+
     private Map<String, BgpSpeaker> bgpSpeakers = new ConcurrentHashMap<>();
     private Map<IpAddress, BgpPeer> bgpPeers = new ConcurrentHashMap<>();
 
     /**
-     * Reads the info contained in the configuration file.
+     * Reads SDN-IP related information contained in the configuration file.
      *
-     * @param configFilename The name of configuration file for SDN-IP application.
+     * @param configFilename the name of the configuration file for the SDN-IP
+     * application
      */
     private void readConfiguration(String configFilename) {
-        File gatewaysFile = new File(configFilename);
+        File configFile = new File(CONFIG_DIR, configFilename);
         ObjectMapper mapper = new ObjectMapper();
 
         try {
-            Configuration config = mapper.readValue(gatewaysFile, Configuration.class);
+            log.info("Loading config: {}", configFile.getAbsolutePath());
+            Configuration config = mapper.readValue(configFile,
+                                                    Configuration.class);
             for (BgpSpeaker speaker : config.getBgpSpeakers()) {
                 bgpSpeakers.put(speaker.name(), speaker);
             }
@@ -64,13 +71,11 @@
         } catch (FileNotFoundException e) {
             log.warn("Configuration file not found: {}", configFileName);
         } catch (IOException e) {
-            log.error("Error reading JSON file", e);
+            log.error("Error loading configuration", e);
         }
     }
 
     public void init() {
-        log.debug("Config file set to {}", configFileName);
-
         readConfiguration(configFileName);
     }
 
diff --git a/apps/sdnip/src/main/resources/config-examples/README b/apps/sdnip/src/main/resources/config-examples/README
index 0444e41..7642a4d 100644
--- a/apps/sdnip/src/main/resources/config-examples/README
+++ b/apps/sdnip/src/main/resources/config-examples/README
@@ -1 +1,5 @@
-ONOS looks for these config files by default in $KARAF_HOME/config/
\ No newline at end of file
+The SDN-IP configuration files should be copied to directory
+  $ONOS_HOME/tools/package/config
+
+After deployment and starting up the ONOS cluster, ONOS looks for these
+configuration files in /opt/onos/config on each cluster member.
diff --git a/tools/package/config/README b/tools/package/config/README
index 62b758d..970f87a 100644
--- a/tools/package/config/README
+++ b/tools/package/config/README
@@ -1,2 +1,2 @@
-onos-config command will copy files contained in this directory to ONOS instances according to cell definition
-
+The onos-config command will copy files contained in this directory to ONOS
+instances according to cell definition.