[ONOS-5806] Revise virtual provider and provider service
Changes
1. VirtualProvider contains ProviderId
2. VirtualProviderRegistryService Interface is added
3. VirtualProviderManager which is the implementation
of the intetreface is added
Change-Id: I015f0b8d2a6d7ae3bb571f6e1fa0090be3b4f192
diff --git a/incubator/api/src/main/java/org/onosproject/incubator/net/virtual/provider/AbstractVirtualProvider.java b/incubator/api/src/main/java/org/onosproject/incubator/net/virtual/provider/AbstractVirtualProvider.java
index fa5332d..1010417 100644
--- a/incubator/api/src/main/java/org/onosproject/incubator/net/virtual/provider/AbstractVirtualProvider.java
+++ b/incubator/api/src/main/java/org/onosproject/incubator/net/virtual/provider/AbstractVirtualProvider.java
@@ -16,66 +16,22 @@
package org.onosproject.incubator.net.virtual.provider;
-import java.util.Objects;
-
-import static com.google.common.base.MoreObjects.toStringHelper;
+import org.onosproject.net.provider.ProviderId;
public abstract class AbstractVirtualProvider implements VirtualProvider {
- private final String scheme;
- private final String id;
+ private final ProviderId providerId;
/**
- * Creates a provider with the supplied identifier.
+ * Creates a virtual provider with the supplied identifier.
*
- * @param scheme provider scheme
- * @param id provider id
+ * @param id a virtual provider id
*/
- protected AbstractVirtualProvider(String id, String scheme) {
- this.scheme = scheme;
- this.id = id;
- }
-
- /**
- * Returns the device URI scheme to which this provider is bound.
- *
- * @return device URI scheme
- */
- @Override
- public String scheme() {
- return this.scheme;
- }
-
- /**
- * Returns the device URI scheme specific id portion.
- *
- * @return id
- */
- @Override
- public String id() {
- return this.id;
+ protected AbstractVirtualProvider(ProviderId id) {
+ this.providerId = id;
}
@Override
- public int hashCode() {
- return Objects.hash(scheme, id);
- }
-
- @Override
- public boolean equals(Object obj) {
- if (this == obj) {
- return true;
- }
- if (obj instanceof AbstractVirtualProvider) {
- final AbstractVirtualProvider other = (AbstractVirtualProvider) obj;
- return Objects.equals(this.scheme, other.scheme) &&
- Objects.equals(this.id, other.id);
- }
- return false;
- }
-
- @Override
- public String toString() {
- return toStringHelper(this).add("scheme", scheme).add("id", id)
- .toString();
+ public ProviderId id() {
+ return providerId;
}
}
diff --git a/incubator/api/src/main/java/org/onosproject/incubator/net/virtual/provider/AbstractVirtualProviderService.java b/incubator/api/src/main/java/org/onosproject/incubator/net/virtual/provider/AbstractVirtualProviderService.java
index b257d2e..e12f1ef 100644
--- a/incubator/api/src/main/java/org/onosproject/incubator/net/virtual/provider/AbstractVirtualProviderService.java
+++ b/incubator/api/src/main/java/org/onosproject/incubator/net/virtual/provider/AbstractVirtualProviderService.java
@@ -18,13 +18,24 @@
import static com.google.common.base.Preconditions.checkState;
+/**
+ * Base implementation of a virtual provider service,
+ * which tracks the provider to which it is issued and can be invalidated.
+ *
+ * @param <P> type of the information provider
+ */
public abstract class AbstractVirtualProviderService<P extends VirtualProvider>
implements VirtualProviderService {
private boolean isValid = true;
- private final P provider;
+ private P provider = null;
- protected AbstractVirtualProviderService(P provider) {
+ /**
+ * Creates a virtual provider service on behalf of the specified provider.
+ *
+ * @param provider provider to which this service is being issued
+ */
+ protected void setProvider(P provider) {
this.provider = provider;
}
diff --git a/incubator/api/src/main/java/org/onosproject/incubator/net/virtual/provider/VirtualProvider.java b/incubator/api/src/main/java/org/onosproject/incubator/net/virtual/provider/VirtualProvider.java
index e94215d..c9e58e2 100644
--- a/incubator/api/src/main/java/org/onosproject/incubator/net/virtual/provider/VirtualProvider.java
+++ b/incubator/api/src/main/java/org/onosproject/incubator/net/virtual/provider/VirtualProvider.java
@@ -16,6 +16,8 @@
package org.onosproject.incubator.net.virtual.provider;
+import org.onosproject.net.provider.ProviderId;
+
/**
* Abstraction of a provider of information about virtual network environment.
* The role of virtual providers is to translate virtual objects into physical
@@ -24,16 +26,9 @@
public interface VirtualProvider {
/**
- * Returns the device URI scheme to which this provider is bound.
+ * Returns the provider identifier.
*
- * @return device URI scheme
+ * @return provider identification
*/
- String scheme();
-
- /**
- * Returns the device URI scheme specific id portion.
- *
- * @return id
- */
- String id();
+ ProviderId id();
}
diff --git a/incubator/api/src/main/java/org/onosproject/incubator/net/virtual/provider/VirtualProviderRegistryService.java b/incubator/api/src/main/java/org/onosproject/incubator/net/virtual/provider/VirtualProviderRegistryService.java
new file mode 100644
index 0000000..05625e9
--- /dev/null
+++ b/incubator/api/src/main/java/org/onosproject/incubator/net/virtual/provider/VirtualProviderRegistryService.java
@@ -0,0 +1,121 @@
+/*
+ * Copyright 2017-present 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.incubator.net.virtual.provider;
+
+import org.onosproject.incubator.net.virtual.NetworkId;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.provider.ProviderId;
+
+import java.util.Set;
+
+/**
+ * Registry for tracking information providers with the core.
+ */
+public interface VirtualProviderRegistryService {
+
+ /**
+ * Registers the supplied virtual provider.
+ *
+ * @param virtualProvider a virtual provider to be registered
+ * @throws java.lang.IllegalArgumentException if the provider is registered already
+ */
+ void registerProvider(VirtualProvider virtualProvider);
+
+ /**
+ * Unregisters the supplied virtual provider.
+ * As a result the previously issued virtual provider service will be invalidated
+ * and any subsequent invocations of its methods may throw
+ * {@link java.lang.IllegalStateException}.
+ * <p>
+ * Unregistering a virtual provider that has not been previously registered results
+ * in a no-op.
+ * </p>
+ *
+ * @param virtualProvider a virtual provider to be unregistered
+ */
+ void unregisterProvider(VirtualProvider virtualProvider);
+
+ /**
+ * Registers the supplied virtual provider.
+ *
+ * @param networkId a virtual network identifier
+ * @param virtualProviderService a virtual provider service to be registered
+ */
+ void registerProviderService(NetworkId networkId,
+ VirtualProviderService virtualProviderService);
+
+ /**
+ * Unregisters the supplied virtual provider service.
+ *
+ * @param networkId a virtual network identifier
+ * @param virtualProviderService a virtual provider service to be unregistered
+ */
+ void unregisterProviderService(NetworkId networkId,
+ VirtualProviderService virtualProviderService);
+
+ /**
+ * Returns a set of currently registered virtual provider identities.
+ *
+ * @return set of virtual provider identifiers
+ */
+ Set<ProviderId> getProviders();
+
+ /**
+ * Returns a set of currently registered virtual provider identities
+ * corresponding to the requested providerService.
+ *
+ * @param virtualProviderService a virtual provider service
+ * @return set of virtual provider identifiers
+ */
+ Set<ProviderId> getProvidersByService(VirtualProviderService virtualProviderService);
+
+ /**
+ * Returns the virtual provider registered with the specified provider ID or null
+ * if none is found for the given provider family and default fall-back is
+ * not supported.
+ *
+ * @param providerId provider identifier
+ * @return provider
+ */
+ VirtualProvider getProvider(ProviderId providerId);
+
+ /**
+ * Returns the virtual provider for the specified device ID based on URI scheme.
+ *
+ * @param deviceId virtual device identifier
+ * @return provider bound to the URI scheme
+ */
+ VirtualProvider getProvider(DeviceId deviceId);
+
+ /**
+ * Returns the virtual provider registered with the specified scheme.
+ *
+ * @param scheme provider scheme
+ * @return provider
+ */
+ VirtualProvider getProvider(String scheme);
+
+ /**
+ * Returns the virtual provider service corresponding to the virtual network and provider.
+ *
+ * @param networkId a virtual network identifier
+ * @param virtualProvider a virtual provider
+ * @return a virtual provider service
+ */
+ VirtualProviderService getProviderService(NetworkId networkId,
+ VirtualProvider virtualProvider);
+}
diff --git a/incubator/net/src/main/java/org/onosproject/incubator/net/virtual/impl/provider/VirtualProviderManager.java b/incubator/net/src/main/java/org/onosproject/incubator/net/virtual/impl/provider/VirtualProviderManager.java
new file mode 100644
index 0000000..59c6630
--- /dev/null
+++ b/incubator/net/src/main/java/org/onosproject/incubator/net/virtual/impl/provider/VirtualProviderManager.java
@@ -0,0 +1,171 @@
+/*
+ * Copyright 2017-present 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.incubator.net.virtual.impl.provider;
+
+import com.google.common.collect.ImmutableSet;
+import org.apache.felix.scr.annotations.Component;
+import org.apache.felix.scr.annotations.Service;
+import org.onosproject.incubator.net.virtual.NetworkId;
+import org.onosproject.incubator.net.virtual.provider.VirtualProvider;
+import org.onosproject.incubator.net.virtual.provider.VirtualProviderRegistryService;
+import org.onosproject.incubator.net.virtual.provider.VirtualProviderService;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.provider.ProviderId;
+
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+import java.util.stream.Collectors;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+import static com.google.common.base.Preconditions.checkState;
+
+/**
+ * Implementation of the virtual provider registry and providerService registry service.
+ */
+@Component(immediate = true)
+@Service
+public class VirtualProviderManager
+ implements VirtualProviderRegistryService {
+
+ private final Map<ProviderId, VirtualProvider> providers = new HashMap<>();
+ private final Map<ProviderId, VirtualProviderService> servicesWithProvider = new HashMap<>();
+ private final Map<String, VirtualProvider> providersByScheme = new HashMap<>();
+ private final Map<NetworkId, Set<VirtualProviderService>> servicesByNetwork = new HashMap<>();
+
+ @Override
+ public synchronized void registerProvider(VirtualProvider virtualProvider) {
+ checkNotNull(virtualProvider, "Provider cannot be null");
+ checkState(!providers.containsKey(virtualProvider.id()),
+ "Provider %s already registered", virtualProvider.id());
+
+ // If the provider is a primary one, check for a conflict.
+ ProviderId pid = virtualProvider.id();
+ checkState(pid.isAncillary() || !providersByScheme.containsKey(pid.scheme()),
+ "A primary provider with id %s is already registered",
+ providersByScheme.get(pid.scheme()));
+
+ providers.put(virtualProvider.id(), virtualProvider);
+
+ // Register the provider by URI scheme only if it is not ancillary.
+ if (!pid.isAncillary()) {
+ providersByScheme.put(pid.scheme(), virtualProvider);
+ }
+ }
+
+ @Override
+ public synchronized void unregisterProvider(VirtualProvider virtualProvider) {
+ checkNotNull(virtualProvider, "Provider cannot be null");
+
+ //TODO: invalidate provider services witch subscribe the provider
+ providers.remove(virtualProvider.id());
+
+ if (!virtualProvider.id().isAncillary()) {
+ providersByScheme.remove(virtualProvider.id().scheme());
+ }
+ }
+
+ @Override
+ public synchronized void
+ registerProviderService(NetworkId networkId,
+ VirtualProviderService virtualProviderService) {
+ Set<VirtualProviderService> services = servicesByNetwork.get(networkId);
+
+ if (services == null) {
+ services = new HashSet<>();
+ servicesByNetwork.put(networkId, services);
+ }
+ services.add(virtualProviderService);
+ }
+
+ @Override
+ public synchronized void
+ unregisterProviderService(NetworkId networkId,
+ VirtualProviderService virtualProviderService) {
+ Set<VirtualProviderService> services = servicesByNetwork.get(networkId);
+
+ if (services != null) {
+ services.remove(virtualProviderService);
+ }
+ }
+
+ @Override
+ public synchronized Set<ProviderId> getProviders() {
+ return ImmutableSet.copyOf(providers.keySet());
+ }
+
+ @Override
+ public Set<ProviderId> getProvidersByService(VirtualProviderService virtualProviderService) {
+ Class clazz = getProviderClass(virtualProviderService);
+
+ return ImmutableSet.copyOf(providers.values().stream()
+ .filter(p -> p.getClass()
+ .isAssignableFrom(clazz))
+ .map(p -> p.id()).collect(Collectors.toSet()));
+ }
+
+ @Override
+ public synchronized VirtualProvider getProvider(ProviderId providerId) {
+ return providers.get(providerId);
+ }
+
+ @Override
+ public synchronized VirtualProvider getProvider(DeviceId deviceId) {
+ return providersByScheme.get(deviceId.uri().getScheme());
+ }
+
+ @Override
+ public synchronized VirtualProvider getProvider(String scheme) {
+ return providersByScheme.get(scheme);
+ }
+
+ @Override
+ public synchronized VirtualProviderService
+ getProviderService(NetworkId networkId, VirtualProvider virtualProvider) {
+ Set<VirtualProviderService> services = servicesByNetwork.get(networkId);
+
+ if (services == null) {
+ return null;
+ }
+
+ return services.stream()
+ .filter(s -> virtualProvider.getClass()
+ .isAssignableFrom(getProviderClass(s)))
+ .findFirst().get();
+ }
+
+ /**
+ * Returns the class type of parameter type.
+ * More specifically, it returns the class type of provider service's provider type.
+ *
+ * @param service a virtual provider service
+ * @return the class type of provider service of the service
+ */
+ private Class getProviderClass(VirtualProviderService service) {
+ String className = service.getClass().getGenericSuperclass().getTypeName();
+ String pramType = className.split("<")[1].split(">")[0];
+
+ try {
+ return Class.forName(pramType);
+ } catch (ClassNotFoundException e) {
+ e.printStackTrace();
+ }
+
+ return null;
+ }
+}
diff --git a/incubator/net/src/test/java/org/onosproject/incubator/net/virtual/impl/provider/VirtualProviderManagerTest.java b/incubator/net/src/test/java/org/onosproject/incubator/net/virtual/impl/provider/VirtualProviderManagerTest.java
new file mode 100644
index 0000000..f952633
--- /dev/null
+++ b/incubator/net/src/test/java/org/onosproject/incubator/net/virtual/impl/provider/VirtualProviderManagerTest.java
@@ -0,0 +1,104 @@
+/*
+ * Copyright 2017-present 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.incubator.net.virtual.impl.provider;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.onosproject.incubator.net.virtual.NetworkId;
+import org.onosproject.incubator.net.virtual.provider.AbstractVirtualProvider;
+import org.onosproject.incubator.net.virtual.provider.AbstractVirtualProviderService;
+import org.onosproject.net.provider.ProviderId;
+
+import static org.junit.Assert.assertEquals;
+
+public class VirtualProviderManagerTest {
+
+ private static final String TEST_SCHEME1 = "test1";
+ private static final String TEST_SCHEME2 = "test2";
+ private static final String TEST_ID1 = "org.onosproject.virtual.testprovider1";
+ private static final String TEST_ID2 = "org.onosproject.virtual.testprovider1";
+ private static final NetworkId NETWORK_ID1 = NetworkId.networkId(1);
+ private static final NetworkId NETWORK_ID2 = NetworkId.networkId(2);
+
+ VirtualProviderManager virtualProviderManager;
+
+ @Before
+ public void setUp() throws Exception {
+ virtualProviderManager = new VirtualProviderManager();
+ }
+
+ /**
+ * Tests registerProvider() and unregisterProvider().
+ */
+ @Test
+ public void registerProviderTest() {
+ TestProvider1 provider1 = new TestProvider1();
+ virtualProviderManager.registerProvider(provider1);
+
+ assertEquals("The number of registered provider did not match.", 1,
+ virtualProviderManager.getProviders().size());
+
+ assertEquals("The registered provider did not match", provider1,
+ virtualProviderManager.getProvider(TEST_SCHEME1));
+
+ virtualProviderManager.unregisterProvider(provider1);
+
+ TestProvider2 provider2 = new TestProvider2();
+ virtualProviderManager.registerProvider(provider2);
+
+ assertEquals("The number of registered provider did not match.", 1,
+ virtualProviderManager.getProviders().size());
+
+ virtualProviderManager.unregisterProvider(provider2);
+
+ assertEquals("The number of registered provider did not match.", 0,
+ virtualProviderManager.getProviders().size());
+ }
+
+ /**
+ * Tests registerProviderService() and getProviderService().
+ */
+ @Test
+ public void registerProviderServiceTest() {
+ TestProvider1 provider1 = new TestProvider1();
+ virtualProviderManager.registerProvider(provider1);
+
+ TestProviderService1 providerService1 = new TestProviderService1();
+ virtualProviderManager.registerProviderService(NETWORK_ID1, providerService1);
+
+ assertEquals(providerService1,
+ virtualProviderManager.getProviderService(NETWORK_ID1, provider1));
+ }
+
+ private class TestProvider1 extends AbstractVirtualProvider {
+ protected TestProvider1() {
+ super(new ProviderId(TEST_SCHEME1, TEST_ID1));
+ }
+ }
+
+ private class TestProvider2 extends AbstractVirtualProvider {
+ protected TestProvider2() {
+ super(new ProviderId(TEST_SCHEME2, TEST_ID2));
+ }
+ }
+
+ private class TestProviderService1 extends AbstractVirtualProviderService<TestProvider1> {
+ }
+
+ private class TestProviderService2 extends AbstractVirtualProviderService<TestProvider2> {
+ }
+}