blob: 77cac7814eca0ae2e1c746f97aac522e9e46418a [file] [log] [blame]
yoonseon1f518572017-01-03 17:27:26 -08001/*
Brian O'Connora09fe5b2017-08-03 21:12:30 -07002 * Copyright 2017-present Open Networking Foundation
yoonseon1f518572017-01-03 17:27:26 -08003 *
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
17package org.onosproject.incubator.net.virtual.impl.provider;
18
19import com.google.common.collect.ImmutableSet;
20import org.apache.felix.scr.annotations.Component;
21import org.apache.felix.scr.annotations.Service;
22import org.onosproject.incubator.net.virtual.NetworkId;
23import org.onosproject.incubator.net.virtual.provider.VirtualProvider;
24import org.onosproject.incubator.net.virtual.provider.VirtualProviderRegistryService;
25import org.onosproject.incubator.net.virtual.provider.VirtualProviderService;
26import org.onosproject.net.DeviceId;
27import org.onosproject.net.provider.ProviderId;
Ray Milkeyba547f92018-02-01 15:22:31 -080028import org.slf4j.Logger;
29import org.slf4j.LoggerFactory;
yoonseon1f518572017-01-03 17:27:26 -080030
31import java.util.HashMap;
32import java.util.HashSet;
33import java.util.Map;
34import java.util.Set;
35import java.util.stream.Collectors;
36
37import static com.google.common.base.Preconditions.checkNotNull;
38import static com.google.common.base.Preconditions.checkState;
39
40/**
41 * Implementation of the virtual provider registry and providerService registry service.
42 */
43@Component(immediate = true)
44@Service
45public class VirtualProviderManager
46 implements VirtualProviderRegistryService {
47
48 private final Map<ProviderId, VirtualProvider> providers = new HashMap<>();
49 private final Map<ProviderId, VirtualProviderService> servicesWithProvider = new HashMap<>();
50 private final Map<String, VirtualProvider> providersByScheme = new HashMap<>();
51 private final Map<NetworkId, Set<VirtualProviderService>> servicesByNetwork = new HashMap<>();
Ray Milkeyba547f92018-02-01 15:22:31 -080052 private static Logger log = LoggerFactory.getLogger(VirtualProviderManager.class);
yoonseon1f518572017-01-03 17:27:26 -080053
54 @Override
55 public synchronized void registerProvider(VirtualProvider virtualProvider) {
56 checkNotNull(virtualProvider, "Provider cannot be null");
57 checkState(!providers.containsKey(virtualProvider.id()),
58 "Provider %s already registered", virtualProvider.id());
59
60 // If the provider is a primary one, check for a conflict.
61 ProviderId pid = virtualProvider.id();
62 checkState(pid.isAncillary() || !providersByScheme.containsKey(pid.scheme()),
63 "A primary provider with id %s is already registered",
64 providersByScheme.get(pid.scheme()));
65
66 providers.put(virtualProvider.id(), virtualProvider);
67
68 // Register the provider by URI scheme only if it is not ancillary.
69 if (!pid.isAncillary()) {
70 providersByScheme.put(pid.scheme(), virtualProvider);
71 }
72 }
73
74 @Override
75 public synchronized void unregisterProvider(VirtualProvider virtualProvider) {
76 checkNotNull(virtualProvider, "Provider cannot be null");
77
sangyun-han43c56702017-07-11 11:55:28 +090078 //TODO: invalidate provider services which subscribe the provider
yoonseon1f518572017-01-03 17:27:26 -080079 providers.remove(virtualProvider.id());
80
81 if (!virtualProvider.id().isAncillary()) {
82 providersByScheme.remove(virtualProvider.id().scheme());
83 }
84 }
85
86 @Override
87 public synchronized void
88 registerProviderService(NetworkId networkId,
89 VirtualProviderService virtualProviderService) {
Yoonseon Hanc8089db2017-03-22 20:22:12 +090090 Set<VirtualProviderService> services =
91 servicesByNetwork.computeIfAbsent(networkId, k -> new HashSet<>());
yoonseon1f518572017-01-03 17:27:26 -080092
yoonseon1f518572017-01-03 17:27:26 -080093 services.add(virtualProviderService);
94 }
95
96 @Override
97 public synchronized void
98 unregisterProviderService(NetworkId networkId,
99 VirtualProviderService virtualProviderService) {
100 Set<VirtualProviderService> services = servicesByNetwork.get(networkId);
101
102 if (services != null) {
103 services.remove(virtualProviderService);
104 }
105 }
106
107 @Override
108 public synchronized Set<ProviderId> getProviders() {
109 return ImmutableSet.copyOf(providers.keySet());
110 }
111
112 @Override
yoonseonbd8a93d2016-12-07 15:51:21 -0800113 public Set<ProviderId> getProvidersByService(VirtualProviderService
114 virtualProviderService) {
yoonseon1f518572017-01-03 17:27:26 -0800115 Class clazz = getProviderClass(virtualProviderService);
116
117 return ImmutableSet.copyOf(providers.values().stream()
yoonseonbd8a93d2016-12-07 15:51:21 -0800118 .filter(clazz::isInstance)
119 .map(VirtualProvider::id)
120 .collect(Collectors.toSet()));
yoonseon1f518572017-01-03 17:27:26 -0800121 }
122
123 @Override
124 public synchronized VirtualProvider getProvider(ProviderId providerId) {
125 return providers.get(providerId);
126 }
127
128 @Override
129 public synchronized VirtualProvider getProvider(DeviceId deviceId) {
130 return providersByScheme.get(deviceId.uri().getScheme());
131 }
132
133 @Override
134 public synchronized VirtualProvider getProvider(String scheme) {
135 return providersByScheme.get(scheme);
136 }
137
138 @Override
139 public synchronized VirtualProviderService
Yoonseon Hanc70b4e02016-10-20 15:24:33 -0700140 getProviderService(NetworkId networkId, Class<? extends VirtualProvider> providerClass) {
yoonseon1f518572017-01-03 17:27:26 -0800141 Set<VirtualProviderService> services = servicesByNetwork.get(networkId);
142
143 if (services == null) {
144 return null;
145 }
146
147 return services.stream()
Yoonseon Hanc70b4e02016-10-20 15:24:33 -0700148 .filter(s -> getProviderClass(s).equals(providerClass))
Yoonseon Hanc8089db2017-03-22 20:22:12 +0900149 .findFirst().orElse(null);
yoonseon1f518572017-01-03 17:27:26 -0800150 }
151
152 /**
153 * Returns the class type of parameter type.
154 * More specifically, it returns the class type of provider service's provider type.
155 *
156 * @param service a virtual provider service
157 * @return the class type of provider service of the service
158 */
159 private Class getProviderClass(VirtualProviderService service) {
160 String className = service.getClass().getGenericSuperclass().getTypeName();
161 String pramType = className.split("<")[1].split(">")[0];
162
163 try {
164 return Class.forName(pramType);
165 } catch (ClassNotFoundException e) {
Ray Milkeyba547f92018-02-01 15:22:31 -0800166 log.warn("getProviderClass()", e);
yoonseon1f518572017-01-03 17:27:26 -0800167 }
168
169 return null;
170 }
171}