blob: bfd54bf4f8dc90bea835a4bd3daa2bc4fc7e1bf2 [file] [log] [blame]
Thomas Vachuska4f1a60c2014-10-28 13:39:07 -07001/*
Brian O'Connora09fe5b2017-08-03 21:12:30 -07002 * Copyright 2014-present Open Networking Foundation
Thomas Vachuska4f1a60c2014-10-28 13:39:07 -07003 *
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 */
Brian O'Connorabafb502014-12-02 22:26:20 -080016package org.onosproject.net.provider;
tom64b7aac2014-08-26 00:18:21 -070017
tom132b58a2014-08-28 16:11:28 -070018import com.google.common.collect.ImmutableSet;
Brian O'Connorabafb502014-12-02 22:26:20 -080019import org.onosproject.net.DeviceId;
Ray Milkey48ea5a02019-02-07 08:01:52 -080020import org.slf4j.Logger;
21import org.slf4j.LoggerFactory;
tom132b58a2014-08-28 16:11:28 -070022
tom64b7aac2014-08-26 00:18:21 -070023import java.util.HashMap;
24import java.util.Map;
tom132b58a2014-08-28 16:11:28 -070025import java.util.Set;
tom64b7aac2014-08-26 00:18:21 -070026
tom64b7aac2014-08-26 00:18:21 -070027import static com.google.common.base.Preconditions.checkNotNull;
tom132b58a2014-08-28 16:11:28 -070028import static com.google.common.base.Preconditions.checkState;
tom64b7aac2014-08-26 00:18:21 -070029
30/**
tom96dfcab2014-08-28 09:26:03 -070031 * Base implementation of provider registry.
tom64b7aac2014-08-26 00:18:21 -070032 *
33 * @param <P> type of the information provider
34 * @param <S> type of the provider service
35 */
tom96dfcab2014-08-28 09:26:03 -070036public abstract class AbstractProviderRegistry<P extends Provider, S extends ProviderService<P>>
37 implements ProviderRegistry<P, S> {
tom64b7aac2014-08-26 00:18:21 -070038
tome5ec3fd2014-09-04 15:18:06 -070039 private final Map<ProviderId, P> providers = new HashMap<>();
tom64b7aac2014-08-26 00:18:21 -070040 private final Map<ProviderId, S> services = new HashMap<>();
tom7e02cda2014-09-18 12:05:46 -070041 private final Map<String, P> providersByScheme = new HashMap<>();
tom64b7aac2014-08-26 00:18:21 -070042
43 /**
44 * Creates a new provider service bound to the specified provider.
45 *
46 * @param provider provider
47 * @return provider service
48 */
49 protected abstract S createProviderService(P provider);
50
Thomas Vachuskac4ee7372016-02-02 16:10:09 -080051 /**
52 * Returns the default fall-back provider. Default implementation return null.
53 *
54 * @return default provider
55 */
56 protected P defaultProvider() {
57 return null;
58 }
59
Ray Milkey48ea5a02019-02-07 08:01:52 -080060 private static final Logger log = LoggerFactory
61 .getLogger(AbstractProviderRegistry.class);
62
tom64b7aac2014-08-26 00:18:21 -070063 @Override
64 public synchronized S register(P provider) {
Ray Milkey48ea5a02019-02-07 08:01:52 -080065
66 log.debug("registering provider {} :{}", provider, provider.id());
tom64b7aac2014-08-26 00:18:21 -070067 checkNotNull(provider, "Provider cannot be null");
toma5368862014-10-01 12:35:48 -070068
69 // If the provider is a primary one, check for a conflict.
70 ProviderId pid = provider.id();
71 checkState(pid.isAncillary() || !providersByScheme.containsKey(pid.scheme()),
Ray Milkey48ea5a02019-02-07 08:01:52 -080072 "A primary provider with id %s is already registered",
73 providersByScheme.get(pid.scheme()));
toma5368862014-10-01 12:35:48 -070074
Ray Milkey48ea5a02019-02-07 08:01:52 -080075 checkState(pid.isAncillary() || !services.containsKey(provider.id()),
76 "Provider %s already registered", provider.id());
toma5368862014-10-01 12:35:48 -070077
78 // Register the provider by URI scheme only if it is not ancillary.
Ray Milkey48ea5a02019-02-07 08:01:52 -080079 S service = null;
80
toma5368862014-10-01 12:35:48 -070081 if (!pid.isAncillary()) {
Ray Milkey48ea5a02019-02-07 08:01:52 -080082 service = createProviderService(provider);
83 services.put(provider.id(), service);
84 providers.put(provider.id(), provider);
toma5368862014-10-01 12:35:48 -070085 providersByScheme.put(pid.scheme(), provider);
Ray Milkey48ea5a02019-02-07 08:01:52 -080086 } else {
87 ProviderId servicePid = new ProviderId(provider.id().scheme(), provider.id().id(), false);
88 service = services.get(servicePid);
89 checkState(service != null,
90 "Primary provider with id %s not registered yet", pid);
toma5368862014-10-01 12:35:48 -070091 }
92
tom64b7aac2014-08-26 00:18:21 -070093 return service;
94 }
95
96 @Override
97 public synchronized void unregister(P provider) {
98 checkNotNull(provider, "Provider cannot be null");
tom132b58a2014-08-28 16:11:28 -070099 S service = services.get(provider.id());
Thomas Vachuska5b38dc02018-05-10 15:24:40 -0700100 if (service instanceof AbstractProviderService) {
tom64b7aac2014-08-26 00:18:21 -0700101 ((AbstractProviderService) service).invalidate();
tom132b58a2014-08-28 16:11:28 -0700102 services.remove(provider.id());
tome5ec3fd2014-09-04 15:18:06 -0700103 providers.remove(provider.id());
alshabib23022f72014-10-17 14:50:00 -0700104 if (!provider.id().isAncillary()) {
105 providersByScheme.remove(provider.id().scheme());
106 }
tom64b7aac2014-08-26 00:18:21 -0700107 }
tom64b7aac2014-08-26 00:18:21 -0700108 }
tom132b58a2014-08-28 16:11:28 -0700109
110 @Override
111 public synchronized Set<ProviderId> getProviders() {
112 return ImmutableSet.copyOf(services.keySet());
113 }
114
tome5ec3fd2014-09-04 15:18:06 -0700115 /**
Thomas Vachuskac4ee7372016-02-02 16:10:09 -0800116 * Returns the provider registered with the specified provider ID or null
117 * if none is found for the given provider family and default fall-back is
118 * not supported.
tome5ec3fd2014-09-04 15:18:06 -0700119 *
120 * @param providerId provider identifier
121 * @return provider
122 */
123 protected synchronized P getProvider(ProviderId providerId) {
Thomas Vachuskac4ee7372016-02-02 16:10:09 -0800124 P provider = providers.get(providerId);
125 return provider != null ? provider : defaultProvider();
tome5ec3fd2014-09-04 15:18:06 -0700126 }
127
tom7e02cda2014-09-18 12:05:46 -0700128 /**
129 * Returns the provider for the specified device ID based on URI scheme.
130 *
131 * @param deviceId device identifier
132 * @return provider bound to the URI scheme
133 */
134 protected synchronized P getProvider(DeviceId deviceId) {
Thomas Vachuskac4ee7372016-02-02 16:10:09 -0800135 P provider = providersByScheme.get(deviceId.uri().getScheme());
136 return provider != null ? provider : defaultProvider();
tom7e02cda2014-09-18 12:05:46 -0700137 }
138
Madan Jampaniad3c5262016-01-20 00:50:17 -0800139 /**
140 * Returns the provider registered with the specified scheme.
141 *
142 * @param scheme provider scheme
143 * @return provider
144 */
145 protected synchronized P getProvider(String scheme) {
146 return providersByScheme.get(scheme);
147 }
148
tom64b7aac2014-08-26 00:18:21 -0700149}