Bug #60 : JSON list responses from the NB-APIs returns native object (instead of... 31/1131/3
authorMadhu Venugopal <vmadhu@cisco.com>
Mon, 9 Sep 2013 12:00:39 +0000 (05:00 -0700)
committerGiovanni Meo <gmeo@cisco.com>
Tue, 10 Sep 2013 09:55:38 +0000 (11:55 +0200)
We use Jersey and JAXB frameworks for the NB-API implementation.
Jersey by default uses Jettison for the JSON marshalling/demarshalling. It seems like there is a bug in Jettison for this case.
And the recommended approach is to use Jackson instead.
Among various approaches to replace Jettison with Jackson (including package scanning, etc..), the only easy approach in an
OSGi environment is to directly refer to the JerseyJaxbJsonProvider class from the Northbound application.
JerseyJaxbJsonProvider has dependancies on jersey-xc which is also pulled in.

The Northbound Integration Test has inbuilt assumption that the NB-APIs use Jettison & hence a whole bunch of such bugs were
hidden and not visible to the tests as well. The correct approach is to use JAXB bindings in the IT so that immaterial of
Jettison or Jackson as the NB Marshalling infra, the IT need not change.
But, that is a bigger change and hence to restrict to the changes being addressed, this changeset just fixed these incorrect
assumptions and continued to use the Jettison library for demarshalling (while the actual Northbound API uses Jackson).

Also note that, such infra changes call for bumping both the NB-API version and the bundle version.
But, given the fact that the API freeze is scheduled later in October and more NB related changes are coming, the version bump
process can be scheduled later to ease the development work.

Change-Id: I47d8309dfbe11c251a30316bca37c7823cb0325a
Signed-off-by: Madhu Venugopal <vmadhu@cisco.com>
31 files changed:
opendaylight/commons/opendaylight/pom.xml
opendaylight/northbound/flowprogrammer/pom.xml
opendaylight/northbound/flowprogrammer/src/main/java/org/opendaylight/controller/flowprogrammer/northbound/FlowProgrammerNorthbound.java
opendaylight/northbound/flowprogrammer/src/main/java/org/opendaylight/controller/flowprogrammer/northbound/FlowProgrammerNorthboundRSApplication.java
opendaylight/northbound/hosttracker/pom.xml
opendaylight/northbound/hosttracker/src/main/java/org/opendaylight/controller/hosttracker/northbound/HostTrackerNorthbound.java
opendaylight/northbound/hosttracker/src/main/java/org/opendaylight/controller/hosttracker/northbound/HostTrackerNorthboundRSApplication.java
opendaylight/northbound/integrationtest/pom.xml
opendaylight/northbound/integrationtest/src/test/java/org/opendaylight/controller/northbound/integrationtest/NorthboundIT.java
opendaylight/northbound/networkconfiguration/bridgedomain/pom.xml
opendaylight/northbound/networkconfiguration/bridgedomain/src/main/java/org/opendaylight/controller/networkconfig/bridgedomain/northbound/BridgeDomainNorthboundApplication.java
opendaylight/northbound/staticrouting/pom.xml
opendaylight/northbound/staticrouting/src/main/java/org/opendaylight/controller/forwarding/staticrouting/northbound/StaticRoutingNorthbound.java
opendaylight/northbound/staticrouting/src/main/java/org/opendaylight/controller/forwarding/staticrouting/northbound/StaticRoutingNorthboundRSApplication.java
opendaylight/northbound/statistics/pom.xml
opendaylight/northbound/statistics/src/main/java/org/opendaylight/controller/statistics/northbound/StatisticsNorthboundRSApplication.java
opendaylight/northbound/subnets/pom.xml
opendaylight/northbound/subnets/src/main/java/org/opendaylight/controller/subnets/northbound/SubnetConfigs.java
opendaylight/northbound/subnets/src/main/java/org/opendaylight/controller/subnets/northbound/SubnetsNorthbound.java
opendaylight/northbound/subnets/src/main/java/org/opendaylight/controller/subnets/northbound/SubnetsNorthboundRSApplication.java
opendaylight/northbound/switchmanager/pom.xml
opendaylight/northbound/switchmanager/src/main/java/org/opendaylight/controller/switchmanager/northbound/SwitchNorthboundRSApplication.java
opendaylight/northbound/topology/pom.xml
opendaylight/northbound/topology/src/main/java/org/opendaylight/controller/topology/northbound/TopologyNorthboundJAXRS.java
opendaylight/northbound/topology/src/main/java/org/opendaylight/controller/topology/northbound/TopologyNorthboundRSApplication.java
opendaylight/northbound/topology/src/main/java/org/opendaylight/controller/topology/northbound/TopologyUserLinks.java
opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/action/Action.java
opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/core/TimeStamp.java
opendaylight/samples/northbound/loadbalancer/pom.xml
opendaylight/samples/northbound/loadbalancer/src/main/java/org/opendaylight/controller/samples/loadbalancer/northbound/LoadBalancerNorthbound.java
opendaylight/samples/northbound/loadbalancer/src/main/java/org/opendaylight/controller/samples/loadbalancer/northbound/LoadBalancerNorthboundRSApplication.java

index f6282d8..aecb269 100644 (file)
       <artifactId>jackson-jaxrs</artifactId>
       <version>${jackson.version}</version>
     </dependency>
+    <dependency>
+      <groupId>org.codehaus.jackson</groupId>
+      <artifactId>jackson-xc</artifactId>
+      <version>${jackson.version}</version>
+    </dependency>
     <dependency>
       <groupId>org.codehaus.jettison</groupId>
       <artifactId>jettison</artifactId>
index 6319c7c..7aef065 100644 (file)
@@ -55,6 +55,7 @@
               javax.xml.bind.annotation,
               javax.xml.bind,
               org.slf4j,
+              org.codehaus.jackson.jaxrs,
               !org.codehaus.enunciate.jaxrs
             </Import-Package>
             <Export-Package>
index 7bd36a3..257fbbd 100644 (file)
@@ -417,7 +417,7 @@ public class FlowProgrammerNorthbound {
             @PathParam(value = "name") String name,
             @PathParam("nodeType") String nodeType,
             @PathParam(value = "nodeId") String nodeId,
-            @TypeHint(FlowConfig.class) JAXBElement<FlowConfig> flowConfig) {
+            @TypeHint(FlowConfig.class) FlowConfig flowConfig) {
 
         if (!NorthboundUtils.isAuthorized(
                 getUserName(), containerName, Privilege.WRITE, this)) {
@@ -425,12 +425,13 @@ public class FlowProgrammerNorthbound {
                     "User is not authorized to perform this operation on container "
                             + containerName);
         }
-        if (flowConfig.getValue().getNode() == null) {
+
+        if (flowConfig.getNode() == null) {
             return Response.status(Response.Status.BAD_REQUEST).entity("Invalid Configuration. Node is null or empty")
                     .build();
         }
-        handleResourceCongruence(name, flowConfig.getValue().getName());
-        handleResourceCongruence(nodeId, flowConfig.getValue().getNode().getNodeIDString());
+        handleResourceCongruence(name, flowConfig.getName());
+        handleResourceCongruence(nodeId, flowConfig.getNode().getNodeIDString());
         handleDefaultDisabled(containerName);
 
         IForwardingRulesManager frm = getForwardingRulesManagerService(containerName);
@@ -448,7 +449,7 @@ public class FlowProgrammerNorthbound {
                     + RestMessages.RESOURCECONFLICT.toString());
         }
 
-        Status status = frm.addStaticFlow(flowConfig.getValue());
+        Status status = frm.addStaticFlow(flowConfig);
 
         if (status.isSuccess()) {
             NorthboundUtils.auditlog("Flow", username, "added", name, containerName);
index 3c6a5f8..68c0ec1 100644 (file)
@@ -13,6 +13,8 @@ import java.util.HashSet;
 import java.util.Set;
 import javax.ws.rs.core.Application;
 
+import org.codehaus.jackson.jaxrs.JacksonJaxbJsonProvider;
+
 /**
  * Instance of javax.ws.rs.core.Application used to return the classes
  * that will be instantiated for JAXRS processing, this is necessary
@@ -25,6 +27,7 @@ public class FlowProgrammerNorthboundRSApplication extends Application {
     public Set<Class<?>> getClasses() {
         Set<Class<?>> classes = new HashSet<Class<?>>();
         classes.add(FlowProgrammerNorthbound.class);
+        classes.add(JacksonJaxbJsonProvider.class);
         return classes;
     }
 }
index 74e3386..3757ea1 100644 (file)
@@ -58,6 +58,7 @@
               javax.xml.bind,
               org.slf4j,
               org.apache.catalina.filters,
+              org.codehaus.jackson.jaxrs,
               !org.codehaus.enunciate.jaxrs
             </Import-Package>
             <Web-ContextPath>/controller/nb/v2/host</Web-ContextPath>
index 91185bb..f0bdf5d 100644 (file)
@@ -432,7 +432,7 @@ public class HostTrackerNorthbound {
             @ResponseCode(code = 503, condition = "One or more of Controller services are unavailable") })
     public Response addHost(@Context UriInfo uriInfo, @PathParam("containerName") String containerName,
             @PathParam("networkAddress") String networkAddress,
-            @TypeHint(HostConfig.class) JAXBElement<HostConfig> hostConfig) {
+            @TypeHint(HostConfig.class) HostConfig hostConfig) {
 
         if (!NorthboundUtils.isAuthorized(getUserName(), containerName, Privilege.WRITE, this)) {
             return Response.status(Response.Status.UNAUTHORIZED)
@@ -443,7 +443,7 @@ public class HostTrackerNorthbound {
 
         IfIptoHost hostTracker = getIfIpToHostService(containerName);
 
-        HostConfig hc = hostConfig.getValue();
+        HostConfig hc = hostConfig;
         if (!networkAddress.equals(hc.getNetworkAddress())) {
             return Response.status(Response.Status.CONFLICT)
                     .entity("Resource name in config object doesn't match URI")
index 89bee5b..5d50dbf 100644 (file)
@@ -13,6 +13,8 @@ import java.util.HashSet;
 import java.util.Set;
 import javax.ws.rs.core.Application;
 
+import org.codehaus.jackson.jaxrs.JacksonJaxbJsonProvider;
+
 /**
  * This class is an instance of javax.ws.rs.core.Application used to return the classes
  * that will be instantiated for JAXRS processing, this is necessary
@@ -25,6 +27,7 @@ public class HostTrackerNorthboundRSApplication extends Application {
     public Set<Class<?>> getClasses() {
         Set<Class<?>> classes = new HashSet<Class<?>>();
         classes.add(HostTrackerNorthbound.class);
+        classes.add(JacksonJaxbJsonProvider.class);
         return classes;
     }
 }
index 88cff5e..90b36de 100644 (file)
       <artifactId>jackson-jaxrs</artifactId>
       <version>${jackson.version}</version>
     </dependency>
+    <dependency>
+      <groupId>org.codehaus.jackson</groupId>
+      <artifactId>jackson-xc</artifactId>
+      <version>${jackson.version}</version>
+    </dependency>
     <dependency>
       <groupId>org.codehaus.jettison</groupId>
       <artifactId>jettison</artifactId>
index f7ebfe4..27a50c0 100644 (file)
@@ -189,6 +189,9 @@ public class NorthboundIT {
             }
             is.close();
             connection.disconnect();
+            if (debugMsg) {
+                System.out.println("Response : "+sb.toString());
+            }
             return sb.toString();
         } catch (Exception e) {
             return null;
@@ -203,34 +206,47 @@ public class NorthboundIT {
         Assert.assertEquals(nodeId, (Integer) nodeInfo.getInt("id"));
         Assert.assertEquals(nodeType, nodeInfo.getString("type"));
 
-        JSONObject properties = node.getJSONObject("properties");
-
-        if (timestamp == null || timestampName == null) {
-            Assert.assertFalse(properties.has("timeStamp"));
-        } else {
-            Assert.assertEquals(timestamp, (Integer) properties.getJSONObject("timeStamp").getInt("value"));
-            Assert.assertEquals(timestampName, properties.getJSONObject("timeStamp").getString("name"));
-        }
-        if (actionsValue == null) {
-            Assert.assertFalse(properties.has("actions"));
-        } else {
-            Assert.assertEquals(actionsValue, (Integer) properties.getJSONObject("actions").getInt("value"));
-        }
-        if (capabilitiesValue == null) {
-            Assert.assertFalse(properties.has("capabilities"));
-        } else {
-            Assert.assertEquals(capabilitiesValue,
-                    (Integer) properties.getJSONObject("capabilities").getInt("value"));
-        }
-        if (tablesValue == null) {
-            Assert.assertFalse(properties.has("tables"));
-        } else {
-            Assert.assertEquals(tablesValue, (Integer) properties.getJSONObject("tables").getInt("value"));
-        }
-        if (buffersValue == null) {
-            Assert.assertFalse(properties.has("buffers"));
-        } else {
-            Assert.assertEquals(buffersValue, (Integer) properties.getJSONObject("buffers").getInt("value"));
+        JSONArray propsArray = node.getJSONArray("properties");
+
+        for (int j = 0; j < propsArray.length(); j++) {
+            JSONObject properties = propsArray.getJSONObject(j);
+            String propName = properties.getString("name");
+            if (propName.equals("timeStamp")) {
+                if (timestamp == null || timestampName == null) {
+                    Assert.assertFalse("Timestamp exist", true);
+                } else {
+                    Assert.assertEquals(timestamp, (Integer) properties.getInt("value"));
+                    Assert.assertEquals(timestampName, properties.getString("timestampName"));
+                }
+            }
+            if (propName.equals("actions")) {
+                if (actionsValue == null) {
+                    Assert.assertFalse("Actions exist", true);
+                } else {
+                    Assert.assertEquals(actionsValue, (Integer) properties.getInt("value"));
+                }
+            }
+            if (propName.equals("capabilities")) {
+                if (capabilitiesValue == null) {
+                    Assert.assertFalse("Capabilities exist", true);
+                } else {
+                    Assert.assertEquals(capabilitiesValue, (Integer) properties.getInt("value"));
+                }
+            }
+            if (propName.equals("tables")) {
+                if (tablesValue == null) {
+                    Assert.assertFalse("Tables exist", true);
+                } else {
+                    Assert.assertEquals(tablesValue, (Integer) properties.getInt("value"));
+                }
+            }
+            if (propName.equals("buffers")) {
+                if (buffersValue == null) {
+                    Assert.assertFalse("Buffers exist", true);
+                } else {
+                    Assert.assertEquals(buffersValue, (Integer) properties.getInt("value"));
+                }
+            }
         }
     }
 
@@ -240,29 +256,38 @@ public class NorthboundIT {
 
         JSONObject nodeConnector = nodeConnectorProperties.getJSONObject("nodeconnector");
         JSONObject node = nodeConnector.getJSONObject("node");
-        JSONObject properties = nodeConnectorProperties.getJSONObject("properties");
 
         Assert.assertEquals(ncId, (Integer) nodeConnector.getInt("id"));
         Assert.assertEquals(ncType, nodeConnector.getString("type"));
         Assert.assertEquals(nodeId, (Integer) node.getInt("id"));
         Assert.assertEquals(nodeType, node.getString("type"));
-        if (state == null) {
-            Assert.assertFalse(properties.has("state"));
-        } else {
-            Assert.assertEquals(state, (Integer) properties.getJSONObject("state").getInt("value"));
-        }
-        if (capabilities == null) {
-            Assert.assertFalse(properties.has("capabilities"));
-        } else {
-            Assert.assertEquals(capabilities,
-                    (Integer) properties.getJSONObject("capabilities").getInt("value"));
-        }
-        if (bandwidth == null) {
-            Assert.assertFalse(properties.has("bandwidth"));
-        } else {
-            Assert.assertEquals(bandwidth, (Integer) properties.getJSONObject("bandwidth").getInt("value"));
-        }
 
+        JSONArray propsArray = nodeConnectorProperties.getJSONArray("properties");
+        for (int j = 0; j < propsArray.length(); j++) {
+            JSONObject properties = propsArray.getJSONObject(j);
+            String propName = properties.getString("name");
+            if (propName.equals("state")) {
+                if (state == null) {
+                    Assert.assertFalse("State exist", true);
+                } else {
+                    Assert.assertEquals(state, (Integer) properties.getInt("value"));
+                }
+            }
+            if (propName.equals("capabilities")) {
+                if (capabilities == null) {
+                    Assert.assertFalse("Capabilities exist", true);
+                } else {
+                    Assert.assertEquals(capabilities, (Integer) properties.getInt("value"));
+                }
+            }
+            if (propName.equals("bandwidth")) {
+                if (bandwidth == null) {
+                    Assert.assertFalse("bandwidth exist", true);
+                } else {
+                    Assert.assertEquals(bandwidth, (Integer) properties.getInt("value"));
+                }
+            }
+        }
     }
 
     @Test
@@ -291,14 +316,15 @@ public class NorthboundIT {
         String result = getJsonResult(baseURL + "default/subnet/all");
         JSONTokener jt = new JSONTokener(result);
         JSONObject json = new JSONObject(jt);
-        Assert.assertEquals("{}", result);
+        JSONArray subnetConfigs = json.getJSONArray("subnetConfig");
+        Assert.assertEquals(subnetConfigs.length(), 0);
 
         // Test GET subnet1 expecting 404
         result = getJsonResult(baseURL + "default/subnet/" + name1);
         Assert.assertEquals(404, httpResponseCode.intValue());
 
         // Test POST subnet1
-        JSONObject jo = new JSONObject().append("name", name1).append("subnet", subnet1);
+        JSONObject jo = new JSONObject().put("name", name1).put("subnet", subnet1);
         // execute HTTP request and verify response code
         result = getJsonResult(baseURL + "default/subnet/" + name1, "POST", jo.toString());
         Assert.assertTrue(httpResponseCode == 201);
@@ -312,7 +338,7 @@ public class NorthboundIT {
         Assert.assertEquals(subnet1, json.getString("subnet"));
 
         // Test POST subnet2
-        JSONObject jo2 = new JSONObject().append("name", name2).append("subnet", subnet2);
+        JSONObject jo2 = new JSONObject().put("name", name2).put("subnet", subnet2);
         // execute HTTP request and verify response code
         result = getJsonResult(baseURL + "default/subnet/" + name2, "POST", jo2.toString());
         Assert.assertEquals(201, httpResponseCode.intValue());
@@ -322,7 +348,7 @@ public class NorthboundIT {
         result = getJsonResult(baseURL + "default/subnet/" + name2 + "/node-ports", "POST", jo2.toString());
         Assert.assertEquals(200, httpResponseCode.intValue());
         // Test POST subnet3
-        JSONObject jo3 = new JSONObject().append("name", name3).append("subnet", subnet3);
+        JSONObject jo3 = new JSONObject().put("name", name3).put("subnet", subnet3);
         // execute HTTP request and verify response code
         result = getJsonResult(baseURL + "default/subnet/" + name3, "POST", jo3.toString());
         Assert.assertEquals(201, httpResponseCode.intValue());
@@ -350,14 +376,14 @@ public class NorthboundIT {
                 Assert.assertEquals(subnet1, subnetConfig.getString("subnet"));
             } else if (subnetConfig.getString("name").equals(name2)) {
                 Assert.assertEquals(subnet2, subnetConfig.getString("subnet"));
-                String[] nodePortsGet2 = subnetConfig.getString("nodePorts").split(",");
+                String[] nodePortsGet2 = subnetConfig.getJSONArray("nodePorts").getString(0).split(",");
                 Assert.assertEquals(nodePorts2[0], nodePortsGet2[0]);
                 Assert.assertEquals(nodePorts2[1], nodePortsGet2[1]);
                 Assert.assertEquals(nodePorts2[2], nodePortsGet2[2]);
                 Assert.assertEquals(nodePorts2[3], nodePortsGet2[3]);
             } else if (subnetConfig.getString("name").equals(name3)) {
                 Assert.assertEquals(subnet3, subnetConfig.getString("subnet"));
-                String[] nodePortsGet = subnetConfig.getString("nodePorts").split(",");
+                String[] nodePortsGet = subnetConfig.getJSONArray("nodePorts").getString(0).split(",");
                 Assert.assertEquals(nodePorts3[0], nodePortsGet[0]);
                 Assert.assertEquals(nodePorts3[1], nodePortsGet[1]);
                 Assert.assertEquals(nodePorts3[2], nodePortsGet[2]);
@@ -396,7 +422,8 @@ public class NorthboundIT {
         String result = getJsonResult(baseURL + "default");
         JSONTokener jt = new JSONTokener(result);
         JSONObject json = new JSONObject(jt);
-        Assert.assertEquals("{}", result);
+        JSONArray staticRoutes = json.getJSONArray("staticRoute");
+        Assert.assertEquals(staticRoutes.length(), 0);
 
         // Test insert static route
         String requestBody = "{\"name\":\"" + name1 + "\", \"prefix\":\"" + prefix1 + "\", \"nextHop\":\"" + nextHop1
@@ -412,8 +439,8 @@ public class NorthboundIT {
         result = getJsonResult(baseURL + "default");
         jt = new JSONTokener(result);
         json = new JSONObject(jt);
-        JSONArray staticRoutes = json.getJSONArray("staticRoute");
-        Assert.assertEquals(2, staticRoutes.length());
+        JSONArray staticRouteArray = json.getJSONArray("staticRoute");
+        Assert.assertEquals(2, staticRouteArray.length());
         JSONObject route;
         for (int i = 0; i < staticRoutes.length(); i++) {
             route = staticRoutes.getJSONObject(i);
@@ -453,7 +480,9 @@ public class NorthboundIT {
         result = getJsonResult(baseURL + "default");
         jt = new JSONTokener(result);
         json = new JSONObject(jt);
-        JSONObject singleStaticRoute = json.getJSONObject("staticRoute");
+
+        staticRouteArray = json.getJSONArray("staticRoute");
+        JSONObject singleStaticRoute = staticRouteArray.getJSONObject(0);
         Assert.assertEquals(name2, singleStaticRoute.getString("name"));
 
     }
@@ -511,7 +540,8 @@ public class NorthboundIT {
         result = getJsonResult(baseURL + "node/STUB/" + nodeId_1);
         jt = new JSONTokener(result);
         json = new JSONObject(jt);
-        JSONObject nodeConnectorProperties = json.getJSONObject("nodeConnectorProperties");
+        JSONArray nodeConnectorPropertiesArray = json.getJSONArray("nodeConnectorProperties");
+        JSONObject nodeConnectorProperties = nodeConnectorPropertiesArray.getJSONObject(0);
 
         testNodeConnectorProperties(nodeConnectorProperties, nodeConnectorId_1, ncType, nodeId_1, nodeType, ncState,
                 ncCapabilities, ncBandwidth);
@@ -520,7 +550,10 @@ public class NorthboundIT {
         result = getJsonResult(baseURL + "node/STUB/" + nodeId_2);
         jt = new JSONTokener(result);
         json = new JSONObject(jt);
-        nodeConnectorProperties = json.getJSONObject("nodeConnectorProperties");
+
+        nodeConnectorPropertiesArray = json.getJSONArray("nodeConnectorProperties");
+        nodeConnectorProperties = nodeConnectorPropertiesArray.getJSONObject(0);
+
 
         testNodeConnectorProperties(nodeConnectorProperties, nodeConnectorId_2, ncType, nodeId_2, nodeType, ncState,
                 ncCapabilities, ncBandwidth);
@@ -530,7 +563,8 @@ public class NorthboundIT {
         jt = new JSONTokener(result);
         json = new JSONObject(jt);
 
-        nodeConnectorProperties = json.getJSONObject("nodeConnectorProperties");
+        nodeConnectorPropertiesArray = json.getJSONArray("nodeConnectorProperties");
+        nodeConnectorProperties = nodeConnectorPropertiesArray.getJSONObject(0);
         testNodeConnectorProperties(nodeConnectorProperties, nodeConnectorId_3, ncType, nodeId_3, nodeType, ncState,
                 ncCapabilities, ncBandwidth);
 
@@ -547,8 +581,19 @@ public class NorthboundIT {
         json = new JSONObject(jt);
         node = getJsonInstance(json, "nodeProperties", nodeId_1);
         Assert.assertNotNull(node);
-        Assert.assertEquals(1001, node.getJSONObject("properties").getJSONObject("tier").getInt("value"));
-        Assert.assertEquals("node1", node.getJSONObject("properties").getJSONObject("description").getString("value"));
+
+        JSONArray propsArray = node.getJSONArray("properties");
+
+        for (int j = 0; j < propsArray.length(); j++) {
+            JSONObject properties = propsArray.getJSONObject(j);
+            String propName = properties.getString("name");
+            if (propName.equals("tier")) {
+                Assert.assertEquals(1001, properties.getInt("value"));
+            }
+            if (propName.equals("description")) {
+                Assert.assertEquals("node1", properties.getString("value"));
+            }
+        }
 
         // Test delete nodeConnector property
         // Delete state property of nodeconnector1
@@ -559,7 +604,8 @@ public class NorthboundIT {
         result = getJsonResult(baseURL + "node/STUB/" + nodeId_1);
         jt = new JSONTokener(result);
         json = new JSONObject(jt);
-        nodeConnectorProperties = json.getJSONObject("nodeConnectorProperties");
+        nodeConnectorPropertiesArray = json.getJSONArray("nodeConnectorProperties");
+        nodeConnectorProperties = nodeConnectorPropertiesArray.getJSONObject(0);
 
         testNodeConnectorProperties(nodeConnectorProperties, nodeConnectorId_1, ncType, nodeId_1, nodeType, null,
                 ncCapabilities, ncBandwidth);
@@ -572,7 +618,8 @@ public class NorthboundIT {
         result = getJsonResult(baseURL + "node/STUB/" + nodeId_2);
         jt = new JSONTokener(result);
         json = new JSONObject(jt);
-        nodeConnectorProperties = json.getJSONObject("nodeConnectorProperties");
+        nodeConnectorPropertiesArray = json.getJSONArray("nodeConnectorProperties");
+        nodeConnectorProperties = nodeConnectorPropertiesArray.getJSONObject(0);
 
         testNodeConnectorProperties(nodeConnectorProperties, nodeConnectorId_2, ncType, nodeId_2, nodeType, ncState,
                 null, ncBandwidth);
@@ -588,7 +635,8 @@ public class NorthboundIT {
         result = getJsonResult(baseURL + "node/STUB/" + nodeId_1);
         jt = new JSONTokener(result);
         json = new JSONObject(jt);
-        nodeConnectorProperties = json.getJSONObject("nodeConnectorProperties");
+        nodeConnectorPropertiesArray = json.getJSONArray("nodeConnectorProperties");
+        nodeConnectorProperties = nodeConnectorPropertiesArray.getJSONObject(0);
 
         // Check for new bandwidth value, state value removed from previous
         // test
@@ -599,9 +647,9 @@ public class NorthboundIT {
 
     @Test
     public void testStatistics() throws JSONException {
-        final String actionTypes[] = { "drop", "loopback", "flood", "floodAll", "controller", "swPath", "hwPath", "output",
-                "setDlSrc", "setDlDst", "setDlType", "setVlanId", "setVlanPcp", "setVlanCfi", "popVlan", "pushVlan",
-                "setNwSrc", "setNwDst", "setNwTos", "setTpSrc", "setTpDst" };
+        final String actionTypes[] = { "DROP", "LOOPBACK", "FLOOD", "FLOOD_ALL", "CONTROLLER", "SW_PATH", "HW_PATH", "OUTPUT",
+                "SET_DL_SRC", "SET_DL_DST", "SET_DL_TYPE", "SET_VLAN_ID", "SET_VLAN_PCP", "SET_VLAN_CFI", "POP_VLAN", "PUSH_VLAN",
+                "SET_NW_SRC", "SET_NW_DST", "SET_NW_TOS", "SET_TP_SRC", "SET_TP_DST" };
         System.out.println("Starting Statistics JAXB client.");
 
         String baseURL = "http://127.0.0.1:8080/controller/nb/v2/statistics/default/";
@@ -635,7 +683,8 @@ public class NorthboundIT {
         Assert.assertEquals(node2.getString("type"), "STUB");
 
         // test that port statistic results are correct
-        JSONObject portStat = portStatistics.getJSONObject("portStatistic");
+        JSONArray portStatArray = portStatistics.getJSONArray("portStatistic");
+        JSONObject portStat = portStatArray.getJSONObject(0);
         Assert.assertTrue(portStat.getInt("receivePackets") == 250);
         Assert.assertTrue(portStat.getInt("transmitPackets") == 500);
         Assert.assertTrue(portStat.getInt("receiveBytes") == 1000);
@@ -674,7 +723,9 @@ public class NorthboundIT {
         Assert.assertEquals(node2.getString("type"), "STUB");
 
         // test that port statistic results are correct
-        portStat = json.getJSONObject("portStatistic");
+        portStatArray = json.getJSONArray("portStatistic");
+        portStat = portStatArray.getJSONObject(0);
+
         Assert.assertTrue(portStat.getInt("receivePackets") == 250);
         Assert.assertTrue(portStat.getInt("transmitPackets") == 500);
         Assert.assertTrue(portStat.getInt("receiveBytes") == 1000);
@@ -703,14 +754,18 @@ public class NorthboundIT {
         Assert.assertTrue(flow.getInt("hardTimeout") == 2000);
         Assert.assertTrue(flow.getInt("id") == 12345);
 
-        JSONObject match = (flow.getJSONObject("match").getJSONObject("matchField"));
+        JSONArray matches = (flow.getJSONObject("match").getJSONArray("matchField"));
+        Assert.assertEquals(matches.length(), 1);
+        JSONObject match = matches.getJSONObject(0);
         Assert.assertTrue(match.getString("type").equals("NW_DST"));
         Assert.assertTrue(match.getString("value").equals("1.1.1.1"));
 
-        JSONObject act = flow.getJSONObject("actions");
-        Assert.assertTrue(act.getString("@type").equals(actionType));
+        JSONArray actionsArray = flow.getJSONArray("actions");
+        Assert.assertEquals(actionsArray.length(), 1);
+        JSONObject act = actionsArray.getJSONObject(0);
+        Assert.assertTrue(act.getString("type").equals(actionType));
 
-        if (act.getString("@type").equals("output")) {
+        if (act.getString("type").equals("OUTPUT")) {
             JSONObject port = act.getJSONObject("port");
             JSONObject port_node = port.getJSONObject("node");
             Assert.assertTrue(port.getInt("id") == 51966);
@@ -719,7 +774,7 @@ public class NorthboundIT {
             Assert.assertTrue(port_node.getString("type").equals("STUB"));
         }
 
-        if (act.getString("@type").equals("setDlSrc")) {
+        if (act.getString("type").equals("SET_DL_SRC")) {
             byte srcMatch[] = { (byte) 5, (byte) 4, (byte) 3, (byte) 2, (byte) 1 };
             String src = act.getString("address");
             byte srcBytes[] = new byte[5];
@@ -731,7 +786,7 @@ public class NorthboundIT {
             Assert.assertTrue(Arrays.equals(srcBytes, srcMatch));
         }
 
-        if (act.getString("@type").equals("setDlDst")) {
+        if (act.getString("type").equals("SET_DL_DST")) {
             byte dstMatch[] = { (byte) 1, (byte) 2, (byte) 3, (byte) 4, (byte) 5 };
             String dst = act.getString("address");
             byte dstBytes[] = new byte[5];
@@ -742,21 +797,21 @@ public class NorthboundIT {
             dstBytes[4] = Byte.parseByte(dst.substring(8, 10));
             Assert.assertTrue(Arrays.equals(dstBytes, dstMatch));
         }
-        if (act.getString("@type").equals("setDlType"))
+        if (act.getString("type").equals("SET_DL_TYPE"))
             Assert.assertTrue(act.getInt("dlType") == 10);
-        if (act.getString("@type").equals("setVlanId"))
+        if (act.getString("type").equals("SET_VLAN_ID"))
             Assert.assertTrue(act.getInt("vlanId") == 2);
-        if (act.getString("@type").equals("setVlanPcp"))
+        if (act.getString("type").equals("SET_VLAN_PCP"))
             Assert.assertTrue(act.getInt("pcp") == 3);
-        if (act.getString("@type").equals("setVlanCfi"))
+        if (act.getString("type").equals("SET_VLAN_CFI"))
             Assert.assertTrue(act.getInt("cfi") == 1);
 
-        if (act.getString("@type").equals("setNwSrc"))
+        if (act.getString("type").equals("SET_NW_SRC"))
             Assert.assertTrue(act.getString("address").equals("2.2.2.2"));
-        if (act.getString("@type").equals("setNwDst"))
+        if (act.getString("type").equals("SET_NW_DST"))
             Assert.assertTrue(act.getString("address").equals("1.1.1.1"));
 
-        if (act.getString("@type").equals("pushVlan")) {
+        if (act.getString("type").equals("PUSH_VLAN")) {
             int head = act.getInt("VlanHeader");
             // parsing vlan header
             int id = head & 0xfff;
@@ -768,11 +823,11 @@ public class NorthboundIT {
             Assert.assertTrue(pcp == 1);
             Assert.assertTrue(tag == 0x8100);
         }
-        if (act.getString("@type").equals("setNwTos"))
+        if (act.getString("type").equals("SET_NW_TOS"))
             Assert.assertTrue(act.getInt("tos") == 16);
-        if (act.getString("@type").equals("setTpSrc"))
+        if (act.getString("type").equals("SET_TP_SRC"))
             Assert.assertTrue(act.getInt("port") == 4201);
-        if (act.getString("@type").equals("setTpDst"))
+        if (act.getString("type").equals("SET_TP_DST"))
             Assert.assertTrue(act.getInt("port") == 8080);
     }
 
@@ -786,7 +841,7 @@ public class NorthboundIT {
         Assert.assertTrue(result.equals("404"));
 
         // test add flow1
-        String fc = "{\"dynamic\":\"false\", \"name\":\"test1\", \"node\":{\"id\":\"51966\",\"type\":\"STUB\"}, \"actions\":[\"DROP\"]}";
+        String fc = "{\"name\":\"test1\", \"node\":{\"id\":\"51966\",\"type\":\"STUB\"}, \"actions\":[\"DROP\"]}";
         result = getJsonResult(baseURL + "node/STUB/51966/static-flow/test1", "PUT", fc);
         Assert.assertTrue(httpResponseCode == 201);
 
@@ -797,7 +852,8 @@ public class NorthboundIT {
         JSONTokener jt = new JSONTokener(result);
         JSONObject json = new JSONObject(jt);
         Assert.assertEquals(json.getString("name"), "test1");
-        Assert.assertEquals(json.getString("actions"), "DROP");
+        JSONArray actionsArray = json.getJSONArray("actions");
+        Assert.assertEquals(actionsArray.getString(0), "DROP");
         Assert.assertEquals(json.getString("installInHw"), "true");
         JSONObject node = json.getJSONObject("node");
         Assert.assertEquals(node.getString("type"), "STUB");
@@ -807,13 +863,13 @@ public class NorthboundIT {
         result = getJsonResult(baseURL + "node/STUB/51966/static-flow/test1", "PUT", fc);
         Assert.assertTrue(result.equals("409"));
 
-        fc = "{\"dynamic\":\"false\", \"name\":\"test2\", \"node\":{\"id\":\"51966\",\"type\":\"STUB\"}, \"actions\":[\"DROP\"]}";
+        fc = "{\"name\":\"test2\", \"node\":{\"id\":\"51966\",\"type\":\"STUB\"}, \"actions\":[\"DROP\"]}";
         result = getJsonResult(baseURL + "node/STUB/51966/static-flow/test2", "PUT", fc);
         // test should return 409 for error due to same flow being added.
         Assert.assertTrue(result.equals("409"));
 
         // add second flow that's different
-        fc = "{\"dynamic\":\"false\", \"name\":\"test2\", \"nwSrc\":\"1.1.1.1\", \"node\":{\"id\":\"51966\",\"type\":\"STUB\"}, \"actions\":[\"DROP\"]}";
+        fc = "{\"name\":\"test2\", \"nwSrc\":\"1.1.1.1\", \"node\":{\"id\":\"51966\",\"type\":\"STUB\"}, \"actions\":[\"DROP\"]}";
         result = getJsonResult(baseURL + "node/STUB/51966/static-flow/test2", "PUT", fc);
         Assert.assertTrue(httpResponseCode == 201);
 
@@ -1132,10 +1188,20 @@ public class NorthboundIT {
 
             JSONObject headNC = edge.getJSONObject("headNodeConnector");
             JSONObject headNode = headNC.getJSONObject("node");
-            JSONObject Props = edgeProp.getJSONObject("properties");
-            JSONObject bandw = Props.getJSONObject("bandwidth");
-            JSONObject stt = Props.getJSONObject("state");
-            JSONObject ltc = Props.getJSONObject("latency");
+
+            JSONArray propsArray = edgeProp.getJSONArray("properties");
+
+            JSONObject bandw = null;
+            JSONObject stt = null;
+            JSONObject ltc = null;
+
+            for (int j = 0; j < propsArray.length(); j++) {
+                JSONObject props = propsArray.getJSONObject(j);
+                String propName = props.getString("name");
+                if (propName.equals("bandwidth")) bandw = props;
+                if (propName.equals("state")) stt = props;
+                if (propName.equals("latency")) ltc = props;
+            }
 
             if (headNC.getInt("id") == headNC1_nodeConnId) {
                 Assert.assertEquals(headNode.getString("type"), nodeType);
@@ -1174,10 +1240,10 @@ public class NorthboundIT {
         Integer nodeConnectorId_2 = 34;
 
         JSONObject jo = new JSONObject()
-                .append("name", "userLink_1")
-                .append("srcNodeConnector",
+                .put("name", "userLink_1")
+                .put("srcNodeConnector",
                         nodeConnectorType_1 + "|" + nodeConnectorId_1 + "@" + nodeType_1 + "|" + nodeId_1)
-                .append("dstNodeConnector",
+                .put("dstNodeConnector",
                         nodeConnectorType_2 + "|" + nodeConnectorId_2 + "@" + nodeType_2 + "|" + nodeId_2);
         // execute HTTP request and verify response code
         result = getJsonResult(baseURL + "/user-link", "PUT", jo.toString());
@@ -1331,6 +1397,7 @@ public class NorthboundIT {
                 mavenBundle("org.codehaus.jackson", "jackson-mapper-asl").versionAsInProject(),
                 mavenBundle("org.codehaus.jackson", "jackson-core-asl").versionAsInProject(),
                 mavenBundle("org.codehaus.jackson", "jackson-jaxrs").versionAsInProject(),
+                mavenBundle("org.codehaus.jackson", "jackson-xc").versionAsInProject(),
                 mavenBundle("org.codehaus.jettison", "jettison").versionAsInProject(),
 
                 mavenBundle("commons-io", "commons-io").versionAsInProject(),
index 5993f16..b7da964 100644 (file)
@@ -58,6 +58,7 @@
               javax.xml.bind.annotation,
               javax.xml.bind,
               org.apache.catalina.filters,
+              org.codehaus.jackson.jaxrs,
               !org.codehaus.enunciate.jaxrs
             </Import-Package>
             <Export-Package>
index 1d1fd15..0d98d22 100644 (file)
@@ -13,6 +13,8 @@ import java.util.HashSet;
 import java.util.Set;
 import javax.ws.rs.core.Application;
 
+import org.codehaus.jackson.jaxrs.JacksonJaxbJsonProvider;
+
 /**
  * Instance of javax.ws.rs.core.Application used to return the classes
  * that will be instantiated for JAXRS processing, this is necessary
@@ -25,6 +27,7 @@ public class BridgeDomainNorthboundApplication extends Application {
     public Set<Class<?>> getClasses() {
         Set<Class<?>> classes = new HashSet<Class<?>>();
         classes.add(BridgeDomainNorthbound.class);
+        classes.add(JacksonJaxbJsonProvider.class);
         return classes;
     }
 }
index d308fba..62f5b42 100644 (file)
@@ -56,6 +56,7 @@
               javax.xml.bind.annotation,
               javax.xml.bind,
               org.apache.catalina.filters,
+              org.codehaus.jackson.jaxrs,
               !org.codehaus.enunciate.jaxrs
             </Import-Package>
             <Export-Package>
index 8462ef8..65e68aa 100644 (file)
@@ -233,7 +233,7 @@ public class StaticRoutingNorthbound {
             @Context UriInfo uriInfo,
             @PathParam(value = "containerName") String containerName,
             @PathParam(value = "route") String route,
-            @TypeHint(StaticRoute.class) JAXBElement<StaticRoute> staticRouteData) {
+            @TypeHint(StaticRoute.class) StaticRoute staticRouteData) {
 
 
         if(!NorthboundUtils.isAuthorized(getUserName(), containerName,
@@ -253,7 +253,7 @@ public class StaticRoutingNorthbound {
                     .toString());
         }
 
-        StaticRoute sRoute = staticRouteData.getValue();
+        StaticRoute sRoute = staticRouteData;
         StaticRouteConfig cfgObject = new StaticRouteConfig(sRoute.getName(),
                 sRoute.getPrefix(), sRoute.getNextHop());
         Status response = staticRouting.addStaticRoute(cfgObject);
index a39794d..a98a124 100644 (file)
@@ -13,6 +13,8 @@ import java.util.HashSet;
 import java.util.Set;
 import javax.ws.rs.core.Application;
 
+import org.codehaus.jackson.jaxrs.JacksonJaxbJsonProvider;
+
 /**
  * Instance of javax.ws.rs.core.Application used to return the classes
  * that will be instantiated for JAXRS processing, this is necessary
@@ -25,6 +27,7 @@ public class StaticRoutingNorthboundRSApplication extends Application {
     public Set<Class<?>> getClasses() {
         Set<Class<?>> classes = new HashSet<Class<?>>();
         classes.add(StaticRoutingNorthbound.class);
+        classes.add(JacksonJaxbJsonProvider.class);
         return classes;
     }
 }
index 6a5a08e..eb2bf58 100644 (file)
@@ -64,6 +64,7 @@
                 javax.xml.bind,
                 org.slf4j,
                 org.apache.catalina.filters,
+                org.codehaus.jackson.jaxrs,
                 !org.codehaus.enunciate.jaxrs
               </Import-Package>
             <Export-Package>
index d387407..2b6dccc 100644 (file)
@@ -12,6 +12,8 @@ import java.util.HashSet;
 import java.util.Set;
 import javax.ws.rs.core.Application;
 
+import org.codehaus.jackson.jaxrs.JacksonJaxbJsonProvider;
+
 /**
  * Instance of javax.ws.rs.core.Application used to return the classes
  * that will be instantiated for JAXRS processing, this is necessary
@@ -24,6 +26,7 @@ public class StatisticsNorthboundRSApplication extends Application {
     public Set<Class<?>> getClasses() {
         Set<Class<?>> classes = new HashSet<Class<?>>();
         classes.add(StatisticsNorthbound.class);
+        classes.add(JacksonJaxbJsonProvider.class);
         return classes;
     }
 }
index 72b0a04..9feb95f 100644 (file)
@@ -71,6 +71,7 @@
               javax.xml.bind.annotation,
               org.slf4j,
               org.apache.catalina.filters,
+              org.codehaus.jackson.jaxrs,
               !org.codehaus.enunciate.jaxrs
             </Import-Package>
             <Export-Package>
index a5e805d..50024fd 100644 (file)
@@ -254,7 +254,7 @@ public class SubnetsNorthbound {
             @ResponseCode(code = 503, condition = "Service unavailable") })
     public Response addSubnet(@PathParam("containerName") String containerName,
             @PathParam("subnetName") String subnetName,
-            @TypeHint(SubnetConfig.class) JAXBElement<SubnetConfig> subnetConfigData) {
+            @TypeHint(SubnetConfig.class) SubnetConfig subnetConfigData) {
 
         handleContainerDoesNotExist(containerName);
 
@@ -262,7 +262,7 @@ public class SubnetsNorthbound {
             throw new UnauthorizedException("User is not authorized to perform this operation on container "
                     + containerName);
         }
-        SubnetConfig cfgObject = subnetConfigData.getValue();
+        SubnetConfig cfgObject = subnetConfigData;
         handleNameMismatch(cfgObject.getName(), subnetName);
 
         ISwitchManager switchManager = (ISwitchManager) ServiceHelper.getInstance(ISwitchManager.class, containerName, this);
@@ -377,7 +377,7 @@ public class SubnetsNorthbound {
             @ResponseCode(code = 503, condition = "Service unavailable") })
     public Response modifySubnet(@PathParam("containerName") String containerName,
             @PathParam("subnetName") String subnetName,
-            @TypeHint(SubnetConfig.class) JAXBElement<SubnetConfig> subnetConfigData) {
+            @TypeHint(SubnetConfig.class) SubnetConfig subnetConfigData) {
 
         handleContainerDoesNotExist(containerName);
 
@@ -385,7 +385,7 @@ public class SubnetsNorthbound {
             throw new UnauthorizedException("User is not authorized to perform this operation on container "
                     + containerName);
         }
-        handleNameMismatch(subnetConfigData.getValue().getName(), subnetName);
+        handleNameMismatch(subnetConfigData.getName(), subnetName);
 
         ISwitchManager switchManager = (ISwitchManager) ServiceHelper.getInstance(ISwitchManager.class, containerName,
                 this);
@@ -393,7 +393,7 @@ public class SubnetsNorthbound {
             throw new ServiceUnavailableException("SwitchManager " + RestMessages.SERVICEUNAVAILABLE.toString());
         }
 
-        SubnetConfig subnetConf = subnetConfigData.getValue();
+        SubnetConfig subnetConf = subnetConfigData;
         SubnetConfig existingConf = switchManager.getSubnetConfig(subnetName);
 
         boolean successful = true;
@@ -488,7 +488,7 @@ public class SubnetsNorthbound {
             @ResponseCode(code = 503, condition = "Service unavailable") })
     public Response addNodePorts(@PathParam("containerName") String containerName,
             @PathParam("subnetName") String subnetName,
-            @TypeHint(SubnetConfig.class) JAXBElement<SubnetConfig> subnetConfigData) {
+            @TypeHint(SubnetConfig.class) SubnetConfig subnetConfigData) {
 
         handleContainerDoesNotExist(containerName);
 
@@ -496,9 +496,9 @@ public class SubnetsNorthbound {
             throw new UnauthorizedException("User is not authorized to perform this operation on container "
                     + containerName);
         }
-        handleNameMismatch(subnetConfigData.getValue().getName(), subnetName);
+        handleNameMismatch(subnetConfigData.getName(), subnetName);
 
-        SubnetConfig subnetConf = subnetConfigData.getValue();
+        SubnetConfig subnetConf = subnetConfigData;
 
         ISwitchManager switchManager = (ISwitchManager) ServiceHelper.getInstance(ISwitchManager.class, containerName,
                 this);
@@ -586,7 +586,7 @@ public class SubnetsNorthbound {
             @ResponseCode(code = 503, condition = "Service unavailable") })
     public Response deleteNodePorts(@PathParam("containerName") String containerName,
             @PathParam("subnetName") String subnetName,
-            @TypeHint(SubnetConfig.class) JAXBElement<SubnetConfig> subnetConfigData) {
+            @TypeHint(SubnetConfig.class) SubnetConfig subnetConfigData) {
 
         handleContainerDoesNotExist(containerName);
 
@@ -594,9 +594,9 @@ public class SubnetsNorthbound {
             throw new UnauthorizedException("User is not authorized to perform this operation on container "
                     + containerName);
         }
-        handleNameMismatch(subnetConfigData.getValue().getName(), subnetName);
+        handleNameMismatch(subnetConfigData.getName(), subnetName);
 
-        SubnetConfig subnetConf = subnetConfigData.getValue();
+        SubnetConfig subnetConf = subnetConfigData;
 
         if (subnetConf.getNodePorts() == null || subnetConf.getNodePorts().isEmpty()) {
             throw new BadRequestException(RestMessages.INVALIDDATA.toString() + " : invalid node ports");
index a5eaf94..e03cac6 100644 (file)
@@ -12,6 +12,8 @@ import java.util.Set;
 
 import javax.ws.rs.core.Application;
 
+import org.codehaus.jackson.jaxrs.JacksonJaxbJsonProvider;
+
 /**
  * Instance of javax.ws.rs.core.Application used to return the classes
  * that will be instantiated for JAXRS processing, this is necessary
@@ -24,6 +26,7 @@ public class SubnetsNorthboundRSApplication extends Application {
     public Set<Class<?>> getClasses() {
         Set<Class<?>> classes = new HashSet<Class<?>>();
         classes.add(SubnetsNorthbound.class);
+        classes.add(JacksonJaxbJsonProvider.class);
         return classes;
     }
 }
index 7196883..965075a 100644 (file)
@@ -57,6 +57,7 @@
               javax.xml.bind,
               org.slf4j,
               org.apache.catalina.filters,
+              org.codehaus.jackson.jaxrs,
               !org.codehaus.enunciate.jaxrs
             </Import-Package>
             <Web-ContextPath>/controller/nb/v2/switch</Web-ContextPath>
index d33c3c9..1cdfd31 100644 (file)
@@ -13,6 +13,8 @@ import java.util.HashSet;
 import java.util.Set;
 import javax.ws.rs.core.Application;
 
+import org.codehaus.jackson.jaxrs.JacksonJaxbJsonProvider;
+
 /**
  * Instance of javax.ws.rs.core.Application used to return the classes
  * that will be instantiated for JAXRS processing, this is necessary
@@ -25,6 +27,7 @@ public class SwitchNorthboundRSApplication extends Application {
     public Set<Class<?>> getClasses() {
         Set<Class<?>> classes = new HashSet<Class<?>>();
         classes.add(SwitchNorthbound.class);
+        classes.add(JacksonJaxbJsonProvider.class);
         return classes;
     }
 }
index ec43a5e..b2b7b9c 100644 (file)
@@ -60,6 +60,7 @@
               javax.xml.bind.annotation,
               org.slf4j,
               org.apache.catalina.filters,
+              org.codehaus.jackson.jaxrs,
               !org.codehaus.enunciate.jaxrs
             </Import-Package>
             <Web-ContextPath>/controller/nb/v2/topology</Web-ContextPath>
index c20cb26..508ffaf 100644 (file)
@@ -200,8 +200,7 @@ public class TopologyNorthboundJAXRS {
         if (topo != null) {
             List<EdgeProperties> res = new ArrayList<EdgeProperties>();
             for (Map.Entry<Edge, Set<Property>> entry : topo.entrySet()) {
-                EdgeProperties el = new EdgeProperties(entry.getKey(),
-                        entry.getValue());
+                EdgeProperties el = new EdgeProperties(entry.getKey(), entry.getValue());
                 res.add(el);
             }
             return new Topology(res);
@@ -316,7 +315,7 @@ public class TopologyNorthboundJAXRS {
             @ResponseCode(code = 503, condition = "One or more of Controller services are unavailable") })
     public Response addUserLink(
             @PathParam(value = "containerName") String containerName,
-            @TypeHint(TopologyUserLinkConfig.class) JAXBElement<TopologyUserLinkConfig> userLinkConfig) {
+            @TypeHint(TopologyUserLinkConfig.class) TopologyUserLinkConfig userLinkConfig) {
 
         if (!NorthboundUtils.isAuthorized(
                 getUserName(), containerName, Privilege.WRITE, this)) {
@@ -331,9 +330,9 @@ public class TopologyNorthboundJAXRS {
                     RestMessages.NOCONTAINER.toString());
         }
 
-        Status status = topologyManager.addUserLink(userLinkConfig.getValue());
+        Status status = topologyManager.addUserLink(userLinkConfig);
         if (status.isSuccess()) {
-            NorthboundUtils.auditlog("User Link", username, "added", userLinkConfig.getValue().getName(), containerName);
+            NorthboundUtils.auditlog("User Link", username, "added", userLinkConfig.getName(), containerName);
             return Response.status(Response.Status.CREATED).build();
         }
         throw new InternalServerErrorException(status.getDescription());
index 299bfcd..992cf6a 100644 (file)
@@ -13,6 +13,8 @@ import java.util.HashSet;
 import java.util.Set;
 import javax.ws.rs.core.Application;
 
+import org.codehaus.jackson.jaxrs.JacksonJaxbJsonProvider;
+
 /**
  * Instance of javax.ws.rs.core.Application used to return the classes
  * that will be instantiated for JAXRS processing, this is necessary
@@ -25,6 +27,7 @@ public class TopologyNorthboundRSApplication extends Application {
     public Set<Class<?>> getClasses() {
         Set<Class<?>> classes = new HashSet<Class<?>>();
         classes.add(TopologyNorthboundJAXRS.class);
+        classes.add(JacksonJaxbJsonProvider.class);
         return classes;
     }
 }
index 8fc8fc1..515a61e 100644 (file)
@@ -12,6 +12,7 @@ import java.io.Serializable;
 
 import javax.xml.bind.annotation.XmlAccessType;
 import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlElement;
 import javax.xml.bind.annotation.XmlRootElement;
 import javax.xml.bind.annotation.XmlSeeAlso;
 import javax.xml.bind.annotation.XmlTransient;
@@ -34,7 +35,7 @@ public abstract class Action implements Serializable {
     private static final Logger logger = LoggerFactory.getLogger(Action.class);
     private static boolean debug = false; // Enable to find where in the code an
     // invalid assignment is made
-    @XmlTransient
+    @XmlElement
     protected ActionType type;
     private transient boolean isValid = true;
 
index a2d3d36..c0c8da7 100644 (file)
@@ -29,7 +29,7 @@ public class TimeStamp extends Property {
     private static final long serialVersionUID = 1L;
     @XmlElement(name = "value")
     private long timestamp;
-    @XmlElement(name = "name")
+    @XmlElement(name = "timestampName")
     private String timestampName;
 
     public static final String TimeStampPropName = "timeStamp";
index 3b0ae0c..5ec7202 100644 (file)
@@ -58,6 +58,7 @@
               javax.xml.bind,
               org.slf4j,
               org.apache.catalina.filters,
+              org.codehaus.jackson.jaxrs,
               !org.codehaus.enunciate.jaxrs
             </Import-Package>
             <Web-ContextPath>/one/nb/v2/lb</Web-ContextPath>
index 8ea0d78..5a4473b 100644 (file)
@@ -208,9 +208,9 @@ public class LoadBalancerNorthbound {
         @ResponseCode(code = 409, condition = "VIP already exist"),
         @ResponseCode(code = 415, condition = "Invalid input data")})
     public Response addVIP(@PathParam("containerName") String containerName,
-            @TypeHint(VIP.class) JAXBElement<VIP> inVIP){
+            @TypeHint(VIP.class) VIP inVIP){
 
-        VIP vipInput = inVIP.getValue();
+        VIP vipInput = inVIP;
         String name = vipInput.getName();
         String ip = vipInput.getIp();
         String protocol = vipInput.getProtocol();
@@ -253,9 +253,9 @@ public class LoadBalancerNorthbound {
         @ResponseCode(code = 405, condition = "Pool already attached to the VIP"),
         @ResponseCode(code = 415, condition = "Invalid input name")})
     public Response updateVIP(@PathParam("containerName") String containerName,
-            @TypeHint(VIP.class) JAXBElement<VIP> inVIP) {
+            @TypeHint(VIP.class) VIP inVIP) {
 
-        VIP vipInput = inVIP.getValue();
+        VIP vipInput = inVIP;
         String name = vipInput.getName();
         String poolName = vipInput.getPoolName();
         if(name.isEmpty() ||
@@ -325,9 +325,9 @@ public class LoadBalancerNorthbound {
         @ResponseCode(code = 409, condition = "Pool already exist"),
         @ResponseCode(code = 415, condition = "Invalid input data")})
     public Response addPool(@PathParam("containerName") String containerName,
-            @TypeHint(Pool.class) JAXBElement<Pool> inPool) {
+            @TypeHint(Pool.class) Pool inPool) {
 
-        Pool poolInput = inPool.getValue();
+        Pool poolInput = inPool;
         String name = poolInput.getName();
         String lbMethod =poolInput.getLbMethod();
         if(name.isEmpty() ||
@@ -398,9 +398,9 @@ public class LoadBalancerNorthbound {
         @ResponseCode(code = 409, condition = "Pool member already exist"),
         @ResponseCode(code = 415, condition = "Invalid input data")})
     public Response addPoolMember(@PathParam("containerName") String containerName,
-            @TypeHint(PoolMember.class) JAXBElement<PoolMember> inPoolMember){
+            @TypeHint(PoolMember.class) PoolMember inPoolMember){
 
-        PoolMember pmInput = inPoolMember.getValue();
+        PoolMember pmInput = inPoolMember;
         String name = pmInput.getName();
         String memberIP = pmInput.getIp();
         String poolName = pmInput.getPoolName();
index 0c17c84..2f5aaca 100644 (file)
@@ -12,6 +12,8 @@ import java.util.HashSet;
 import java.util.Set;
 import javax.ws.rs.core.Application;
 
+import org.codehaus.jackson.jaxrs.JacksonJaxbJsonProvider;
+
 /**
  * This class is an instance of javax.ws.rs.core.Application and is used to return the classes
  * that will be instantiated for JAXRS processing. This is necessary
@@ -23,6 +25,7 @@ public class LoadBalancerNorthboundRSApplication extends Application {
     public Set<Class<?>> getClasses() {
         Set<Class<?>> classes = new HashSet<Class<?>>();
         classes.add(LoadBalancerNorthbound.class);
+        classes.add(JacksonJaxbJsonProvider.class);
         return classes;
     }
 }

©2013 OpenDaylight, A Linux Foundation Collaborative Project. All Rights Reserved.
OpenDaylight is a registered trademark of The OpenDaylight Project, Inc.
Linux Foundation and OpenDaylight are registered trademarks of the Linux Foundation.
Linux is a registered trademark of Linus Torvalds.