ONOS-2445: Implement API to declare resource boundary
Change-Id: I91cd59a068a1ec2624089c3a60eb21e0bf7e12c7
diff --git a/core/api/src/main/java/org/onosproject/net/newresource/ResourceAdminService.java b/core/api/src/main/java/org/onosproject/net/newresource/ResourceAdminService.java
new file mode 100644
index 0000000..5fcb132
--- /dev/null
+++ b/core/api/src/main/java/org/onosproject/net/newresource/ResourceAdminService.java
@@ -0,0 +1,37 @@
+/*
+ * Copyright 2015 Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.net.newresource;
+
+import com.google.common.annotations.Beta;
+
+import java.util.function.Predicate;
+
+/**
+ * Service for administering resource service behavior.
+ */
+@Beta
+public interface ResourceAdminService {
+ /**
+ * Define a boundary of the resource specified by the class.
+ * The specified predicate is expected to return true if the supplied value is
+ * in the resource boundary and return false if it is out of the boundary.
+ *
+ * @param cls class of the resource type
+ * @param predicate predicate returning true if the value is in the boundary
+ * @param <T> type of the resource
+ */
+ <T> void defineResourceBoundary(Class<T> cls, Predicate<T> predicate);
+}
diff --git a/core/net/src/main/java/org/onosproject/net/newresource/impl/ResourceManager.java b/core/net/src/main/java/org/onosproject/net/newresource/impl/ResourceManager.java
index 3ebbdc0..785613c 100644
--- a/core/net/src/main/java/org/onosproject/net/newresource/impl/ResourceManager.java
+++ b/core/net/src/main/java/org/onosproject/net/newresource/impl/ResourceManager.java
@@ -24,6 +24,7 @@
import org.onosproject.net.newresource.DefaultResource;
import org.onosproject.net.newresource.DefaultResourceAllocation;
import org.onosproject.net.newresource.Resource;
+import org.onosproject.net.newresource.ResourceAdminService;
import org.onosproject.net.newresource.ResourceAllocation;
import org.onosproject.net.newresource.ResourceConsumer;
import org.onosproject.net.newresource.ResourceService;
@@ -34,6 +35,9 @@
import java.util.Collection;
import java.util.List;
import java.util.Optional;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+import java.util.function.Predicate;
import java.util.stream.Collectors;
import static com.google.common.base.Preconditions.checkNotNull;
@@ -44,7 +48,9 @@
@Component(immediate = true, enabled = false)
@Service
@Beta
-public final class ResourceManager implements ResourceService {
+public final class ResourceManager implements ResourceService, ResourceAdminService {
+
+ private final ConcurrentMap<Class<?>, Predicate<?>> boundaries = new ConcurrentHashMap<>();
@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
protected ResourceStore store;
@@ -175,6 +181,24 @@
return !consumer.isPresent();
}
+ @Override
+ public <T> void defineResourceBoundary(Class<T> cls, Predicate<T> predicate) {
+ boundaries.put(cls, predicate);
+ }
+
+ /**
+ * Returns the predicate associated with the specified resource.
+ *
+ * @param resource resource whose associated predicate is to be returned
+ * @param <T> type of the resource
+ * @return predicate associated with the resource
+ * Null if the resource doesn't have an associated predicate.
+ */
+ @SuppressWarnings("unchecked")
+ private <T> Predicate<T> lookupPredicate(T resource) {
+ return (Predicate<T>) boundaries.get(resource.getClass());
+ }
+
/**
* Returns if the specified resource is in the resource range.
* E.g. VLAN ID against a link must be within 12 bit address space.
@@ -184,8 +208,12 @@
* @param <T> type of the resource
* @return true if the resource within the range, false otherwise
*/
- private <S, T> boolean isValid(Resource<S, T> resource) {
- // TODO: implement
- return true;
+ <S, T> boolean isValid(Resource<S, T> resource) {
+ Predicate<T> predicate = lookupPredicate(resource.resource());
+ if (predicate == null) {
+ return true;
+ }
+
+ return predicate.test(resource.resource());
}
}
diff --git a/core/net/src/test/java/org/onosproject/net/newresource/impl/ResourceManagerTest.java b/core/net/src/test/java/org/onosproject/net/newresource/impl/ResourceManagerTest.java
new file mode 100644
index 0000000..f3b61fc
--- /dev/null
+++ b/core/net/src/test/java/org/onosproject/net/newresource/impl/ResourceManagerTest.java
@@ -0,0 +1,101 @@
+/*
+ * Copyright 2015 Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.net.newresource.impl;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.onlab.packet.VlanId;
+import org.onosproject.net.ConnectPoint;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.LinkKey;
+import org.onosproject.net.PortNumber;
+import org.onosproject.net.newresource.DefaultResource;
+
+import java.util.function.Predicate;
+
+import static org.hamcrest.Matchers.is;
+import static org.junit.Assert.*;
+
+/**
+ * Unit tests for ResourceManager.
+ */
+public class ResourceManagerTest {
+
+ private static final DeviceId D1 = DeviceId.deviceId("of:001");
+ private static final DeviceId D2 = DeviceId.deviceId("of:002");
+ private static final PortNumber P1 = PortNumber.portNumber(1);
+ private static final ConnectPoint CP1_1 = new ConnectPoint(D1, P1);
+ private static final ConnectPoint CP2_1 = new ConnectPoint(D2, P1);
+ private static final short VLAN_LOWER_LIMIT = 0;
+ private static final short VLAN_UPPER_LIMIT = 1024;
+
+ private final Predicate<VlanId> vlanPredicate =
+ x -> x.toShort() >= VLAN_LOWER_LIMIT && x.toShort() < VLAN_UPPER_LIMIT;
+ private ResourceManager manager;
+
+ @Before
+ public void setUp() {
+ manager = new ResourceManager();
+ }
+
+ /**
+ * Tests resource boundaries.
+ */
+ @Test
+ public void testBoundary() {
+ manager.defineResourceBoundary(VlanId.class, vlanPredicate);
+
+ LinkKey linkKey = LinkKey.linkKey(CP1_1, CP2_1);
+
+ assertThat(manager.isValid(new DefaultResource<>(linkKey, VlanId.vlanId((short) (VLAN_LOWER_LIMIT - 1)))),
+ is(false));
+
+ assertThat(manager.isValid(new DefaultResource<>(linkKey, VlanId.vlanId(VLAN_LOWER_LIMIT))),
+ is(true));
+
+ assertThat(manager.isValid(new DefaultResource<>(linkKey, VlanId.vlanId((short) 100))),
+ is(true));
+
+ assertThat(manager.isValid(new DefaultResource<>(linkKey, VlanId.vlanId((short) (VLAN_UPPER_LIMIT - 1)))),
+ is(true));
+
+ assertThat(manager.isValid(new DefaultResource<>(linkKey, VlanId.vlanId(VLAN_UPPER_LIMIT))),
+ is(false));
+ }
+
+ /**
+ * Tests the case that a boundary is not set.
+ */
+ @Test
+ public void testWhenBoundaryNotSet() {
+ LinkKey linkKey = LinkKey.linkKey(CP1_1, CP2_1);
+
+ assertThat(manager.isValid(new DefaultResource<>(linkKey, VlanId.vlanId((short) (VLAN_LOWER_LIMIT - 1)))),
+ is(true));
+
+ assertThat(manager.isValid(new DefaultResource<>(linkKey, VlanId.vlanId(VLAN_LOWER_LIMIT))),
+ is(true));
+
+ assertThat(manager.isValid(new DefaultResource<>(linkKey, VlanId.vlanId((short) 100))),
+ is(true));
+
+ assertThat(manager.isValid(new DefaultResource<>(linkKey, VlanId.vlanId((short) (VLAN_UPPER_LIMIT - 1)))),
+ is(true));
+
+ assertThat(manager.isValid(new DefaultResource<>(linkKey, VlanId.vlanId(VLAN_UPPER_LIMIT))),
+ is(true));
+ }
+}