Sho SHIMIZU
Committed by Gerrit Code Review

Introduce two specific types of ResourceId for Discrete and Continuous

Change-Id: I4a29beaabe32ba78fb03336192095edadc63e3c9
...@@ -53,7 +53,7 @@ public abstract class Resource { ...@@ -53,7 +53,7 @@ public abstract class Resource {
53 public static final Discrete ROOT = new Discrete(); 53 public static final Discrete ROOT = new Discrete();
54 54
55 public static Resource discrete(DeviceId device) { 55 public static Resource discrete(DeviceId device) {
56 - return new Discrete(ResourceId.of(device)); 56 + return new Discrete(ResourceId.discrete(device));
57 } 57 }
58 58
59 /** 59 /**
...@@ -64,7 +64,7 @@ public abstract class Resource { ...@@ -64,7 +64,7 @@ public abstract class Resource {
64 * @return resource path instance 64 * @return resource path instance
65 */ 65 */
66 public static Resource discrete(DeviceId device, Object... components) { 66 public static Resource discrete(DeviceId device, Object... components) {
67 - return new Discrete(ResourceId.of(device, components)); 67 + return new Discrete(ResourceId.discrete(device, components));
68 } 68 }
69 69
70 /** 70 /**
...@@ -76,7 +76,7 @@ public abstract class Resource { ...@@ -76,7 +76,7 @@ public abstract class Resource {
76 * @return resource path instance 76 * @return resource path instance
77 */ 77 */
78 public static Resource discrete(DeviceId device, PortNumber port, Object... components) { 78 public static Resource discrete(DeviceId device, PortNumber port, Object... components) {
79 - return new Discrete(ResourceId.of(device, port, components)); 79 + return new Discrete(ResourceId.discrete(device, port, components));
80 } 80 }
81 81
82 /** 82 /**
...@@ -85,13 +85,15 @@ public abstract class Resource { ...@@ -85,13 +85,15 @@ public abstract class Resource {
85 * @param value amount of the resource 85 * @param value amount of the resource
86 * @param device device ID which is the first component of the path 86 * @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. 87 * @param components following components of the path. The order represents hierarchical structure of the resource.
88 + * The last element of this list must be an {@link Class} instance. Otherwise, this method throws
89 + * an IllegalArgumentException.
88 * @return resource path instance 90 * @return resource path instance
89 */ 91 */
90 public static Resource continuous(double value, DeviceId device, Object... components) { 92 public static Resource continuous(double value, DeviceId device, Object... components) {
91 checkArgument(components.length > 0, 93 checkArgument(components.length > 0,
92 "Length of components must be greater thant 0, but " + components.length); 94 "Length of components must be greater thant 0, but " + components.length);
93 95
94 - return new Continuous(ResourceId.of(device, components), value); 96 + return new Continuous(ResourceId.continuous(device, components), value);
95 } 97 }
96 98
97 /** 99 /**
...@@ -101,10 +103,12 @@ public abstract class Resource { ...@@ -101,10 +103,12 @@ public abstract class Resource {
101 * @param device device ID which is the first component of the path. 103 * @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. 104 * @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. 105 * @param components following components of the path. The order represents hierarchical structure of the resource.
106 + * The last element of this list must be an {@link Class} instance. Otherwise, this method throws
107 + * an IllegalArgumentException.
104 * @return resource path instance 108 * @return resource path instance
105 */ 109 */
106 public static Resource continuous(double value, DeviceId device, PortNumber port, Object... components) { 110 public static Resource continuous(double value, DeviceId device, PortNumber port, Object... components) {
107 - return new Continuous(ResourceId.of(device, port, components), value); 111 + return new Continuous(ResourceId.continuous(device, port, components), value);
108 } 112 }
109 113
110 /** 114 /**
...@@ -139,6 +143,14 @@ public abstract class Resource { ...@@ -139,6 +143,14 @@ public abstract class Resource {
139 } 143 }
140 144
141 /** 145 /**
146 + * Returns the volume of this resource.
147 + *
148 + * @return the volume of this resource
149 + */
150 + // TODO: think about other naming possibilities. amount? quantity?
151 + public abstract <T> T volume();
152 +
153 + /**
142 * Returns the parent resource path of this instance. 154 * 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. 155 * E.g. if this path is Link:1/VLAN ID:100, the return value is the resource path for Link:1.
144 * 156 *
...@@ -199,30 +211,10 @@ public abstract class Resource { ...@@ -199,30 +211,10 @@ public abstract class Resource {
199 } 211 }
200 212
201 @Override 213 @Override
202 - public int hashCode() {
203 - return id.hashCode();
204 - }
205 -
206 - @Override
207 - public boolean equals(Object obj) {
208 - if (this == obj) {
209 - return true;
210 - }
211 -
212 - if (obj == null) {
213 - return false;
214 - }
215 - if (this.getClass() != obj.getClass()) {
216 - return false;
217 - }
218 - final Resource that = (Resource) obj;
219 - return Objects.equals(this.id, that.id);
220 - }
221 -
222 - @Override
223 public String toString() { 214 public String toString() {
224 return MoreObjects.toStringHelper(this) 215 return MoreObjects.toStringHelper(this)
225 - .add("id", id) 216 + .add("id", id())
217 + .add("volume", volume())
226 .toString(); 218 .toString();
227 } 219 }
228 220
...@@ -243,6 +235,39 @@ public abstract class Resource { ...@@ -243,6 +235,39 @@ public abstract class Resource {
243 private Discrete(ResourceId id) { 235 private Discrete(ResourceId id) {
244 super(id); 236 super(id);
245 } 237 }
238 +
239 + /**
240 + * The user of this methods must receive the return value as the correct type.
241 + * Otherwise, this methods throws an exception.
242 + *
243 + * @param <T> type of the return value
244 + * @return the volume of this resource
245 + */
246 + @SuppressWarnings("unchecked")
247 + @Override
248 + // TODO: consider receiving Class<T> as an argument. Which approach is convenient?
249 + public <T> T volume() {
250 + return (T) last();
251 + }
252 +
253 + @Override
254 + public int hashCode() {
255 + // the value returing from volume() is excluded due to optimization
256 + return id().hashCode();
257 + }
258 +
259 + @Override
260 + public boolean equals(Object obj) {
261 + if (this == obj) {
262 + return true;
263 + }
264 + if (obj == null || getClass() != obj.getClass()) {
265 + return false;
266 + }
267 + final Discrete other = (Discrete) obj;
268 + // the value returing from volume() is excluded due to optimization
269 + return Objects.equals(this.id(), other.id());
270 + }
246 } 271 }
247 272
248 /** 273 /**
...@@ -261,16 +286,35 @@ public abstract class Resource { ...@@ -261,16 +286,35 @@ public abstract class Resource {
261 this.value = value; 286 this.value = value;
262 } 287 }
263 288
289 + /**
290 + * The user of this methods must receive the return value as Double or double.
291 + * Otherwise, this methods throws an exception.
292 + *
293 + * @param <T> type of the return value
294 + * @return the volume of this resource
295 + */
296 + @SuppressWarnings("unchecked")
297 + @Override
298 + public <T> T volume() {
299 + return (T) Double.valueOf(value);
300 + }
301 +
264 @Override 302 @Override
265 public int hashCode() { 303 public int hashCode() {
266 - return super.hashCode(); 304 + return Objects.hash(id(), value);
267 } 305 }
268 306
269 - // explicitly overriding to express that we intentionally ignore
270 - // `value` in equality comparison
271 @Override 307 @Override
272 public boolean equals(Object obj) { 308 public boolean equals(Object obj) {
273 - return super.equals(obj); 309 + if (this == obj) {
310 + return true;
311 + }
312 + if (obj == null || getClass() != obj.getClass()) {
313 + return false;
314 + }
315 + final Continuous other = (Continuous) obj;
316 + return Objects.equals(this.id(), other.id())
317 + && Objects.equals(this.value, other.value);
274 } 318 }
275 319
276 /** 320 /**
...@@ -278,17 +322,10 @@ public abstract class Resource { ...@@ -278,17 +322,10 @@ public abstract class Resource {
278 * 322 *
279 * @return the value of the resource amount 323 * @return the value of the resource amount
280 */ 324 */
325 + // FIXME: overlapping a purpose with volume()
281 public double value() { 326 public double value() {
282 return value; 327 return value;
283 } 328 }
284 -
285 - @Override
286 - public String toString() {
287 - return MoreObjects.toStringHelper(this)
288 - .add("id", id())
289 - .add("value", value)
290 - .toString();
291 - }
292 } 329 }
293 330
294 } 331 }
......
...@@ -20,35 +20,63 @@ import com.google.common.collect.ImmutableList; ...@@ -20,35 +20,63 @@ import com.google.common.collect.ImmutableList;
20 import org.onosproject.net.DeviceId; 20 import org.onosproject.net.DeviceId;
21 import org.onosproject.net.PortNumber; 21 import org.onosproject.net.PortNumber;
22 22
23 +import java.util.Arrays;
23 import java.util.Objects; 24 import java.util.Objects;
24 25
26 +import static com.google.common.base.Preconditions.checkArgument;
25 import static com.google.common.base.Preconditions.checkNotNull; 27 import static com.google.common.base.Preconditions.checkNotNull;
28 +import static com.google.common.base.Preconditions.checkState;
26 29
27 /** 30 /**
28 * Represents identifier of resource. 31 * Represents identifier of resource.
29 * This class is exposed to public, but intended to use only in ResourceStore implementations. 32 * This class is exposed to public, but intended to use only in ResourceStore implementations.
30 */ 33 */
31 @Beta 34 @Beta
32 -public final class ResourceId { 35 +public abstract class ResourceId {
33 - static final ResourceId ROOT = new ResourceId(); 36 + static final ResourceId ROOT = new Discrete();
34 37
35 final ImmutableList<Object> components; 38 final ImmutableList<Object> components;
36 39
37 - static ResourceId of(DeviceId device, Object... components) { 40 + static ResourceId discrete(DeviceId device, Object... components) {
38 - return new ResourceId(ImmutableList.builder() 41 + return new Discrete(ImmutableList.builder()
39 .add(device) 42 .add(device)
40 .add(components) 43 .add(components)
41 .build()); 44 .build());
42 } 45 }
43 46
44 - static ResourceId of(DeviceId device, PortNumber port, Object... components) { 47 + static ResourceId discrete(DeviceId device, PortNumber port, Object... components) {
45 - return new ResourceId(ImmutableList.builder() 48 + return new Discrete(ImmutableList.builder()
46 .add(device) 49 .add(device)
47 .add(port) 50 .add(port)
48 .add(components) 51 .add(components)
49 .build()); 52 .build());
50 } 53 }
51 54
55 + static ResourceId continuous(DeviceId device, Object... components) {
56 + Object last = components[components.length - 1];
57 + checkArgument(last instanceof Class<?>);
58 +
59 + return continuous(ImmutableList.builder()
60 + .add(device)
61 + .add(Arrays.copyOfRange(components, 0, components.length - 1)), (Class<?>) last);
62 + }
63 +
64 + static ResourceId continuous(DeviceId device, PortNumber port, Object... components) {
65 + Object last = components[components.length - 1];
66 + checkArgument(last instanceof Class<?>);
67 +
68 + return continuous(ImmutableList.builder()
69 + .add(device)
70 + .add(port)
71 + .add(Arrays.copyOfRange(components, 0, components.length - 1)), (Class<?>) last);
72 + }
73 +
74 + private static ResourceId continuous(ImmutableList.Builder<Object> parentComponents, Class<?> last) {
75 + return new Continuous(parentComponents
76 + .add(last.getCanonicalName())
77 + .build(), last.getSimpleName());
78 + }
79 +
52 private ResourceId(ImmutableList<Object> components) { 80 private ResourceId(ImmutableList<Object> components) {
53 this.components = checkNotNull(components); 81 this.components = checkNotNull(components);
54 } 82 }
...@@ -63,16 +91,32 @@ public final class ResourceId { ...@@ -63,16 +91,32 @@ public final class ResourceId {
63 if (components.size() == 1) { 91 if (components.size() == 1) {
64 return ROOT; 92 return ROOT;
65 } else { 93 } else {
66 - return new ResourceId(components.subList(0, components.size() - 1)); 94 + return new Discrete(components.subList(0, components.size() - 1));
67 } 95 }
68 } 96 }
69 97
70 - ResourceId child(Object child) { 98 + /**
71 - return new ResourceId(ImmutableList.builder() 99 + * Returns a resource ID of a child of this resource based on the specified object.
100 + * If the argument is an instance of {@link Class}, this method returns an instance of
101 + * {@link Continuous}. Otherwise, it returns an instance of {@link Discrete}
102 + * This method only work when the receiver is {@link Discrete}. Otherwise,
103 + * this method throws an exception.
104 + *
105 + * @param child the last component of the child
106 + * @return a child resource ID
107 + */
108 + public ResourceId child(Object child) {
109 + checkState(this instanceof Discrete);
110 +
111 + if (child instanceof Class<?>) {
112 + return continuous(ImmutableList.builder().addAll(components), (Class<?>) child);
113 + } else {
114 + return new Discrete(ImmutableList.builder()
72 .addAll(components) 115 .addAll(components)
73 .add(child) 116 .add(child)
74 .build()); 117 .build());
75 } 118 }
119 + }
76 120
77 @Override 121 @Override
78 public int hashCode() { 122 public int hashCode() {
...@@ -84,11 +128,10 @@ public final class ResourceId { ...@@ -84,11 +128,10 @@ public final class ResourceId {
84 if (this == obj) { 128 if (this == obj) {
85 return true; 129 return true;
86 } 130 }
87 - if (!(obj instanceof ResourceId)) { 131 + if (obj == null || getClass() != obj.getClass()) {
88 return false; 132 return false;
89 } 133 }
90 - 134 + final ResourceId other = (ResourceId) obj;
91 - ResourceId other = (ResourceId) obj;
92 return Objects.equals(this.components, other.components); 135 return Objects.equals(this.components, other.components);
93 } 136 }
94 137
...@@ -96,4 +139,45 @@ public final class ResourceId { ...@@ -96,4 +139,45 @@ public final class ResourceId {
96 public String toString() { 139 public String toString() {
97 return components.toString(); 140 return components.toString();
98 } 141 }
142 +
143 + /**
144 + * ResourceId for {@link Resource.Discrete}.
145 + *
146 + * Note: This class is exposed to the public, but intended to be used in the resource API
147 + * implementation only. It is not for resource API user.
148 + */
149 + public static final class Discrete extends ResourceId {
150 + private Discrete(ImmutableList<Object> components) {
151 + super(components);
152 + }
153 +
154 + private Discrete() {
155 + super();
156 + }
157 + }
158 +
159 + /**
160 + * ResourceId for {@link Resource.Continuous}
161 + *
162 + * Note: This class is exposed to the public, but intended to be used in the resource API
163 + * implementation only. It is not for resource API user.
164 + */
165 + public static final class Continuous extends ResourceId {
166 + // for printing purpose only (used in toString() implementation)
167 + private final String name;
168 +
169 + private Continuous(ImmutableList<Object> components, String name) {
170 + super(components);
171 + this.name = checkNotNull(name);
172 + }
173 +
174 + @Override
175 + public String toString() {
176 + // due to performance consideration, the value might need to be stored in a field
177 + return ImmutableList.builder()
178 + .addAll(components.subList(0, components.size() - 1))
179 + .add(name)
180 + .build().toString();
181 + }
182 + }
99 } 183 }
......
...@@ -132,6 +132,7 @@ public interface ResourceService extends ListenerService<ResourceEvent, Resource ...@@ -132,6 +132,7 @@ public interface ResourceService extends ListenerService<ResourceEvent, Resource
132 * @return list of allocation information. 132 * @return list of allocation information.
133 * If the resource is not allocated, the return value is an empty list. 133 * If the resource is not allocated, the return value is an empty list.
134 */ 134 */
135 + // TODO: need to change the argument type to ResourceId
135 List<ResourceAllocation> getResourceAllocation(Resource resource); 136 List<ResourceAllocation> getResourceAllocation(Resource resource);
136 137
137 /** 138 /**
...@@ -143,6 +144,7 @@ public interface ResourceService extends ListenerService<ResourceEvent, Resource ...@@ -143,6 +144,7 @@ public interface ResourceService extends ListenerService<ResourceEvent, Resource
143 * @return non-empty collection of resource allocations if resources are allocated with the subject and type, 144 * @return non-empty collection of resource allocations if resources are allocated with the subject and type,
144 * empty collection if no resource is allocated with the subject and type 145 * empty collection if no resource is allocated with the subject and type
145 */ 146 */
147 + // TODO: might need to change the first argument type to ResourceId or ResourceId.Discrete
146 <T> Collection<ResourceAllocation> getResourceAllocations(Resource parent, Class<T> cls); 148 <T> Collection<ResourceAllocation> getResourceAllocations(Resource parent, Class<T> cls);
147 149
148 /** 150 /**
...@@ -159,6 +161,7 @@ public interface ResourceService extends ListenerService<ResourceEvent, Resource ...@@ -159,6 +161,7 @@ public interface ResourceService extends ListenerService<ResourceEvent, Resource
159 * @param parent parent resource 161 * @param parent parent resource
160 * @return available resources under the specified resource 162 * @return available resources under the specified resource
161 */ 163 */
164 + // TODO: need to change the argument type to ResourceId or ResourceId.Discrete
162 Collection<Resource> getAvailableResources(Resource parent); 165 Collection<Resource> getAvailableResources(Resource parent);
163 166
164 /** 167 /**
...@@ -167,6 +170,7 @@ public interface ResourceService extends ListenerService<ResourceEvent, Resource ...@@ -167,6 +170,7 @@ public interface ResourceService extends ListenerService<ResourceEvent, Resource
167 * @param parent parent resource 170 * @param parent parent resource
168 * @return registered resources under the specified resource 171 * @return registered resources under the specified resource
169 */ 172 */
173 + // TODO: need to change the argument type to ResourceId or ResourceId.Discrete
170 Collection<Resource> getRegisteredResources(Resource parent); 174 Collection<Resource> getRegisteredResources(Resource parent);
171 175
172 176
......
...@@ -84,6 +84,7 @@ public interface ResourceStore extends Store<ResourceEvent, ResourceStoreDelegat ...@@ -84,6 +84,7 @@ public interface ResourceStore extends Store<ResourceEvent, ResourceStoreDelegat
84 * @return resource consumers who are allocated the resource. 84 * @return resource consumers who are allocated the resource.
85 * Returns empty list if there is no such consumer. 85 * Returns empty list if there is no such consumer.
86 */ 86 */
87 + // TODO: need to change the argument type to ResourceId
87 List<ResourceConsumer> getConsumers(Resource resource); 88 List<ResourceConsumer> getConsumers(Resource resource);
88 89
89 /** 90 /**
...@@ -108,6 +109,7 @@ public interface ResourceStore extends Store<ResourceEvent, ResourceStoreDelegat ...@@ -108,6 +109,7 @@ public interface ResourceStore extends Store<ResourceEvent, ResourceStoreDelegat
108 * @param parent parent of the resource to be returned 109 * @param parent parent of the resource to be returned
109 * @return a collection of the child resources of the specified resource 110 * @return a collection of the child resources of the specified resource
110 */ 111 */
112 + // TODO: need to change the argument type to ResourceId or ResourceId.Discrete
111 Collection<Resource> getChildResources(Resource parent); 113 Collection<Resource> getChildResources(Resource parent);
112 114
113 /** 115 /**
...@@ -120,5 +122,6 @@ public interface ResourceStore extends Store<ResourceEvent, ResourceStoreDelegat ...@@ -120,5 +122,6 @@ public interface ResourceStore extends Store<ResourceEvent, ResourceStoreDelegat
120 * @return a collection of the resources which belongs to the specified subject and 122 * @return a collection of the resources which belongs to the specified subject and
121 * whose type is the specified class. 123 * whose type is the specified class.
122 */ 124 */
125 + // TODO: need to change the argument type to ResourceId or ResourceId.Discrete
123 <T> Collection<Resource> getAllocatedResources(Resource parent, Class<T> cls); 126 <T> Collection<Resource> getAllocatedResources(Resource parent, Class<T> cls);
124 } 127 }
......
1 +/*
2 + * Copyright 2016 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 + */
16 +package org.onosproject.net.newresource;
17 +
18 +import org.junit.Test;
19 +import org.onlab.util.Bandwidth;
20 +import org.onosproject.net.DeviceId;
21 +import org.onosproject.net.PortNumber;
22 +
23 +import java.util.Arrays;
24 +
25 +import static org.hamcrest.Matchers.is;
26 +import static org.junit.Assert.assertThat;
27 +
28 +public class ResourceIdTest {
29 + private static final DeviceId D1 = DeviceId.deviceId("a");
30 + private static final PortNumber P1 = PortNumber.portNumber(1);
31 + private static final Bandwidth BW1 = Bandwidth.gbps(1);
32 +
33 + @Test
34 + public void testDiscreteToString() {
35 + ResourceId resource = ResourceId.discrete(D1, P1);
36 +
37 + assertThat(resource.toString(), is(Arrays.asList(D1, P1).toString()));
38 + }
39 +
40 + @Test
41 + public void testContinuousToString() {
42 + ResourceId resource = ResourceId.continuous(D1, P1, Bandwidth.class);
43 +
44 + assertThat(resource.toString(), is(Arrays.asList(D1, P1, Bandwidth.class.getSimpleName()).toString()));
45 + }
46 +
47 + @Test(expected = IllegalArgumentException.class)
48 + public void testInitWithNonClassInstance() {
49 + ResourceId.continuous(D1, P1, BW1);
50 + }
51 +}
...@@ -42,8 +42,8 @@ public class ResourceTest { ...@@ -42,8 +42,8 @@ public class ResourceTest {
42 Resource resource1 = Resource.discrete(D1, P1, VLAN1); 42 Resource resource1 = Resource.discrete(D1, P1, VLAN1);
43 Resource sameAsResource1 = Resource.discrete(D1, P1, VLAN1); 43 Resource sameAsResource1 = Resource.discrete(D1, P1, VLAN1);
44 Resource resource2 = Resource.discrete(D2, P1, VLAN1); 44 Resource resource2 = Resource.discrete(D2, P1, VLAN1);
45 - Resource resource3 = Resource.continuous(BW1.bps(), D1, P1, BW1); 45 + Resource resource3 = Resource.continuous(BW1.bps(), D1, P1, Bandwidth.class);
46 - Resource sameAsResource3 = Resource.continuous(BW1.bps(), D1, P1, BW1); 46 + Resource sameAsResource3 = Resource.continuous(BW1.bps(), D1, P1, Bandwidth.class);
47 47
48 new EqualsTester() 48 new EqualsTester()
49 .addEqualityGroup(resource1, sameAsResource1) 49 .addEqualityGroup(resource1, sameAsResource1)
...@@ -64,9 +64,9 @@ public class ResourceTest { ...@@ -64,9 +64,9 @@ public class ResourceTest {
64 ResourceId id1 = Resource.discrete(D1, P1, VLAN1).id(); 64 ResourceId id1 = Resource.discrete(D1, P1, VLAN1).id();
65 ResourceId sameAsId1 = Resource.discrete(D1, P1, VLAN1).id(); 65 ResourceId sameAsId1 = Resource.discrete(D1, P1, VLAN1).id();
66 ResourceId id2 = Resource.discrete(D2, P1, VLAN1).id(); 66 ResourceId id2 = Resource.discrete(D2, P1, VLAN1).id();
67 - ResourceId id3 = Resource.continuous(BW1.bps(), D1, P1, BW1).id(); 67 + ResourceId id3 = Resource.continuous(BW1.bps(), D1, P1, Bandwidth.class).id();
68 // intentionally set a different value 68 // intentionally set a different value
69 - ResourceId sameAsId3 = Resource.continuous(BW2.bps(), D1, P1, BW1).id(); 69 + ResourceId sameAsId3 = Resource.continuous(BW2.bps(), D1, P1, Bandwidth.class).id();
70 70
71 new EqualsTester() 71 new EqualsTester()
72 .addEqualityGroup(id1, sameAsId1) 72 .addEqualityGroup(id1, sameAsId1)
...@@ -104,4 +104,20 @@ public class ResourceTest { ...@@ -104,4 +104,20 @@ public class ResourceTest {
104 DeviceId child = (DeviceId) resource.last(); 104 DeviceId child = (DeviceId) resource.last();
105 assertThat(child, is(D1)); 105 assertThat(child, is(D1));
106 } 106 }
107 +
108 + @Test
109 + public void testVolumeOfDiscrete() {
110 + Resource resource = Resource.discrete(D1);
111 +
112 + DeviceId volume = resource.volume();
113 + assertThat(volume, is(D1));
114 + }
115 +
116 + @Test
117 + public void testVolumeOfContinuous() {
118 + Resource resource = Resource.continuous(BW1.bps(), D1, P1, Bandwidth.class);
119 +
120 + double volume = resource.volume();
121 + assertThat(volume, is(BW1.bps()));
122 + }
107 } 123 }
......
...@@ -339,7 +339,7 @@ public class ConsistentResourceStore extends AbstractStore<ResourceEvent, Resour ...@@ -339,7 +339,7 @@ public class ConsistentResourceStore extends AbstractStore<ResourceEvent, Resour
339 } else { 339 } else {
340 Resource.Continuous requested = (Resource.Continuous) resource; 340 Resource.Continuous requested = (Resource.Continuous) resource;
341 Resource.Continuous registered = v.value().stream() 341 Resource.Continuous registered = v.value().stream()
342 - .filter(c -> c.equals(resource)) 342 + .filter(c -> c.id().equals(resource.id()))
343 .findFirst() 343 .findFirst()
344 .map(c -> (Resource.Continuous) c) 344 .map(c -> (Resource.Continuous) c)
345 .get(); 345 .get();
...@@ -415,7 +415,7 @@ public class ConsistentResourceStore extends AbstractStore<ResourceEvent, Resour ...@@ -415,7 +415,7 @@ public class ConsistentResourceStore extends AbstractStore<ResourceEvent, Resour
415 .filter(discreteConsumers::containsKey); 415 .filter(discreteConsumers::containsKey);
416 416
417 Stream<Resource.Continuous> continuous = children.value().stream() 417 Stream<Resource.Continuous> continuous = children.value().stream()
418 - .filter(x -> x.last().getClass().equals(cls)) 418 + .filter(x -> x.id().equals(parent.id().child(cls)))
419 .filter(x -> x instanceof Resource.Continuous) 419 .filter(x -> x instanceof Resource.Continuous)
420 .map(x -> (Resource.Continuous) x) 420 .map(x -> (Resource.Continuous) x)
421 .filter(x -> continuousConsumers.containsKey(x.id())) 421 .filter(x -> continuousConsumers.containsKey(x.id()))
......
...@@ -437,6 +437,8 @@ public final class KryoNamespaces { ...@@ -437,6 +437,8 @@ public final class KryoNamespaces {
437 Resource.Discrete.class, 437 Resource.Discrete.class,
438 Resource.Continuous.class, 438 Resource.Continuous.class,
439 ResourceId.class, 439 ResourceId.class,
440 + ResourceId.Discrete.class,
441 + ResourceId.Continuous.class,
440 ResourceAllocation.class, 442 ResourceAllocation.class,
441 // Constraints 443 // Constraints
442 LambdaConstraint.class, 444 LambdaConstraint.class,
......