blob: 52304f4058a714d343ef5adc95ab913e09f8ae57 [file] [log] [blame]
Yuta HIGUCHIbf0a8712014-06-30 18:59:46 -07001package net.onrc.onos.core.topology;
2
Pavlin Radoslavov31f85102014-08-15 13:55:44 -07003import java.nio.ByteBuffer;
Yuta HIGUCHIbf0a8712014-06-30 18:59:46 -07004import java.util.Collections;
5import java.util.Map;
6import java.util.Objects;
7import java.util.concurrent.ConcurrentHashMap;
8import java.util.concurrent.ConcurrentMap;
9
Pavlin Radoslavova5637c02014-07-30 15:55:11 -070010import static com.google.common.base.Preconditions.checkNotNull;
Yuta HIGUCHIbf0a8712014-06-30 18:59:46 -070011
Pavlin Radoslavov31f85102014-08-15 13:55:44 -070012import net.onrc.onos.core.util.Dpid;
13
Yuta HIGUCHIbf0a8712014-06-30 18:59:46 -070014/**
15 * Base class for Topology Elements.
16 * <p/>
17 * Self-contained element, it is expected to be used as if it is an immutable
18 * object.
19 *
20 * @param <T> Sub-class' type.
21 * (Required to define a method returning itself's type)
22 */
Pavlin Radoslavov31f85102014-08-15 13:55:44 -070023public abstract class TopologyElement<T extends TopologyElement<T>>
Yuta HIGUCHI1222ac52014-07-09 16:50:28 -070024 implements ITopologyElement, StringAttributes, UpdateStringAttributes {
25
26 // TODO: Where should the attribute names be defined?
27 /**
28 * Attribute name for type.
29 */
30 public static final String TYPE = "type";
31 /**
Pavlin Radoslavov695f8952014-07-23 16:57:01 -070032 * Attribute "type" value representing that the object belongs to Packet
33 * layer.
Yuta HIGUCHI1222ac52014-07-09 16:50:28 -070034 */
Yuta HIGUCHIdbc33122014-07-10 13:32:32 -070035 public static final String TYPE_PACKET_LAYER = "packet";
Yuta HIGUCHI1222ac52014-07-09 16:50:28 -070036 /**
Pavlin Radoslavov695f8952014-07-23 16:57:01 -070037 * Attribute "type" value representing that the object belongs to Optical
38 * layer.
Yuta HIGUCHI1222ac52014-07-09 16:50:28 -070039 */
Yuta HIGUCHIdbc33122014-07-10 13:32:32 -070040 public static final String TYPE_OPTICAL_LAYER = "optical";
Pavlin Radoslavov695f8952014-07-23 16:57:01 -070041 /**
42 * Attribute "type" value representing that the object belongs to all
43 * layers.
44 */
45 public static final String TYPE_ALL_LAYERS = "AllLayers";
Yuta HIGUCHI1222ac52014-07-09 16:50:28 -070046
Praseed Balakrishnan2aa6c0b2014-07-17 11:42:05 -070047 public static final String ELEMENT_CONFIG_STATE = "ConfigState";
48
49 public static final String ELEMENT_ADMIN_STATUS = "AdminStatus";
Yuta HIGUCHIbf0a8712014-06-30 18:59:46 -070050
Praseed Balakrishnanfa21be12014-07-15 14:42:26 -070051 /**
52 * Attribute name for device type.
53 */
54 public static final String ELEMENT_TYPE = "ElementType";
55
Yuta HIGUCHIbf0a8712014-06-30 18:59:46 -070056 private boolean isFrozen = false;
57
58 private ConcurrentMap<String, String> stringAttributes;
59
60
61
62 /**
63 * Default constructor for serializer.
64 */
65 protected TopologyElement() {
66 this.isFrozen = false;
67 this.stringAttributes = new ConcurrentHashMap<>();
68 }
69
70 /**
Yuta HIGUCHI7926ba32014-07-09 11:39:32 -070071 * Creates an unfrozen copy of given Object.
Yuta HIGUCHIbf0a8712014-06-30 18:59:46 -070072 * <p/>
73 * Sub-classes should do a deep-copies if necessary.
74 *
75 * @param original to make copy of.
76 */
77 public TopologyElement(TopologyElement<T> original) {
78 this.isFrozen = false;
79 this.stringAttributes = new ConcurrentHashMap<>(original.stringAttributes);
Praseed Balakrishnan2aa6c0b2014-07-17 11:42:05 -070080
Yuta HIGUCHIbf0a8712014-06-30 18:59:46 -070081 }
82
83
84 /**
85 * Tests if this instance is frozen.
86 *
87 * @return true if frozen.
88 */
89 public boolean isFrozen() {
90 return isFrozen;
91 }
92
93 /**
94 * Freezes this instance to avoid further modifications.
95 *
96 * @return this
97 */
98 @SuppressWarnings("unchecked")
99 public T freeze() {
100 isFrozen = true;
101 return (T) this;
102 }
103
104 @Override
105 public int hashCode() {
106 return stringAttributes.hashCode();
107 }
108
109 /*
110 * (non-Javadoc)
111 * Equality based only on string attributes.
112 *
113 * Subclasses should call super.equals().
114 */
115 @Override
116 public boolean equals(Object obj) {
117 if (this == obj) {
118 return true;
119 }
120 if (obj == null) {
121 return false;
122 }
123 if (getClass() != obj.getClass()) {
124 return false;
125 }
126 @SuppressWarnings("unchecked")
127 TopologyElement<T> other = (TopologyElement<T>) obj;
128 return Objects.equals(stringAttributes, other.stringAttributes);
129 }
130
131 @Override
132 public String getStringAttribute(String attr) {
133 return this.stringAttributes.get(attr);
134 }
135
136 @Override
137 public String getStringAttribute(String attr, String def) {
138 final String v = getStringAttribute(attr);
139 if (v == null) {
140 return def;
141 } else {
142 return v;
143 }
144 }
145
146 @Override
147 public Map<String, String> getAllStringAttributes() {
148 return Collections.unmodifiableMap(this.stringAttributes);
149 }
150
151 @Override
152 public boolean createStringAttribute(String attr, String value) {
153 if (isFrozen) {
154 throw new IllegalStateException("Tried to modify frozen object: " + this);
155 }
Pavlin Radoslavova5637c02014-07-30 15:55:11 -0700156 checkNotNull(value, "attribute value cannot be null");
Yuta HIGUCHIbf0a8712014-06-30 18:59:46 -0700157
158 return this.stringAttributes.putIfAbsent(attr, value) == null;
159 }
160
161 @Override
162 public boolean replaceStringAttribute(String attr, String oldValue, String value) {
163 if (isFrozen) {
164 throw new IllegalStateException("Tried to modify frozen object: " + this);
165 }
Pavlin Radoslavova5637c02014-07-30 15:55:11 -0700166 checkNotNull(value, "attribute value cannot be null");
Yuta HIGUCHIbf0a8712014-06-30 18:59:46 -0700167
168 return this.stringAttributes.replace(attr, oldValue, value);
169 }
170
171 @Override
172 public boolean deleteStringAttribute(String attr, String expectedValue) {
173 if (isFrozen) {
174 throw new IllegalStateException("Tried to modify frozen object: " + this);
175 }
176
177 return this.stringAttributes.remove(attr, expectedValue);
178 }
179
180 @Override
181 public void deleteStringAttribute(String attr) {
182 if (isFrozen) {
183 throw new IllegalStateException("Tried to modify frozen object: " + this);
184 }
185
186 this.stringAttributes.remove(attr);
187 }
Yuta HIGUCHI1222ac52014-07-09 16:50:28 -0700188
189 @Override
190 public String getType() {
Yuta HIGUCHIdbc33122014-07-10 13:32:32 -0700191 return getStringAttribute(TYPE, TYPE_PACKET_LAYER);
Yuta HIGUCHI1222ac52014-07-09 16:50:28 -0700192 }
Praseed Balakrishnan2aa6c0b2014-07-17 11:42:05 -0700193
194 /**
195 * Returns the config state of topology element.
196 *
197 * @return ConfigState
198 */
199 @Override
200 public ConfigState getConfigState() {
Pavlin Radoslavovae7e8482014-08-11 16:58:19 -0700201 return ConfigState.valueOf(getStringAttribute(ELEMENT_CONFIG_STATE,
202 ConfigState.NOT_CONFIGURED.toString()));
Praseed Balakrishnan2aa6c0b2014-07-17 11:42:05 -0700203 }
204
205 /**
206 * Returns the status of topology element.
207 *
208 * @return AdminStatus
209 */
210 @Override
211 public AdminStatus getStatus() {
212 return AdminStatus.valueOf(getStringAttribute(ELEMENT_ADMIN_STATUS));
213 }
Pavlin Radoslavov31f85102014-08-15 13:55:44 -0700214
215 /**
216 * Gets the topology event origin DPID.
217 *
218 * @return the topology event origin DPID.
219 */
220 abstract Dpid getOriginDpid();
221
222 /**
223 * Gets the topology event ID as a ByteBuffer.
224 *
225 * @return the topology event ID as a ByteBuffer.
226 */
227 abstract ByteBuffer getIDasByteBuffer();
Yuta HIGUCHIbf0a8712014-06-30 18:59:46 -0700228}