CORD Subscriber GUI -- First shot at modeling bundles from functions.

Change-Id: I7ce653058d2e669b9252efbd50fe2314950e5a9a
diff --git a/apps/demo/cord-gui/pom.xml b/apps/demo/cord-gui/pom.xml
index fffb6d5..ff31ea8 100644
--- a/apps/demo/cord-gui/pom.xml
+++ b/apps/demo/cord-gui/pom.xml
@@ -54,6 +54,21 @@
             <artifactId>commons-io</artifactId>
             <version>2.4</version>
         </dependency>
+        <dependency>
+            <groupId>com.fasterxml.jackson.core</groupId>
+            <artifactId>jackson-core</artifactId>
+            <version>2.4.4</version>
+        </dependency>
+        <dependency>
+            <groupId>com.fasterxml.jackson.core</groupId>
+            <artifactId>jackson-databind</artifactId>
+            <version>2.4.4</version>
+        </dependency>
+        <dependency>
+            <groupId>com.google.guava</groupId>
+            <artifactId>guava</artifactId>
+            <version>18.0</version>
+        </dependency>
     </dependencies>
 
 </project>
diff --git a/apps/demo/cord-gui/src/main/java/org/onosproject/cord/gui/model/BundleDescriptor.java b/apps/demo/cord-gui/src/main/java/org/onosproject/cord/gui/model/BundleDescriptor.java
new file mode 100644
index 0000000..8ba5aef
--- /dev/null
+++ b/apps/demo/cord-gui/src/main/java/org/onosproject/cord/gui/model/BundleDescriptor.java
@@ -0,0 +1,47 @@
+/*
+ * Copyright 2015 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.cord.gui.model;
+
+import java.util.Set;
+
+/**
+ * Defines a bundle of {@link XosFunctionDescriptor XOS functions}.
+ */
+public interface BundleDescriptor {
+
+    /**
+     * Bundle internal identifier.
+     *
+     * @return bundle identifier
+     */
+    String id();
+
+    /**
+     * Bundle display name.
+     *
+     * @return display name
+     */
+    String displayName();
+
+    /**
+     * The set of functions in this bundle instance.
+     *
+     * @return the functions
+     */
+    Set<XosFunctionDescriptor> functions();
+}
diff --git a/apps/demo/cord-gui/src/main/java/org/onosproject/cord/gui/model/BundleFactory.java b/apps/demo/cord-gui/src/main/java/org/onosproject/cord/gui/model/BundleFactory.java
new file mode 100644
index 0000000..a42e0ea
--- /dev/null
+++ b/apps/demo/cord-gui/src/main/java/org/onosproject/cord/gui/model/BundleFactory.java
@@ -0,0 +1,57 @@
+/*
+ * Copyright 2015 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.cord.gui.model;
+
+import com.google.common.collect.ImmutableList;
+
+import java.util.List;
+
+/**
+ * Utility factory for creating bundles and functions etc.
+ */
+public class BundleFactory {
+
+    private static final String BASIC_ID = "basic";
+    private static final String BASIC_DISPLAY_NAME = "Basic Bundle";
+
+    private static final String FAMILY_ID = "family";
+    private static final String FAMILY_DISPLAY_NAME = "Family Bundle";
+
+    // no instantiation
+    private BundleFactory() {}
+
+    private static final BundleDescriptor BASIC =
+            new DefaultBundleDescriptor(BASIC_ID, BASIC_DISPLAY_NAME,
+                                        XosFunctionDescriptor.INTERNET,
+                                        XosFunctionDescriptor.FIREWALL);
+
+    private static final BundleDescriptor FAMILY =
+            new DefaultBundleDescriptor(FAMILY_ID, FAMILY_DISPLAY_NAME,
+                                        XosFunctionDescriptor.INTERNET,
+                                        XosFunctionDescriptor.FIREWALL,
+                                        XosFunctionDescriptor.URL_FILTERING);
+
+    /**
+     * Returns the list of available bundles.
+     *
+     * @return available bundles
+     */
+    public static List<BundleDescriptor> availableBundles() {
+        return ImmutableList.of(BASIC, FAMILY);
+    }
+}
diff --git a/apps/demo/cord-gui/src/main/java/org/onosproject/cord/gui/model/DefaultBundleDescriptor.java b/apps/demo/cord-gui/src/main/java/org/onosproject/cord/gui/model/DefaultBundleDescriptor.java
new file mode 100644
index 0000000..45a2bda
--- /dev/null
+++ b/apps/demo/cord-gui/src/main/java/org/onosproject/cord/gui/model/DefaultBundleDescriptor.java
@@ -0,0 +1,60 @@
+/*
+ * Copyright 2015 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.cord.gui.model;
+
+import com.google.common.collect.ImmutableSet;
+
+import java.util.Set;
+
+
+/**
+ * Base implementation of BundleDescriptor.
+ */
+public class DefaultBundleDescriptor implements BundleDescriptor {
+
+    private final String id;
+    private final String displayName;
+    private final Set<XosFunctionDescriptor> functions;
+
+    /**
+     * Constructs a bundle descriptor.
+     *
+     * @param id bundle identifier
+     * @param displayName bundle display name
+     * @param functions functions that make up this bundle
+     */
+    DefaultBundleDescriptor(String id, String displayName,
+                            XosFunctionDescriptor... functions) {
+        this.id = id;
+        this.displayName = displayName;
+        this.functions = ImmutableSet.copyOf(functions);
+    }
+
+
+    public String id() {
+        return id;
+    }
+
+    public String displayName() {
+        return displayName;
+    }
+
+    public Set<XosFunctionDescriptor> functions() {
+        return functions;
+    }
+}
diff --git a/apps/demo/cord-gui/src/main/java/org/onosproject/cord/gui/model/DefaultXosFunction.java b/apps/demo/cord-gui/src/main/java/org/onosproject/cord/gui/model/DefaultXosFunction.java
new file mode 100644
index 0000000..6bdee4f
--- /dev/null
+++ b/apps/demo/cord-gui/src/main/java/org/onosproject/cord/gui/model/DefaultXosFunction.java
@@ -0,0 +1,52 @@
+/*
+ * Copyright 2015 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.cord.gui.model;
+
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.node.ObjectNode;
+
+/**
+ * Default implementation of an XOS function.
+ */
+public class DefaultXosFunction implements XosFunction {
+
+    private static final ObjectMapper MAPPER = new ObjectMapper();
+
+    private final XosFunctionDescriptor descriptor;
+
+    public DefaultXosFunction(XosFunctionDescriptor xfd) {
+        descriptor = xfd;
+    }
+
+    public XosFunctionDescriptor descriptor() {
+        return descriptor;
+    }
+
+    public ObjectNode params() {
+        return MAPPER.createObjectNode();
+    }
+
+    public String toJson() {
+        return null;
+    }
+
+    public JsonNode toJsonNode() {
+        return null;
+    }
+}
diff --git a/apps/demo/cord-gui/src/main/java/org/onosproject/cord/gui/model/JsonBlob.java b/apps/demo/cord-gui/src/main/java/org/onosproject/cord/gui/model/JsonBlob.java
new file mode 100644
index 0000000..5c20b62
--- /dev/null
+++ b/apps/demo/cord-gui/src/main/java/org/onosproject/cord/gui/model/JsonBlob.java
@@ -0,0 +1,40 @@
+/*
+ * Copyright 2015 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.cord.gui.model;
+
+import com.fasterxml.jackson.databind.JsonNode;
+
+/**
+ * An object that can be serialized to JSON.
+ */
+public interface JsonBlob {
+
+    /**
+     * Returns an Object Node representation of this object.
+     *
+     * @return object node hierarchy
+     */
+    JsonNode toJsonNode();
+
+    /**
+     * Returns a JSON string representation of this object.
+     *
+     * @return JSON serialization
+     */
+    String toJson();
+}
diff --git a/apps/demo/cord-gui/src/main/java/org/onosproject/cord/gui/model/XosFunction.java b/apps/demo/cord-gui/src/main/java/org/onosproject/cord/gui/model/XosFunction.java
new file mode 100644
index 0000000..c580149
--- /dev/null
+++ b/apps/demo/cord-gui/src/main/java/org/onosproject/cord/gui/model/XosFunction.java
@@ -0,0 +1,43 @@
+/*
+ * Copyright 2015 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.cord.gui.model;
+
+
+import com.fasterxml.jackson.databind.node.ObjectNode;
+
+/**
+ * Designates a specific instance of an XOS function.
+ */
+public interface XosFunction extends JsonBlob {
+
+    /**
+     * Returns the descriptor for this function.
+     *
+     * @return function identifier
+     */
+    XosFunctionDescriptor descriptor();
+
+    /**
+     * Returns the current state of this function, encapsulated
+     * as a JSON node.
+     *
+     * @return parameters for the function
+     */
+    ObjectNode params();
+}
+
diff --git a/apps/demo/cord-gui/src/main/java/org/onosproject/cord/gui/model/XosFunctionDescriptor.java b/apps/demo/cord-gui/src/main/java/org/onosproject/cord/gui/model/XosFunctionDescriptor.java
new file mode 100644
index 0000000..a61322b
--- /dev/null
+++ b/apps/demo/cord-gui/src/main/java/org/onosproject/cord/gui/model/XosFunctionDescriptor.java
@@ -0,0 +1,82 @@
+/*
+ * Copyright 2015 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.cord.gui.model;
+
+/**
+ * Designates XOS Functions.
+ */
+public enum XosFunctionDescriptor {
+    /**
+     * Internet function.
+     */
+    INTERNET("internet",
+             "Internet",
+             "Basic internet connectivity."),
+
+    /**
+     * Firewall function.
+     */
+    FIREWALL("firewall",
+             "Firewall",
+             "Normal firewall protection."),
+
+    /**
+     * URL Filtering function (parental controls).
+     */
+    URL_FILTERING("url_filtering",
+                  "Parental Control",
+                  "Variable levels of URL filtering.");
+
+    private final String id;
+    private final String displayName;
+    private final String description;
+
+    XosFunctionDescriptor(String id, String displayName, String description) {
+        this.id = id;
+        this.displayName = displayName;
+        this.description = description;
+    }
+
+    /**
+     * Returns this function's internal identifier.
+     *
+     * @return the identifier
+     */
+    public String id() {
+        return id;
+    }
+
+    /**
+     * Returns this function's display name.
+     *
+     * @return display name
+     */
+    public String displayName() {
+        return displayName;
+    }
+
+    /**
+     * Returns a short, textual description of the function.
+     *
+     * @return textual description
+     */
+    public String description() {
+        return description;
+    }
+
+}
diff --git a/apps/demo/cord-gui/src/main/resources/org/onosproject/cord/gui/local/bundle-0.json b/apps/demo/cord-gui/src/main/resources/org/onosproject/cord/gui/local/bundle-0.json
index b7df611..833db37 100644
--- a/apps/demo/cord-gui/src/main/resources/org/onosproject/cord/gui/local/bundle-0.json
+++ b/apps/demo/cord-gui/src/main/resources/org/onosproject/cord/gui/local/bundle-0.json
@@ -1,5 +1,6 @@
 {
   "bundle": {
+    "id": "basic",
     "name": "Basic Bundle",
     "functions": [
       {
diff --git a/apps/demo/cord-gui/src/main/resources/org/onosproject/cord/gui/local/bundle-1.json b/apps/demo/cord-gui/src/main/resources/org/onosproject/cord/gui/local/bundle-1.json
index 169d269..ba19716 100644
--- a/apps/demo/cord-gui/src/main/resources/org/onosproject/cord/gui/local/bundle-1.json
+++ b/apps/demo/cord-gui/src/main/resources/org/onosproject/cord/gui/local/bundle-1.json
@@ -1,5 +1,6 @@
 {
   "bundle": {
+    "id": "family",
     "name": "Family Bundle",
     "functions": [
       {
diff --git a/apps/demo/cord-gui/src/test/org/onosproject/cord/gui/model/BundleFactoryTest.java b/apps/demo/cord-gui/src/test/org/onosproject/cord/gui/model/BundleFactoryTest.java
new file mode 100644
index 0000000..f2b94b6
--- /dev/null
+++ b/apps/demo/cord-gui/src/test/org/onosproject/cord/gui/model/BundleFactoryTest.java
@@ -0,0 +1,61 @@
+/*
+ * Copyright 2015 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.cord.gui.model;
+
+import org.junit.Test;
+
+import java.util.Set;
+
+import static org.junit.Assert.*;
+import static org.onosproject.cord.gui.model.BundleFactory.availableBundles;
+import static org.onosproject.cord.gui.model.XosFunctionDescriptor.*;
+
+/**
+ * Unit tests for {@link BundleFactory}.
+ */
+public class BundleFactoryTest {
+
+    @Test
+    public void bundleCount() {
+        assertEquals("wrong count", 2, availableBundles().size());
+    }
+
+    @Test
+    public void basicBundle() {
+        BundleDescriptor bundle = availableBundles().get(0);
+        assertEquals("wrong id", "basic", bundle.id());
+        assertEquals("wrong id", "Basic Bundle", bundle.displayName());
+        Set<XosFunctionDescriptor> funcs = bundle.functions();
+        assertTrue("missing internet", funcs.contains(INTERNET));
+        assertTrue("missing firewall", funcs.contains(FIREWALL));
+        assertFalse("unexpected url-f", funcs.contains(URL_FILTERING));
+    }
+
+    @Test
+    public void familyBundle() {
+        BundleDescriptor bundle = availableBundles().get(1);
+        assertEquals("wrong id", "family", bundle.id());
+        assertEquals("wrong id", "Family Bundle", bundle.displayName());
+        Set<XosFunctionDescriptor> funcs = bundle.functions();
+        assertTrue("missing internet", funcs.contains(INTERNET));
+        assertTrue("missing firewall", funcs.contains(FIREWALL));
+        assertTrue("missing url-f", funcs.contains(URL_FILTERING));
+    }
+
+}
+
diff --git a/apps/demo/cord-gui/src/test/org/onosproject/cord/gui/model/XosFunctionDescriptorTest.java b/apps/demo/cord-gui/src/test/org/onosproject/cord/gui/model/XosFunctionDescriptorTest.java
new file mode 100644
index 0000000..7068c16
--- /dev/null
+++ b/apps/demo/cord-gui/src/test/org/onosproject/cord/gui/model/XosFunctionDescriptorTest.java
@@ -0,0 +1,56 @@
+/*
+ * Copyright 2015 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.cord.gui.model;
+
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+import static org.onosproject.cord.gui.model.XosFunctionDescriptor.*;
+
+/**
+ * Sanity unit tests for {@link XosFunctionDescriptor}.
+ */
+public class XosFunctionDescriptorTest {
+
+    @Test
+    public void numberOfFunctions() {
+        assertEquals("unexpected constant count", 3, values().length);
+    }
+
+    @Test
+    public void internet() {
+        assertEquals("wrong id", "internet", INTERNET.id());
+        assertEquals("wrong display", "Internet", INTERNET.displayName());
+        assertTrue("wrong desc", INTERNET.description().startsWith("Basic"));
+    }
+
+    @Test
+    public void firewall() {
+        assertEquals("wrong id", "firewall", FIREWALL.id());
+        assertEquals("wrong display", "Firewall", FIREWALL.displayName());
+        assertTrue("wrong desc", FIREWALL.description().startsWith("Normal"));
+    }
+
+    @Test
+    public void urlFiltering() {
+        assertEquals("wrong id", "url_filtering", URL_FILTERING.id());
+        assertEquals("wrong display", "Parental Control", URL_FILTERING.displayName());
+        assertTrue("wrong desc", URL_FILTERING.description().startsWith("Variable"));
+    }
+}