blob: 2e86509bf9537fac081ef3bb8447f6905bff2239 [file] [log] [blame]
Sho SHIMIZU1f5e5912015-08-10 17:00:00 -07001/*
Sho SHIMIZU7e6d18e2016-01-07 18:44:33 -08002 * Copyright 2015-2016 Open Networking Laboratory
Sho SHIMIZU1f5e5912015-08-10 17:00:00 -07003 *
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;
Sho SHIMIZUb1f16252015-11-25 23:03:16 -080020import org.onosproject.net.DeviceId;
21import org.onosproject.net.PortNumber;
Sho SHIMIZU1f5e5912015-08-10 17:00:00 -070022
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.
Sho SHIMIZUb1f16252015-11-25 23:03:16 -080044 * For example, resource path, Device:1/Port:1/VLAN ID:100, is valid, but resource path,
45 * 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 -070046 */
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 SHIMIZU76b30f72016-01-11 14:08:35 -080051 private final ResourceId id;
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 SHIMIZUb1f16252015-11-25 23:03:16 -080055 public static ResourcePath discrete(DeviceId device) {
Sho SHIMIZU76b30f72016-01-11 14:08:35 -080056 return new Discrete(ResourceId.of(device));
Sho SHIMIZUb1f16252015-11-25 23:03:16 -080057 }
58
Sho SHIMIZU1f5e5912015-08-10 17:00:00 -070059 /**
Sho SHIMIZU60ac58e2015-11-11 12:16:38 -080060 * Creates an resource path which represents a discrete-type resource from the specified components.
Sho SHIMIZU1f5e5912015-08-10 17:00:00 -070061 *
Sho SHIMIZUb1f16252015-11-25 23:03:16 -080062 * @param device device ID which is the first component of the path
63 * @param components following components of the path. The order represents hierarchical structure of the resource.
Sho SHIMIZUe5524562015-11-24 14:41:20 -080064 * @return resource path instance
Sho SHIMIZU1f5e5912015-08-10 17:00:00 -070065 */
Sho SHIMIZUb1f16252015-11-25 23:03:16 -080066 public static ResourcePath discrete(DeviceId device, Object... components) {
Sho SHIMIZU76b30f72016-01-11 14:08:35 -080067 return new Discrete(ResourceId.of(device, components));
Sho SHIMIZUb1f16252015-11-25 23:03:16 -080068 }
69
70 /**
71 * Creates an resource path which represents a discrete-type resource from the specified components.
72 *
73 * @param device device ID which is the first component of the path
74 * @param port port number which is the second component of the path
75 * @param components following components of the path. The order represents hierarchical structure of the resource.
76 * @return resource path instance
77 */
78 public static ResourcePath discrete(DeviceId device, PortNumber port, Object... components) {
Sho SHIMIZU76b30f72016-01-11 14:08:35 -080079 return new Discrete(ResourceId.of(device, port, components));
Sho SHIMIZU60ac58e2015-11-11 12:16:38 -080080 }
81
82 /**
83 * Creates an resource path which represents a continuous-type resource from the specified components.
84 *
85 * @param value amount of the resource
Sho SHIMIZUb1f16252015-11-25 23:03:16 -080086 * @param device device ID which is the first component of the path
87 * @param components following components of the path. The order represents hierarchical structure of the resource.
Sho SHIMIZUe5524562015-11-24 14:41:20 -080088 * @return resource path instance
Sho SHIMIZU60ac58e2015-11-11 12:16:38 -080089 */
Sho SHIMIZUb1f16252015-11-25 23:03:16 -080090 public static ResourcePath continuous(double value, DeviceId device, Object... components) {
91 checkArgument(components.length > 0,
92 "Length of components must be greater thant 0, but " + components.length);
93
Sho SHIMIZU76b30f72016-01-11 14:08:35 -080094 return new Continuous(ResourceId.of(device, components), value);
Sho SHIMIZUb1f16252015-11-25 23:03:16 -080095 }
96
97 /**
98 * Creates an resource path which represents a continuous-type resource from the specified components.
99 *
100 * @param value amount of the resource
101 * @param device device ID which is the first component of the path.
102 * @param port port number which is the second component of the path.
103 * @param components following components of the path. The order represents hierarchical structure of the resource.
104 * @return resource path instance
105 */
106 public static ResourcePath continuous(double value, DeviceId device, PortNumber port, Object... components) {
Sho SHIMIZU76b30f72016-01-11 14:08:35 -0800107 return new Continuous(ResourceId.of(device, port, components), value);
Sho SHIMIZU1f5e5912015-08-10 17:00:00 -0700108 }
109
110 /**
Sho SHIMIZU5fb1ea32016-01-14 10:58:14 -0800111 * Creates an resource path from the specified id.
Sho SHIMIZU1f5e5912015-08-10 17:00:00 -0700112 *
Sho SHIMIZU5fb1ea32016-01-14 10:58:14 -0800113 * @param id id of the path
Sho SHIMIZU1f5e5912015-08-10 17:00:00 -0700114 */
Sho SHIMIZU76b30f72016-01-11 14:08:35 -0800115 protected ResourcePath(ResourceId id) {
116 checkNotNull(id);
Sho SHIMIZU1f5e5912015-08-10 17:00:00 -0700117
Sho SHIMIZU76b30f72016-01-11 14:08:35 -0800118 this.id = id;
119 if (id.components.size() == 1) {
Sho SHIMIZU60ac58e2015-11-11 12:16:38 -0800120 this.parent = ROOT;
121 } else {
Sho SHIMIZU76b30f72016-01-11 14:08:35 -0800122 this.parent = new Discrete(id.parent());
Sho SHIMIZU60ac58e2015-11-11 12:16:38 -0800123 }
Sho SHIMIZUc9546a32015-11-10 11:22:28 -0800124 }
125
Sho SHIMIZU1f5e5912015-08-10 17:00:00 -0700126 // for serialization
127 private ResourcePath() {
Sho SHIMIZUc9546a32015-11-10 11:22:28 -0800128 this.parent = null;
Sho SHIMIZU76b30f72016-01-11 14:08:35 -0800129 this.id = ResourceId.ROOT;
Sho SHIMIZU1f5e5912015-08-10 17:00:00 -0700130 }
131
132 /**
133 * Returns the components of this resource path.
134 *
135 * @return the components of this resource path
136 */
137 public List<Object> components() {
Sho SHIMIZU76b30f72016-01-11 14:08:35 -0800138 return id.components;
Sho SHIMIZU1f5e5912015-08-10 17:00:00 -0700139 }
140
141 /**
142 * Returns the parent resource path of this instance.
143 * E.g. if this path is Link:1/VLAN ID:100, the return value is the resource path for Link:1.
144 *
145 * @return the parent resource path of this instance.
146 * If there is no parent, empty instance will be returned.
147 */
Sho SHIMIZU60ac58e2015-11-11 12:16:38 -0800148 public Optional<Discrete> parent() {
Sho SHIMIZUc9546a32015-11-10 11:22:28 -0800149 return Optional.ofNullable(parent);
Sho SHIMIZU1f5e5912015-08-10 17:00:00 -0700150 }
151
Sho SHIMIZU9e1e9de2015-11-25 15:48:48 -0800152 /**
153 * Returns a child resource path of this instance with specifying the child object.
154 * The child resource path is discrete-type.
155 *
156 * @param child child object
157 * @return a child resource path
158 */
Sho SHIMIZUc9546a32015-11-10 11:22:28 -0800159 public ResourcePath child(Object child) {
Sho SHIMIZU60ac58e2015-11-11 12:16:38 -0800160 checkState(this instanceof Discrete);
161
Sho SHIMIZU76b30f72016-01-11 14:08:35 -0800162 return new Discrete(id().child(child));
Sho SHIMIZU60ac58e2015-11-11 12:16:38 -0800163 }
164
Sho SHIMIZU9e1e9de2015-11-25 15:48:48 -0800165 /**
166 * Returns a child resource path of this instance with specifying a child object and
167 * value. The child resource path is continuous-type.
168 *
169 * @param child child object
170 * @param value value
171 * @return a child resource path
172 */
Sho SHIMIZU60ac58e2015-11-11 12:16:38 -0800173 public ResourcePath child(Object child, double value) {
174 checkState(this instanceof Discrete);
175
Sho SHIMIZU76b30f72016-01-11 14:08:35 -0800176 return new Continuous(id.child(child), value);
Sho SHIMIZU01120782015-08-21 15:48:43 -0700177 }
178
179 /**
Sho SHIMIZU1f5e5912015-08-10 17:00:00 -0700180 * Returns the last component of this instance.
181 *
182 * @return the last component of this instance.
183 * The return value is equal to the last object of {@code components()}.
184 */
Sho SHIMIZUc9546a32015-11-10 11:22:28 -0800185 public Object last() {
Sho SHIMIZU76b30f72016-01-11 14:08:35 -0800186 if (id.components.isEmpty()) {
Sho SHIMIZU7e6d18e2016-01-07 18:44:33 -0800187 return null;
188 }
Sho SHIMIZU76b30f72016-01-11 14:08:35 -0800189 return id.components.get(id.components.size() - 1);
Sho SHIMIZU7e6d18e2016-01-07 18:44:33 -0800190 }
191
192 /**
Sho SHIMIZU5fb1ea32016-01-14 10:58:14 -0800193 * Returns the ID of this resource path.
Sho SHIMIZU7e6d18e2016-01-07 18:44:33 -0800194 *
Sho SHIMIZU5fb1ea32016-01-14 10:58:14 -0800195 * @return the ID of this resource path
Sho SHIMIZU7e6d18e2016-01-07 18:44:33 -0800196 */
Sho SHIMIZU76b30f72016-01-11 14:08:35 -0800197 public ResourceId id() {
198 return id;
Sho SHIMIZU1f5e5912015-08-10 17:00:00 -0700199 }
200
201 @Override
202 public int hashCode() {
Sho SHIMIZU76b30f72016-01-11 14:08:35 -0800203 return id.hashCode();
Sho SHIMIZU1f5e5912015-08-10 17:00:00 -0700204 }
205
206 @Override
207 public boolean equals(Object obj) {
208 if (this == obj) {
209 return true;
210 }
211 if (!(obj instanceof ResourcePath)) {
212 return false;
213 }
214 final ResourcePath that = (ResourcePath) obj;
Sho SHIMIZU76b30f72016-01-11 14:08:35 -0800215 return Objects.equals(this.id, that.id);
Sho SHIMIZU1f5e5912015-08-10 17:00:00 -0700216 }
217
218 @Override
219 public String toString() {
220 return MoreObjects.toStringHelper(this)
Sho SHIMIZU5fb1ea32016-01-14 10:58:14 -0800221 .add("id", id)
Sho SHIMIZU1f5e5912015-08-10 17:00:00 -0700222 .toString();
223 }
Sho SHIMIZU60ac58e2015-11-11 12:16:38 -0800224
225 /**
226 * Represents a resource path which specifies a resource which can be measured
227 * as a discrete unit. A VLAN ID and a MPLS label of a link are examples of the resource.
228 * <p>
229 * Note: This class is exposed to the public, but intended to be used in the resource API
230 * implementation only. It is not for resource API user.
231 * </p>
232 */
Sho SHIMIZU6196cae2015-11-25 12:02:12 -0800233 @Beta
Sho SHIMIZU60ac58e2015-11-11 12:16:38 -0800234 public static final class Discrete extends ResourcePath {
235 private Discrete() {
236 super();
237 }
238
Sho SHIMIZU5fb1ea32016-01-14 10:58:14 -0800239 private Discrete(ResourceId id) {
240 super(id);
Sho SHIMIZU60ac58e2015-11-11 12:16:38 -0800241 }
242 }
243
244 /**
245 * Represents a resource path which specifies a resource which can be measured
246 * as continuous value. Bandwidth of a link is an example of the resource.
247 * <p>
248 * Note: This class is exposed to the public, but intended to be used in the resource API
249 * implementation only. It is not for resource API user.
250 */
Sho SHIMIZU6196cae2015-11-25 12:02:12 -0800251 @Beta
Sho SHIMIZU60ac58e2015-11-11 12:16:38 -0800252 public static final class Continuous extends ResourcePath {
Sho SHIMIZU60ac58e2015-11-11 12:16:38 -0800253 private final double value;
254
Sho SHIMIZU5fb1ea32016-01-14 10:58:14 -0800255 private Continuous(ResourceId id, double value) {
256 super(id);
Sho SHIMIZU60ac58e2015-11-11 12:16:38 -0800257 this.value = value;
258 }
259
Sho SHIMIZU7e6d18e2016-01-07 18:44:33 -0800260 @Override
261 public int hashCode() {
Sho SHIMIZU76b30f72016-01-11 14:08:35 -0800262 return Objects.hash(this.id(), this.value);
Sho SHIMIZU7e6d18e2016-01-07 18:44:33 -0800263 }
264
265 @Override
266 public boolean equals(Object obj) {
267 if (this == obj) {
268 return true;
269 }
270
271 if (!(obj instanceof Continuous)) {
272 return false;
273 }
274
275 if (!super.equals(obj)) {
276 return false;
277 }
278
279 final Continuous other = (Continuous) obj;
Sho SHIMIZU76b30f72016-01-11 14:08:35 -0800280 return Objects.equals(this.id(), other.id());
Sho SHIMIZU60ac58e2015-11-11 12:16:38 -0800281 }
282
283 /**
284 * Returns the value of the resource amount.
285 *
286 * @return the value of the resource amount
287 */
288 public double value() {
289 return value;
290 }
291 }
Sho SHIMIZU7e6d18e2016-01-07 18:44:33 -0800292
Sho SHIMIZU1f5e5912015-08-10 17:00:00 -0700293}