Sho SHIMIZU
Committed by Gerrit Code Review

ONOS-2445: Implement API to declare resource boundary

Change-Id: I91cd59a068a1ec2624089c3a60eb21e0bf7e12c7
1 +/*
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 + */
16 +package org.onosproject.net.newresource;
17 +
18 +import com.google.common.annotations.Beta;
19 +
20 +import java.util.function.Predicate;
21 +
22 +/**
23 + * Service for administering resource service behavior.
24 + */
25 +@Beta
26 +public interface ResourceAdminService {
27 + /**
28 + * Define a boundary of the resource specified by the class.
29 + * The specified predicate is expected to return true if the supplied value is
30 + * in the resource boundary and return false if it is out of the boundary.
31 + *
32 + * @param cls class of the resource type
33 + * @param predicate predicate returning true if the value is in the boundary
34 + * @param <T> type of the resource
35 + */
36 + <T> void defineResourceBoundary(Class<T> cls, Predicate<T> predicate);
37 +}
...@@ -24,6 +24,7 @@ import org.apache.felix.scr.annotations.Service; ...@@ -24,6 +24,7 @@ import org.apache.felix.scr.annotations.Service;
24 import org.onosproject.net.newresource.DefaultResource; 24 import org.onosproject.net.newresource.DefaultResource;
25 import org.onosproject.net.newresource.DefaultResourceAllocation; 25 import org.onosproject.net.newresource.DefaultResourceAllocation;
26 import org.onosproject.net.newresource.Resource; 26 import org.onosproject.net.newresource.Resource;
27 +import org.onosproject.net.newresource.ResourceAdminService;
27 import org.onosproject.net.newresource.ResourceAllocation; 28 import org.onosproject.net.newresource.ResourceAllocation;
28 import org.onosproject.net.newresource.ResourceConsumer; 29 import org.onosproject.net.newresource.ResourceConsumer;
29 import org.onosproject.net.newresource.ResourceService; 30 import org.onosproject.net.newresource.ResourceService;
...@@ -34,6 +35,9 @@ import java.util.Arrays; ...@@ -34,6 +35,9 @@ import java.util.Arrays;
34 import java.util.Collection; 35 import java.util.Collection;
35 import java.util.List; 36 import java.util.List;
36 import java.util.Optional; 37 import java.util.Optional;
38 +import java.util.concurrent.ConcurrentHashMap;
39 +import java.util.concurrent.ConcurrentMap;
40 +import java.util.function.Predicate;
37 import java.util.stream.Collectors; 41 import java.util.stream.Collectors;
38 42
39 import static com.google.common.base.Preconditions.checkNotNull; 43 import static com.google.common.base.Preconditions.checkNotNull;
...@@ -44,7 +48,9 @@ import static com.google.common.base.Preconditions.checkNotNull; ...@@ -44,7 +48,9 @@ import static com.google.common.base.Preconditions.checkNotNull;
44 @Component(immediate = true, enabled = false) 48 @Component(immediate = true, enabled = false)
45 @Service 49 @Service
46 @Beta 50 @Beta
47 -public final class ResourceManager implements ResourceService { 51 +public final class ResourceManager implements ResourceService, ResourceAdminService {
52 +
53 + private final ConcurrentMap<Class<?>, Predicate<?>> boundaries = new ConcurrentHashMap<>();
48 54
49 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) 55 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
50 protected ResourceStore store; 56 protected ResourceStore store;
...@@ -175,6 +181,24 @@ public final class ResourceManager implements ResourceService { ...@@ -175,6 +181,24 @@ public final class ResourceManager implements ResourceService {
175 return !consumer.isPresent(); 181 return !consumer.isPresent();
176 } 182 }
177 183
184 + @Override
185 + public <T> void defineResourceBoundary(Class<T> cls, Predicate<T> predicate) {
186 + boundaries.put(cls, predicate);
187 + }
188 +
189 + /**
190 + * Returns the predicate associated with the specified resource.
191 + *
192 + * @param resource resource whose associated predicate is to be returned
193 + * @param <T> type of the resource
194 + * @return predicate associated with the resource
195 + * Null if the resource doesn't have an associated predicate.
196 + */
197 + @SuppressWarnings("unchecked")
198 + private <T> Predicate<T> lookupPredicate(T resource) {
199 + return (Predicate<T>) boundaries.get(resource.getClass());
200 + }
201 +
178 /** 202 /**
179 * Returns if the specified resource is in the resource range. 203 * Returns if the specified resource is in the resource range.
180 * E.g. VLAN ID against a link must be within 12 bit address space. 204 * E.g. VLAN ID against a link must be within 12 bit address space.
...@@ -184,8 +208,12 @@ public final class ResourceManager implements ResourceService { ...@@ -184,8 +208,12 @@ public final class ResourceManager implements ResourceService {
184 * @param <T> type of the resource 208 * @param <T> type of the resource
185 * @return true if the resource within the range, false otherwise 209 * @return true if the resource within the range, false otherwise
186 */ 210 */
187 - private <S, T> boolean isValid(Resource<S, T> resource) { 211 + <S, T> boolean isValid(Resource<S, T> resource) {
188 - // TODO: implement 212 + Predicate<T> predicate = lookupPredicate(resource.resource());
213 + if (predicate == null) {
189 return true; 214 return true;
190 } 215 }
216 +
217 + return predicate.test(resource.resource());
218 + }
191 } 219 }
......
1 +/*
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 + */
16 +package org.onosproject.net.newresource.impl;
17 +
18 +import org.junit.Before;
19 +import org.junit.Test;
20 +import org.onlab.packet.VlanId;
21 +import org.onosproject.net.ConnectPoint;
22 +import org.onosproject.net.DeviceId;
23 +import org.onosproject.net.LinkKey;
24 +import org.onosproject.net.PortNumber;
25 +import org.onosproject.net.newresource.DefaultResource;
26 +
27 +import java.util.function.Predicate;
28 +
29 +import static org.hamcrest.Matchers.is;
30 +import static org.junit.Assert.*;
31 +
32 +/**
33 + * Unit tests for ResourceManager.
34 + */
35 +public class ResourceManagerTest {
36 +
37 + private static final DeviceId D1 = DeviceId.deviceId("of:001");
38 + private static final DeviceId D2 = DeviceId.deviceId("of:002");
39 + private static final PortNumber P1 = PortNumber.portNumber(1);
40 + private static final ConnectPoint CP1_1 = new ConnectPoint(D1, P1);
41 + private static final ConnectPoint CP2_1 = new ConnectPoint(D2, P1);
42 + private static final short VLAN_LOWER_LIMIT = 0;
43 + private static final short VLAN_UPPER_LIMIT = 1024;
44 +
45 + private final Predicate<VlanId> vlanPredicate =
46 + x -> x.toShort() >= VLAN_LOWER_LIMIT && x.toShort() < VLAN_UPPER_LIMIT;
47 + private ResourceManager manager;
48 +
49 + @Before
50 + public void setUp() {
51 + manager = new ResourceManager();
52 + }
53 +
54 + /**
55 + * Tests resource boundaries.
56 + */
57 + @Test
58 + public void testBoundary() {
59 + manager.defineResourceBoundary(VlanId.class, vlanPredicate);
60 +
61 + LinkKey linkKey = LinkKey.linkKey(CP1_1, CP2_1);
62 +
63 + assertThat(manager.isValid(new DefaultResource<>(linkKey, VlanId.vlanId((short) (VLAN_LOWER_LIMIT - 1)))),
64 + is(false));
65 +
66 + assertThat(manager.isValid(new DefaultResource<>(linkKey, VlanId.vlanId(VLAN_LOWER_LIMIT))),
67 + is(true));
68 +
69 + assertThat(manager.isValid(new DefaultResource<>(linkKey, VlanId.vlanId((short) 100))),
70 + is(true));
71 +
72 + assertThat(manager.isValid(new DefaultResource<>(linkKey, VlanId.vlanId((short) (VLAN_UPPER_LIMIT - 1)))),
73 + is(true));
74 +
75 + assertThat(manager.isValid(new DefaultResource<>(linkKey, VlanId.vlanId(VLAN_UPPER_LIMIT))),
76 + is(false));
77 + }
78 +
79 + /**
80 + * Tests the case that a boundary is not set.
81 + */
82 + @Test
83 + public void testWhenBoundaryNotSet() {
84 + LinkKey linkKey = LinkKey.linkKey(CP1_1, CP2_1);
85 +
86 + assertThat(manager.isValid(new DefaultResource<>(linkKey, VlanId.vlanId((short) (VLAN_LOWER_LIMIT - 1)))),
87 + is(true));
88 +
89 + assertThat(manager.isValid(new DefaultResource<>(linkKey, VlanId.vlanId(VLAN_LOWER_LIMIT))),
90 + is(true));
91 +
92 + assertThat(manager.isValid(new DefaultResource<>(linkKey, VlanId.vlanId((short) 100))),
93 + is(true));
94 +
95 + assertThat(manager.isValid(new DefaultResource<>(linkKey, VlanId.vlanId((short) (VLAN_UPPER_LIMIT - 1)))),
96 + is(true));
97 +
98 + assertThat(manager.isValid(new DefaultResource<>(linkKey, VlanId.vlanId(VLAN_UPPER_LIMIT))),
99 + is(true));
100 + }
101 +}