blob: ea94955e26736c25876050305328b6ee13cbf080 [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 */
202 public static final class Discrete extends ResourcePath {
203 private Discrete() {
204 super();
205 }
206
207 private Discrete(List<Object> components) {
208 super(components);
209 }
210
211 private Discrete(Discrete parent, Object last) {
212 super(parent, last);
213 }
214 }
215
216 /**
217 * Represents a resource path which specifies a resource which can be measured
218 * as continuous value. Bandwidth of a link is an example of the resource.
219 * <p>
220 * Note: This class is exposed to the public, but intended to be used in the resource API
221 * implementation only. It is not for resource API user.
222 */
223 public static final class Continuous extends ResourcePath {
224 // Note: value is not taken into account for equality
225 private final double value;
226
227 private Continuous(List<Object> components, double value) {
228 super(components);
229 this.value = value;
230 }
231
232 public Continuous(Discrete parent, Object last, double value) {
233 super(parent, last);
234 this.value = value;
235 }
236
237 /**
238 * Returns the value of the resource amount.
239 *
240 * @return the value of the resource amount
241 */
242 public double value() {
243 return value;
244 }
245 }
Sho SHIMIZU1f5e5912015-08-10 17:00:00 -0700246}