Add namespace support to KVObject.
- Tests modified to address ONOS-1277
- Removed obsolete fields in KVDevice
- This feature may be required, if we need multi-tenacy support or
multi-layer topology view.
Change-Id: Ie3cf9b29f4864cbec691edbd712b4b1c03b22dc0
diff --git a/src/main/java/net/onrc/onos/core/datastore/topology/KVDevice.java b/src/main/java/net/onrc/onos/core/datastore/topology/KVDevice.java
index 15cdc57..306ebc5 100644
--- a/src/main/java/net/onrc/onos/core/datastore/topology/KVDevice.java
+++ b/src/main/java/net/onrc/onos/core/datastore/topology/KVDevice.java
@@ -28,7 +28,6 @@
/**
* Device object.
* <p/>
- * TODO switch to ProtoBuf, etc.
*/
public class KVDevice extends KVObject {
private static final Logger log = LoggerFactory.getLogger(KVDevice.class);
@@ -48,21 +47,29 @@
}
};
- public static final String GLOBAL_DEVICE_TABLE_NAME = "G:Device";
-
- // FIXME these should be Enum or some number, not String
- private static final String PROP_MAC = "mac";
- private static final String PROP_PORT_IDS = "port-ids";
+ static final String DEVICE_TABLE_SUFFIX = ":Device";
private final byte[] mac;
private TreeSet<byte[]> portIds;
- private transient boolean isPortIdsModified;
- // Assuming mac is unique cluster-wide
+ /**
+ * Generate a DeviceID from MAC address.
+ * <p/>
+ * We're assuming MAC address can be an unique identifier for Device.
+ *
+ * @param mac MAC address
+ * @return DeviceID
+ */
public static byte[] getDeviceID(final byte[] mac) {
return DeviceEvent.getDeviceID(mac).array();
}
+ /**
+ * Gets the MAC address from DeviceID.
+ *
+ * @param key DeviceID
+ * @return MAC address
+ */
public static byte[] getMacFromKey(final byte[] key) {
ByteBuffer keyBuf = ByteBuffer.wrap(key);
if (keyBuf.getChar() != 'D') {
@@ -73,80 +80,175 @@
return mac;
}
+ /**
+ * KVDevice constructor for default namespace.
+ *
+ * @param mac MAC address
+ */
public KVDevice(final byte[] mac) {
- super(DataStoreClient.getClient().getTable(GLOBAL_DEVICE_TABLE_NAME), getDeviceID(mac));
-
- this.mac = mac.clone();
- this.portIds = new TreeSet<>(ByteArrayComparator.BYTEARRAY_COMPARATOR);
- this.isPortIdsModified = true;
+ this(mac, DEFAULT_NAMESPACE);
}
/**
- * Get an instance from Key.
+ * KVDevice constructor for specified namespace.
*
- * @param key
- * @return
+ * @param mac MAC address
+ * @param namespace namespace to create this object
+ */
+ public KVDevice(final byte[] mac, final String namespace) {
+ super(DataStoreClient.getClient()
+ .getTable(namespace + DEVICE_TABLE_SUFFIX),
+ getDeviceID(mac), namespace);
+
+ this.mac = mac.clone();
+ this.portIds = new TreeSet<>(ByteArrayComparator.BYTEARRAY_COMPARATOR);
+ }
+
+ /**
+ * Gets an instance from DeviceID in default namespace.
+ *
+ * @param key DeviceID
+ * @return KVDevice instance
* @note You need to call `read()` to get the DB content.
*/
public static KVDevice createFromKey(final byte[] key) {
- return new KVDevice(getMacFromKey(key));
+ return createFromKey(key, DEFAULT_NAMESPACE);
}
+ /**
+ * Gets an instance from DeviceID in specified namespace.
+ *
+ * @param key DeviceID
+ * @param namespace namespace to create this object in
+ * @return KVDevice instance
+ * @note You need to call `read()` to get the DB content.
+ */
+ public static KVDevice createFromKey(final byte[] key, final String namespace) {
+ return new KVDevice(getMacFromKey(key), namespace);
+ }
+
+ /**
+ * Gets all the Devices in default namespace.
+ *
+ * @return Devices
+ */
public static Iterable<KVDevice> getAllDevices() {
- return new DeviceEnumerator();
+ return new DeviceEnumerator(DEFAULT_NAMESPACE);
}
+ /**
+ * Gets all the Devices in specified namespace.
+ *
+ * @param namespace namespace to iterate over
+ * @return Devices
+ */
+ public static Iterable<KVDevice> getAllDevices(final String namespace) {
+ return new DeviceEnumerator(namespace);
+ }
+
+ /**
+ * Utility class to provide Iterable interface.
+ */
public static class DeviceEnumerator implements Iterable<KVDevice> {
+ private final String namespace;
+
+ /**
+ * Constructor to iterate Links in specified namespace.
+ *
+ * @param namespace namespace to iterate through
+ */
+ public DeviceEnumerator(final String namespace) {
+ this.namespace = namespace;
+ }
+
@Override
public Iterator<KVDevice> iterator() {
- return new DeviceIterator();
+ return new DeviceIterator(namespace);
}
}
+ /**
+ * Utility class to provide Iterator over all the Device objects.
+ */
public static class DeviceIterator extends AbstractObjectIterator<KVDevice> {
- public DeviceIterator() {
- super(DataStoreClient.getClient().getTable(GLOBAL_DEVICE_TABLE_NAME));
+ /**
+ * Constructor to create an iterator to iterate all the Devices
+ * in specified namespace.
+ *
+ * @param namespace namespace to iterate through
+ */
+ public DeviceIterator(final String namespace) {
+ super(DataStoreClient.getClient()
+ .getTable(namespace + DEVICE_TABLE_SUFFIX), namespace);
}
@Override
public KVDevice next() {
IKVEntry o = enumerator.next();
- KVDevice e = KVDevice.createFromKey(o.getKey());
+ KVDevice e = KVDevice.createFromKey(o.getKey(), namespace);
e.deserialize(o.getValue(), o.getVersion());
return e;
}
}
+ /**
+ * Gets the MAC address.
+ *
+ * @return MAC address
+ */
public byte[] getMac() {
return mac.clone();
}
+ /**
+ * Gets the DeviceID.
+ *
+ * @return DeviceID
+ */
public byte[] getId() {
return getKey();
}
+ /**
+ * Add a port to this Device's attachment points.
+ *
+ * @param portId PortID of the port which this Device is attached
+ */
public void addPortId(final byte[] portId) {
- // TODO: Should we copy portId, or reference is OK.
- isPortIdsModified |= portIds.add(portId);
- }
-
- public void removePortId(final byte[] portId) {
- isPortIdsModified |= portIds.remove(portId);
- }
-
- public void emptyPortIds() {
- portIds.clear();
- this.isPortIdsModified = true;
- }
-
- public void addAllToPortIds(final Collection<byte[]> newPortIds) {
- // TODO: Should we copy portId, or reference is OK.
- isPortIdsModified |= portIds.addAll(newPortIds);
+ portIds.add(portId.clone());
}
/**
+ * Remove a port from this Device's attachment points.
+ *
+ * @param portId PortID to remove
+ */
+ public void removePortId(final byte[] portId) {
+ portIds.remove(portId);
+ }
+
+ /**
+ * Empty this Device's attachment points.
+ */
+ public void emptyPortIds() {
+ portIds.clear();
+ }
+
+ /**
+ * Add ports to this Device's attachment points.
+ *
+ * @param newPortIds PortIDs which this Device is attached
+ */
+ public void addAllToPortIds(final Collection<byte[]> newPortIds) {
+ // TODO: Should we copy each portId, or reference is OK.
+ portIds.addAll(newPortIds);
+ }
+
+ /**
+ * Gets all the PortIDs which this Device is attached.
+ *
* @return Unmodifiable Set view of all the PortIds;
*/
public Set<byte[]> getAllPortIds() {
diff --git a/src/main/java/net/onrc/onos/core/datastore/topology/KVLink.java b/src/main/java/net/onrc/onos/core/datastore/topology/KVLink.java
index 2e4d079..4ad9b74 100644
--- a/src/main/java/net/onrc/onos/core/datastore/topology/KVLink.java
+++ b/src/main/java/net/onrc/onos/core/datastore/topology/KVLink.java
@@ -40,19 +40,38 @@
}
};
+ /**
+ * Internal data structure to represent a port on a switch.
+ */
public static class SwitchPort {
public final Long dpid;
public final Long number;
+ /**
+ * Constructor.
+ *
+ * @param dpid datapath ID of this switch port
+ * @param number port number of this port on switch({@code dpid})
+ */
public SwitchPort(final Long dpid, final Long number) {
this.dpid = dpid;
this.number = number;
}
+ /**
+ * Gets the PortID of a port this object represent.
+ *
+ * @return PortID
+ */
public byte[] getPortID() {
return KVPort.getPortID(dpid, number);
}
+ /**
+ * Gets the SwitchID of a switch this object represent.
+ *
+ * @return SwitchID
+ */
public byte[] getSwitchID() {
return KVSwitch.getSwitchID(dpid);
}
@@ -64,9 +83,12 @@
}
- public static final String GLOBAL_LINK_TABLE_NAME = "G:Link";
+ static final String LINK_TABLE_SUFFIX = ":Link";
// must not re-order enum members, ordinal will be sent over wire
+ /**
+ * Status.
+ */
public enum STATUS {
INACTIVE, ACTIVE;
}
@@ -75,16 +97,37 @@
private final SwitchPort dst;
private STATUS status;
+ /**
+ * Generate a LinkID from Link 4-tuples.
+ *
+ * @param srcDpid source DPID
+ * @param srcPortNo source port number
+ * @param dstDpid destination DPID
+ * @param dstPortNo destination port number
+ * @return LinkID
+ */
public static byte[] getLinkID(final Long srcDpid, final Long srcPortNo,
final Long dstDpid, final Long dstPortNo) {
return LinkEvent.getLinkID(srcDpid, srcPortNo, dstDpid,
dstPortNo).array();
}
+ /**
+ * Gets Link 4-tuples from LinkID.
+ *
+ * @param key LinkID
+ * @return Link 4-tuple: [src DPID, src PortNo, dst DPID, dst PortNo]
+ */
public static long[] getLinkTupleFromKey(final byte[] key) {
return getLinkTupleFromKey(ByteBuffer.wrap(key));
}
+ /**
+ * Gets Link 4-tuples from LinkID.
+ *
+ * @param keyBuf LinkID
+ * @return Link 4-tuple: [src DPID, src PortNo, dst DPID, dst PortNo]
+ */
public static long[] getLinkTupleFromKey(final ByteBuffer keyBuf) {
if (keyBuf.getChar() != 'L') {
throw new IllegalArgumentException("Invalid Link key");
@@ -102,10 +145,36 @@
return tuple;
}
+
+ /**
+ * KVLink constructor for default namespace.
+ *
+ * @param srcDpid source DPID
+ * @param srcPortNo source port number
+ * @param dstDpid destination DPID
+ * @param dstPortNo destination port number
+ */
public KVLink(final Long srcDpid, final Long srcPortNo,
final Long dstDpid, final Long dstPortNo) {
- super(DataStoreClient.getClient().getTable(GLOBAL_LINK_TABLE_NAME), getLinkID(srcDpid,
- srcPortNo, dstDpid, dstPortNo));
+ this(srcDpid, srcPortNo, dstDpid, dstPortNo, DEFAULT_NAMESPACE);
+ }
+
+ /**
+ * KVLink constructor for specified namespace.
+ *
+ * @param srcDpid source DPID
+ * @param srcPortNo source port number
+ * @param dstDpid destination DPID
+ * @param dstPortNo destination port number
+ * @param namespace namespace to create this object
+ */
+ public KVLink(final Long srcDpid, final Long srcPortNo,
+ final Long dstDpid, final Long dstPortNo,
+ final String namespace) {
+ super(DataStoreClient.getClient()
+ .getTable(namespace + LINK_TABLE_SUFFIX),
+ getLinkID(srcDpid, srcPortNo, dstDpid, dstPortNo),
+ namespace);
src = new SwitchPort(srcDpid, srcPortNo);
dst = new SwitchPort(dstDpid, dstPortNo);
@@ -113,61 +182,139 @@
}
/**
- * Get an instance from Key.
+ * Gets an instance from LinkID in default namespace.
*
- * @param key
+ * @param key LinkID
* @return KVLink instance
* @note You need to call `read()` to get the DB content.
*/
public static KVLink createFromKey(final byte[] key) {
+ return createFromKey(key, DEFAULT_NAMESPACE);
+ }
+
+ /**
+ * Gets an instance from LinkID in specified namespace.
+ *
+ * @param key LinkID
+ * @param namespace namespace to create this object in
+ * @return KVLink instance
+ * @note You need to call `read()` to get the DB content.
+ */
+ public static KVLink createFromKey(final byte[] key, final String namespace) {
long[] linkTuple = getLinkTupleFromKey(key);
- return new KVLink(linkTuple[0], linkTuple[1], linkTuple[2],
- linkTuple[3]);
+ return new KVLink(linkTuple[0], linkTuple[1],
+ linkTuple[2], linkTuple[3],
+ namespace);
}
+ /**
+ * Gets all the Links in default namespace.
+ *
+ * @return Links
+ */
public static Iterable<KVLink> getAllLinks() {
- return new LinkEnumerator();
+ return getAllLinks(DEFAULT_NAMESPACE);
}
+ /**
+ * Gets all the Links in specified namespace.
+ *
+ * @param namespace namespace to iterate over
+ * @return Links
+ */
+ public static Iterable<KVLink> getAllLinks(final String namespace) {
+ return new LinkEnumerator(namespace);
+ }
+
+ /**
+ * Utility class to provide Iterable interface.
+ */
public static class LinkEnumerator implements Iterable<KVLink> {
+ private final String namespace;
+
+ /**
+ * Constructor to iterate Links in specified namespace.
+ *
+ * @param namespace namespace to iterate through
+ */
+ public LinkEnumerator(final String namespace) {
+ this.namespace = namespace;
+ }
+
@Override
public Iterator<KVLink> iterator() {
- return new LinkIterator();
+ return new LinkIterator(namespace);
}
}
+ /**
+ * Utility class to provide Iterator over all the Link objects.
+ */
public static class LinkIterator extends AbstractObjectIterator<KVLink> {
- public LinkIterator() {
- super(DataStoreClient.getClient().getTable(GLOBAL_LINK_TABLE_NAME));
+ /**
+ * Constructor to create an iterator to iterate all the Links
+ * in specified namespace.
+ *
+ * @param namespace namespace to iterate through
+ */
+ public LinkIterator(final String namespace) {
+ super(DataStoreClient.getClient()
+ .getTable(namespace + LINK_TABLE_SUFFIX),
+ namespace);
}
@Override
public KVLink next() {
IKVEntry o = enumerator.next();
- KVLink e = KVLink.createFromKey(o.getKey());
+ KVLink e = KVLink.createFromKey(o.getKey(), namespace);
e.deserialize(o.getValue(), o.getVersion());
return e;
}
}
+ /**
+ * Gets the status.
+ *
+ * @return status
+ */
public STATUS getStatus() {
return status;
}
+ /**
+ * Sets the status.
+ *
+ * @param status new status
+ */
public void setStatus(final STATUS status) {
this.status = status;
}
+ /**
+ * Gets the source SwitchPort object.
+ *
+ * @return source SwitchPort object
+ */
public SwitchPort getSrc() {
return src;
}
+ /**
+ * Gets the destination SwitchPort object.
+ *
+ * @return destination SwitchPort object
+ */
public SwitchPort getDst() {
return dst;
}
+ /**
+ * Gets the LinkID of this object.
+ *
+ * @return LinkID
+ */
public byte[] getId() {
return getKey();
}
diff --git a/src/main/java/net/onrc/onos/core/datastore/topology/KVPort.java b/src/main/java/net/onrc/onos/core/datastore/topology/KVPort.java
index c0894c1..d166566 100644
--- a/src/main/java/net/onrc/onos/core/datastore/topology/KVPort.java
+++ b/src/main/java/net/onrc/onos/core/datastore/topology/KVPort.java
@@ -44,9 +44,12 @@
}
};
- public static final String GLOBAL_PORT_TABLE_NAME = "G:Port";
+ static final String PORT_TABLE_SUFFIX = ":Port";
// must not re-order enum members, ordinal will be sent over wire
+ /**
+ * Status.
+ */
public enum STATUS {
INACTIVE, ACTIVE;
}
@@ -56,14 +59,33 @@
private STATUS status;
+ /**
+ * Generate a PortID from port pair (dpid, number).
+ *
+ * @param dpid DPID of a switch it reside on.
+ * @param number port number of this
+ * @return PortID
+ */
public static byte[] getPortID(final Long dpid, final Long number) {
return PortEvent.getPortID(dpid, number).array();
}
+ /**
+ * Gets the port pair from PortID.
+ *
+ * @param key PortID
+ * @return port pair (dpid, number)
+ */
public static long[] getPortPairFromKey(final byte[] key) {
return getPortPairFromKey(ByteBuffer.wrap(key));
}
+ /**
+ * Gets the port pair from PortID.
+ *
+ * @param keyBuf PortID
+ * @return port pair (dpid, number)
+ */
public static long[] getPortPairFromKey(final ByteBuffer keyBuf) {
if (keyBuf.getChar() != 'S') {
throw new IllegalArgumentException("Invalid Port key:" + keyBuf
@@ -82,20 +104,47 @@
}
+ /**
+ * Gets the port number from PortID.
+ *
+ * @param key PortID
+ * @return port number
+ */
public static long getDpidFromKey(final byte[] key) {
return getPortPairFromKey(key)[0];
}
+ /**
+ * Gets the dpid of an switch from PortID.
+ *
+ * @param key PortID
+ * @return dpid
+ */
public static long getNumberFromKey(final byte[] key) {
return getPortPairFromKey(key)[1];
}
- // FIXME specify DPID,number here, or Should caller specify the key it self?
- // In other words, should layer above have the control of the ID?
+ /**
+ * KVPort constructor for default namespace.
+ *
+ * @param dpid DPID of the switch this port is on
+ * @param number port number of this port
+ */
public KVPort(final Long dpid, final Long number) {
- super(DataStoreClient.getClient().getTable(GLOBAL_PORT_TABLE_NAME), getPortID(dpid, number));
+ this(dpid, number, DEFAULT_NAMESPACE);
+ }
- // TODO Auto-generated constructor stub
+ /**
+ * KVPort constructor for specified namespace.
+ *
+ * @param dpid DPID of the switch this port is on
+ * @param number port number of this port
+ * @param namespace namespace to create this object
+ */
+ public KVPort(final Long dpid, final Long number, final String namespace) {
+ super(DataStoreClient.getClient()
+ .getTable(namespace + PORT_TABLE_SUFFIX),
+ getPortID(dpid, number), namespace);
this.dpid = dpid;
this.number = number;
@@ -103,60 +152,136 @@
}
/**
- * Get an instance from Key.
+ * Gets an instance from PortID in default namespace.
*
- * @param key
- * @return KVPort instance
+ * @param key PortID
+ * @return {@link KVPort} instance
* @note You need to call `read()` to get the DB content.
*/
public static KVPort createFromKey(final byte[] key) {
+ return createFromKey(key, DEFAULT_NAMESPACE);
+ }
+
+ /**
+ * Gets an instance from PortID in specified namespace.
+ *
+ * @param key PortID
+ * @param namespace namespace to create this object.
+ * @return {@link KVPort} instance
+ * @note You need to call `read()` to get the DB content.
+ */
+ public static KVPort createFromKey(final byte[] key, final String namespace) {
long[] pair = getPortPairFromKey(key);
- return new KVPort(pair[0], pair[1]);
+ return new KVPort(pair[0], pair[1], namespace);
}
+ /**
+ * Gets all the Ports in default namespace.
+ *
+ * @return Ports
+ */
public static Iterable<KVPort> getAllPorts() {
- return new PortEnumerator();
+ return getAllPorts(DEFAULT_NAMESPACE);
}
+ /**
+ * Gets all the Ports in specified namespace.
+ *
+ * @param namespace namespace to iterate over
+ * @return Ports
+ */
+ public static Iterable<KVPort> getAllPorts(final String namespace) {
+ return new PortEnumerator(namespace);
+ }
+
+ /**
+ * Utility class to provide Iterable interface.
+ */
public static class PortEnumerator implements Iterable<KVPort> {
+ private final String namespace;
+
+ /**
+ * Constructor to iterate Ports in specified namespace.
+ *
+ * @param namespace namespace to iterate through
+ */
+ public PortEnumerator(final String namespace) {
+ this.namespace = namespace;
+ }
+
@Override
public Iterator<KVPort> iterator() {
- return new PortIterator();
+ return new PortIterator(namespace);
}
}
+ /**
+ * Utility class to provide Iterator over all the Port objects.
+ */
public static class PortIterator extends AbstractObjectIterator<KVPort> {
- public PortIterator() {
- super(DataStoreClient.getClient().getTable(GLOBAL_PORT_TABLE_NAME));
+ /**
+ * Constructor to create an iterator to iterate all the Ports
+ * in specified namespace.
+ *
+ * @param namespace namespace to iterate through
+ */
+ public PortIterator(final String namespace) {
+ super(DataStoreClient.getClient()
+ .getTable(namespace + PORT_TABLE_SUFFIX), namespace);
}
@Override
public KVPort next() {
IKVEntry o = enumerator.next();
- KVPort e = KVPort.createFromKey(o.getKey());
+ KVPort e = KVPort.createFromKey(o.getKey(), namespace);
e.deserialize(o.getValue(), o.getVersion());
return e;
}
}
+ /**
+ * Gets the status.
+ *
+ * @return status
+ */
public STATUS getStatus() {
return status;
}
+ /**
+ * Sets the status.
+ *
+ * @param status new status
+ */
public void setStatus(final STATUS status) {
this.status = status;
}
+ /**
+ * Gets the DPID of the switch this port is on.
+ *
+ * @return DPID of the switch this port is on
+ */
public Long getDpid() {
return dpid;
}
+ /**
+ * Gets the port number of this port.
+ *
+ * @return port number of this port
+ */
public Long getNumber() {
return number;
}
+ /**
+ * Gets the PortID.
+ *
+ * @return PortID
+ */
public byte[] getId() {
return getKey();
}
diff --git a/src/main/java/net/onrc/onos/core/datastore/topology/KVSwitch.java b/src/main/java/net/onrc/onos/core/datastore/topology/KVSwitch.java
index a38e17d..aed08be 100644
--- a/src/main/java/net/onrc/onos/core/datastore/topology/KVSwitch.java
+++ b/src/main/java/net/onrc/onos/core/datastore/topology/KVSwitch.java
@@ -43,9 +43,12 @@
}
};
- public static final String GLOBAL_SWITCH_TABLE_NAME = "G:Switch";
+ static final String SWITCH_TABLE_SUFFIX = ":Switch";
// must not re-order enum members, ordinal will be sent over wire
+ /**
+ * Status.
+ */
public enum STATUS {
INACTIVE, ACTIVE;
}
@@ -53,14 +56,32 @@
private final Long dpid;
private STATUS status;
+ /**
+ * Generate a SwitchID from dpid.
+ *
+ * @param dpid dpid of the switch
+ * @return SwitchID
+ */
public static byte[] getSwitchID(final Long dpid) {
return SwitchEvent.getSwitchID(dpid).array();
}
+ /**
+ * Gets the DPID from SwitchID.
+ *
+ * @param key SwitchID
+ * @return dpid
+ */
public static long getDpidFromKey(final byte[] key) {
return getDpidFromKey(ByteBuffer.wrap(key));
}
+ /**
+ * Gets the DPID from SwitchID.
+ *
+ * @param keyBuf SwitchID
+ * @return dpid
+ */
public static long getDpidFromKey(final ByteBuffer keyBuf) {
if (keyBuf.getChar() != 'S') {
throw new IllegalArgumentException("Invalid Switch key");
@@ -68,65 +89,154 @@
return keyBuf.getLong();
}
- // FIXME specify DPID here, or Should caller specify the key it self?
- // In other words, should layer above have the control of the ID?
+ // FIXME Should the parameter be DPID here, or should caller specify the key?
+ // Should layer above have the control of the ID computation/generation?
+ /**
+ * KVSwitch constructor for default namespace.
+ *
+ * @param dpid dpid of this switch
+ */
public KVSwitch(final Long dpid) {
- super(DataStoreClient.getClient().getTable(GLOBAL_SWITCH_TABLE_NAME), getSwitchID(dpid));
-
- this.dpid = dpid;
- this.status = STATUS.INACTIVE;
+ this(dpid, KVObject.DEFAULT_NAMESPACE);
}
/**
- * Get an instance from Key.
+ * KVSwitch constructor for specified namespace.
*
- * @param key
- * @return KVSwitch instance
+ * @param dpid dpid of this switch
+ * @param namespace namespace to create this object
+ */
+ public KVSwitch(final Long dpid, final String namespace) {
+ super(DataStoreClient.getClient()
+ .getTable(namespace + SWITCH_TABLE_SUFFIX),
+ getSwitchID(dpid), namespace);
+
+ this.dpid = dpid;
+ this.status = STATUS.INACTIVE;
+ // may need to store namespace here or at KVObject.
+ }
+
+ /**
+ * Gets an instance from SwitchID in default namespace.
+ *
+ * @param key SwitchID
+ * @return {@link KVSwitch} instance
* @note You need to call `read()` to get the DB content.
*/
public static KVSwitch createFromKey(final byte[] key) {
return new KVSwitch(getDpidFromKey(key));
}
- public static Iterable<KVSwitch> getAllSwitches() {
- return new SwitchEnumerator();
+ /**
+ * Gets an instance from SwitchID in specified namespace.
+ *
+ * @param key SwitchID
+ * @param namespace namespace to create this object
+ * @return {@link KVSwitch} instance
+ * @note You need to call `read()` to get the DB content.
+ */
+ public static KVSwitch createFromKey(final byte[] key, final String namespace) {
+ return new KVSwitch(getDpidFromKey(key), namespace);
}
+ /**
+ * Gets all the switches in default namespace.
+ *
+ * @return All the {@link KVSwitch}
+ */
+ public static Iterable<KVSwitch> getAllSwitches() {
+ return getAllSwitches(DEFAULT_NAMESPACE);
+ }
+
+ /**
+ * Gets all the switches in specified namespace.
+ *
+ * @param namespace Namespace to get all switches.
+ * @return All the {@link KVSwitch}
+ */
+ public static Iterable<KVSwitch> getAllSwitches(final String namespace) {
+ return new SwitchEnumerator(namespace);
+ }
+
+ /**
+ * Utility class to provide Iterable interface.
+ */
public static class SwitchEnumerator implements Iterable<KVSwitch> {
+ private final String namespace;
+
+ /**
+ * Constructor to iterate Ports in specified namespace.
+ *
+ * @param namespace namespace to iterate through
+ */
+ public SwitchEnumerator(final String namespace) {
+ this.namespace = namespace;
+ }
+
@Override
public Iterator<KVSwitch> iterator() {
- return new SwitchIterator();
+ return new SwitchIterator(namespace);
}
}
+ /**
+ * Utility class to provide Iterator over all the Switch objects.
+ */
public static class SwitchIterator extends AbstractObjectIterator<KVSwitch> {
- public SwitchIterator() {
- super(DataStoreClient.getClient().getTable(GLOBAL_SWITCH_TABLE_NAME));
+ /**
+ * Constructor to create an iterator to iterate all the Switches
+ * in specified namespace.
+ *
+ * @param namespace namespace to iterate through
+ */
+ public SwitchIterator(final String namespace) {
+ super(DataStoreClient.getClient()
+ .getTable(namespace + SWITCH_TABLE_SUFFIX), namespace);
}
@Override
public KVSwitch next() {
IKVEntry o = enumerator.next();
- KVSwitch e = KVSwitch.createFromKey(o.getKey());
+ KVSwitch e = KVSwitch.createFromKey(o.getKey(), namespace);
e.deserialize(o.getValue(), o.getVersion());
return e;
}
}
+ /**
+ * Gets the status.
+ *
+ * @return status
+ */
public STATUS getStatus() {
return status;
}
+ /**
+ * Sets the status.
+ *
+ * @param status new status
+ */
public void setStatus(final STATUS status) {
this.status = status;
}
+ /**
+ * Gets the DPID of the switch this port is on.
+ *
+ * @return DPID of the switch this port is on
+ */
public Long getDpid() {
return dpid;
}
+ /**
+ * Gets the SwitchID.
+ *
+ * @return SwitchID
+ */
public byte[] getId() {
return getKey();
}
diff --git a/src/main/java/net/onrc/onos/core/datastore/utils/KVObject.java b/src/main/java/net/onrc/onos/core/datastore/utils/KVObject.java
index aad0310..15666b2 100644
--- a/src/main/java/net/onrc/onos/core/datastore/utils/KVObject.java
+++ b/src/main/java/net/onrc/onos/core/datastore/utils/KVObject.java
@@ -44,12 +44,18 @@
}
};
+ /**
+ * Default namespace name for KVObject.
+ */
+ public static final String DEFAULT_NAMESPACE = "G";
+
+ private final String namespace;
private final IKVTable table;
private final byte[] key;
/**
- * serialized value version stored on data store or
- * {@link IKVTable.getVersionNonexistant()} if is a new object.
+ * Serialized-value version stored on data store or
+ * {@link IKVTable.getVersionNonexistant()} if it is a new object.
*/
private long version;
@@ -58,17 +64,36 @@
*/
private Map<Object, Object> propertyMap;
- public KVObject(final IKVTable table, final byte[] key) {
- this(table, key, null, table.getVersionNonexistant());
+ /**
+ * KVObject constructor without value secified for specified namespace.
+ *
+ * @param table table where this object resides
+ * @param key Key or ID of this object
+ * @param namespace namespace where this object resides
+ */
+ public KVObject(final IKVTable table, final byte[] key, final String namespace) {
+ this(table, key, null, table.getVersionNonexistant(), namespace);
}
- public KVObject(final IKVTable table, final byte[] key, final byte[] value, final long version) {
+ /**
+ * KVObject constructor for specified namespace.
+ *
+ * @param table table where this object resides
+ * @param key Key or ID of this object
+ * @param value Value blob representation of this object
+ * @param version version of this Value blob
+ * @param namespace namespace where this object resides
+ */
+ public KVObject(final IKVTable table, final byte[] key,
+ final byte[] value, final long version,
+ final String namespace) {
if (table == null) {
throw new IllegalArgumentException("table cannot be null");
}
if (key == null) {
throw new IllegalArgumentException("key cannot be null");
}
+ this.namespace = namespace;
this.table = table;
this.key = key.clone();
this.version = version;
@@ -79,24 +104,47 @@
}
}
- protected static KVObject createFromKey(final byte[] key) {
- // Equivalent of this method is expected to be implemented by SubClasses
- throw new UnsupportedOperationException(
- "createFromKey() is not expected to be called for RCObject");
+ /**
+ * Gets the namespace which this object reside.
+ *
+ * @return the namespace which this object reside
+ */
+ public String getNamespace() {
+ return namespace;
}
+ /**
+ * Gets the table where this object resides.
+ *
+ * @return table where this object resides
+ */
public IKVTable getTable() {
return table;
}
+ /**
+ * Gets the table ID of the table where this object resides.
+ *
+ * @return the table ID of the table where this object resides
+ */
public IKVTableID getTableId() {
return table.getTableId();
}
+ /**
+ * Gets the Key or ID of this object.
+ *
+ * @return Key or ID of this object
+ */
public byte[] getKey() {
return key.clone();
}
+ /**
+ * Gets the version of this objects value blob.
+ *
+ * @return version of this objects value blob
+ */
public long getVersion() {
return version;
}
@@ -111,6 +159,12 @@
return this.propertyMap;
}
+ /**
+ * Replaces the user-defined object properties.
+ *
+ * @param newMap new user-defined object properties
+ * @return old user-defined object properties
+ */
protected Map<Object, Object> replacePropertyMap(final Map<Object, Object> newMap) {
Map<Object, Object> oldMap = this.propertyMap;
this.propertyMap = newMap;
@@ -128,10 +182,16 @@
return serializePropertyMap(DEFAULT_KRYO.get(), this.propertyMap);
}
+ /**
+ * Serialize user-defined object properties.
+ *
+ * @param kryo {@link Kryo} instance to use for serialization
+ * @param propMap user-defined object properties
+ * @return serialized byte array
+ */
protected byte[] serializePropertyMap(final Kryo kryo,
final Map<Object, Object> propMap) {
-
// value
byte[] rcTemp = new byte[1024 * 1024];
Output output = new Output(rcTemp);
@@ -183,7 +243,15 @@
return true;
}
- protected <T extends Map<?, ?>> T deserializePropertyMap(final Kryo kryo,
+ /**
+ * Deserialize user-defined object properties.
+ *
+ * @param kryo {@link Kryo} instance to use for deserialization
+ * @param bytes serialized byte array
+ * @param type Type of user-defined object properties
+ * @return user-defined object properties
+ */
+ protected static <T extends Map<?, ?>> T deserializePropertyMap(final Kryo kryo,
final byte[] bytes, final Class<T> type) {
if (bytes == null || bytes.length == 0) {
@@ -433,9 +501,16 @@
Iterator<E> {
protected Iterator<IKVEntry> enumerator;
+ protected final String namespace;
+ @Deprecated
public AbstractObjectIterator(final IKVTable table) {
+ this(table, DEFAULT_NAMESPACE);
+ }
+
+ public AbstractObjectIterator(final IKVTable table, final String namespace) {
this.enumerator = table.getAllEntries().iterator();
+ this.namespace = namespace;
}
@Override
@@ -452,6 +527,9 @@
// return obj;
// }
+ /**
+ * Not implemented.
+ */
@Deprecated
@Override
public void remove() {
diff --git a/src/test/java/net/onrc/onos/core/datastore/topology/KVSwitchTest.java b/src/test/java/net/onrc/onos/core/datastore/topology/KVSwitchTest.java
index 607e0fb..fac33f5 100644
--- a/src/test/java/net/onrc/onos/core/datastore/topology/KVSwitchTest.java
+++ b/src/test/java/net/onrc/onos/core/datastore/topology/KVSwitchTest.java
@@ -8,6 +8,7 @@
import java.util.HashMap;
import java.util.Map;
+import java.util.UUID;
import net.onrc.onos.core.datastore.DataStoreClient;
import net.onrc.onos.core.datastore.IKVTable;
@@ -31,14 +32,16 @@
System.setProperty("net.onrc.onos.core.datastore.hazelcast.client.attemptLimit", "0");
}
+ private static final String namespace = UUID.randomUUID().toString();
+
IKVTable switchTable;
static final Long DPID1 = 0x1L;
KVSwitch sw1;
@Before
public void setUp() throws Exception {
- switchTable = DataStoreClient.getClient().getTable(KVSwitch.GLOBAL_SWITCH_TABLE_NAME);
- sw1 = new KVSwitch(DPID1);
+ switchTable = DataStoreClient.getClient().getTable(namespace + KVSwitch.SWITCH_TABLE_SUFFIX);
+ sw1 = new KVSwitch(DPID1, namespace);
}
@After
@@ -48,7 +51,7 @@
public KVSwitch assertSwitchInDataStore(final Long dpid, final STATUS status) {
try {
- final KVSwitch sw = new KVSwitch(dpid);
+ final KVSwitch sw = new KVSwitch(dpid, namespace);
sw.read();
assertNotEquals(DataStoreClient.getClient().getVersionNonexistant(), sw.getVersion());
assertEquals(dpid, sw.getDpid());
@@ -61,7 +64,7 @@
}
public void assertSwitchNotInDataStore(final Long dpid) {
- final KVSwitch sw = new KVSwitch(dpid);
+ final KVSwitch sw = new KVSwitch(dpid, namespace);
try {
sw.read();
fail("Switch was not supposed to be there in datastore");
@@ -75,14 +78,14 @@
final int NUM_SWITCHES = 100;
Map<Long, KVSwitch> expected = new HashMap<>();
for (long dpid = 1; dpid <= NUM_SWITCHES; ++dpid) {
- KVSwitch sw = new KVSwitch(dpid);
+ KVSwitch sw = new KVSwitch(dpid, namespace);
sw.setStatus(STATUS.ACTIVE);
sw.create();
assertNotEquals(DataStoreClient.getClient().getVersionNonexistant(), sw.getVersion());
expected.put(sw.getDpid(), sw);
}
- Iterable<KVSwitch> switches = KVSwitch.getAllSwitches();
+ Iterable<KVSwitch> switches = KVSwitch.getAllSwitches(namespace);
for (KVSwitch sw : switches) {
KVSwitch expectedSw = expected.get(sw.getDpid());
@@ -110,7 +113,7 @@
@Test(expected = ObjectExistsException.class)
public void testCreateFailAlreadyExist() throws ObjectExistsException {
// setup pre-existing Switch
- KVSwitch sw = new KVSwitch(DPID1);
+ KVSwitch sw = new KVSwitch(DPID1, namespace);
sw.forceCreate();
assertNotEquals(DataStoreClient.getClient().getVersionNonexistant(), sw.getVersion());
assertSwitchInDataStore(DPID1, STATUS.INACTIVE);
@@ -123,7 +126,7 @@
@Test
public void testForceCreate() {
// setup pre-existing Switch
- KVSwitch sw = new KVSwitch(DPID1);
+ KVSwitch sw = new KVSwitch(DPID1, namespace);
sw.forceCreate();
assertNotEquals(DataStoreClient.getClient().getVersionNonexistant(), sw.getVersion());
assertSwitchInDataStore(DPID1, STATUS.INACTIVE);
@@ -141,7 +144,7 @@
@Test
public void testRead() throws ObjectDoesntExistException {
// setup pre-existing Switch
- KVSwitch sw = new KVSwitch(DPID1);
+ KVSwitch sw = new KVSwitch(DPID1, namespace);
sw.setStatus(STATUS.ACTIVE);
sw.forceCreate();
assertNotEquals(DataStoreClient.getClient().getVersionNonexistant(), sw.getVersion());
@@ -164,7 +167,7 @@
@Test
public void testUpdate() throws ObjectDoesntExistException, WrongVersionException {
// setup pre-existing Switch
- KVSwitch sw = new KVSwitch(DPID1);
+ KVSwitch sw = new KVSwitch(DPID1, namespace);
sw.setStatus(STATUS.ACTIVE);
sw.forceCreate();
assertNotEquals(DataStoreClient.getClient().getVersionNonexistant(), sw.getVersion());
@@ -185,7 +188,7 @@
@Test
public void testDelete() throws ObjectDoesntExistException, WrongVersionException {
// setup pre-existing Switch
- KVSwitch sw = new KVSwitch(DPID1);
+ KVSwitch sw = new KVSwitch(DPID1, namespace);
sw.setStatus(STATUS.ACTIVE);
sw.forceCreate();
assertNotEquals(DataStoreClient.getClient().getVersionNonexistant(), sw.getVersion());
@@ -205,7 +208,7 @@
@Test
public void testForceDelete() {
// setup pre-existing Switch
- KVSwitch sw = new KVSwitch(DPID1);
+ KVSwitch sw = new KVSwitch(DPID1, namespace);
sw.setStatus(STATUS.ACTIVE);
sw.forceCreate();
assertNotEquals(DataStoreClient.getClient().getVersionNonexistant(), sw.getVersion());
diff --git a/src/test/java/net/onrc/onos/core/datastore/topology/KVTopologyTest.java b/src/test/java/net/onrc/onos/core/datastore/topology/KVTopologyTest.java
index 7921099..ff37995 100644
--- a/src/test/java/net/onrc/onos/core/datastore/topology/KVTopologyTest.java
+++ b/src/test/java/net/onrc/onos/core/datastore/topology/KVTopologyTest.java
@@ -17,6 +17,7 @@
import java.util.List;
import java.util.Map;
import java.util.TreeMap;
+import java.util.UUID;
import net.onrc.onos.core.datastore.DataStoreClient;
import net.onrc.onos.core.datastore.IKVClient;
@@ -57,19 +58,21 @@
private static final Long DPID1 = 0x1L;
+ private static final String namespace = UUID.randomUUID().toString();
+
@Before
@After
public void wipeTopology() throws Exception {
- IKVTable switchTable = DataStoreClient.getClient().getTable(KVSwitch.GLOBAL_SWITCH_TABLE_NAME);
+ IKVTable switchTable = DataStoreClient.getClient().getTable(namespace + KVSwitch.SWITCH_TABLE_SUFFIX);
DataStoreClient.getClient().dropTable(switchTable);
- IKVTable portTable = DataStoreClient.getClient().getTable(KVPort.GLOBAL_PORT_TABLE_NAME);
+ IKVTable portTable = DataStoreClient.getClient().getTable(namespace + KVPort.PORT_TABLE_SUFFIX);
DataStoreClient.getClient().dropTable(portTable);
- IKVTable linkTable = DataStoreClient.getClient().getTable(KVLink.GLOBAL_LINK_TABLE_NAME);
+ IKVTable linkTable = DataStoreClient.getClient().getTable(namespace + KVLink.LINK_TABLE_SUFFIX);
DataStoreClient.getClient().dropTable(linkTable);
- IKVTable deviceTable = DataStoreClient.getClient().getTable(KVDevice.GLOBAL_DEVICE_TABLE_NAME);
+ IKVTable deviceTable = DataStoreClient.getClient().getTable(namespace + KVDevice.DEVICE_TABLE_SUFFIX);
DataStoreClient.getClient().dropTable(deviceTable);
}
@@ -77,7 +80,7 @@
public void basicSwitchTest() {
// create switch 0x1
try {
- KVSwitch sw = new KVSwitch(DPID1);
+ KVSwitch sw = new KVSwitch(DPID1, namespace);
sw.setStatus(KVSwitch.STATUS.ACTIVE);
sw.create();
assertNotEquals(VERSION_NONEXISTENT, sw.getVersion());
@@ -89,7 +92,7 @@
}
// read switch 0x1
- KVSwitch swRead = new KVSwitch(DPID1);
+ KVSwitch swRead = new KVSwitch(DPID1, namespace);
try {
swRead.read();
assertNotEquals(VERSION_NONEXISTENT, swRead.getVersion());
@@ -113,7 +116,7 @@
}
// read 0x1 again and delete
- KVSwitch swRead2 = new KVSwitch(DPID1);
+ KVSwitch swRead2 = new KVSwitch(DPID1, namespace);
try {
swRead2.read();
assertNotEquals(VERSION_NONEXISTENT, swRead2.getVersion());
@@ -133,7 +136,7 @@
}
// make sure 0x1 is deleted
- KVObject swRead3 = new KVSwitch(DPID1);
+ KVObject swRead3 = new KVSwitch(DPID1, namespace);
try {
swRead3.read();
fail(swRead3 + " was supposed to be deleted, but read succeed");
@@ -155,7 +158,7 @@
// d1 - s1p1 - s1 - s1p2 - s2p1 - s2 - s2p2
- KVSwitch sw1 = new KVSwitch(DPID1);
+ KVSwitch sw1 = new KVSwitch(DPID1, namespace);
sw1.setStatus(KVSwitch.STATUS.ACTIVE);
try {
sw1.create();
@@ -167,9 +170,9 @@
fail("Switch creation failed " + e);
}
- KVPort sw1p1 = new KVPort(DPID1, SW1_PORTNO1);
+ KVPort sw1p1 = new KVPort(DPID1, SW1_PORTNO1, namespace);
sw1p1.setStatus(KVPort.STATUS.ACTIVE);
- KVPort sw1p2 = new KVPort(DPID1, SW1_PORTNO2);
+ KVPort sw1p2 = new KVPort(DPID1, SW1_PORTNO2, namespace);
sw1p2.setStatus(KVPort.STATUS.ACTIVE);
try {
sw1p1.create();
@@ -198,7 +201,7 @@
fail("Switch update failed " + e);
}
- KVDevice d1 = new KVDevice(DEVICE1_MAC_SW1P1);
+ KVDevice d1 = new KVDevice(DEVICE1_MAC_SW1P1, namespace);
d1.addPortId(sw1p1.getId());
try {
@@ -222,14 +225,14 @@
fail("Device creation failed " + e);
}
- KVSwitch sw2 = new KVSwitch(DPID2);
+ KVSwitch sw2 = new KVSwitch(DPID2, namespace);
sw2.setStatus(KVSwitch.STATUS.ACTIVE);
- KVPort sw2p1 = new KVPort(DPID2, SW2_PORTNO1);
+ KVPort sw2p1 = new KVPort(DPID2, SW2_PORTNO1, namespace);
sw2p1.setStatus(KVPort.STATUS.ACTIVE);
- KVPort sw2p2 = new KVPort(DPID2, SW2_PORTNO2);
+ KVPort sw2p2 = new KVPort(DPID2, SW2_PORTNO2, namespace);
sw2p2.setStatus(KVPort.STATUS.ACTIVE);
- KVDevice d2 = new KVDevice(DEVICE2_MAC_SW2P2);
+ KVDevice d2 = new KVDevice(DEVICE2_MAC_SW2P2, namespace);
d2.addPortId(sw2p2.getId());
IKVClient client = DataStoreClient.getClient();
@@ -263,7 +266,7 @@
assertArrayEquals(sw2p2.getId(), d2.getAllPortIds().iterator().next());
}
- KVLink l1 = new KVLink(DPID1, SW1_PORTNO2, DPID2, SW2_PORTNO1);
+ KVLink l1 = new KVLink(DPID1, SW1_PORTNO2, DPID2, SW2_PORTNO1, namespace);
l1.setStatus(KVLink.STATUS.ACTIVE);
try {
@@ -299,7 +302,7 @@
private static void topologyWalk() {
- Iterable<KVSwitch> swIt = KVSwitch.getAllSwitches();
+ Iterable<KVSwitch> swIt = KVSwitch.getAllSwitches(namespace);
List<Long> switchesExpected = new ArrayList<>(Arrays.asList(DPID1, DPID2));
System.out.println("Enumerating Switches start");
@@ -313,7 +316,7 @@
}
System.out.println("Enumerating Switches end");
- KVSwitch sw1 = new KVSwitch(DPID1);
+ KVSwitch sw1 = new KVSwitch(DPID1, namespace);
try {
sw1.read();
assertNotEquals(VERSION_NONEXISTENT, sw1.getVersion());
@@ -324,7 +327,7 @@
fail("Reading switch failed " + e);
}
- KVSwitch sw2 = new KVSwitch(DPID2);
+ KVSwitch sw2 = new KVSwitch(DPID2, namespace);
if (KVObject.multiRead(Arrays.asList(sw2))) {
fail("Failed to read switch " + sw2);
} else {
@@ -341,7 +344,7 @@
put(DPID2, new ArrayList<>(Arrays.asList(SW2_PORTNO1, SW2_PORTNO2)));
} };
- for (KVPort port : KVPort.getAllPorts()) {
+ for (KVPort port : KVPort.getAllPorts(namespace)) {
System.out.println(port + " @ " + port.getVersion());
assertNotEquals(VERSION_NONEXISTENT, port.getVersion());
assertEquals(KVPort.STATUS.ACTIVE, port.getStatus());
@@ -360,7 +363,7 @@
put(DEVICE2_MAC_SW2P2, KVPort.getPortID(DPID2, SW2_PORTNO2));
} };
- for (KVDevice device : KVDevice.getAllDevices()) {
+ for (KVDevice device : KVDevice.getAllDevices(namespace)) {
System.out.println(device + " @ " + device.getVersion());
assertNotEquals(VERSION_NONEXISTENT, device.getVersion());
@@ -369,7 +372,7 @@
expectedDevice.remove(device.getMac());
}
- for (KVLink link : KVLink.getAllLinks()) {
+ for (KVLink link : KVLink.getAllLinks(namespace)) {
System.out.println(link + " @ " + link.getVersion());
assertNotEquals(VERSION_NONEXISTENT, link.getVersion());
@@ -385,7 +388,7 @@
private static void topologyDelete() {
- for (KVSwitch sw : KVSwitch.getAllSwitches()) {
+ for (KVSwitch sw : KVSwitch.getAllSwitches(namespace)) {
try {
sw.read();
sw.delete();
@@ -396,7 +399,7 @@
}
}
- for (KVPort p : KVPort.getAllPorts()) {
+ for (KVPort p : KVPort.getAllPorts(namespace)) {
try {
p.read();
p.delete();
@@ -407,12 +410,12 @@
}
}
- for (KVDevice d : KVDevice.getAllDevices()) {
+ for (KVDevice d : KVDevice.getAllDevices(namespace)) {
d.forceDelete();
assertNotEquals(VERSION_NONEXISTENT, d.getVersion());
}
- for (KVLink l : KVLink.getAllLinks()) {
+ for (KVLink l : KVLink.getAllLinks(namespace)) {
try {
l.read();
l.delete();