diff --git a/core/api/src/main/java/org/onlab/onos/net/Annotations.java b/core/api/src/main/java/org/onlab/onos/net/Annotations.java new file mode 100644 index 0000000000..6076172afb --- /dev/null +++ b/core/api/src/main/java/org/onlab/onos/net/Annotations.java @@ -0,0 +1,113 @@ +package org.onlab.onos.net; + +import com.google.common.collect.ImmutableMap; + +import java.util.Map; +import java.util.Objects; +import java.util.Set; + +/** + * Represents a set of simple annotations that can be used to add arbitrary + * attributes to various parts of the data model. + */ +public final class Annotations { + + private final Map map; + + /** + * Creates a new set of annotations using the specified immutable map. + * + * @param map immutable map of key/value pairs + */ + private Annotations(ImmutableMap map) { + this.map = map; + } + + /** + * Creates a new annotations builder. + * + * @return new annotations builder + */ + public static Builder builder() { + return new Builder(); + } + + /** + * Returns the set of keys for available annotations. Note that this set + * includes keys for any attributes tagged for removal. + * + * @return annotation keys + */ + public Set keys() { + return map.keySet(); + } + + /** + * Returns the value of the specified annotation. + * + * @param key annotation key + * @return annotation value + */ + public String value(String key) { + String value = map.get(key); + return Objects.equals(Builder.REMOVED, value) ? null : value; + } + + /** + * Indicates whether the specified key has been tagged as removed. This is + * used to for merging sparse annotation sets. + * + * @param key annotation key + * @return true if the previous annotation has been tagged for removal + */ + public boolean isRemoved(String key) { + return Objects.equals(Builder.REMOVED, map.get(key)); + } + + /** + * Facility for gradually building model annotations. + */ + public static final class Builder { + + private static final String REMOVED = "~rEmOvEd~"; + private final ImmutableMap.Builder builder = ImmutableMap.builder(); + + // Private construction is forbidden. + private Builder() { + } + + /** + * Adds the specified annotation. Any previous value associated with + * the given annotation key will be overwritten. + * + * @param key annotation key + * @param value annotation value + * @return self + */ + public Builder set(String key, String value) { + builder.put(key, value); + return this; + } + + /** + * Adds the specified annotation. Any previous value associated with + * the given annotation key will be tagged for removal. + * + * @param key annotation key + * @return self + */ + public Builder remove(String key) { + builder.put(key, REMOVED); + return this; + } + + /** + * Returns immutable annotations built from the accrued key/values pairs. + * + * @return annotations + */ + public Annotations build() { + return new Annotations(builder.build()); + } + } +} diff --git a/core/api/src/main/java/org/onlab/onos/net/DefaultPort.java b/core/api/src/main/java/org/onlab/onos/net/DefaultPort.java index 534cbe4268..ac574987f0 100644 --- a/core/api/src/main/java/org/onlab/onos/net/DefaultPort.java +++ b/core/api/src/main/java/org/onlab/onos/net/DefaultPort.java @@ -2,12 +2,13 @@ package org.onlab.onos.net; import static com.google.common.base.MoreObjects.toStringHelper; +import java.util.Map; import java.util.Objects; /** * Default port implementation. */ -public class DefaultPort implements Port { +public class DefaultPort extends AbstractAnnotated implements Port { private final Element element; private final PortNumber number; @@ -19,9 +20,13 @@ public class DefaultPort implements Port { * @param element parent network element * @param number port number * @param isEnabled indicator whether the port is up and active + * @param annotations optional key/value annotations */ + @SafeVarargs public DefaultPort(Element element, PortNumber number, - boolean isEnabled) { + boolean isEnabled, + Map... annotations) { + super(annotations); this.element = element; this.number = number; this.isEnabled = isEnabled; diff --git a/core/api/src/main/java/org/onlab/onos/net/Element.java b/core/api/src/main/java/org/onlab/onos/net/Element.java index 5d3969e13e..1c5e22b5e6 100644 --- a/core/api/src/main/java/org/onlab/onos/net/Element.java +++ b/core/api/src/main/java/org/onlab/onos/net/Element.java @@ -3,7 +3,7 @@ package org.onlab.onos.net; /** * Base abstraction of a network element, i.e. an infrastructure device or an end-station host. */ -public interface Element extends Provided { +public interface Element extends Annotated, Provided { /** * Returns the network element identifier. diff --git a/core/api/src/main/java/org/onlab/onos/net/Link.java b/core/api/src/main/java/org/onlab/onos/net/Link.java index 0b60b9c7aa..be2f99bf31 100644 --- a/core/api/src/main/java/org/onlab/onos/net/Link.java +++ b/core/api/src/main/java/org/onlab/onos/net/Link.java @@ -3,7 +3,7 @@ package org.onlab.onos.net; /** * Abstraction of a network infrastructure link. */ -public interface Link extends Provided { +public interface Link extends Annotated, Provided { /** * Coarse representation of the link type. diff --git a/core/api/src/main/java/org/onlab/onos/net/Port.java b/core/api/src/main/java/org/onlab/onos/net/Port.java index 2ebbd15b18..e2da4a177d 100644 --- a/core/api/src/main/java/org/onlab/onos/net/Port.java +++ b/core/api/src/main/java/org/onlab/onos/net/Port.java @@ -4,7 +4,7 @@ package org.onlab.onos.net; /** * Abstraction of a network port. */ -public interface Port { +public interface Port extends Annotated { /** * Returns the port number.