Expose String Attributes to JSON

Change-Id: Ibc6de214cb8cedb7c262336adcfb283637fe9dc5
diff --git a/src/main/java/net/onrc/onos/core/topology/web/serializers/LinkSerializer.java b/src/main/java/net/onrc/onos/core/topology/web/serializers/LinkSerializer.java
index bec4760..44f5cc3 100644
--- a/src/main/java/net/onrc/onos/core/topology/web/serializers/LinkSerializer.java
+++ b/src/main/java/net/onrc/onos/core/topology/web/serializers/LinkSerializer.java
@@ -1,6 +1,7 @@
 package net.onrc.onos.core.topology.web.serializers;
 
 import java.io.IOException;
+import java.util.Map.Entry;
 
 import net.onrc.onos.core.topology.Link;
 
@@ -27,6 +28,11 @@
         jsonGenerator.writeStartObject();
         jsonGenerator.writeObjectField("src", link.getSrcPort().asSwitchPort());
         jsonGenerator.writeObjectField("dst", link.getDstPort().asSwitchPort());
+        jsonGenerator.writeObjectFieldStart("stringAttributes");
+        for (Entry<String, String> entry : link.getAllStringAttributes().entrySet()) {
+            jsonGenerator.writeStringField(entry.getKey(), entry.getValue());
+        }
+        jsonGenerator.writeEndObject(); // stringAttributes
         jsonGenerator.writeEndObject();
     }
 }
diff --git a/src/main/java/net/onrc/onos/core/topology/web/serializers/PortSerializer.java b/src/main/java/net/onrc/onos/core/topology/web/serializers/PortSerializer.java
index a0d7385..69d710e 100644
--- a/src/main/java/net/onrc/onos/core/topology/web/serializers/PortSerializer.java
+++ b/src/main/java/net/onrc/onos/core/topology/web/serializers/PortSerializer.java
@@ -1,6 +1,7 @@
 package net.onrc.onos.core.topology.web.serializers;
 
 import java.io.IOException;
+import java.util.Map.Entry;
 
 import net.onrc.onos.core.topology.Port;
 
@@ -35,6 +36,11 @@
         jsonGenerator.writeNumberField("portNumber",
                                        (0xffff & port.getNumber().value()));
         jsonGenerator.writeStringField("desc", port.getDescription());
+        jsonGenerator.writeObjectFieldStart("stringAttributes");
+        for (Entry<String, String> entry : port.getAllStringAttributes().entrySet()) {
+            jsonGenerator.writeStringField(entry.getKey(), entry.getValue());
+        }
+        jsonGenerator.writeEndObject(); // stringAttributes
         jsonGenerator.writeEndObject();
     }
 }
diff --git a/src/main/java/net/onrc/onos/core/topology/web/serializers/SwitchSerializer.java b/src/main/java/net/onrc/onos/core/topology/web/serializers/SwitchSerializer.java
index 3b74c53..79516b4 100644
--- a/src/main/java/net/onrc/onos/core/topology/web/serializers/SwitchSerializer.java
+++ b/src/main/java/net/onrc/onos/core/topology/web/serializers/SwitchSerializer.java
@@ -1,6 +1,7 @@
 package net.onrc.onos.core.topology.web.serializers;
 
 import java.io.IOException;
+import java.util.Map.Entry;
 
 import net.onrc.onos.core.topology.Port;
 import net.onrc.onos.core.topology.Switch;
@@ -32,6 +33,11 @@
             jsonGenerator.writeObject(port);
         }
         jsonGenerator.writeEndArray();
+        jsonGenerator.writeObjectFieldStart("stringAttributes");
+        for (Entry<String, String> entry : sw.getAllStringAttributes().entrySet()) {
+            jsonGenerator.writeStringField(entry.getKey(), entry.getValue());
+        }
+        jsonGenerator.writeEndObject(); // stringAttributes
         jsonGenerator.writeEndObject();
     }
 }
diff --git a/src/test/java/net/onrc/onos/api/rest/TestRestTopologyGet.java b/src/test/java/net/onrc/onos/api/rest/TestRestTopologyGet.java
index edad41d..bf8d831 100644
--- a/src/test/java/net/onrc/onos/api/rest/TestRestTopologyGet.java
+++ b/src/test/java/net/onrc/onos/api/rest/TestRestTopologyGet.java
@@ -1,6 +1,7 @@
 package net.onrc.onos.api.rest;
 
 import net.onrc.onos.core.intent.runtime.PathCalcRuntimeModule;
+
 import org.json.JSONArray;
 import org.json.JSONException;
 import org.json.JSONObject;
@@ -13,15 +14,14 @@
 import org.restlet.data.Status;
 import org.restlet.resource.ClientResource;
 
+import com.google.common.collect.ImmutableList;
 import java.util.HashSet;
+import java.util.List;
 import java.util.Set;
 
 import static net.onrc.onos.api.rest.ClientResourceStatusMatcher.hasStatusOf;
 import static org.hamcrest.MatcherAssert.assertThat;
-import static org.hamcrest.Matchers.equalTo;
-import static org.hamcrest.Matchers.hasItems;
-import static org.hamcrest.Matchers.is;
-import static org.hamcrest.Matchers.notNullValue;
+import static org.hamcrest.Matchers.*;
 
 /**
  * Tests for topology REST get operations.
@@ -59,12 +59,15 @@
      * @param switches JSON array of switches
      * @throws JSONException if the JSON is not properly specified
      */
+    @SuppressWarnings("unchecked")
     private void checkSwitches(final JSONArray switches) throws JSONException {
         assertThat(switches.length(), is(equalTo(4)));
 
         // Check that the first switch has the proper data
         final JSONObject switch0 = switches.getJSONObject(0);
-        assertThat(switch0.length(), is(equalTo(3)));
+        final List<String> keys = ImmutableList.<String>copyOf(switch0.keys());
+        assertThat(keys,
+                hasItems("dpid", "state", "ports"));
         assertThat(switch0.getString("dpid"), is(equalTo("00:00:00:00:00:00:00:02")));
         assertThat(switch0.getString("state"), is(equalTo("ACTIVE")));