aboutsummaryrefslogtreecommitdiffstats
path: root/framework/src/onos/core/api/src
diff options
context:
space:
mode:
Diffstat (limited to 'framework/src/onos/core/api/src')
-rw-r--r--framework/src/onos/core/api/src/main/java/org/onosproject/net/AbstractDescription.java15
-rw-r--r--framework/src/onos/core/api/src/main/java/org/onosproject/net/DefaultHost.java3
-rw-r--r--framework/src/onos/core/api/src/main/java/org/onosproject/net/behaviour/BridgeConfig.java9
-rw-r--r--framework/src/onos/core/api/src/main/java/org/onosproject/net/config/Config.java143
-rw-r--r--framework/src/onos/core/api/src/main/java/org/onosproject/net/config/NetworkConfigService.java4
-rw-r--r--framework/src/onos/core/api/src/main/java/org/onosproject/net/config/NetworkConfigStore.java2
-rw-r--r--framework/src/onos/core/api/src/main/java/org/onosproject/net/device/DefaultDeviceDescription.java25
-rw-r--r--framework/src/onos/core/api/src/main/java/org/onosproject/net/device/DefaultPortDescription.java22
-rw-r--r--framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/DefaultTrafficSelector.java21
-rw-r--r--framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/TrafficSelector.java33
-rw-r--r--framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/criteria/Criteria.java28
-rw-r--r--framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/instructions/ExtensionType.java3
-rw-r--r--framework/src/onos/core/api/src/main/java/org/onosproject/net/host/DefaultHostDescription.java21
-rw-r--r--framework/src/onos/core/api/src/main/java/org/onosproject/net/host/HostEvent.java29
-rw-r--r--framework/src/onos/core/api/src/main/java/org/onosproject/net/link/DefaultLinkDescription.java20
-rw-r--r--framework/src/onos/core/api/src/main/java/org/onosproject/net/newresource/ResourcePath.java168
-rw-r--r--framework/src/onos/core/api/src/test/java/org/onosproject/net/newresource/ResourceAllocationTest.java6
-rw-r--r--framework/src/onos/core/api/src/test/java/org/onosproject/net/newresource/ResourcePathTest.java32
-rw-r--r--framework/src/onos/core/api/src/test/java/org/onosproject/store/service/TestEventuallyConsistentMap.java3
19 files changed, 519 insertions, 68 deletions
diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/AbstractDescription.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/AbstractDescription.java
index d81b83cc..34042dad 100644
--- a/framework/src/onos/core/api/src/main/java/org/onosproject/net/AbstractDescription.java
+++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/AbstractDescription.java
@@ -16,6 +16,7 @@
package org.onosproject.net;
import static com.google.common.base.Preconditions.checkArgument;
+import com.google.common.base.Objects;
/**
* Base implementation of an annotated model description.
@@ -46,4 +47,18 @@ public abstract class AbstractDescription implements Annotated {
return annotations;
}
+ @Override
+ public int hashCode() {
+ return Objects.hashCode(annotations);
+ }
+
+ @Override
+ public boolean equals(Object object) {
+ if (object instanceof AbstractDescription) {
+ AbstractDescription that = (AbstractDescription) object;
+ return Objects.equal(this.annotations, that.annotations);
+ }
+ return false;
+ }
+
}
diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/DefaultHost.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/DefaultHost.java
index 2877701e..557fa5c1 100644
--- a/framework/src/onos/core/api/src/main/java/org/onosproject/net/DefaultHost.java
+++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/DefaultHost.java
@@ -98,7 +98,8 @@ public class DefaultHost extends AbstractElement implements Host {
return Objects.equals(this.id, other.id) &&
Objects.equals(this.mac, other.mac) &&
Objects.equals(this.vlan, other.vlan) &&
- Objects.equals(this.location, other.location);
+ Objects.equals(this.location, other.location) &&
+ Objects.equals(this.ipAddresses(), other.ipAddresses());
}
return false;
}
diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/behaviour/BridgeConfig.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/behaviour/BridgeConfig.java
index e3d6993c..cf7bed6d 100644
--- a/framework/src/onos/core/api/src/main/java/org/onosproject/net/behaviour/BridgeConfig.java
+++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/behaviour/BridgeConfig.java
@@ -36,6 +36,15 @@ public interface BridgeConfig extends HandlerBehaviour {
void addBridge(BridgeName bridgeName);
/**
+ * Adds a bridge with given bridge name, dpid and exPortName.
+ *
+ * @param bridgeName bridge name
+ * @param dpid dpid
+ * @param exPortName external port name
+ */
+ void addBridge(BridgeName bridgeName, String dpid, String exPortName);
+
+ /**
* Adds a bridge with given bridge name and dpid, and sets the controller
* of the bridge with given controllers.
*
diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/config/Config.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/config/Config.java
index 5cdc0c12..3757d327 100644
--- a/framework/src/onos/core/api/src/main/java/org/onosproject/net/config/Config.java
+++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/config/Config.java
@@ -20,10 +20,15 @@ import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ArrayNode;
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.google.common.annotations.Beta;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Iterators;
import com.google.common.collect.Lists;
+import org.onlab.packet.IpAddress;
+import org.onlab.packet.MacAddress;
import java.util.Collection;
import java.util.List;
+import java.util.Set;
import java.util.function.Function;
import static com.google.common.base.Preconditions.checkNotNull;
@@ -51,6 +56,21 @@ public abstract class Config<S> {
protected ConfigApplyDelegate delegate;
/**
+ * Indicator of whether a configuration JSON field is required.
+ */
+ public enum FieldPresence {
+ /**
+ * Signifies that config field is an optional one.
+ */
+ OPTIONAL,
+
+ /**
+ * Signifies that config field is mandatory.
+ */
+ MANDATORY
+ }
+
+ /**
* Initializes the configuration behaviour with necessary context.
*
* @param subject configuration subject
@@ -71,6 +91,29 @@ public abstract class Config<S> {
}
/**
+ * Indicates whether or not the backing JSON node contains valid data.
+ * <p>
+ * Default implementation returns true.
+ * Subclasses are expected to override this with their own validation.
+ * </p>
+ *
+ * @return true if the data is valid; false otherwise
+ */
+ public boolean isValid() {
+ // TODO: figure out what assertions could be made in the base class
+ // NOTE: The thought is to have none, but instead to provide a set
+ // of predicates to allow configs to test validity of present fields,
+ // e.g.:
+ // isString(path)
+ // isBoolean(path)
+ // isNumber(path, [min, max])
+ // isDecimal(path, [min, max])
+ // isMacAddress(path)
+ // isIpAddress(path)
+ return true;
+ }
+
+ /**
* Returns the specific subject to which this configuration pertains.
*
* @return configuration subject
@@ -309,4 +352,104 @@ public abstract class Config<S> {
return this;
}
+ /**
+ * Indicates whether only the specified fields are present in the backing JSON.
+ *
+ * @param allowedFields allowed field names
+ * @return true if all allowedFields are present; false otherwise
+ */
+ protected boolean hasOnlyFields(String... allowedFields) {
+ Set<String> fields = ImmutableSet.copyOf(allowedFields);
+ return !Iterators.any(object.fieldNames(), f -> !fields.contains(f));
+ }
+
+ /**
+ * Indicates whether the specified field holds a valid MAC address.
+ *
+ * @param field JSON field name
+ * @param presence specifies if field is optional or mandatory
+ * @return true if valid; false otherwise
+ * @throws IllegalArgumentException if field is present, but not valid MAC
+ */
+ protected boolean isMacAddress(String field, FieldPresence presence) {
+ JsonNode node = object.path(field);
+ return isValid(node, presence, node.isTextual() &&
+ MacAddress.valueOf(node.asText()) != null);
+ }
+
+ /**
+ * Indicates whether the specified field holds a valid IP address.
+ *
+ * @param field JSON field name
+ * @param presence specifies if field is optional or mandatory
+ * @return true if valid; false otherwise
+ * @throws IllegalArgumentException if field is present, but not valid IP
+ */
+ protected boolean isIpAddress(String field, FieldPresence presence) {
+ JsonNode node = object.path(field);
+ return isValid(node, presence, node.isTextual() &&
+ IpAddress.valueOf(node.asText()) != null);
+ }
+
+ /**
+ * Indicates whether the specified field holds a valid string value.
+ *
+ * @param field JSON field name
+ * @param presence specifies if field is optional or mandatory
+ * @param pattern optional regex pattern
+ * @return true if valid; false otherwise
+ * @throws IllegalArgumentException if field is present, but not valid MAC
+ */
+ protected boolean isString(String field, FieldPresence presence, String... pattern) {
+ JsonNode node = object.path(field);
+ return isValid(node, presence, node.isTextual() &&
+ (pattern.length > 0 && node.asText().matches(pattern[0]) || pattern.length < 1));
+ }
+
+ /**
+ * Indicates whether the specified field holds a valid number.
+ *
+ * @param field JSON field name
+ * @param presence specifies if field is optional or mandatory
+ * @param minMax optional min/max values
+ * @return true if valid; false otherwise
+ * @throws IllegalArgumentException if field is present, but not valid
+ */
+ protected boolean isNumber(String field, FieldPresence presence, long... minMax) {
+ JsonNode node = object.path(field);
+ return isValid(node, presence, (node.isLong() || node.isInt()) &&
+ (minMax.length > 0 && minMax[0] <= node.asLong() || minMax.length < 1) &&
+ (minMax.length > 1 && minMax[1] > node.asLong() || minMax.length < 2));
+ }
+
+ /**
+ * Indicates whether the specified field holds a valid decimal number.
+ *
+ * @param field JSON field name
+ * @param presence specifies if field is optional or mandatory
+ * @param minMax optional min/max values
+ * @return true if valid; false otherwise
+ * @throws IllegalArgumentException if field is present, but not valid
+ */
+ protected boolean isDecimal(String field, FieldPresence presence, double... minMax) {
+ JsonNode node = object.path(field);
+ return isValid(node, presence, (node.isDouble() || node.isFloat()) &&
+ (minMax.length > 0 && minMax[0] <= node.asDouble() || minMax.length < 1) &&
+ (minMax.length > 1 && minMax[1] > node.asDouble() || minMax.length < 2));
+ }
+
+ /**
+ * Indicates whether the node is present and of correct value or not
+ * mandatory and absent.
+ *
+ * @param node JSON node
+ * @param presence specifies if field is optional or mandatory
+ * @param correctValue true if the value is correct
+ * @return true if the field is as expected
+ */
+ private boolean isValid(JsonNode node, FieldPresence presence, boolean correctValue) {
+ boolean isMandatory = presence == FieldPresence.MANDATORY;
+ return isMandatory && correctValue || !isMandatory && !node.isNull() || correctValue;
+ }
+
}
diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/config/NetworkConfigService.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/config/NetworkConfigService.java
index 8eb69a45..f1b22c41 100644
--- a/framework/src/onos/core/api/src/main/java/org/onosproject/net/config/NetworkConfigService.java
+++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/config/NetworkConfigService.java
@@ -119,7 +119,7 @@ public interface NetworkConfigService
/**
* Applies configuration for the specified subject and configuration
- * class using the raw JSON object. If configuration already exists, it
+ * class using the raw JSON node. If configuration already exists, it
* will be updated.
*
* @param subject configuration subject
@@ -128,6 +128,8 @@ public interface NetworkConfigService
* @param <S> type of subject
* @param <C> type of configuration
* @return configuration or null if one is not available
+ * @throws IllegalArgumentException if the supplied JSON node contains
+ * invalid data
*/
<S, C extends Config<S>> C applyConfig(S subject, Class<C> configClass,
JsonNode json);
diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/config/NetworkConfigStore.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/config/NetworkConfigStore.java
index 9dd66e8d..9be4b120 100644
--- a/framework/src/onos/core/api/src/main/java/org/onosproject/net/config/NetworkConfigStore.java
+++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/config/NetworkConfigStore.java
@@ -113,6 +113,8 @@ public interface NetworkConfigStore extends Store<NetworkConfigEvent, NetworkCon
* @param <S> type of subject
* @param <C> type of configuration
* @return configuration object
+ * @throws IllegalArgumentException if the supplied JSON node contains
+ * invalid data
*/
<S, C extends Config<S>> C applyConfig(S subject, Class<C> configClass,
JsonNode json);
diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/device/DefaultDeviceDescription.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/device/DefaultDeviceDescription.java
index 0fcc800d..9074792c 100644
--- a/framework/src/onos/core/api/src/main/java/org/onosproject/net/device/DefaultDeviceDescription.java
+++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/device/DefaultDeviceDescription.java
@@ -24,6 +24,7 @@ import java.net.URI;
import static com.google.common.base.MoreObjects.toStringHelper;
import static com.google.common.base.Preconditions.checkNotNull;
import static org.onosproject.net.Device.Type;
+import com.google.common.base.Objects;
/**
* Default implementation of immutable device description entity.
@@ -132,6 +133,30 @@ public class DefaultDeviceDescription extends AbstractDescription
.toString();
}
+ @Override
+ public int hashCode() {
+ return Objects.hashCode(super.hashCode(), uri, type, manufacturer,
+ hwVersion, swVersion, serialNumber, chassisId);
+ }
+
+ @Override
+ public boolean equals(Object object) {
+ if (object instanceof DefaultDeviceDescription) {
+ if (!super.equals(object)) {
+ return false;
+ }
+ DefaultDeviceDescription that = (DefaultDeviceDescription) object;
+ return Objects.equal(this.uri, that.uri)
+ && Objects.equal(this.type, that.type)
+ && Objects.equal(this.manufacturer, that.manufacturer)
+ && Objects.equal(this.hwVersion, that.hwVersion)
+ && Objects.equal(this.swVersion, that.swVersion)
+ && Objects.equal(this.serialNumber, that.serialNumber)
+ && Objects.equal(this.chassisId, that.chassisId);
+ }
+ return false;
+ }
+
// default constructor for serialization
private DefaultDeviceDescription() {
this.uri = null;
diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/device/DefaultPortDescription.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/device/DefaultPortDescription.java
index 572d201c..d62e932c 100644
--- a/framework/src/onos/core/api/src/main/java/org/onosproject/net/device/DefaultPortDescription.java
+++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/device/DefaultPortDescription.java
@@ -21,6 +21,7 @@ import org.onosproject.net.PortNumber;
import org.onosproject.net.SparseAnnotations;
import static org.onosproject.net.Port.Type;
+import com.google.common.base.Objects;
/**
* Default implementation of immutable port description.
@@ -117,4 +118,25 @@ public class DefaultPortDescription extends AbstractDescription
.toString();
}
+ @Override
+ public int hashCode() {
+ return Objects.hashCode(super.hashCode(), number, isEnabled, type,
+ portSpeed);
+ }
+
+ @Override
+ public boolean equals(Object object) {
+ if (object != null && getClass() == object.getClass()) {
+ if (!super.equals(object)) {
+ return false;
+ }
+ DefaultPortDescription that = (DefaultPortDescription) object;
+ return Objects.equal(this.number, that.number)
+ && Objects.equal(this.isEnabled, that.isEnabled)
+ && Objects.equal(this.type, that.type)
+ && Objects.equal(this.portSpeed, that.portSpeed);
+ }
+ return false;
+ }
+
}
diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/DefaultTrafficSelector.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/DefaultTrafficSelector.java
index 453a7648..a842d600 100644
--- a/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/DefaultTrafficSelector.java
+++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/DefaultTrafficSelector.java
@@ -23,6 +23,7 @@ import java.util.Objects;
import java.util.Set;
import java.util.TreeSet;
+import org.onlab.packet.Ip4Address;
import org.onlab.packet.Ip6Address;
import org.onlab.packet.IpPrefix;
import org.onlab.packet.MacAddress;
@@ -353,6 +354,26 @@ public final class DefaultTrafficSelector implements TrafficSelector {
}
@Override
+ public Builder matchArpTpa(Ip4Address addr) {
+ return add(Criteria.matchArpTpa(addr));
+ }
+
+ @Override
+ public Builder matchArpSpa(Ip4Address addr) {
+ return add(Criteria.matchArpSpa(addr));
+ }
+
+ @Override
+ public Builder matchArpTha(MacAddress addr) {
+ return add(Criteria.matchArpTha(addr));
+ }
+
+ @Override
+ public Builder matchArpSha(MacAddress addr) {
+ return add(Criteria.matchArpSha(addr));
+ }
+
+ @Override
public TrafficSelector build() {
return new DefaultTrafficSelector(ImmutableSet.copyOf(selector.values()));
}
diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/TrafficSelector.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/TrafficSelector.java
index 1286ffc1..9fe88d5a 100644
--- a/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/TrafficSelector.java
+++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/TrafficSelector.java
@@ -17,6 +17,7 @@ package org.onosproject.net.flow;
import java.util.Set;
+import org.onlab.packet.Ip4Address;
import org.onlab.packet.Ip6Address;
import org.onlab.packet.IpPrefix;
import org.onlab.packet.MacAddress;
@@ -386,6 +387,38 @@ public interface TrafficSelector {
Builder matchIPv6ExthdrFlags(short exthdrFlags);
/**
+ * Matches a arp IPv4 destination address.
+ *
+ * @param addr a arp IPv4 destination address
+ * @return a selection builder
+ */
+ Builder matchArpTpa(Ip4Address addr);
+
+ /**
+ * Matches a arp IPv4 source address.
+ *
+ * @param addr a arp IPv4 source address
+ * @return a selection builder
+ */
+ Builder matchArpSpa(Ip4Address addr);
+
+ /**
+ * Matches a arp_eth_dst address.
+ *
+ * @param addr a arp_eth_dst address
+ * @return a selection builder
+ */
+ Builder matchArpTha(MacAddress addr);
+
+ /**
+ * Matches a arp_eth_src address.
+ *
+ * @param addr a arp_eth_src address
+ * @return a selection builder
+ */
+ Builder matchArpSha(MacAddress addr);
+
+ /**
* Builds an immutable traffic selector.
*
* @return traffic selector
diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/criteria/Criteria.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/criteria/Criteria.java
index bc1a094c..554b8e74 100644
--- a/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/criteria/Criteria.java
+++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/criteria/Criteria.java
@@ -510,9 +510,9 @@ public final class Criteria {
}
/**
- * Creates a match on IPv4 source field using the specified value.
+ * Creates a match on IPv4 destination field using the specified value.
*
- * @param ip ipv4 source value
+ * @param ip ipv4 destination value
* @return match criterion
*/
public static Criterion matchArpTpa(Ip4Address ip) {
@@ -520,15 +520,35 @@ public final class Criteria {
}
/**
- * Creates a match on MAC source field using the specified value.
+ * Creates a match on IPv4 source field using the specified value.
*
- * @param mac MAC source value
+ * @param ip ipv4 source value
+ * @return match criterion
+ */
+ public static Criterion matchArpSpa(Ip4Address ip) {
+ return new ArpPaCriterion(ip, Type.ARP_SPA);
+ }
+
+ /**
+ * Creates a match on MAC destination field using the specified value.
+ *
+ * @param mac MAC destination value
* @return match criterion
*/
public static Criterion matchArpTha(MacAddress mac) {
return new ArpHaCriterion(mac, Type.ARP_THA);
}
+ /**
+ * Creates a match on MAC source field using the specified value.
+ *
+ * @param mac MAC source value
+ * @return match criterion
+ */
+ public static Criterion matchArpSha(MacAddress mac) {
+ return new ArpHaCriterion(mac, Type.ARP_SHA);
+ }
+
public static Criterion dummy() {
return new DummyCriterion();
}
diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/instructions/ExtensionType.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/instructions/ExtensionType.java
index 747a85b5..3e1cb75c 100644
--- a/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/instructions/ExtensionType.java
+++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/instructions/ExtensionType.java
@@ -32,7 +32,8 @@ public final class ExtensionType {
*/
public enum ExtensionTypes {
// TODO fix type numbers to include experimenter id
- NICIRA_SET_TUNNEL_DST(31);
+ NICIRA_SET_TUNNEL_DST(31),
+ NICIRA_RESUBMIT(32);
private ExtensionType type;
diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/host/DefaultHostDescription.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/host/DefaultHostDescription.java
index 1f05197a..307a6078 100644
--- a/framework/src/onos/core/api/src/main/java/org/onosproject/net/host/DefaultHostDescription.java
+++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/host/DefaultHostDescription.java
@@ -28,6 +28,7 @@ import org.onlab.packet.VlanId;
import com.google.common.collect.ImmutableSet;
import static com.google.common.base.MoreObjects.toStringHelper;
+import com.google.common.base.Objects;
/**
* Default implementation of an immutable host description.
@@ -119,4 +120,24 @@ public class DefaultHostDescription extends AbstractDescription
.toString();
}
+ @Override
+ public int hashCode() {
+ return Objects.hashCode(super.hashCode(), mac, vlan, location, ip);
+ }
+
+ @Override
+ public boolean equals(Object object) {
+ if (object != null && getClass() == object.getClass()) {
+ if (!super.equals(object)) {
+ return false;
+ }
+ DefaultHostDescription that = (DefaultHostDescription) object;
+ return Objects.equal(this.mac, that.mac)
+ && Objects.equal(this.vlan, that.vlan)
+ && Objects.equal(this.location, that.location)
+ && Objects.equal(this.ip, that.ip);
+ }
+ return false;
+ }
+
}
diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/host/HostEvent.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/host/HostEvent.java
index 58ac0bb8..92824cf8 100644
--- a/framework/src/onos/core/api/src/main/java/org/onosproject/net/host/HostEvent.java
+++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/host/HostEvent.java
@@ -18,7 +18,6 @@ package org.onosproject.net.host;
import org.joda.time.LocalDateTime;
import org.onosproject.event.AbstractEvent;
import org.onosproject.net.Host;
-import org.onosproject.net.HostLocation;
import static com.google.common.base.MoreObjects.toStringHelper;
@@ -52,7 +51,7 @@ public class HostEvent extends AbstractEvent<HostEvent.Type, Host> {
HOST_MOVED
}
- private HostLocation prevLocation;
+ private Host prevSubject;
/**
* Creates an event of a given type and for the specified host and the
@@ -77,25 +76,29 @@ public class HostEvent extends AbstractEvent<HostEvent.Type, Host> {
}
/**
- * Creates an event with HOST_MOVED type along with the previous location
- * of the host.
+ * Creates an event with previous subject.
*
+ * The previous subject is ignored if the type is not moved or updated
+ *
+ * @param type host event type
* @param host event host subject
- * @param prevLocation previous location of the host
+ * @param prevSubject previous host subject
*/
- public HostEvent(Host host, HostLocation prevLocation) {
- super(Type.HOST_MOVED, host);
- this.prevLocation = prevLocation;
+ public HostEvent(Type type, Host host, Host prevSubject) {
+ super(type, host);
+ if (type == Type.HOST_MOVED || type == Type.HOST_UPDATED) {
+ this.prevSubject = prevSubject;
+ }
}
/**
- * Gets the previous location information in this host event.
+ * Gets the previous subject in this host event.
*
- * @return the previous location, or null if previous location is not
+ * @return the previous subject, or null if previous subject is not
* specified.
*/
- public HostLocation prevLocation() {
- return this.prevLocation;
+ public Host prevSubject() {
+ return this.prevSubject;
}
@Override
@@ -104,7 +107,7 @@ public class HostEvent extends AbstractEvent<HostEvent.Type, Host> {
.add("time", new LocalDateTime(time()))
.add("type", type())
.add("subject", subject())
- .add("prevLocation", prevLocation())
+ .add("prevSubject", prevSubject())
.toString();
}
}
diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/link/DefaultLinkDescription.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/link/DefaultLinkDescription.java
index 891eb65d..cba17640 100644
--- a/framework/src/onos/core/api/src/main/java/org/onosproject/net/link/DefaultLinkDescription.java
+++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/link/DefaultLinkDescription.java
@@ -20,6 +20,7 @@ import org.onosproject.net.AbstractDescription;
import org.onosproject.net.ConnectPoint;
import org.onosproject.net.Link;
import org.onosproject.net.SparseAnnotations;
+import com.google.common.base.Objects;
/**
* Default implementation of immutable link description entity.
@@ -70,4 +71,23 @@ public class DefaultLinkDescription extends AbstractDescription
.add("type", type()).toString();
}
+ @Override
+ public int hashCode() {
+ return Objects.hashCode(super.hashCode(), src, dst, type);
+ }
+
+ @Override
+ public boolean equals(Object object) {
+ if (object != null && getClass() == object.getClass()) {
+ if (!super.equals(object)) {
+ return false;
+ }
+ DefaultLinkDescription that = (DefaultLinkDescription) object;
+ return Objects.equal(this.src, that.src)
+ && Objects.equal(this.dst, that.dst)
+ && Objects.equal(this.type, that.type);
+ }
+ return false;
+ }
+
}
diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/newresource/ResourcePath.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/newresource/ResourcePath.java
index 3aa29f6b..d87682a9 100644
--- a/framework/src/onos/core/api/src/main/java/org/onosproject/net/newresource/ResourcePath.java
+++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/newresource/ResourcePath.java
@@ -19,12 +19,14 @@ import com.google.common.annotations.Beta;
import com.google.common.base.MoreObjects;
import com.google.common.collect.ImmutableList;
-import java.util.Arrays;
+import java.util.LinkedList;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
+import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkNotNull;
+import static com.google.common.base.Preconditions.checkState;
/**
* An object that is used to locate a resource in a network.
@@ -32,32 +34,45 @@ import static com.google.common.base.Preconditions.checkNotNull;
* of elementary resources that are not globally identifiable. A ResourcePath can be a globally
* unique resource identifier.
*
+ * Two types of resource are considered. One is discrete type and the other is continuous type.
+ * Discrete type resource is a resource whose amount is measured as a discrete unit. VLAN ID and
+ * MPLS label are examples of discrete type resource. Continuous type resource is a resource whose
+ * amount is measured as a continuous value. Bandwidth is an example of continuous type resource.
+ * A double value is associated with a continuous type value.
+ *
* Users of this class must keep the semantics of resources regarding the hierarchical structure.
* For example, resource path, Link:1/VLAN ID:100, is valid, but resource path, VLAN ID:100/Link:1
* is not valid because a link is not a sub-component of a VLAN ID.
*/
@Beta
-public final class ResourcePath {
+public abstract class ResourcePath {
- private final List<Object> resources;
+ private final Discrete parent;
+ private final Object last;
- public static final ResourcePath ROOT = new ResourcePath(ImmutableList.of());
+ public static final Discrete ROOT = new Discrete();
- public static ResourcePath child(ResourcePath parent, Object child) {
- ImmutableList<Object> components = ImmutableList.builder()
- .addAll(parent.components())
- .add(child)
- .build();
- return new ResourcePath(components);
+ /**
+ * Creates an resource path which represents a discrete-type resource from the specified components.
+ *
+ * @param components components of the path. The order represents hierarchical structure of the resource.
+ */
+ public static ResourcePath discrete(Object... components) {
+ if (components.length == 0) {
+ return ROOT;
+ } else {
+ return new Discrete(ImmutableList.copyOf(components));
+ }
}
/**
- * Creates an resource path from the specified components.
+ * Creates an resource path which represents a continuous-type resource from the specified components.
*
+ * @param value amount of the resource
* @param components components of the path. The order represents hierarchical structure of the resource.
*/
- public ResourcePath(Object... components) {
- this(Arrays.asList(components));
+ public static ResourcePath continuous(double value, Object... components) {
+ return new Continuous(ImmutableList.copyOf(components), value);
}
/**
@@ -65,15 +80,37 @@ public final class ResourcePath {
*
* @param components components of the path. The order represents hierarchical structure of the resource.
*/
- public ResourcePath(List<Object> components) {
+ ResourcePath(List<Object> components) {
checkNotNull(components);
+ checkArgument(!components.isEmpty());
+
+ LinkedList<Object> children = new LinkedList<>(components);
+ this.last = children.pollLast();
+ if (children.isEmpty()) {
+ this.parent = ROOT;
+ } else {
+ this.parent = new Discrete(children);
+ }
+ }
- this.resources = ImmutableList.copyOf(components);
+ /**
+ * Creates an resource path from the specified parent and child.
+ *
+ * @param parent the parent of this resource
+ * @param last a child of the parent
+ */
+ ResourcePath(Discrete parent, Object last) {
+ checkNotNull(parent);
+ checkNotNull(last);
+
+ this.parent = parent;
+ this.last = last;
}
// for serialization
private ResourcePath() {
- this.resources = null;
+ this.parent = null;
+ this.last = null;
}
/**
@@ -82,7 +119,15 @@ public final class ResourcePath {
* @return the components of this resource path
*/
public List<Object> components() {
- return resources;
+ LinkedList<Object> components = new LinkedList<>();
+
+ ResourcePath current = this;
+ while (current.parent().isPresent()) {
+ components.addFirst(current.last);
+ current = current.parent;
+ }
+
+ return components;
}
/**
@@ -92,21 +137,20 @@ public final class ResourcePath {
* @return the parent resource path of this instance.
* If there is no parent, empty instance will be returned.
*/
- public Optional<ResourcePath> parent() {
- if (!isRoot()) {
- return Optional.of(new ResourcePath(resources.subList(0, resources.size() - 1)));
- }
+ public Optional<Discrete> parent() {
+ return Optional.ofNullable(parent);
+ }
+
+ public ResourcePath child(Object child) {
+ checkState(this instanceof Discrete);
- return Optional.empty();
+ return new Discrete((Discrete) this, child);
}
- /**
- * Returns true if the path represents root.
- *
- * @return true if the path represents root, false otherwise.
- */
- public boolean isRoot() {
- return resources.size() == 0;
+ public ResourcePath child(Object child, double value) {
+ checkState(this instanceof Discrete);
+
+ return new Continuous((Discrete) this, child, value);
}
/**
@@ -115,14 +159,13 @@ public final class ResourcePath {
* @return the last component of this instance.
* The return value is equal to the last object of {@code components()}.
*/
- public Object lastComponent() {
- int last = resources.size() - 1;
- return resources.get(last);
+ public Object last() {
+ return last;
}
@Override
public int hashCode() {
- return resources.hashCode();
+ return Objects.hash(this.parent, this.last);
}
@Override
@@ -134,13 +177,68 @@ public final class ResourcePath {
return false;
}
final ResourcePath that = (ResourcePath) obj;
- return Objects.equals(this.resources, that.resources);
+ return Objects.equals(this.parent, that.parent)
+ && Objects.equals(this.last, that.last);
}
@Override
public String toString() {
return MoreObjects.toStringHelper(this)
- .add("resources", resources)
+ .add("parent", parent)
+ .add("last", last)
.toString();
}
+
+ /**
+ * Represents a resource path which specifies a resource which can be measured
+ * as a discrete unit. A VLAN ID and a MPLS label of a link are examples of the resource.
+ * <p>
+ * Note: This class is exposed to the public, but intended to be used in the resource API
+ * implementation only. It is not for resource API user.
+ * </p>
+ */
+ public static final class Discrete extends ResourcePath {
+ private Discrete() {
+ super();
+ }
+
+ private Discrete(List<Object> components) {
+ super(components);
+ }
+
+ private Discrete(Discrete parent, Object last) {
+ super(parent, last);
+ }
+ }
+
+ /**
+ * Represents a resource path which specifies a resource which can be measured
+ * as continuous value. Bandwidth of a link is an example of the resource.
+ * <p>
+ * Note: This class is exposed to the public, but intended to be used in the resource API
+ * implementation only. It is not for resource API user.
+ */
+ public static final class Continuous extends ResourcePath {
+ // Note: value is not taken into account for equality
+ private final double value;
+
+ private Continuous(List<Object> components, double value) {
+ super(components);
+ this.value = value;
+ }
+
+ public Continuous(Discrete parent, Object last, double value) {
+ super(parent, last);
+ this.value = value;
+ }
+
+ /**
+ * Returns the value of the resource amount.
+ *
+ * @return the value of the resource amount
+ */
+ public double value() {
+ return value;
+ }
+ }
}
diff --git a/framework/src/onos/core/api/src/test/java/org/onosproject/net/newresource/ResourceAllocationTest.java b/framework/src/onos/core/api/src/test/java/org/onosproject/net/newresource/ResourceAllocationTest.java
index a84927a0..5f448221 100644
--- a/framework/src/onos/core/api/src/test/java/org/onosproject/net/newresource/ResourceAllocationTest.java
+++ b/framework/src/onos/core/api/src/test/java/org/onosproject/net/newresource/ResourceAllocationTest.java
@@ -38,9 +38,9 @@ public class ResourceAllocationTest {
@Test
public void testEquals() {
- ResourceAllocation alloc1 = new ResourceAllocation(new ResourcePath(LK1, VLAN1), IID1);
- ResourceAllocation sameAsAlloc1 = new ResourceAllocation(new ResourcePath(LK1, VLAN1), IID1);
- ResourceAllocation alloc2 = new ResourceAllocation(new ResourcePath(LK2, VLAN1), IID1);
+ ResourceAllocation alloc1 = new ResourceAllocation(ResourcePath.discrete(LK1, VLAN1), IID1);
+ ResourceAllocation sameAsAlloc1 = new ResourceAllocation(ResourcePath.discrete(LK1, VLAN1), IID1);
+ ResourceAllocation alloc2 = new ResourceAllocation(ResourcePath.discrete(LK2, VLAN1), IID1);
new EqualsTester()
.addEqualityGroup(alloc1, sameAsAlloc1)
diff --git a/framework/src/onos/core/api/src/test/java/org/onosproject/net/newresource/ResourcePathTest.java b/framework/src/onos/core/api/src/test/java/org/onosproject/net/newresource/ResourcePathTest.java
index 4a8886a4..35dcf1ec 100644
--- a/framework/src/onos/core/api/src/test/java/org/onosproject/net/newresource/ResourcePathTest.java
+++ b/framework/src/onos/core/api/src/test/java/org/onosproject/net/newresource/ResourcePathTest.java
@@ -18,6 +18,7 @@ package org.onosproject.net.newresource;
import com.google.common.testing.EqualsTester;
import org.junit.Test;
import org.onlab.packet.VlanId;
+import org.onlab.util.Bandwidth;
import org.onosproject.net.ConnectPoint;
import org.onosproject.net.DeviceId;
import org.onosproject.net.LinkKey;
@@ -25,6 +26,7 @@ import org.onosproject.net.PortNumber;
import java.util.Optional;
+import static org.hamcrest.Matchers.contains;
import static org.hamcrest.Matchers.is;
import static org.junit.Assert.assertThat;
@@ -36,37 +38,49 @@ public class ResourcePathTest {
private static final ConnectPoint CP1_1 = new ConnectPoint(D1, P1);
private static final ConnectPoint CP2_1 = new ConnectPoint(D2, P1);
private static final VlanId VLAN1 = VlanId.vlanId((short) 100);
+ private static final Bandwidth BW1 = Bandwidth.gbps(2);
+ private static final Bandwidth BW2 = Bandwidth.gbps(1);
@Test
public void testEquals() {
- ResourcePath resource1 = new ResourcePath(LinkKey.linkKey(CP1_1, CP2_1), VLAN1);
- ResourcePath sameAsResource1 = new ResourcePath(LinkKey.linkKey(CP1_1, CP2_1), VLAN1);
- ResourcePath resource2 = new ResourcePath(LinkKey.linkKey(CP2_1, CP1_1), VLAN1);
+ ResourcePath resource1 = ResourcePath.discrete(LinkKey.linkKey(CP1_1, CP2_1), VLAN1);
+ ResourcePath sameAsResource1 = ResourcePath.discrete(LinkKey.linkKey(CP1_1, CP2_1), VLAN1);
+ ResourcePath resource2 = ResourcePath.discrete(LinkKey.linkKey(CP2_1, CP1_1), VLAN1);
+ ResourcePath resource3 = ResourcePath.continuous(BW1.bps(), LinkKey.linkKey(CP1_1, CP2_1), BW1);
+ ResourcePath sameAsResource3 = ResourcePath.continuous(BW2.bps(), LinkKey.linkKey(CP1_1, CP2_1), BW1);
new EqualsTester()
.addEqualityGroup(resource1, sameAsResource1)
.addEqualityGroup(resource2)
+ .addEqualityGroup(resource3, sameAsResource3) // this is intentional
.testEquals();
}
@Test
public void testCreateWithZeroComponent() {
- ResourcePath path = new ResourcePath();
+ ResourcePath path = ResourcePath.discrete();
assertThat(path, is(ResourcePath.ROOT));
}
@Test
+ public void testComponents() {
+ ResourcePath port = ResourcePath.discrete(D1, P1);
+
+ assertThat(port.components(), contains(D1, P1));
+ }
+
+ @Test
public void testThereIsParent() {
- ResourcePath path = new ResourcePath(LinkKey.linkKey(CP1_1, CP2_1), VLAN1);
- ResourcePath parent = new ResourcePath(LinkKey.linkKey(CP1_1, CP2_1));
+ ResourcePath path = ResourcePath.discrete(LinkKey.linkKey(CP1_1, CP2_1), VLAN1);
+ ResourcePath parent = ResourcePath.discrete(LinkKey.linkKey(CP1_1, CP2_1));
assertThat(path.parent(), is(Optional.of(parent)));
}
@Test
public void testNoParent() {
- ResourcePath path = new ResourcePath(LinkKey.linkKey(CP1_1, CP2_1));
+ ResourcePath path = ResourcePath.discrete(LinkKey.linkKey(CP1_1, CP2_1));
assertThat(path.parent(), is(Optional.of(ResourcePath.ROOT)));
}
@@ -74,9 +88,9 @@ public class ResourcePathTest {
@Test
public void testBase() {
LinkKey linkKey = LinkKey.linkKey(CP1_1, CP2_1);
- ResourcePath path = new ResourcePath(linkKey);
+ ResourcePath path = ResourcePath.discrete(linkKey);
- LinkKey child = (LinkKey) path.lastComponent();
+ LinkKey child = (LinkKey) path.last();
assertThat(child, is(linkKey));
}
}
diff --git a/framework/src/onos/core/api/src/test/java/org/onosproject/store/service/TestEventuallyConsistentMap.java b/framework/src/onos/core/api/src/test/java/org/onosproject/store/service/TestEventuallyConsistentMap.java
index 4f612de2..02462e85 100644
--- a/framework/src/onos/core/api/src/test/java/org/onosproject/store/service/TestEventuallyConsistentMap.java
+++ b/framework/src/onos/core/api/src/test/java/org/onosproject/store/service/TestEventuallyConsistentMap.java
@@ -30,7 +30,8 @@ import org.onlab.util.KryoNamespace;
import org.onosproject.cluster.NodeId;
import org.onosproject.store.Timestamp;
-import static org.onosproject.store.service.EventuallyConsistentMapEvent.Type.*;
+import static org.onosproject.store.service.EventuallyConsistentMapEvent.Type.PUT;
+import static org.onosproject.store.service.EventuallyConsistentMapEvent.Type.REMOVE;
/**
* Testing version of an Eventually Consistent Map.