blob: 72f8ac0193ad47fa94ee06c20286c5e5081bb93a [file] [log] [blame]
Sho SHIMIZU1f5e5912015-08-10 17:00:00 -07001/*
2 * Copyright 2015 Open Networking Laboratory
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16package org.onosproject.net.newresource;
17
18import com.google.common.annotations.Beta;
19import com.google.common.base.MoreObjects;
20import com.google.common.collect.ImmutableList;
Sho SHIMIZUb1f16252015-11-25 23:03:16 -080021import org.onosproject.net.DeviceId;
22import org.onosproject.net.PortNumber;
Sho SHIMIZU1f5e5912015-08-10 17:00:00 -070023
Sho SHIMIZUc9546a32015-11-10 11:22:28 -080024import java.util.LinkedList;
Sho SHIMIZU1f5e5912015-08-10 17:00:00 -070025import java.util.List;
26import java.util.Objects;
27import java.util.Optional;
28
Sho SHIMIZU60ac58e2015-11-11 12:16:38 -080029import static com.google.common.base.Preconditions.checkArgument;
Sho SHIMIZU1f5e5912015-08-10 17:00:00 -070030import static com.google.common.base.Preconditions.checkNotNull;
Sho SHIMIZU60ac58e2015-11-11 12:16:38 -080031import static com.google.common.base.Preconditions.checkState;
Sho SHIMIZU1f5e5912015-08-10 17:00:00 -070032
33/**
34 * An object that is used to locate a resource in a network.
35 * A ResourcePath represents a path that is hierarchical and composed of a sequence
36 * of elementary resources that are not globally identifiable. A ResourcePath can be a globally
37 * unique resource identifier.
38 *
Sho SHIMIZU60ac58e2015-11-11 12:16:38 -080039 * Two types of resource are considered. One is discrete type and the other is continuous type.
40 * Discrete type resource is a resource whose amount is measured as a discrete unit. VLAN ID and
41 * MPLS label are examples of discrete type resource. Continuous type resource is a resource whose
42 * amount is measured as a continuous value. Bandwidth is an example of continuous type resource.
43 * A double value is associated with a continuous type value.
44 *
Sho SHIMIZU1f5e5912015-08-10 17:00:00 -070045 * Users of this class must keep the semantics of resources regarding the hierarchical structure.
Sho SHIMIZUb1f16252015-11-25 23:03:16 -080046 * For example, resource path, Device:1/Port:1/VLAN ID:100, is valid, but resource path,
47 * VLAN ID:100/Device:1/Port:1 is not valid because a link is not a sub-component of a VLAN ID.
Sho SHIMIZU1f5e5912015-08-10 17:00:00 -070048 */
49@Beta
Sho SHIMIZU60ac58e2015-11-11 12:16:38 -080050public abstract class ResourcePath {
Sho SHIMIZU1f5e5912015-08-10 17:00:00 -070051
Sho SHIMIZU60ac58e2015-11-11 12:16:38 -080052 private final Discrete parent;
Sho SHIMIZUc9546a32015-11-10 11:22:28 -080053 private final Object last;
Sho SHIMIZU1f5e5912015-08-10 17:00:00 -070054
Sho SHIMIZU60ac58e2015-11-11 12:16:38 -080055 public static final Discrete ROOT = new Discrete();
Sho SHIMIZUba41fc12015-08-12 15:43:22 -070056
Sho SHIMIZUb1f16252015-11-25 23:03:16 -080057 public static ResourcePath discrete(DeviceId device) {
58 return new Discrete(ImmutableList.of(device));
59 }
60
Sho SHIMIZU1f5e5912015-08-10 17:00:00 -070061 /**
Sho SHIMIZU60ac58e2015-11-11 12:16:38 -080062 * Creates an resource path which represents a discrete-type resource from the specified components.
Sho SHIMIZU1f5e5912015-08-10 17:00:00 -070063 *
Sho SHIMIZUb1f16252015-11-25 23:03:16 -080064 * @param device device ID which is the first component of the path
65 * @param components following components of the path. The order represents hierarchical structure of the resource.
Sho SHIMIZUe5524562015-11-24 14:41:20 -080066 * @return resource path instance
Sho SHIMIZU1f5e5912015-08-10 17:00:00 -070067 */
Sho SHIMIZUb1f16252015-11-25 23:03:16 -080068 public static ResourcePath discrete(DeviceId device, Object... components) {
69 return new Discrete(ImmutableList.builder()
70 .add(device)
71 .add(components)
72 .build());
73 }
74
75 /**
76 * Creates an resource path which represents a discrete-type resource from the specified components.
77 *
78 * @param device device ID which is the first component of the path
79 * @param port port number which is the second component of the path
80 * @param components following components of the path. The order represents hierarchical structure of the resource.
81 * @return resource path instance
82 */
83 public static ResourcePath discrete(DeviceId device, PortNumber port, Object... components) {
84 return new Discrete(ImmutableList.builder()
85 .add(device)
86 .add(port)
87 .add(components)
88 .build());
Sho SHIMIZU60ac58e2015-11-11 12:16:38 -080089 }
90
91 /**
92 * Creates an resource path which represents a continuous-type resource from the specified components.
93 *
94 * @param value amount of the resource
Sho SHIMIZUb1f16252015-11-25 23:03:16 -080095 * @param device device ID which is the first component of the path
96 * @param components following components of the path. The order represents hierarchical structure of the resource.
Sho SHIMIZUe5524562015-11-24 14:41:20 -080097 * @return resource path instance
Sho SHIMIZU60ac58e2015-11-11 12:16:38 -080098 */
Sho SHIMIZUb1f16252015-11-25 23:03:16 -080099 public static ResourcePath continuous(double value, DeviceId device, Object... components) {
100 checkArgument(components.length > 0,
101 "Length of components must be greater thant 0, but " + components.length);
102
103 return new Continuous(ImmutableList.builder()
104 .add(device)
105 .add(components)
106 .build(), value);
107 }
108
109 /**
110 * Creates an resource path which represents a continuous-type resource from the specified components.
111 *
112 * @param value amount of the resource
113 * @param device device ID which is the first component of the path.
114 * @param port port number which is the second component of the path.
115 * @param components following components of the path. The order represents hierarchical structure of the resource.
116 * @return resource path instance
117 */
118 public static ResourcePath continuous(double value, DeviceId device, PortNumber port, Object... components) {
119 return new Continuous(ImmutableList.builder()
120 .add(device)
121 .add(port)
122 .add(components)
123 .build(), value);
Sho SHIMIZU1f5e5912015-08-10 17:00:00 -0700124 }
125
126 /**
127 * Creates an resource path from the specified components.
128 *
129 * @param components components of the path. The order represents hierarchical structure of the resource.
130 */
Sho SHIMIZUb1f16252015-11-25 23:03:16 -0800131 protected ResourcePath(List<Object> components) {
Sho SHIMIZU1f5e5912015-08-10 17:00:00 -0700132 checkNotNull(components);
Sho SHIMIZU60ac58e2015-11-11 12:16:38 -0800133 checkArgument(!components.isEmpty());
Sho SHIMIZU1f5e5912015-08-10 17:00:00 -0700134
Sho SHIMIZUc9546a32015-11-10 11:22:28 -0800135 LinkedList<Object> children = new LinkedList<>(components);
136 this.last = children.pollLast();
Sho SHIMIZU60ac58e2015-11-11 12:16:38 -0800137 if (children.isEmpty()) {
138 this.parent = ROOT;
139 } else {
140 this.parent = new Discrete(children);
141 }
Sho SHIMIZUc9546a32015-11-10 11:22:28 -0800142 }
143
144 /**
145 * Creates an resource path from the specified parent and child.
146 *
147 * @param parent the parent of this resource
148 * @param last a child of the parent
149 */
Sho SHIMIZUb1f16252015-11-25 23:03:16 -0800150 protected ResourcePath(Discrete parent, Object last) {
Sho SHIMIZU60ac58e2015-11-11 12:16:38 -0800151 checkNotNull(parent);
152 checkNotNull(last);
153
154 this.parent = parent;
155 this.last = last;
Sho SHIMIZU1f5e5912015-08-10 17:00:00 -0700156 }
157
158 // for serialization
159 private ResourcePath() {
Sho SHIMIZUc9546a32015-11-10 11:22:28 -0800160 this.parent = null;
161 this.last = null;
Sho SHIMIZU1f5e5912015-08-10 17:00:00 -0700162 }
163
164 /**
165 * Returns the components of this resource path.
166 *
167 * @return the components of this resource path
168 */
169 public List<Object> components() {
Sho SHIMIZUc9546a32015-11-10 11:22:28 -0800170 LinkedList<Object> components = new LinkedList<>();
171
Sho SHIMIZU69dc5842015-11-20 16:31:12 -0800172 ResourcePath current = this;
173 while (current.parent().isPresent()) {
174 components.addFirst(current.last);
175 current = current.parent;
Sho SHIMIZUc9546a32015-11-10 11:22:28 -0800176 }
177
178 return components;
Sho SHIMIZU1f5e5912015-08-10 17:00:00 -0700179 }
180
181 /**
182 * Returns the parent resource path of this instance.
183 * E.g. if this path is Link:1/VLAN ID:100, the return value is the resource path for Link:1.
184 *
185 * @return the parent resource path of this instance.
186 * If there is no parent, empty instance will be returned.
187 */
Sho SHIMIZU60ac58e2015-11-11 12:16:38 -0800188 public Optional<Discrete> parent() {
Sho SHIMIZUc9546a32015-11-10 11:22:28 -0800189 return Optional.ofNullable(parent);
Sho SHIMIZU1f5e5912015-08-10 17:00:00 -0700190 }
191
Sho SHIMIZU9e1e9de2015-11-25 15:48:48 -0800192 /**
193 * Returns a child resource path of this instance with specifying the child object.
194 * The child resource path is discrete-type.
195 *
196 * @param child child object
197 * @return a child resource path
198 */
Sho SHIMIZUc9546a32015-11-10 11:22:28 -0800199 public ResourcePath child(Object child) {
Sho SHIMIZU60ac58e2015-11-11 12:16:38 -0800200 checkState(this instanceof Discrete);
201
202 return new Discrete((Discrete) this, child);
203 }
204
Sho SHIMIZU9e1e9de2015-11-25 15:48:48 -0800205 /**
206 * Returns a child resource path of this instance with specifying a child object and
207 * value. The child resource path is continuous-type.
208 *
209 * @param child child object
210 * @param value value
211 * @return a child resource path
212 */
Sho SHIMIZU60ac58e2015-11-11 12:16:38 -0800213 public ResourcePath child(Object child, double value) {
214 checkState(this instanceof Discrete);
215
216 return new Continuous((Discrete) this, child, value);
Sho SHIMIZU01120782015-08-21 15:48:43 -0700217 }
218
219 /**
Sho SHIMIZU1f5e5912015-08-10 17:00:00 -0700220 * Returns the last component of this instance.
221 *
222 * @return the last component of this instance.
223 * The return value is equal to the last object of {@code components()}.
224 */
Sho SHIMIZUc9546a32015-11-10 11:22:28 -0800225 public Object last() {
226 return last;
Sho SHIMIZU1f5e5912015-08-10 17:00:00 -0700227 }
228
229 @Override
230 public int hashCode() {
Sho SHIMIZUc9546a32015-11-10 11:22:28 -0800231 return Objects.hash(this.parent, this.last);
Sho SHIMIZU1f5e5912015-08-10 17:00:00 -0700232 }
233
234 @Override
235 public boolean equals(Object obj) {
236 if (this == obj) {
237 return true;
238 }
239 if (!(obj instanceof ResourcePath)) {
240 return false;
241 }
242 final ResourcePath that = (ResourcePath) obj;
Sho SHIMIZUc9546a32015-11-10 11:22:28 -0800243 return Objects.equals(this.parent, that.parent)
244 && Objects.equals(this.last, that.last);
Sho SHIMIZU1f5e5912015-08-10 17:00:00 -0700245 }
246
247 @Override
248 public String toString() {
249 return MoreObjects.toStringHelper(this)
Sho SHIMIZUc9546a32015-11-10 11:22:28 -0800250 .add("parent", parent)
251 .add("last", last)
Sho SHIMIZU1f5e5912015-08-10 17:00:00 -0700252 .toString();
253 }
Sho SHIMIZU60ac58e2015-11-11 12:16:38 -0800254
255 /**
256 * Represents a resource path which specifies a resource which can be measured
257 * as a discrete unit. A VLAN ID and a MPLS label of a link are examples of the resource.
258 * <p>
259 * Note: This class is exposed to the public, but intended to be used in the resource API
260 * implementation only. It is not for resource API user.
261 * </p>
262 */
Sho SHIMIZU6196cae2015-11-25 12:02:12 -0800263 @Beta
Sho SHIMIZU60ac58e2015-11-11 12:16:38 -0800264 public static final class Discrete extends ResourcePath {
265 private Discrete() {
266 super();
267 }
268
269 private Discrete(List<Object> components) {
270 super(components);
271 }
272
273 private Discrete(Discrete parent, Object last) {
274 super(parent, last);
275 }
276 }
277
278 /**
279 * Represents a resource path which specifies a resource which can be measured
280 * as continuous value. Bandwidth of a link is an example of the resource.
281 * <p>
282 * Note: This class is exposed to the public, but intended to be used in the resource API
283 * implementation only. It is not for resource API user.
284 */
Sho SHIMIZU6196cae2015-11-25 12:02:12 -0800285 @Beta
Sho SHIMIZU60ac58e2015-11-11 12:16:38 -0800286 public static final class Continuous extends ResourcePath {
287 // Note: value is not taken into account for equality
288 private final double value;
289
290 private Continuous(List<Object> components, double value) {
291 super(components);
292 this.value = value;
293 }
294
295 public Continuous(Discrete parent, Object last, double value) {
296 super(parent, last);
297 this.value = value;
298 }
299
300 /**
301 * Returns the value of the resource amount.
302 *
303 * @return the value of the resource amount
304 */
305 public double value() {
306 return value;
307 }
308 }
Sho SHIMIZU1f5e5912015-08-10 17:00:00 -0700309}