/* * 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.computeIfAbsent(networkId, k -> new HashSet<>()); 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(clazz::isInstance) .map(VirtualProvider::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, Class<? extends VirtualProvider> providerClass) { Set<VirtualProviderService> services = servicesByNetwork.get(networkId); if (services == null) { return null; } return services.stream() .filter(s -> getProviderClass(s).equals(providerClass)) .findFirst().orElse(null); } /** * 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; } }