CORD-Support-App: generate JSON blob of devices, hosts, (filtered) links.
- also, update cell simon-single.
- fixed checkstyle (unused import)

Change-Id: I7fc4d601a5f2d79a993fab5a5b664348440a85ea
diff --git a/apps/cord-support/BUCK b/apps/cord-support/BUCK
new file mode 100644
index 0000000..c39a4e4
--- /dev/null
+++ b/apps/cord-support/BUCK
@@ -0,0 +1,28 @@
+COMPILE_DEPS = [
+  '//lib:CORE_DEPS',
+  '//lib:javax.ws.rs-api',
+  '//utils/rest:onlab-rest',
+  '//core/store/serializers:onos-core-serializers',
+]
+
+TEST_DEPS = [
+  '//lib:TEST_REST',
+  '//lib:jersey-server',
+]
+
+osgi_jar_with_tests (
+  deps = COMPILE_DEPS,
+  test_deps = TEST_DEPS,
+  web_context = '/onos/cord-support',
+  api_title = 'CORD Support App',
+  api_version = '1.0',
+  api_description = 'REST API for CORD inquiry to ONOS topology',
+  api_package = 'org.onosproject.cordsupport',
+)
+
+onos_app (
+  title = 'CORD Support App',
+  category = 'Utility',
+  url = 'http://onosproject.org',
+  description = 'CORD Support application.',
+)
diff --git a/apps/cord-support/src/main/java/org/onosproject/cordsupport/CordSupportWebApplication.java b/apps/cord-support/src/main/java/org/onosproject/cordsupport/CordSupportWebApplication.java
new file mode 100644
index 0000000..72020a2
--- /dev/null
+++ b/apps/cord-support/src/main/java/org/onosproject/cordsupport/CordSupportWebApplication.java
@@ -0,0 +1,32 @@
+/*
+ * Copyright 2017-present Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.cordsupport;
+
+import org.onlab.rest.AbstractWebApplication;
+
+import java.util.Set;
+
+/**
+ * REST end-point to provide ONOS topology information.
+ * This is in support of CORD demo visualizations.
+ */
+public class CordSupportWebApplication extends AbstractWebApplication {
+    @Override
+    public Set<Class<?>> getClasses() {
+        return getClasses(CordSupportWebResource.class);
+    }
+}
diff --git a/apps/cord-support/src/main/java/org/onosproject/cordsupport/CordSupportWebResource.java b/apps/cord-support/src/main/java/org/onosproject/cordsupport/CordSupportWebResource.java
new file mode 100644
index 0000000..17dc4fe
--- /dev/null
+++ b/apps/cord-support/src/main/java/org/onosproject/cordsupport/CordSupportWebResource.java
@@ -0,0 +1,116 @@
+/*
+ * Copyright 2017-present Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.cordsupport;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.node.ArrayNode;
+import com.fasterxml.jackson.databind.node.ObjectNode;
+import org.onosproject.net.Device;
+import org.onosproject.net.Host;
+import org.onosproject.net.Link;
+import org.onosproject.net.device.DeviceService;
+import org.onosproject.net.host.HostService;
+import org.onosproject.net.link.LinkService;
+import org.onosproject.rest.AbstractWebResource;
+
+import javax.ws.rs.GET;
+import javax.ws.rs.Path;
+import javax.ws.rs.core.Response;
+import java.util.HashSet;
+import java.util.Set;
+
+import static javax.ws.rs.core.MediaType.APPLICATION_JSON_TYPE;
+
+/**
+ * CORD support REST implementation.
+ */
+@Path("topo")
+public class CordSupportWebResource extends AbstractWebResource {
+
+    private static final String TILDE = "~";
+
+    private final ObjectMapper mapper = new ObjectMapper();
+    private final Set<String> seenLinks = new HashSet<>();
+
+    @GET
+    public Response queryTopology() {
+        ObjectNode root = mapper.createObjectNode();
+
+        addDevices(root);
+        addHosts(root);
+        addLinks(root);
+
+        return Response.ok(root.toString(), APPLICATION_JSON_TYPE).build();
+    }
+
+    private void addDevices(ObjectNode root) {
+        ArrayNode devices = createArray(root, "devices");
+        get(DeviceService.class).getDevices()
+                .forEach(dev -> devices.add(json(dev)));
+    }
+
+    private void addHosts(ObjectNode root) {
+        ArrayNode hosts = createArray(root, "hosts");
+        get(HostService.class).getHosts()
+                .forEach(host -> hosts.add(json(host)));
+    }
+
+    private void addLinks(ObjectNode root) {
+        ArrayNode links = createArray(root, "links");
+        seenLinks.clear();
+        get(LinkService.class).getLinks()
+                .forEach(link -> {
+                    String canon = canonicalRep(link);
+                    if (!seenLinks.contains(canon)) {
+                        seenLinks.add(canon);
+                        links.add(json(link));
+                    }
+                });
+    }
+
+    private String canonicalRep(Link link) {
+        String a = link.src().toString();
+        String b = link.dst().toString();
+        return a.compareTo(b) < 0 ? a + TILDE + b : b + TILDE + a;
+    }
+
+    private ArrayNode createArray(ObjectNode root, String key) {
+        ArrayNode result = mapper.createArrayNode();
+        root.set(key, result);
+        return result;
+    }
+
+    private ObjectNode json(Device device) {
+        return mapper.createObjectNode()
+                .put("id", device.id().toString())
+                .put("type", device.type().toString());
+    }
+
+    private ObjectNode json(Host host) {
+        return mapper.createObjectNode()
+                .put("id", host.id().toString())
+                .put("location", host.location().toString());
+    }
+
+    private ObjectNode json(Link link) {
+        return mapper.createObjectNode()
+                .put("canon", canonicalRep(link))
+                .put("src", link.src().toString())
+                .put("dst", link.dst().toString());
+    }
+
+}
diff --git a/apps/cord-support/src/main/java/org/onosproject/cordsupport/package-info.java b/apps/cord-support/src/main/java/org/onosproject/cordsupport/package-info.java
new file mode 100644
index 0000000..de85265
--- /dev/null
+++ b/apps/cord-support/src/main/java/org/onosproject/cordsupport/package-info.java
@@ -0,0 +1,21 @@
+/*
+ * Copyright 2017-present Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * CORD support application. Provides topology information about the
+ * underlying ONOS instances and managed network in a CORD deployment.
+ */
+package org.onosproject.cordsupport;
diff --git a/apps/cord-support/src/main/webapp/WEB-INF/web.xml b/apps/cord-support/src/main/webapp/WEB-INF/web.xml
new file mode 100644
index 0000000..9e0b4a4
--- /dev/null
+++ b/apps/cord-support/src/main/webapp/WEB-INF/web.xml
@@ -0,0 +1,58 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ~ Copyright 2017-present Open Networking Laboratory
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~     http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+
+<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee"
+         xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
+         xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
+         id="ONOS" version="2.5">
+    <display-name>CORD Support REST API</display-name>
+
+    <security-constraint>
+        <web-resource-collection>
+            <web-resource-name>Secured</web-resource-name>
+            <url-pattern>/*</url-pattern>
+        </web-resource-collection>
+        <auth-constraint>
+            <role-name>admin</role-name>
+        </auth-constraint>
+    </security-constraint>
+
+    <security-role>
+        <role-name>admin</role-name>
+    </security-role>
+
+    <login-config>
+        <auth-method>BASIC</auth-method>
+        <realm-name>karaf</realm-name>
+    </login-config>
+
+    <servlet>
+        <servlet-name>JAX-RS Service</servlet-name>
+        <servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class>
+        <init-param>
+            <param-name>javax.ws.rs.Application</param-name>
+            <param-value>org.onosproject.cordsupport.CordSupportWebApplication</param-value>
+        </init-param>
+        <load-on-startup>1</load-on-startup>
+    </servlet>
+
+    <servlet-mapping>
+        <servlet-name>JAX-RS Service</servlet-name>
+        <url-pattern>/*</url-pattern>
+    </servlet-mapping>
+
+</web-app>
diff --git a/modules.defs b/modules.defs
index f4d7ad1..5e4a315 100644
--- a/modules.defs
+++ b/modules.defs
@@ -190,6 +190,7 @@
     '//apps/flowspec-api:onos-apps-flowspec-api-oar',
     '//apps/yang:onos-apps-yang-oar',
     '//apps/yang-gui:onos-apps-yang-gui-oar',
+    '//apps/cord-support:onos-apps-cord-support-oar'
 ]
 
 APP_JARS = [
diff --git a/tools/test/cells/simon-single b/tools/test/cells/simon-single
index f28c714..1011419 100644
--- a/tools/test/cells/simon-single
+++ b/tools/test/cells/simon-single
@@ -4,4 +4,4 @@
 export OC1="192.168.56.1"
 export OCN="192.168.56.99"
 
-export ONOS_APPS="drivers,openflow,fwd,null"
+export ONOS_APPS="drivers,openflow,fwd,null,cord-support"