blob: 0a4d385da838e9374aae02d0a915d7bc79cb1096 [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.
59 */
Sho SHIMIZU60ac58e2015-11-11 12:16:38 -080060 public static ResourcePath discrete(Object... components) {
61 if (components.length == 0) {
62 return ROOT;
63 } else {
64 return new Discrete(ImmutableList.copyOf(components));
65 }
66 }
67
68 /**
69 * Creates an resource path which represents a continuous-type resource from the specified components.
70 *
71 * @param value amount of the resource
72 * @param components components of the path. The order represents hierarchical structure of the resource.
73 */
74 public static ResourcePath continuous(double value, Object... components) {
75 return new Continuous(ImmutableList.copyOf(components), value);
Sho SHIMIZU1f5e5912015-08-10 17:00:00 -070076 }
77
78 /**
79 * Creates an resource path from the specified components.
80 *
81 * @param components components of the path. The order represents hierarchical structure of the resource.
82 */
Sho SHIMIZU60ac58e2015-11-11 12:16:38 -080083 ResourcePath(List<Object> components) {
Sho SHIMIZU1f5e5912015-08-10 17:00:00 -070084 checkNotNull(components);
Sho SHIMIZU60ac58e2015-11-11 12:16:38 -080085 checkArgument(!components.isEmpty());
Sho SHIMIZU1f5e5912015-08-10 17:00:00 -070086
Sho SHIMIZUc9546a32015-11-10 11:22:28 -080087 LinkedList<Object> children = new LinkedList<>(components);
88 this.last = children.pollLast();
Sho SHIMIZU60ac58e2015-11-11 12:16:38 -080089 if (children.isEmpty()) {
90 this.parent = ROOT;
91 } else {
92 this.parent = new Discrete(children);
93 }
Sho SHIMIZUc9546a32015-11-10 11:22:28 -080094 }
95
96 /**
97 * Creates an resource path from the specified parent and child.
98 *
99 * @param parent the parent of this resource
100 * @param last a child of the parent
101 */
Sho SHIMIZU60ac58e2015-11-11 12:16:38 -0800102 ResourcePath(Discrete parent, Object last) {
103 checkNotNull(parent);
104 checkNotNull(last);
105
106 this.parent = parent;
107 this.last = last;
Sho SHIMIZU1f5e5912015-08-10 17:00:00 -0700108 }
109
110 // for serialization
111 private ResourcePath() {
Sho SHIMIZUc9546a32015-11-10 11:22:28 -0800112 this.parent = null;
113 this.last = null;
Sho SHIMIZU1f5e5912015-08-10 17:00:00 -0700114 }
115
116 /**
117 * Returns the components of this resource path.
118 *
119 * @return the components of this resource path
120 */
121 public List<Object> components() {
Sho SHIMIZUc9546a32015-11-10 11:22:28 -0800122 LinkedList<Object> components = new LinkedList<>();
123
Sho SHIMIZU60ac58e2015-11-11 12:16:38 -0800124 Optional<Discrete> parentPath = Optional.ofNullable(parent);
125 while (parentPath.isPresent()) {
Sho SHIMIZUc9546a32015-11-10 11:22:28 -0800126 components.addFirst(last);
Sho SHIMIZU60ac58e2015-11-11 12:16:38 -0800127 parentPath = parent.parent();
Sho SHIMIZUc9546a32015-11-10 11:22:28 -0800128 }
129
130 return components;
Sho SHIMIZU1f5e5912015-08-10 17:00:00 -0700131 }
132
133 /**
134 * Returns the parent resource path of this instance.
135 * E.g. if this path is Link:1/VLAN ID:100, the return value is the resource path for Link:1.
136 *
137 * @return the parent resource path of this instance.
138 * If there is no parent, empty instance will be returned.
139 */
Sho SHIMIZU60ac58e2015-11-11 12:16:38 -0800140 public Optional<Discrete> parent() {
Sho SHIMIZUc9546a32015-11-10 11:22:28 -0800141 return Optional.ofNullable(parent);
Sho SHIMIZU1f5e5912015-08-10 17:00:00 -0700142 }
143
Sho SHIMIZUc9546a32015-11-10 11:22:28 -0800144 public ResourcePath child(Object child) {
Sho SHIMIZU60ac58e2015-11-11 12:16:38 -0800145 checkState(this instanceof Discrete);
146
147 return new Discrete((Discrete) this, child);
148 }
149
150 public ResourcePath child(Object child, double value) {
151 checkState(this instanceof Discrete);
152
153 return new Continuous((Discrete) this, child, value);
Sho SHIMIZU01120782015-08-21 15:48:43 -0700154 }
155
156 /**
Sho SHIMIZU1f5e5912015-08-10 17:00:00 -0700157 * Returns the last component of this instance.
158 *
159 * @return the last component of this instance.
160 * The return value is equal to the last object of {@code components()}.
161 */
Sho SHIMIZUc9546a32015-11-10 11:22:28 -0800162 public Object last() {
163 return last;
Sho SHIMIZU1f5e5912015-08-10 17:00:00 -0700164 }
165
166 @Override
167 public int hashCode() {
Sho SHIMIZUc9546a32015-11-10 11:22:28 -0800168 return Objects.hash(this.parent, this.last);
Sho SHIMIZU1f5e5912015-08-10 17:00:00 -0700169 }
170
171 @Override
172 public boolean equals(Object obj) {
173 if (this == obj) {
174 return true;
175 }
176 if (!(obj instanceof ResourcePath)) {
177 return false;
178 }
179 final ResourcePath that = (ResourcePath) obj;
Sho SHIMIZUc9546a32015-11-10 11:22:28 -0800180 return Objects.equals(this.parent, that.parent)
181 && Objects.equals(this.last, that.last);
Sho SHIMIZU1f5e5912015-08-10 17:00:00 -0700182 }
183
184 @Override
185 public String toString() {
186 return MoreObjects.toStringHelper(this)
Sho SHIMIZUc9546a32015-11-10 11:22:28 -0800187 .add("parent", parent)
188 .add("last", last)
Sho SHIMIZU1f5e5912015-08-10 17:00:00 -0700189 .toString();
190 }
Sho SHIMIZU60ac58e2015-11-11 12:16:38 -0800191
192 /**
193 * Represents a resource path which specifies a resource which can be measured
194 * as a discrete unit. A VLAN ID and a MPLS label of a link are examples of the resource.
195 * <p>
196 * Note: This class is exposed to the public, but intended to be used in the resource API
197 * implementation only. It is not for resource API user.
198 * </p>
199 */
200 public static final class Discrete extends ResourcePath {
201 private Discrete() {
202 super();
203 }
204
205 private Discrete(List<Object> components) {
206 super(components);
207 }
208
209 private Discrete(Discrete parent, Object last) {
210 super(parent, last);
211 }
212 }
213
214 /**
215 * Represents a resource path which specifies a resource which can be measured
216 * as continuous value. Bandwidth of a link is an example of the resource.
217 * <p>
218 * Note: This class is exposed to the public, but intended to be used in the resource API
219 * implementation only. It is not for resource API user.
220 */
221 public static final class Continuous extends ResourcePath {
222 // Note: value is not taken into account for equality
223 private final double value;
224
225 private Continuous(List<Object> components, double value) {
226 super(components);
227 this.value = value;
228 }
229
230 public Continuous(Discrete parent, Object last, double value) {
231 super(parent, last);
232 this.value = value;
233 }
234
235 /**
236 * Returns the value of the resource amount.
237 *
238 * @return the value of the resource amount
239 */
240 public double value() {
241 return value;
242 }
243 }
Sho SHIMIZU1f5e5912015-08-10 17:00:00 -0700244}