blob: c0c4e34f813daee1a9214abbe5acb14fb558de4e [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;
21
Sho SHIMIZUc9546a32015-11-10 11:22:28 -080022import java.util.LinkedList;
Sho SHIMIZU1f5e5912015-08-10 17:00:00 -070023import java.util.List;
24import java.util.Objects;
25import java.util.Optional;
26
Sho SHIMIZU60ac58e2015-11-11 12:16:38 -080027import static com.google.common.base.Preconditions.checkArgument;
Sho SHIMIZU1f5e5912015-08-10 17:00:00 -070028import static com.google.common.base.Preconditions.checkNotNull;
Sho SHIMIZU60ac58e2015-11-11 12:16:38 -080029import static com.google.common.base.Preconditions.checkState;
Sho SHIMIZU1f5e5912015-08-10 17:00:00 -070030
31/**
32 * An object that is used to locate a resource in a network.
33 * A ResourcePath represents a path that is hierarchical and composed of a sequence
34 * of elementary resources that are not globally identifiable. A ResourcePath can be a globally
35 * unique resource identifier.
36 *
Sho SHIMIZU60ac58e2015-11-11 12:16:38 -080037 * Two types of resource are considered. One is discrete type and the other is continuous type.
38 * Discrete type resource is a resource whose amount is measured as a discrete unit. VLAN ID and
39 * MPLS label are examples of discrete type resource. Continuous type resource is a resource whose
40 * amount is measured as a continuous value. Bandwidth is an example of continuous type resource.
41 * A double value is associated with a continuous type value.
42 *
Sho SHIMIZU1f5e5912015-08-10 17:00:00 -070043 * Users of this class must keep the semantics of resources regarding the hierarchical structure.
44 * For example, resource path, Link:1/VLAN ID:100, is valid, but resource path, VLAN ID:100/Link:1
45 * is not valid because a link is not a sub-component of a VLAN ID.
46 */
47@Beta
Sho SHIMIZU60ac58e2015-11-11 12:16:38 -080048public abstract class ResourcePath {
Sho SHIMIZU1f5e5912015-08-10 17:00:00 -070049
Sho SHIMIZU60ac58e2015-11-11 12:16:38 -080050 private final Discrete parent;
Sho SHIMIZUc9546a32015-11-10 11:22:28 -080051 private final Object last;
Sho SHIMIZU1f5e5912015-08-10 17:00:00 -070052
Sho SHIMIZU60ac58e2015-11-11 12:16:38 -080053 public static final Discrete ROOT = new Discrete();
Sho SHIMIZUba41fc12015-08-12 15:43:22 -070054
Sho SHIMIZU1f5e5912015-08-10 17:00:00 -070055 /**
Sho SHIMIZU60ac58e2015-11-11 12:16:38 -080056 * Creates an resource path which represents a discrete-type resource from the specified components.
Sho SHIMIZU1f5e5912015-08-10 17:00:00 -070057 *
58 * @param components components of the path. The order represents hierarchical structure of the resource.
Sho SHIMIZUe5524562015-11-24 14:41:20 -080059 * @return resource path instance
Sho SHIMIZU1f5e5912015-08-10 17:00:00 -070060 */
Sho SHIMIZU60ac58e2015-11-11 12:16:38 -080061 public static ResourcePath discrete(Object... components) {
62 if (components.length == 0) {
63 return ROOT;
64 } else {
65 return new Discrete(ImmutableList.copyOf(components));
66 }
67 }
68
69 /**
70 * Creates an resource path which represents a continuous-type resource from the specified components.
71 *
72 * @param value amount of the resource
73 * @param components components of the path. The order represents hierarchical structure of the resource.
Sho SHIMIZUe5524562015-11-24 14:41:20 -080074 * @return resource path instance
Sho SHIMIZU60ac58e2015-11-11 12:16:38 -080075 */
76 public static ResourcePath continuous(double value, Object... components) {
77 return new Continuous(ImmutableList.copyOf(components), value);
Sho SHIMIZU1f5e5912015-08-10 17:00:00 -070078 }
79
80 /**
81 * Creates an resource path from the specified components.
82 *
83 * @param components components of the path. The order represents hierarchical structure of the resource.
84 */
Sho SHIMIZU60ac58e2015-11-11 12:16:38 -080085 ResourcePath(List<Object> components) {
Sho SHIMIZU1f5e5912015-08-10 17:00:00 -070086 checkNotNull(components);
Sho SHIMIZU60ac58e2015-11-11 12:16:38 -080087 checkArgument(!components.isEmpty());
Sho SHIMIZU1f5e5912015-08-10 17:00:00 -070088
Sho SHIMIZUc9546a32015-11-10 11:22:28 -080089 LinkedList<Object> children = new LinkedList<>(components);
90 this.last = children.pollLast();
Sho SHIMIZU60ac58e2015-11-11 12:16:38 -080091 if (children.isEmpty()) {
92 this.parent = ROOT;
93 } else {
94 this.parent = new Discrete(children);
95 }
Sho SHIMIZUc9546a32015-11-10 11:22:28 -080096 }
97
98 /**
99 * Creates an resource path from the specified parent and child.
100 *
101 * @param parent the parent of this resource
102 * @param last a child of the parent
103 */
Sho SHIMIZU60ac58e2015-11-11 12:16:38 -0800104 ResourcePath(Discrete parent, Object last) {
105 checkNotNull(parent);
106 checkNotNull(last);
107
108 this.parent = parent;
109 this.last = last;
Sho SHIMIZU1f5e5912015-08-10 17:00:00 -0700110 }
111
112 // for serialization
113 private ResourcePath() {
Sho SHIMIZUc9546a32015-11-10 11:22:28 -0800114 this.parent = null;
115 this.last = null;
Sho SHIMIZU1f5e5912015-08-10 17:00:00 -0700116 }
117
118 /**
119 * Returns the components of this resource path.
120 *
121 * @return the components of this resource path
122 */
123 public List<Object> components() {
Sho SHIMIZUc9546a32015-11-10 11:22:28 -0800124 LinkedList<Object> components = new LinkedList<>();
125
Sho SHIMIZU69dc5842015-11-20 16:31:12 -0800126 ResourcePath current = this;
127 while (current.parent().isPresent()) {
128 components.addFirst(current.last);
129 current = current.parent;
Sho SHIMIZUc9546a32015-11-10 11:22:28 -0800130 }
131
132 return components;
Sho SHIMIZU1f5e5912015-08-10 17:00:00 -0700133 }
134
135 /**
136 * Returns the parent resource path of this instance.
137 * E.g. if this path is Link:1/VLAN ID:100, the return value is the resource path for Link:1.
138 *
139 * @return the parent resource path of this instance.
140 * If there is no parent, empty instance will be returned.
141 */
Sho SHIMIZU60ac58e2015-11-11 12:16:38 -0800142 public Optional<Discrete> parent() {
Sho SHIMIZUc9546a32015-11-10 11:22:28 -0800143 return Optional.ofNullable(parent);
Sho SHIMIZU1f5e5912015-08-10 17:00:00 -0700144 }
145
Sho SHIMIZU9e1e9de2015-11-25 15:48:48 -0800146 /**
147 * Returns a child resource path of this instance with specifying the child object.
148 * The child resource path is discrete-type.
149 *
150 * @param child child object
151 * @return a child resource path
152 */
Sho SHIMIZUc9546a32015-11-10 11:22:28 -0800153 public ResourcePath child(Object child) {
Sho SHIMIZU60ac58e2015-11-11 12:16:38 -0800154 checkState(this instanceof Discrete);
155
156 return new Discrete((Discrete) this, child);
157 }
158
Sho SHIMIZU9e1e9de2015-11-25 15:48:48 -0800159 /**
160 * Returns a child resource path of this instance with specifying a child object and
161 * value. The child resource path is continuous-type.
162 *
163 * @param child child object
164 * @param value value
165 * @return a child resource path
166 */
Sho SHIMIZU60ac58e2015-11-11 12:16:38 -0800167 public ResourcePath child(Object child, double value) {
168 checkState(this instanceof Discrete);
169
170 return new Continuous((Discrete) this, child, value);
Sho SHIMIZU01120782015-08-21 15:48:43 -0700171 }
172
173 /**
Sho SHIMIZU1f5e5912015-08-10 17:00:00 -0700174 * Returns the last component of this instance.
175 *
176 * @return the last component of this instance.
177 * The return value is equal to the last object of {@code components()}.
178 */
Sho SHIMIZUc9546a32015-11-10 11:22:28 -0800179 public Object last() {
180 return last;
Sho SHIMIZU1f5e5912015-08-10 17:00:00 -0700181 }
182
183 @Override
184 public int hashCode() {
Sho SHIMIZUc9546a32015-11-10 11:22:28 -0800185 return Objects.hash(this.parent, this.last);
Sho SHIMIZU1f5e5912015-08-10 17:00:00 -0700186 }
187
188 @Override
189 public boolean equals(Object obj) {
190 if (this == obj) {
191 return true;
192 }
193 if (!(obj instanceof ResourcePath)) {
194 return false;
195 }
196 final ResourcePath that = (ResourcePath) obj;
Sho SHIMIZUc9546a32015-11-10 11:22:28 -0800197 return Objects.equals(this.parent, that.parent)
198 && Objects.equals(this.last, that.last);
Sho SHIMIZU1f5e5912015-08-10 17:00:00 -0700199 }
200
201 @Override
202 public String toString() {
203 return MoreObjects.toStringHelper(this)
Sho SHIMIZUc9546a32015-11-10 11:22:28 -0800204 .add("parent", parent)
205 .add("last", last)
Sho SHIMIZU1f5e5912015-08-10 17:00:00 -0700206 .toString();
207 }
Sho SHIMIZU60ac58e2015-11-11 12:16:38 -0800208
209 /**
210 * Represents a resource path which specifies a resource which can be measured
211 * as a discrete unit. A VLAN ID and a MPLS label of a link are examples of the resource.
212 * <p>
213 * Note: This class is exposed to the public, but intended to be used in the resource API
214 * implementation only. It is not for resource API user.
215 * </p>
216 */
Sho SHIMIZU6196cae2015-11-25 12:02:12 -0800217 @Beta
Sho SHIMIZU60ac58e2015-11-11 12:16:38 -0800218 public static final class Discrete extends ResourcePath {
219 private Discrete() {
220 super();
221 }
222
223 private Discrete(List<Object> components) {
224 super(components);
225 }
226
227 private Discrete(Discrete parent, Object last) {
228 super(parent, last);
229 }
230 }
231
232 /**
233 * Represents a resource path which specifies a resource which can be measured
234 * as continuous value. Bandwidth of a link is an example of the resource.
235 * <p>
236 * Note: This class is exposed to the public, but intended to be used in the resource API
237 * implementation only. It is not for resource API user.
238 */
Sho SHIMIZU6196cae2015-11-25 12:02:12 -0800239 @Beta
Sho SHIMIZU60ac58e2015-11-11 12:16:38 -0800240 public static final class Continuous extends ResourcePath {
241 // Note: value is not taken into account for equality
242 private final double value;
243
244 private Continuous(List<Object> components, double value) {
245 super(components);
246 this.value = value;
247 }
248
249 public Continuous(Discrete parent, Object last, double value) {
250 super(parent, last);
251 this.value = value;
252 }
253
254 /**
255 * Returns the value of the resource amount.
256 *
257 * @return the value of the resource amount
258 */
259 public double value() {
260 return value;
261 }
262 }
Sho SHIMIZU1f5e5912015-08-10 17:00:00 -0700263}