blob: ebd87ea9a86dc5d60ce35aa53be2b2a40f94a99d [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;
yoonseon1f518572017-01-03 17:27:26 -080020import org.onosproject.incubator.net.virtual.NetworkId;
21import org.onosproject.incubator.net.virtual.provider.VirtualProvider;
22import org.onosproject.incubator.net.virtual.provider.VirtualProviderRegistryService;
23import org.onosproject.incubator.net.virtual.provider.VirtualProviderService;
24import org.onosproject.net.DeviceId;
25import org.onosproject.net.provider.ProviderId;
Ray Milkeyd84f89b2018-08-17 14:54:17 -070026import org.osgi.service.component.annotations.Component;
Ray Milkeyba547f92018-02-01 15:22:31 -080027import org.slf4j.Logger;
28import org.slf4j.LoggerFactory;
yoonseon1f518572017-01-03 17:27:26 -080029
30import java.util.HashMap;
31import java.util.HashSet;
32import java.util.Map;
33import java.util.Set;
34import java.util.stream.Collectors;
35
36import static com.google.common.base.Preconditions.checkNotNull;
37import static com.google.common.base.Preconditions.checkState;
38
39/**
40 * Implementation of the virtual provider registry and providerService registry service.
41 */
Ray Milkeyd84f89b2018-08-17 14:54:17 -070042@Component(service = VirtualProviderRegistryService.class)
43public class VirtualProviderManager implements VirtualProviderRegistryService {
yoonseon1f518572017-01-03 17:27:26 -080044
45 private final Map<ProviderId, VirtualProvider> providers = new HashMap<>();
46 private final Map<ProviderId, VirtualProviderService> servicesWithProvider = new HashMap<>();
47 private final Map<String, VirtualProvider> providersByScheme = new HashMap<>();
48 private final Map<NetworkId, Set<VirtualProviderService>> servicesByNetwork = new HashMap<>();
Ray Milkeyba547f92018-02-01 15:22:31 -080049 private static Logger log = LoggerFactory.getLogger(VirtualProviderManager.class);
yoonseon1f518572017-01-03 17:27:26 -080050
51 @Override
52 public synchronized void registerProvider(VirtualProvider virtualProvider) {
53 checkNotNull(virtualProvider, "Provider cannot be null");
54 checkState(!providers.containsKey(virtualProvider.id()),
55 "Provider %s already registered", virtualProvider.id());
56
57 // If the provider is a primary one, check for a conflict.
58 ProviderId pid = virtualProvider.id();
59 checkState(pid.isAncillary() || !providersByScheme.containsKey(pid.scheme()),
60 "A primary provider with id %s is already registered",
61 providersByScheme.get(pid.scheme()));
62
63 providers.put(virtualProvider.id(), virtualProvider);
64
65 // Register the provider by URI scheme only if it is not ancillary.
66 if (!pid.isAncillary()) {
67 providersByScheme.put(pid.scheme(), virtualProvider);
68 }
69 }
70
71 @Override
72 public synchronized void unregisterProvider(VirtualProvider virtualProvider) {
73 checkNotNull(virtualProvider, "Provider cannot be null");
74
sangyun-han43c56702017-07-11 11:55:28 +090075 //TODO: invalidate provider services which subscribe the provider
yoonseon1f518572017-01-03 17:27:26 -080076 providers.remove(virtualProvider.id());
77
78 if (!virtualProvider.id().isAncillary()) {
79 providersByScheme.remove(virtualProvider.id().scheme());
80 }
81 }
82
83 @Override
84 public synchronized void
85 registerProviderService(NetworkId networkId,
86 VirtualProviderService virtualProviderService) {
Yoonseon Hanc8089db2017-03-22 20:22:12 +090087 Set<VirtualProviderService> services =
88 servicesByNetwork.computeIfAbsent(networkId, k -> new HashSet<>());
yoonseon1f518572017-01-03 17:27:26 -080089
yoonseon1f518572017-01-03 17:27:26 -080090 services.add(virtualProviderService);
91 }
92
93 @Override
94 public synchronized void
95 unregisterProviderService(NetworkId networkId,
96 VirtualProviderService virtualProviderService) {
97 Set<VirtualProviderService> services = servicesByNetwork.get(networkId);
98
99 if (services != null) {
100 services.remove(virtualProviderService);
101 }
102 }
103
104 @Override
105 public synchronized Set<ProviderId> getProviders() {
106 return ImmutableSet.copyOf(providers.keySet());
107 }
108
109 @Override
yoonseonbd8a93d2016-12-07 15:51:21 -0800110 public Set<ProviderId> getProvidersByService(VirtualProviderService
111 virtualProviderService) {
yoonseon1f518572017-01-03 17:27:26 -0800112 Class clazz = getProviderClass(virtualProviderService);
113
114 return ImmutableSet.copyOf(providers.values().stream()
yoonseonbd8a93d2016-12-07 15:51:21 -0800115 .filter(clazz::isInstance)
116 .map(VirtualProvider::id)
117 .collect(Collectors.toSet()));
yoonseon1f518572017-01-03 17:27:26 -0800118 }
119
120 @Override
121 public synchronized VirtualProvider getProvider(ProviderId providerId) {
122 return providers.get(providerId);
123 }
124
125 @Override
126 public synchronized VirtualProvider getProvider(DeviceId deviceId) {
127 return providersByScheme.get(deviceId.uri().getScheme());
128 }
129
130 @Override
131 public synchronized VirtualProvider getProvider(String scheme) {
132 return providersByScheme.get(scheme);
133 }
134
135 @Override
136 public synchronized VirtualProviderService
Yoonseon Hanc70b4e02016-10-20 15:24:33 -0700137 getProviderService(NetworkId networkId, Class<? extends VirtualProvider> providerClass) {
yoonseon1f518572017-01-03 17:27:26 -0800138 Set<VirtualProviderService> services = servicesByNetwork.get(networkId);
139
140 if (services == null) {
141 return null;
142 }
143
144 return services.stream()
Yoonseon Hanc70b4e02016-10-20 15:24:33 -0700145 .filter(s -> getProviderClass(s).equals(providerClass))
Yoonseon Hanc8089db2017-03-22 20:22:12 +0900146 .findFirst().orElse(null);
yoonseon1f518572017-01-03 17:27:26 -0800147 }
148
149 /**
150 * Returns the class type of parameter type.
151 * More specifically, it returns the class type of provider service's provider type.
152 *
153 * @param service a virtual provider service
154 * @return the class type of provider service of the service
155 */
156 private Class getProviderClass(VirtualProviderService service) {
157 String className = service.getClass().getGenericSuperclass().getTypeName();
158 String pramType = className.split("<")[1].split(">")[0];
159
160 try {
161 return Class.forName(pramType);
162 } catch (ClassNotFoundException e) {
Ray Milkeyba547f92018-02-01 15:22:31 -0800163 log.warn("getProviderClass()", e);
yoonseon1f518572017-01-03 17:27:26 -0800164 }
165
166 return null;
167 }
168}