blob: 51f287df0fe38abb744c079ff988c81ff686d676 [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 SHIMIZUc9546a32015-11-10 11:22:28 -0800146 public ResourcePath child(Object child) {
Sho SHIMIZU60ac58e2015-11-11 12:16:38 -0800147 checkState(this instanceof Discrete);
148
149 return new Discrete((Discrete) this, child);
150 }
151
152 public ResourcePath child(Object child, double value) {
153 checkState(this instanceof Discrete);
154
155 return new Continuous((Discrete) this, child, value);
Sho SHIMIZU01120782015-08-21 15:48:43 -0700156 }
157
158 /**
Sho SHIMIZU1f5e5912015-08-10 17:00:00 -0700159 * Returns the last component of this instance.
160 *
161 * @return the last component of this instance.
162 * The return value is equal to the last object of {@code components()}.
163 */
Sho SHIMIZUc9546a32015-11-10 11:22:28 -0800164 public Object last() {
165 return last;
Sho SHIMIZU1f5e5912015-08-10 17:00:00 -0700166 }
167
168 @Override
169 public int hashCode() {
Sho SHIMIZUc9546a32015-11-10 11:22:28 -0800170 return Objects.hash(this.parent, this.last);
Sho SHIMIZU1f5e5912015-08-10 17:00:00 -0700171 }
172
173 @Override
174 public boolean equals(Object obj) {
175 if (this == obj) {
176 return true;
177 }
178 if (!(obj instanceof ResourcePath)) {
179 return false;
180 }
181 final ResourcePath that = (ResourcePath) obj;
Sho SHIMIZUc9546a32015-11-10 11:22:28 -0800182 return Objects.equals(this.parent, that.parent)
183 && Objects.equals(this.last, that.last);
Sho SHIMIZU1f5e5912015-08-10 17:00:00 -0700184 }
185
186 @Override
187 public String toString() {
188 return MoreObjects.toStringHelper(this)
Sho SHIMIZUc9546a32015-11-10 11:22:28 -0800189 .add("parent", parent)
190 .add("last", last)
Sho SHIMIZU1f5e5912015-08-10 17:00:00 -0700191 .toString();
192 }
Sho SHIMIZU60ac58e2015-11-11 12:16:38 -0800193
194 /**
195 * Represents a resource path which specifies a resource which can be measured
196 * as a discrete unit. A VLAN ID and a MPLS label of a link are examples of the resource.
197 * <p>
198 * Note: This class is exposed to the public, but intended to be used in the resource API
199 * implementation only. It is not for resource API user.
200 * </p>
201 */
Sho SHIMIZU6196cae2015-11-25 12:02:12 -0800202 @Beta
Sho SHIMIZU60ac58e2015-11-11 12:16:38 -0800203 public static final class Discrete extends ResourcePath {
204 private Discrete() {
205 super();
206 }
207
208 private Discrete(List<Object> components) {
209 super(components);
210 }
211
212 private Discrete(Discrete parent, Object last) {
213 super(parent, last);
214 }
215 }
216
217 /**
218 * Represents a resource path which specifies a resource which can be measured
219 * as continuous value. Bandwidth of a link is an example of the resource.
220 * <p>
221 * Note: This class is exposed to the public, but intended to be used in the resource API
222 * implementation only. It is not for resource API user.
223 */
Sho SHIMIZU6196cae2015-11-25 12:02:12 -0800224 @Beta
Sho SHIMIZU60ac58e2015-11-11 12:16:38 -0800225 public static final class Continuous extends ResourcePath {
226 // Note: value is not taken into account for equality
227 private final double value;
228
229 private Continuous(List<Object> components, double value) {
230 super(components);
231 this.value = value;
232 }
233
234 public Continuous(Discrete parent, Object last, double value) {
235 super(parent, last);
236 this.value = value;
237 }
238
239 /**
240 * Returns the value of the resource amount.
241 *
242 * @return the value of the resource amount
243 */
244 public double value() {
245 return value;
246 }
247 }
Sho SHIMIZU1f5e5912015-08-10 17:00:00 -0700248}