blob: 8954a384d92b6f41e660f8f931824a9fcd9ffd42 [file] [log] [blame]
jiangruib80e4c72015-11-27 15:00:51 +08001/*
Brian O'Connora09fe5b2017-08-03 21:12:30 -07002 * Copyright 2015-present Open Networking Foundation
jiangruib80e4c72015-11-27 15:00:51 +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 */
16package org.onosproject.vtnrsc.router.impl;
17
Ray Milkeyd84f89b2018-08-17 14:54:17 -070018import com.google.common.collect.Sets;
jiangruib80e4c72015-11-27 15:00:51 +080019import org.onlab.util.KryoNamespace;
20import org.onosproject.core.ApplicationId;
21import org.onosproject.core.CoreService;
22import org.onosproject.store.serializers.KryoNamespaces;
23import org.onosproject.store.service.EventuallyConsistentMap;
24import org.onosproject.store.service.EventuallyConsistentMapEvent;
25import org.onosproject.store.service.EventuallyConsistentMapListener;
26import org.onosproject.store.service.StorageService;
27import org.onosproject.store.service.WallClockTimestamp;
28import org.onosproject.vtnrsc.DefaultRouter;
29import org.onosproject.vtnrsc.FixedIp;
30import org.onosproject.vtnrsc.Router;
31import org.onosproject.vtnrsc.RouterGateway;
32import org.onosproject.vtnrsc.RouterId;
33import org.onosproject.vtnrsc.SubnetId;
34import org.onosproject.vtnrsc.TenantId;
35import org.onosproject.vtnrsc.TenantNetworkId;
36import org.onosproject.vtnrsc.VirtualPortId;
37import org.onosproject.vtnrsc.router.RouterEvent;
38import org.onosproject.vtnrsc.router.RouterListener;
39import org.onosproject.vtnrsc.router.RouterService;
40import org.onosproject.vtnrsc.subnet.SubnetService;
41import org.onosproject.vtnrsc.tenantnetwork.TenantNetworkService;
42import org.onosproject.vtnrsc.virtualport.VirtualPortService;
Ray Milkeyd84f89b2018-08-17 14:54:17 -070043import org.osgi.service.component.annotations.Activate;
44import org.osgi.service.component.annotations.Component;
45import org.osgi.service.component.annotations.Deactivate;
46import org.osgi.service.component.annotations.Reference;
47import org.osgi.service.component.annotations.ReferenceCardinality;
jiangruib80e4c72015-11-27 15:00:51 +080048import org.slf4j.Logger;
49
Ray Milkeyd84f89b2018-08-17 14:54:17 -070050import java.util.Collection;
51import java.util.Collections;
52import java.util.Set;
53
54import static com.google.common.base.Preconditions.checkNotNull;
55import static org.slf4j.LoggerFactory.getLogger;
jiangruib80e4c72015-11-27 15:00:51 +080056
57/**
58 * Provides implementation of the Router service.
59 */
Ray Milkeyd84f89b2018-08-17 14:54:17 -070060@Component(immediate = true, service = RouterService.class)
jiangruib80e4c72015-11-27 15:00:51 +080061public class RouterManager implements RouterService {
62
63 private static final String ROUTER_ID_NULL = "Router ID cannot be null";
64 private static final String ROUTER_NOT_NULL = "Router cannot be null";
65 private static final String ROUTER = "vtn-router-store";
66 private static final String VTNRSC_APP = "org.onosproject.vtnrsc";
67 private static final String LISTENER_NOT_NULL = "Listener cannot be null";
68 private static final String EVENT_NOT_NULL = "event cannot be null";
69
70 private final Logger log = getLogger(getClass());
71 private final Set<RouterListener> listeners = Sets.newCopyOnWriteArraySet();
72 private EventuallyConsistentMapListener<RouterId, Router> routerListener = new InnerRouterStoreListener();
73 protected EventuallyConsistentMap<RouterId, Router> routerStore;
74 protected ApplicationId appId;
75
Ray Milkeyd84f89b2018-08-17 14:54:17 -070076 @Reference(cardinality = ReferenceCardinality.MANDATORY)
jiangruib80e4c72015-11-27 15:00:51 +080077 protected StorageService storageService;
78
Ray Milkeyd84f89b2018-08-17 14:54:17 -070079 @Reference(cardinality = ReferenceCardinality.MANDATORY)
jiangruib80e4c72015-11-27 15:00:51 +080080 protected CoreService coreService;
81
Ray Milkeyd84f89b2018-08-17 14:54:17 -070082 @Reference(cardinality = ReferenceCardinality.MANDATORY)
jiangruib80e4c72015-11-27 15:00:51 +080083 protected TenantNetworkService tenantNetworkService;
84
Ray Milkeyd84f89b2018-08-17 14:54:17 -070085 @Reference(cardinality = ReferenceCardinality.MANDATORY)
jiangruib80e4c72015-11-27 15:00:51 +080086 protected VirtualPortService virtualPortService;
87
Ray Milkeyd84f89b2018-08-17 14:54:17 -070088 @Reference(cardinality = ReferenceCardinality.MANDATORY)
jiangruib80e4c72015-11-27 15:00:51 +080089 protected SubnetService subnetService;
90
91 @Activate
92 public void activate() {
93 appId = coreService.registerApplication(VTNRSC_APP);
94 KryoNamespace.Builder serializer = KryoNamespace
95 .newBuilder()
96 .register(KryoNamespaces.API)
97 .register(Router.class, RouterId.class, DefaultRouter.class,
98 TenantNetworkId.class, TenantId.class,
99 VirtualPortId.class, DefaultRouter.class,
100 RouterGateway.class, Router.Status.class,
drlb04ca992016-03-21 20:42:43 -0400101 SubnetId.class, FixedIp.class);
jiangruib80e4c72015-11-27 15:00:51 +0800102 routerStore = storageService
103 .<RouterId, Router>eventuallyConsistentMapBuilder()
104 .withName(ROUTER).withSerializer(serializer)
105 .withTimestampProvider((k, v) -> new WallClockTimestamp())
106 .build();
107 routerStore.addListener(routerListener);
108 log.info("Started");
109 }
110
111 @Deactivate
112 public void deactivate() {
113 routerStore.removeListener(routerListener);
114 routerStore.destroy();
115 listeners.clear();
116 log.info("Stopped");
117 }
118
119 @Override
120 public boolean exists(RouterId routerId) {
121 checkNotNull(routerId, ROUTER_ID_NULL);
122 return routerStore.containsKey(routerId);
123 }
124
125 @Override
126 public Collection<Router> getRouters() {
127 return Collections.unmodifiableCollection(routerStore.values());
128 }
129
130 @Override
131 public Router getRouter(RouterId routerId) {
132 checkNotNull(routerId, ROUTER_ID_NULL);
133 return routerStore.get(routerId);
134 }
135
136 @Override
137 public boolean createRouters(Collection<Router> routers) {
138 checkNotNull(routers, ROUTER_NOT_NULL);
139 for (Router router : routers) {
140 verifyRouterData(router);
141 routerStore.put(router.id(), router);
142 if (!routerStore.containsKey(router.id())) {
143 log.debug("The router is created failed whose identifier is {}",
144 router.id().toString());
145 return false;
146 }
147 }
148 return true;
149 }
150
151 @Override
152 public boolean updateRouters(Collection<Router> routers) {
153 checkNotNull(routers, ROUTER_NOT_NULL);
Satish K4a83f922015-11-28 15:50:12 +0530154 for (Router router : routers) {
155 if (!routerStore.containsKey(router.id())) {
156 log.debug("The routers is not exist whose identifier is {}",
157 router.id().toString());
158 throw new IllegalArgumentException(
159 "routers ID doesn't exist");
160 }
161 verifyRouterData(router);
162 routerStore.put(router.id(), router);
163 if (!router.equals(routerStore.get(router.id()))) {
164 log.debug("The router is updated failed whose identifier is {}",
165 router.id().toString());
166 return false;
jiangruib80e4c72015-11-27 15:00:51 +0800167 }
168 }
169 return true;
170 }
171
172 @Override
173 public boolean removeRouters(Collection<RouterId> routerIds) {
174 checkNotNull(routerIds, ROUTER_ID_NULL);
Satish K4a83f922015-11-28 15:50:12 +0530175 for (RouterId routerId : routerIds) {
176 if (!routerStore.containsKey(routerId)) {
177 log.debug("The router is not exist whose identifier is {}",
178 routerId.toString());
179 throw new IllegalArgumentException(
180 "router ID doesn't exist");
181 }
182 Router router = routerStore.get(routerId);
183 routerStore.remove(routerId, router);
184 if (routerStore.containsKey(routerId)) {
185 log.debug("The router deleted is failed whose identifier is {}",
186 routerId.toString());
187 return false;
jiangruib80e4c72015-11-27 15:00:51 +0800188 }
189 }
190 return true;
191 }
192
193 @Override
194 public void addListener(RouterListener listener) {
195 checkNotNull(listener, LISTENER_NOT_NULL);
196 listeners.add(listener);
197 }
198
199 @Override
200 public void removeListener(RouterListener listener) {
201 checkNotNull(listener, LISTENER_NOT_NULL);
202 listeners.remove(listener);
203 }
204
205 /**
206 * Verifies validity of Router data.
207 *
208 * @param routers router instance
209 */
210 private void verifyRouterData(Router routers) {
211 checkNotNull(routers, ROUTER_NOT_NULL);
212 if (routers.gatewayPortid() != null
213 && !virtualPortService.exists(routers.gatewayPortid())) {
214 log.debug("The gateway port ID is not exist whose identifier is {}",
215 routers.gatewayPortid().toString());
216 throw new IllegalArgumentException("gateway port ID doesn't exist");
217 }
218
219 if (routers.externalGatewayInfo() != null) {
220 RouterGateway routerGateway = routers.externalGatewayInfo();
221 if (!tenantNetworkService.exists(routerGateway.networkId())) {
222 log.debug("The network ID of gateway info is not exist whose identifier is {}",
223 routers.id().toString());
224 throw new IllegalArgumentException(
225 "network ID of gateway info doesn't exist");
226 }
227 Iterable<FixedIp> fixedIps = routerGateway.externalFixedIps();
228 for (FixedIp fixedIp : fixedIps) {
229 if (!subnetService.exists(fixedIp.subnetId())) {
230 log.debug("The subnet ID of gateway info is not exist whose identifier is {}",
231 routers.id().toString());
232 throw new IllegalArgumentException(
233 "subnet ID of gateway info doesn't exist");
234 }
235 }
236 }
237 }
238
239 private class InnerRouterStoreListener
240 implements EventuallyConsistentMapListener<RouterId, Router> {
241
242 @Override
243 public void event(EventuallyConsistentMapEvent<RouterId, Router> event) {
244 checkNotNull(event, EVENT_NOT_NULL);
245 Router router = event.value();
246 if (EventuallyConsistentMapEvent.Type.PUT == event.type()) {
247 notifyListeners(new RouterEvent(RouterEvent.Type.ROUTER_PUT,
248 router));
249 }
250 if (EventuallyConsistentMapEvent.Type.REMOVE == event.type()) {
251 notifyListeners(new RouterEvent(RouterEvent.Type.ROUTER_DELETE,
252 router));
253 }
254 }
255 }
256
257 /**
258 * Notifies specify event to all listeners.
259 *
260 * @param event Floating IP event
261 */
262 private void notifyListeners(RouterEvent event) {
263 checkNotNull(event, EVENT_NOT_NULL);
264 listeners.forEach(listener -> listener.event(event));
265 }
266}