After the Jackson migration (https://git.opendaylight.org/gerrit/#/c/1131), the marshalled JSON output
got misaligned from its XML counterpart. This is because of the "special" handling of XmlElementRef by
Jettison.
Please refer to http://pastebin.com/6kCSuddg for various marshalled JSON output for Jettison, Jackson and Moxy.
Having tried & exhausted various mechanisms (using Jackson and Moxy), finally decided to use the Jackson
annotations to take care of this requirement. Changes involves :
1. Modified NodeConnectProperties, EdgProperties and NodeProperties to use @JsonIgnore and @JsonProperty
2. Reverted a few NorthboundIT changes as prior to the gerrit#1131 version to align to the JSON format.
3. Added @XmlAccessorType(XmlAccessType.NONE) in all the Property classes to avoid including unnecessary data.
Change-Id: I574956328fa841b2165e0c10ddec995c70b76e4d
Signed-off-by: Madhu Venugopal <vmadhu@cisco.com>
Assert.assertEquals(nodeId, (Integer) nodeInfo.getInt("id"));
Assert.assertEquals(nodeType, nodeInfo.getString("type"));
- 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"));
- }
- }
+ 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"));
}
}
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"));
-
- 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"));
- }
- }
+ 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"));
}
}
json = new JSONObject(jt);
node = getJsonInstance(json, "nodeProperties", nodeId_1);
Assert.assertNotNull(node);
-
- 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"));
- }
- }
+ Assert.assertEquals(1001, node.getJSONObject("properties").getJSONObject("tier").getInt("value"));
+ Assert.assertEquals("node1", node.getJSONObject("properties").getJSONObject("description").getString("value"));
// Test delete nodeConnector property
// Delete state property of nodeconnector1
JSONObject headNC = edge.getJSONObject("headNodeConnector");
JSONObject headNode = headNC.getJSONObject("node");
-
- 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;
- }
- }
+ JSONObject Props = edgeProp.getJSONObject("properties");
+ JSONObject bandw = Props.getJSONObject("bandwidth");
+ JSONObject stt = Props.getJSONObject("state");
+ JSONObject ltc = Props.getJSONObject("latency");
if (headNC.getInt("id") == headNC1_nodeConnId) {
Assert.assertEquals(headNode.getString("type"), nodeType);
Integer nodeId_1 = 3366;
String nodeConnectorType_1 = "STUB";
Integer nodeConnectorId_1 = 12;
-
String nodeType_2 = "STUB";
Integer nodeId_2 = 4477;
String nodeConnectorType_2 = "STUB";
}
}
}
-
// Configure the OSGi container
@Configuration
public Option[] config() {
org.slf4j,
org.apache.catalina.filters,
org.codehaus.jackson.jaxrs,
+ org.codehaus.jackson.annotate,
!org.codehaus.enunciate.jaxrs
</Import-Package>
<Web-ContextPath>/controller/nb/v2/switchmanager</Web-ContextPath>
package org.opendaylight.controller.switchmanager.northbound;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
import java.util.Set;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlElementRef;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlElementWrapper;
+import org.codehaus.jackson.annotate.JsonIgnore;
+import org.codehaus.jackson.annotate.JsonProperty;
import org.opendaylight.controller.sal.core.NodeConnector;
import org.opendaylight.controller.sal.core.Property;
private NodeConnector nodeconnector;
@XmlElementRef
@XmlElementWrapper
+ @JsonIgnore
private Set<Property> properties;
// JAXB required constructor
this.properties = properties;
}
+ @JsonProperty(value="properties")
+ public Map<String, Property> getMapProperties() {
+ Map<String, Property> map = new HashMap<String, Property>();
+ for (Property p : properties) {
+ map.put(p.getName(), p);
+ }
+ return map;
+ }
+
+ public void setMapProperties(Map<String, Property> propertiesMap) {
+ this.properties = new HashSet<Property>(propertiesMap.values());
+ }
+
public Set<Property> getProperties() {
return properties;
}
package org.opendaylight.controller.switchmanager.northbound;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
import java.util.Set;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlElementRef;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlElementWrapper;
+import org.codehaus.jackson.annotate.JsonIgnore;
+import org.codehaus.jackson.annotate.JsonProperty;
import org.opendaylight.controller.sal.core.Node;
import org.opendaylight.controller.sal.core.Property;
private Node node;
@XmlElementRef
@XmlElementWrapper
+ @JsonIgnore
private Set<Property> properties;
// JAXB required constructor
this.properties = properties;
}
+ @JsonProperty(value="properties")
+ public Map<String, Property> getMapProperties() {
+ Map<String, Property> map = new HashMap<String, Property>();
+ for (Property p : properties) {
+ map.put(p.getName(), p);
+ }
+ return map;
+ }
+
+ public void setMapProperties(Map<String, Property> propertiesMap) {
+ this.properties = new HashSet<Property>(propertiesMap.values());
+ }
+
public Set<Property> getProperties() {
return properties;
}
org.opendaylight.controller.usermanager,
org.opendaylight.controller.topologymanager,
com.sun.jersey.spi.container.servlet,
+ org.codehaus.jackson.annotate,
javax.ws.rs,
javax.ws.rs.core,
javax.xml.bind,
package org.opendaylight.controller.topology.northbound;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
import java.util.Set;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlElementWrapper;
import javax.xml.bind.annotation.XmlRootElement;
+import org.codehaus.jackson.annotate.JsonIgnore;
+import org.codehaus.jackson.annotate.JsonProperty;
import org.opendaylight.controller.sal.core.Edge;
import org.opendaylight.controller.sal.core.Property;
private Edge edge;
@XmlElementRef
@XmlElementWrapper
+ @JsonIgnore
private Set<Property> properties;
// JAXB required constructor
this.properties = properties;
}
+ @JsonProperty(value="properties")
+ public Map<String, Property> getMapProperties() {
+ Map<String, Property> map = new HashMap<String, Property>();
+ for (Property p : properties) {
+ map.put(p.getName(), p);
+ }
+ return map;
+ }
+
+ public void setMapProperties(Map<String, Property> propertiesMap) {
+ this.properties = new HashSet<Property>(propertiesMap.values());
+ }
+
public Set<Property> getProperties() {
return properties;
}
-
public void setProperties(Set<Property> properties) {
this.properties = properties;
}
package org.opendaylight.controller.sal.core;
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
*/
@XmlRootElement
+@XmlAccessorType(XmlAccessType.NONE)
public class Actions extends Property {
private static final long serialVersionUID = 1L;
@XmlElement(name="value")
package org.opendaylight.controller.sal.core;
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlRootElement;
/**
* seconds.
*/
@XmlRootElement
+@XmlAccessorType(XmlAccessType.NONE)
@SuppressWarnings("serial")
public class AdvertisedBandwidth extends Bandwidth {
public static final String AdvertisedBandwidthPropName = "advertisedBandwidth";
package org.opendaylight.controller.sal.core;
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
* seconds.
*/
@XmlRootElement
+@XmlAccessorType(XmlAccessType.NONE)
public class Bandwidth extends Property {
private static final long serialVersionUID = 1L;
package org.opendaylight.controller.sal.core;
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
* Describes supported buffers (#packets)
*/
@XmlRootElement
+@XmlAccessorType(XmlAccessType.NONE)
public class Buffers extends Property {
private static final long serialVersionUID = 1L;
@XmlElement(name="value")
package org.opendaylight.controller.sal.core;
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
* Describes supported capabilities
*/
@XmlRootElement
+@XmlAccessorType(XmlAccessType.NONE)
public class Capabilities extends Property {
private static final long serialVersionUID = 1L;
@XmlElement(name="value")
package org.opendaylight.controller.sal.core;
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
*/
@XmlRootElement
@SuppressWarnings("serial")
+@XmlAccessorType(XmlAccessType.NONE)
public class Config extends Property {
@XmlElement(name="value")
private short configValue;
package org.opendaylight.controller.sal.core;
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
*/
@XmlRootElement
@SuppressWarnings("serial")
+@XmlAccessorType(XmlAccessType.NONE)
public class Description extends Property {
@XmlElement(name="value")
private String descriptionValue;
package org.opendaylight.controller.sal.core;
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
* The class represents the forwarding mode property of a node.
*/
@XmlRootElement
+@XmlAccessorType(XmlAccessType.NONE)
@SuppressWarnings("serial")
public class ForwardingMode extends Property {
@XmlElement(name="value")
package org.opendaylight.controller.sal.core;
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
* Describe a latency in picoseconds or multiple of its.
*/
@XmlRootElement
+@XmlAccessorType(XmlAccessType.NONE)
public class Latency extends Property {
private static final long serialVersionUID = 1L;
package org.opendaylight.controller.sal.core;
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
* The class represents the Name property of an element.
*/
@XmlRootElement
+@XmlAccessorType(XmlAccessType.NONE)
@SuppressWarnings("serial")
public class Name extends Property {
@XmlElement(name="value")
package org.opendaylight.controller.sal.core;
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlRootElement;
/**
* bits per seconds.
*/
@XmlRootElement
+@XmlAccessorType(XmlAccessType.NONE)
public class PeerBandwidth extends Bandwidth {
private static final long serialVersionUID = 1L;
import java.io.Serializable;
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlSeeAlso;
* element
*/
@XmlRootElement
+@XmlAccessorType(XmlAccessType.NONE)
@XmlSeeAlso({ Config.class, Name.class, State.class, TimeStamp.class,
Latency.class, Bandwidth.class, Tier.class, Actions.class,
AdvertisedBandwidth.class, Buffers.class, Capabilities.class,
package org.opendaylight.controller.sal.core;
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
*
*/
@XmlRootElement
+@XmlAccessorType(XmlAccessType.NONE)
@SuppressWarnings("serial")
public class State extends Property {
@XmlElement(name="value")
package org.opendaylight.controller.sal.core;
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlRootElement;
/**
* seconds.
*/
@XmlRootElement
+@XmlAccessorType(XmlAccessType.NONE)
public class SupportedBandwidth extends Bandwidth {
private static final long serialVersionUID = 1L;
public static final String SupportedBandwidthPropName = "supportedBandwidth";
package org.opendaylight.controller.sal.core;
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
* Describes supported # of datapath tables
*/
@XmlRootElement
+@XmlAccessorType(XmlAccessType.NONE)
public class Tables extends Property {
private static final long serialVersionUID = 1L;
@XmlElement(name="value")
package org.opendaylight.controller.sal.core;
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
*
*/
@XmlRootElement
+@XmlAccessorType(XmlAccessType.NONE)
@SuppressWarnings("serial")
public class Tier extends Property {
@XmlElement(name="value")
import java.util.Date;
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
* to qualify what are we talking about
*/
@XmlRootElement
+@XmlAccessorType(XmlAccessType.NONE)
public class TimeStamp extends Property {
private static final long serialVersionUID = 1L;
@XmlElement(name = "value")
private long timestamp;
- @XmlElement(name = "timestampName")
+ @XmlElement(name = "name")
private String timestampName;
public static final String TimeStampPropName = "timeStamp";