Implemented CLI commands to show SDN-IP routes
diff --git a/apps/sdnip/pom.xml b/apps/sdnip/pom.xml
index 0ad0c11..ce77bf7 100644
--- a/apps/sdnip/pom.xml
+++ b/apps/sdnip/pom.xml
@@ -48,6 +48,20 @@
     </dependency>
 
     <dependency>
+      <groupId>org.onlab.onos</groupId>
+      <artifactId>onos-cli</artifactId>
+      <version>${project.version}</version>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.karaf.shell</groupId>
+      <artifactId>org.apache.karaf.shell.console</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.osgi</groupId>
+      <artifactId>org.osgi.core</artifactId>
+    </dependency>
+
+    <dependency>
       <groupId>org.easymock</groupId>
       <artifactId>easymock</artifactId>
       <scope>test</scope>
diff --git a/apps/sdnip/src/main/java/org/onlab/onos/sdnip/Router.java b/apps/sdnip/src/main/java/org/onlab/onos/sdnip/Router.java
index 2a1a655..dc29285 100644
--- a/apps/sdnip/src/main/java/org/onlab/onos/sdnip/Router.java
+++ b/apps/sdnip/src/main/java/org/onlab/onos/sdnip/Router.java
@@ -62,10 +62,8 @@
 
     private static final Logger log = LoggerFactory.getLogger(Router.class);
 
-    // Store all route updates in a InvertedRadixTree.
-    // The key in this Tree is the binary sting of prefix of route.
-    // The Ip4Address is the next hop address of route, and is also the value
-    // of each entry.
+    // Store all route updates in a radix tree.
+    // The key in this tree is the binary string of prefix of the route.
     private InvertedRadixTree<RouteEntry> bgpRoutes;
 
     // Stores all incoming route updates in a queue.
@@ -102,7 +100,7 @@
      * Class constructor.
      *
      * @param intentService the intent service
-     * @param proxyArp the proxy ARP service
+     * @param hostService the host service
      * @param configInfoService the configuration service
      * @param interfaceService the interface service
      */
@@ -441,8 +439,8 @@
     /**
      * Processes adding a route entry.
      * <p/>
-     * Put new route entry into InvertedRadixTree. If there was an existing
-     * nexthop for this prefix, but the next hop was different, then execute
+     * Put new route entry into the radix tree. If there was an existing
+     * next hop for this prefix, but the next hop was different, then execute
      * deleting old route entry. If the next hop is the SDN domain, we do not
      * handle it at the moment. Otherwise, execute adding a route.
      *
@@ -623,8 +621,8 @@
     /**
      * Executes deleting a route entry.
      * <p/>
-     * Removes prefix from InvertedRadixTree, if success, then try to delete
-     * the relative intent.
+     * Removes prefix from radix tree, and if successful, then try to delete
+     * the related intent.
      *
      * @param routeEntry the route entry to delete
      */
@@ -690,9 +688,9 @@
     public void arpResponse(IpAddress ipAddress, MacAddress macAddress) {
         log.debug("Received ARP response: {} => {}", ipAddress, macAddress);
 
-         // We synchronize on this to prevent changes to the InvertedRadixTree
-         // while we're pushing intent. If the InvertedRadixTree changes, the
-         // InvertedRadixTree and intent could get out of sync.
+         // We synchronize on this to prevent changes to the radix tree
+         // while we're pushing intents. If the tree changes, the
+         // tree and intents could get out of sync.
         synchronized (this) {
 
             Set<RouteEntry> routesToPush =
@@ -709,14 +707,14 @@
                     log.debug("Pushing prefix {} next hop {}",
                               routeEntry.prefix(), routeEntry.nextHop());
                     // We only push prefix flows if the prefix is still in the
-                    // InvertedRadixTree and the next hop is the same as our
+                    // radix tree and the next hop is the same as our
                     // update.
                     // The prefix could have been removed while we were waiting
                     // for the ARP, or the next hop could have changed.
                     addRouteIntentToNextHop(prefix, ipAddress, macAddress);
                 } else {
                     log.debug("Received ARP response, but {}/{} is no longer in"
-                            + " InvertedRadixTree", routeEntry.prefix(),
+                            + " the radix tree", routeEntry.prefix(),
                             routeEntry.nextHop());
                 }
             }
diff --git a/apps/sdnip/src/main/java/org/onlab/onos/sdnip/SdnIp.java b/apps/sdnip/src/main/java/org/onlab/onos/sdnip/SdnIp.java
index 3f94cba..e7ed601 100644
--- a/apps/sdnip/src/main/java/org/onlab/onos/sdnip/SdnIp.java
+++ b/apps/sdnip/src/main/java/org/onlab/onos/sdnip/SdnIp.java
@@ -2,14 +2,18 @@
 
 import static org.slf4j.LoggerFactory.getLogger;
 
+import java.util.Collection;
+
 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.Reference;
 import org.apache.felix.scr.annotations.ReferenceCardinality;
+import org.apache.felix.scr.annotations.Service;
 import org.onlab.onos.net.host.HostService;
 import org.onlab.onos.net.intent.IntentService;
 import org.onlab.onos.sdnip.RouteUpdate.Type;
+import org.onlab.onos.sdnip.bgp.BgpRouteEntry;
 import org.onlab.onos.sdnip.bgp.BgpSessionManager;
 import org.onlab.onos.sdnip.config.SdnIpConfigReader;
 import org.onlab.packet.IpAddress;
@@ -17,10 +21,11 @@
 import org.slf4j.Logger;
 
 /**
- * Placeholder SDN-IP component.
+ * Component for the SDN-IP peering application.
  */
 @Component(immediate = true)
-public class SdnIp {
+@Service
+public class SdnIp implements SdnIpService {
 
     private final Logger log = getLogger(getClass());
 
@@ -64,4 +69,14 @@
     protected void deactivate() {
         log.info("Stopped");
     }
+
+    @Override
+    public Collection<BgpRouteEntry> getBgpRoutes() {
+        return bgpSessionManager.getBgpRoutes();
+    }
+
+    @Override
+    public Collection<RouteEntry> getRoutes() {
+        return router.getRoutes();
+    }
 }
diff --git a/apps/sdnip/src/main/java/org/onlab/onos/sdnip/SdnIpService.java b/apps/sdnip/src/main/java/org/onlab/onos/sdnip/SdnIpService.java
new file mode 100644
index 0000000..187ebb2
--- /dev/null
+++ b/apps/sdnip/src/main/java/org/onlab/onos/sdnip/SdnIpService.java
@@ -0,0 +1,24 @@
+package org.onlab.onos.sdnip;
+
+import java.util.Collection;
+
+import org.onlab.onos.sdnip.bgp.BgpRouteEntry;
+
+/**
+ * Service interface exported by SDN-IP.
+ */
+public interface SdnIpService {
+    /**
+     * Gets the BGP routes.
+     *
+     * @return the BGP routes
+     */
+    public Collection<BgpRouteEntry> getBgpRoutes();
+
+    /**
+     * Gets all the routes known to SDN-IP.
+     *
+     * @return the SDN-IP routes
+     */
+    public Collection<RouteEntry> getRoutes();
+}
diff --git a/apps/sdnip/src/main/java/org/onlab/onos/sdnip/cli/BgpRoutesListCommand.java b/apps/sdnip/src/main/java/org/onlab/onos/sdnip/cli/BgpRoutesListCommand.java
new file mode 100644
index 0000000..63cc305
--- /dev/null
+++ b/apps/sdnip/src/main/java/org/onlab/onos/sdnip/cli/BgpRoutesListCommand.java
@@ -0,0 +1,57 @@
+package org.onlab.onos.sdnip.cli;
+
+import org.apache.karaf.shell.commands.Command;
+import org.onlab.onos.cli.AbstractShellCommand;
+import org.onlab.onos.sdnip.SdnIpService;
+import org.onlab.onos.sdnip.bgp.BgpConstants;
+import org.onlab.onos.sdnip.bgp.BgpRouteEntry;
+
+/**
+ * Command to show the routes learned through BGP.
+ */
+@Command(scope = "onos", name = "bgp-routes",
+         description = "Lists all routes received from BGP")
+public class BgpRoutesListCommand extends AbstractShellCommand {
+
+    private static final String FORMAT =
+            "prefix=%s, nexthop=%s, origin=%s, localpref=%s, med=%s, aspath=%s, bgpid=%s";
+
+    @Override
+    protected void execute() {
+        SdnIpService service = get(SdnIpService.class);
+
+        for (BgpRouteEntry route : service.getBgpRoutes()) {
+            printRoute(route);
+        }
+    }
+
+    private void printRoute(BgpRouteEntry route) {
+        if (route != null) {
+            print(FORMAT, route.prefix(), route.nextHop(),
+                    originToString(route.getOrigin()), route.getLocalPref(),
+                    route.getMultiExitDisc(), route.getAsPath(),
+                    route.getBgpSession().getRemoteBgpId());
+        }
+    }
+
+    private static String originToString(int origin) {
+        String originString = "UNKNOWN";
+
+        switch (origin) {
+        case BgpConstants.Update.Origin.IGP:
+            originString = "IGP";
+            break;
+        case BgpConstants.Update.Origin.EGP:
+            originString = "EGP";
+            break;
+        case BgpConstants.Update.Origin.INCOMPLETE:
+            originString = "INCOMPLETE";
+            break;
+        default:
+            break;
+        }
+
+        return originString;
+    }
+
+}
diff --git a/apps/sdnip/src/main/java/org/onlab/onos/sdnip/cli/RoutesListCommand.java b/apps/sdnip/src/main/java/org/onlab/onos/sdnip/cli/RoutesListCommand.java
new file mode 100644
index 0000000..1af409a
--- /dev/null
+++ b/apps/sdnip/src/main/java/org/onlab/onos/sdnip/cli/RoutesListCommand.java
@@ -0,0 +1,32 @@
+package org.onlab.onos.sdnip.cli;
+
+import org.apache.karaf.shell.commands.Command;
+import org.onlab.onos.cli.AbstractShellCommand;
+import org.onlab.onos.sdnip.RouteEntry;
+import org.onlab.onos.sdnip.SdnIpService;
+
+/**
+ * Command to show the list of routes in SDN-IP's routing table.
+ */
+@Command(scope = "onos", name = "routes",
+        description = "Lists all routes known to SDN-IP")
+public class RoutesListCommand extends AbstractShellCommand {
+
+    private static final String FORMAT =
+            "prefix=%s, nexthop=%s";
+
+    @Override
+    protected void execute() {
+        SdnIpService service = get(SdnIpService.class);
+
+        for (RouteEntry route : service.getRoutes()) {
+            printRoute(route);
+        }
+    }
+
+    private void printRoute(RouteEntry route) {
+        if (route != null) {
+            print(FORMAT, route.prefix(), route.nextHop());
+        }
+    }
+}
diff --git a/apps/sdnip/src/main/resources/OSGI-INF/blueprint/shell-config.xml b/apps/sdnip/src/main/resources/OSGI-INF/blueprint/shell-config.xml
new file mode 100644
index 0000000..62fccec
--- /dev/null
+++ b/apps/sdnip/src/main/resources/OSGI-INF/blueprint/shell-config.xml
@@ -0,0 +1,11 @@
+<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0">
+
+  <command-bundle xmlns="http://karaf.apache.org/xmlns/shell/v1.1.0">
+    <command>
+      <action class="org.onlab.onos.sdnip.cli.BgpRoutesListCommand"/>
+    </command>
+    <command>
+      <action class="org.onlab.onos.sdnip.cli.RoutesListCommand"/>
+    </command>
+  </command-bundle>
+</blueprint>