blob: cbae272ad07bc913c9455ac4de3a83e0f7c2d082 [file] [log] [blame]
Hyunsun Moon44aac662017-02-18 02:07:01 +09001/*
Brian O'Connora09fe5b2017-08-03 21:12:30 -07002 * Copyright 2017-present Open Networking Foundation
Hyunsun Moon44aac662017-02-18 02:07:01 +09003 *
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.openstacknetworking.impl;
17
Hyunsun Moonae51e732017-04-25 17:46:21 +090018import com.google.common.collect.ImmutableList;
Hyunsun Moon44aac662017-02-18 02:07:01 +090019import com.google.common.collect.ImmutableSet;
Jian Lie6e609f2019-05-14 17:45:54 +090020import org.onlab.packet.IpAddress;
21import org.onlab.packet.MacAddress;
22import org.onlab.packet.VlanId;
Hyunsun Moon44aac662017-02-18 02:07:01 +090023import org.onlab.util.KryoNamespace;
24import org.onosproject.core.ApplicationId;
25import org.onosproject.core.CoreService;
Jian Lie6e609f2019-05-14 17:45:54 +090026import org.onosproject.openstacknetworking.api.ExternalPeerRouter;
Hyunsun Moon44aac662017-02-18 02:07:01 +090027import org.onosproject.openstacknetworking.api.OpenstackNetworkEvent;
28import org.onosproject.openstacknetworking.api.OpenstackNetworkStore;
29import org.onosproject.openstacknetworking.api.OpenstackNetworkStoreDelegate;
30import org.onosproject.store.AbstractStore;
31import org.onosproject.store.serializers.KryoNamespaces;
32import org.onosproject.store.service.ConsistentMap;
33import org.onosproject.store.service.MapEvent;
34import org.onosproject.store.service.MapEventListener;
35import org.onosproject.store.service.Serializer;
36import org.onosproject.store.service.StorageService;
37import org.onosproject.store.service.Versioned;
38import org.openstack4j.model.network.IPVersionType;
Jian Li02a94982018-02-03 02:49:07 +090039import org.openstack4j.model.network.Ipv6AddressMode;
40import org.openstack4j.model.network.Ipv6RaMode;
Hyunsun Moon44aac662017-02-18 02:07:01 +090041import org.openstack4j.model.network.Network;
42import org.openstack4j.model.network.NetworkType;
43import org.openstack4j.model.network.Port;
44import org.openstack4j.model.network.State;
45import org.openstack4j.model.network.Subnet;
46import org.openstack4j.openstack.networking.domain.NeutronAllowedAddressPair;
47import org.openstack4j.openstack.networking.domain.NeutronExtraDhcpOptCreate;
48import org.openstack4j.openstack.networking.domain.NeutronHostRoute;
49import org.openstack4j.openstack.networking.domain.NeutronIP;
50import org.openstack4j.openstack.networking.domain.NeutronNetwork;
51import org.openstack4j.openstack.networking.domain.NeutronPool;
52import org.openstack4j.openstack.networking.domain.NeutronPort;
53import org.openstack4j.openstack.networking.domain.NeutronSubnet;
Ray Milkeyd84f89b2018-08-17 14:54:17 -070054import org.osgi.service.component.annotations.Activate;
55import org.osgi.service.component.annotations.Component;
56import org.osgi.service.component.annotations.Deactivate;
57import org.osgi.service.component.annotations.Reference;
58import org.osgi.service.component.annotations.ReferenceCardinality;
Hyunsun Moon44aac662017-02-18 02:07:01 +090059import org.slf4j.Logger;
60
Jian Lie6e609f2019-05-14 17:45:54 +090061import java.util.HashSet;
Jian Licaedc8b2018-02-19 17:21:06 +090062import java.util.LinkedHashMap;
Hyunsun Moonae51e732017-04-25 17:46:21 +090063import java.util.List;
Jian Lib7873422018-08-18 22:34:39 +090064import java.util.Objects;
Hyunsun Moon44aac662017-02-18 02:07:01 +090065import java.util.Set;
66import java.util.concurrent.ExecutorService;
Hyunsun Moon44aac662017-02-18 02:07:01 +090067
68import static com.google.common.base.Preconditions.checkArgument;
69import static java.util.concurrent.Executors.newSingleThreadExecutor;
70import static org.onlab.util.Tools.groupedThreads;
71import static org.onosproject.openstacknetworking.api.Constants.OPENSTACK_NETWORKING_APP_ID;
Jian Lie6e609f2019-05-14 17:45:54 +090072import static org.onosproject.openstacknetworking.api.OpenstackNetworkEvent.Type.EXTERNAL_PEER_ROUTER_CREATED;
73import static org.onosproject.openstacknetworking.api.OpenstackNetworkEvent.Type.EXTERNAL_PEER_ROUTER_MAC_UPDATED;
74import static org.onosproject.openstacknetworking.api.OpenstackNetworkEvent.Type.EXTERNAL_PEER_ROUTER_REMOVED;
75import static org.onosproject.openstacknetworking.api.OpenstackNetworkEvent.Type.EXTERNAL_PEER_ROUTER_UPDATED;
Jian Li78885a22018-03-02 11:33:02 +090076import static org.onosproject.openstacknetworking.api.OpenstackNetworkEvent.Type.OPENSTACK_NETWORK_CREATED;
Jian Li00105802020-02-25 03:30:20 +090077import static org.onosproject.openstacknetworking.api.OpenstackNetworkEvent.Type.OPENSTACK_NETWORK_PRE_REMOVED;
Jian Li78885a22018-03-02 11:33:02 +090078import static org.onosproject.openstacknetworking.api.OpenstackNetworkEvent.Type.OPENSTACK_NETWORK_REMOVED;
79import static org.onosproject.openstacknetworking.api.OpenstackNetworkEvent.Type.OPENSTACK_NETWORK_UPDATED;
80import static org.onosproject.openstacknetworking.api.OpenstackNetworkEvent.Type.OPENSTACK_PORT_CREATED;
Jian Li8f64feb2018-07-24 13:20:16 +090081import static org.onosproject.openstacknetworking.api.OpenstackNetworkEvent.Type.OPENSTACK_PORT_PRE_REMOVE;
Jian Li78885a22018-03-02 11:33:02 +090082import static org.onosproject.openstacknetworking.api.OpenstackNetworkEvent.Type.OPENSTACK_PORT_REMOVED;
83import static org.onosproject.openstacknetworking.api.OpenstackNetworkEvent.Type.OPENSTACK_PORT_SECURITY_GROUP_ADDED;
84import static org.onosproject.openstacknetworking.api.OpenstackNetworkEvent.Type.OPENSTACK_PORT_SECURITY_GROUP_REMOVED;
85import static org.onosproject.openstacknetworking.api.OpenstackNetworkEvent.Type.OPENSTACK_PORT_UPDATED;
86import static org.onosproject.openstacknetworking.api.OpenstackNetworkEvent.Type.OPENSTACK_SUBNET_CREATED;
87import static org.onosproject.openstacknetworking.api.OpenstackNetworkEvent.Type.OPENSTACK_SUBNET_REMOVED;
88import static org.onosproject.openstacknetworking.api.OpenstackNetworkEvent.Type.OPENSTACK_SUBNET_UPDATED;
Hyunsun Moon44aac662017-02-18 02:07:01 +090089import static org.slf4j.LoggerFactory.getLogger;
90
91/**
92 * Manages the inventory of OpenStack network, subnet, and port using a {@code ConsistentMap}.
93 */
Ray Milkeyd84f89b2018-08-17 14:54:17 -070094@Component(immediate = true, service = OpenstackNetworkStore.class)
Hyunsun Moon44aac662017-02-18 02:07:01 +090095public class DistributedOpenstackNetworkStore
96 extends AbstractStore<OpenstackNetworkEvent, OpenstackNetworkStoreDelegate>
97 implements OpenstackNetworkStore {
98
99 protected final Logger log = getLogger(getClass());
100
101 private static final String ERR_NOT_FOUND = " does not exist";
102 private static final String ERR_DUPLICATE = " already exists";
103
104 private static final KryoNamespace SERIALIZER_NEUTRON_L2 = KryoNamespace.newBuilder()
105 .register(KryoNamespaces.API)
106 .register(Network.class)
107 .register(NeutronNetwork.class)
108 .register(State.class)
109 .register(NetworkType.class)
110 .register(Port.class)
111 .register(NeutronPort.class)
112 .register(NeutronIP.class)
113 .register(NeutronAllowedAddressPair.class)
114 .register(NeutronExtraDhcpOptCreate.class)
115 .register(Subnet.class)
116 .register(NeutronSubnet.class)
117 .register(NeutronPool.class)
118 .register(NeutronHostRoute.class)
119 .register(IPVersionType.class)
Jian Li02a94982018-02-03 02:49:07 +0900120 .register(Ipv6AddressMode.class)
121 .register(Ipv6RaMode.class)
Jian Licaedc8b2018-02-19 17:21:06 +0900122 .register(LinkedHashMap.class)
Hyunsun Moon44aac662017-02-18 02:07:01 +0900123 .build();
124
Jian Lie6e609f2019-05-14 17:45:54 +0900125 private static final KryoNamespace
126 SERIALIZER_EXTERNAL_PEER_ROUTER_MAP = KryoNamespace.newBuilder()
127 .register(KryoNamespaces.API)
128 .register(ExternalPeerRouter.class)
129 .register(DefaultExternalPeerRouter.class)
130 .register(MacAddress.class)
131 .register(IpAddress.class)
132 .register(VlanId.class)
133 .build();
134
Ray Milkeyd84f89b2018-08-17 14:54:17 -0700135 @Reference(cardinality = ReferenceCardinality.MANDATORY)
Hyunsun Moon44aac662017-02-18 02:07:01 +0900136 protected CoreService coreService;
137
Ray Milkeyd84f89b2018-08-17 14:54:17 -0700138 @Reference(cardinality = ReferenceCardinality.MANDATORY)
Hyunsun Moon44aac662017-02-18 02:07:01 +0900139 protected StorageService storageService;
140
141 private final ExecutorService eventExecutor = newSingleThreadExecutor(
142 groupedThreads(this.getClass().getSimpleName(), "event-handler", log));
143
Jian Li5ecfd1a2018-12-10 11:41:03 +0900144 private final MapEventListener<String, Network>
145 networkMapListener = new OpenstackNetworkMapListener();
146 private final MapEventListener<String, Subnet>
147 subnetMapListener = new OpenstackSubnetMapListener();
148 private final MapEventListener<String, Port>
149 portMapListener = new OpenstackPortMapListener();
Jian Lie6e609f2019-05-14 17:45:54 +0900150 private final MapEventListener<String, ExternalPeerRouter>
151 peerRouterListener = new ExternalPeerRouterMapListener();
Hyunsun Moon44aac662017-02-18 02:07:01 +0900152
Jian Lie6e609f2019-05-14 17:45:54 +0900153 private ConsistentMap<String, ExternalPeerRouter> externalPeerRouterStore;
Hyunsun Moon44aac662017-02-18 02:07:01 +0900154 private ConsistentMap<String, Network> osNetworkStore;
155 private ConsistentMap<String, Subnet> osSubnetStore;
156 private ConsistentMap<String, Port> osPortStore;
157
158 @Activate
159 protected void activate() {
160 ApplicationId appId = coreService.registerApplication(OPENSTACK_NETWORKING_APP_ID);
161
162 osNetworkStore = storageService.<String, Network>consistentMapBuilder()
163 .withSerializer(Serializer.using(SERIALIZER_NEUTRON_L2))
164 .withName("openstack-networkstore")
165 .withApplicationId(appId)
166 .build();
167 osNetworkStore.addListener(networkMapListener);
168
169 osSubnetStore = storageService.<String, Subnet>consistentMapBuilder()
170 .withSerializer(Serializer.using(SERIALIZER_NEUTRON_L2))
171 .withName("openstack-subnetstore")
172 .withApplicationId(appId)
173 .build();
174 osSubnetStore.addListener(subnetMapListener);
175
176 osPortStore = storageService.<String, Port>consistentMapBuilder()
177 .withSerializer(Serializer.using(SERIALIZER_NEUTRON_L2))
178 .withName("openstack-portstore")
179 .withApplicationId(appId)
180 .build();
181 osPortStore.addListener(portMapListener);
182
Jian Lie6e609f2019-05-14 17:45:54 +0900183 externalPeerRouterStore = storageService.<String, ExternalPeerRouter>consistentMapBuilder()
184 .withSerializer(Serializer.using(SERIALIZER_EXTERNAL_PEER_ROUTER_MAP))
185 .withName("external-routermap")
186 .withApplicationId(appId)
187 .build();
188 externalPeerRouterStore.addListener(peerRouterListener);
189
Hyunsun Moon44aac662017-02-18 02:07:01 +0900190 log.info("Started");
191 }
192
193 @Deactivate
194 protected void deactivate() {
195 osNetworkStore.removeListener(networkMapListener);
196 osSubnetStore.removeListener(subnetMapListener);
197 osPortStore.removeListener(portMapListener);
Jian Lie6e609f2019-05-14 17:45:54 +0900198 externalPeerRouterStore.removeListener(peerRouterListener);
Hyunsun Moon44aac662017-02-18 02:07:01 +0900199 eventExecutor.shutdown();
200
201 log.info("Stopped");
202 }
203
204 @Override
205 public void createNetwork(Network osNet) {
206 osNetworkStore.compute(osNet.getId(), (id, existing) -> {
Jian Li5b22f112020-10-05 22:36:41 +0900207 final String error = osNet.getId() + ERR_DUPLICATE;
Hyunsun Moon44aac662017-02-18 02:07:01 +0900208 checkArgument(existing == null, error);
209 return osNet;
210 });
211 }
212
213 @Override
214 public void updateNetwork(Network osNet) {
215 osNetworkStore.compute(osNet.getId(), (id, existing) -> {
Jian Li5b22f112020-10-05 22:36:41 +0900216 final String error = osNet.getId() + ERR_NOT_FOUND;
Hyunsun Moon44aac662017-02-18 02:07:01 +0900217 checkArgument(existing != null, error);
218 return osNet;
219 });
220 }
221
222 @Override
223 public Network removeNetwork(String netId) {
224 Versioned<Network> osNet = osNetworkStore.remove(netId);
225 return osNet == null ? null : osNet.value();
226 }
227
228 @Override
229 public Network network(String netId) {
Jian Li78885a22018-03-02 11:33:02 +0900230 return osNetworkStore.asJavaMap().get(netId);
Hyunsun Moon44aac662017-02-18 02:07:01 +0900231 }
232
233 @Override
234 public Set<Network> networks() {
Jian Li78885a22018-03-02 11:33:02 +0900235 return ImmutableSet.copyOf(osNetworkStore.asJavaMap().values());
Hyunsun Moon44aac662017-02-18 02:07:01 +0900236 }
237
238 @Override
239 public void createSubnet(Subnet osSubnet) {
240 osSubnetStore.compute(osSubnet.getId(), (id, existing) -> {
241 final String error = osSubnet.getId() + ERR_DUPLICATE;
242 checkArgument(existing == null, error);
243 return osSubnet;
244 });
245 }
246
247 @Override
248 public void updateSubnet(Subnet osSubnet) {
249 osSubnetStore.compute(osSubnet.getId(), (id, existing) -> {
250 final String error = osSubnet.getId() + ERR_NOT_FOUND;
251 checkArgument(existing != null, error);
252 return osSubnet;
253 });
254 }
255
256 @Override
257 public Subnet removeSubnet(String subnetId) {
258 Versioned<Subnet> osSubnet = osSubnetStore.remove(subnetId);
259 return osSubnet == null ? null : osSubnet.value();
260 }
261
262 @Override
263 public Subnet subnet(String subnetId) {
Jian Li78885a22018-03-02 11:33:02 +0900264 return osSubnetStore.asJavaMap().get(subnetId);
Hyunsun Moon44aac662017-02-18 02:07:01 +0900265 }
266
267 @Override
268 public Set<Subnet> subnets() {
Jian Li78885a22018-03-02 11:33:02 +0900269 return ImmutableSet.copyOf(osSubnetStore.asJavaMap().values());
Hyunsun Moon44aac662017-02-18 02:07:01 +0900270 }
271
272 @Override
273 public void createPort(Port osPort) {
274 osPortStore.compute(osPort.getId(), (id, existing) -> {
275 final String error = osPort.getId() + ERR_DUPLICATE;
276 checkArgument(existing == null, error);
277 return osPort;
278 });
279 }
280
281 @Override
282 public void updatePort(Port osPort) {
283 osPortStore.compute(osPort.getId(), (id, existing) -> {
284 final String error = osPort.getId() + ERR_NOT_FOUND;
285 checkArgument(existing != null, error);
286 return osPort;
287 });
288 }
289
290 @Override
291 public Port removePort(String portId) {
292 Versioned<Port> osPort = osPortStore.remove(portId);
293 return osPort == null ? null : osPort.value();
294 }
295
296 @Override
297 public Port port(String portId) {
Jian Li78885a22018-03-02 11:33:02 +0900298 return osPortStore.asJavaMap().get(portId);
Hyunsun Moon44aac662017-02-18 02:07:01 +0900299 }
300
301 @Override
302 public Set<Port> ports() {
Jian Li78885a22018-03-02 11:33:02 +0900303 return ImmutableSet.copyOf(osPortStore.asJavaMap().values());
Hyunsun Moon44aac662017-02-18 02:07:01 +0900304 }
305
Hyunsun Moonc7219222017-03-27 11:05:59 +0900306 @Override
Jian Lie6e609f2019-05-14 17:45:54 +0900307 public ExternalPeerRouter externalPeerRouter(String ipAddress) {
308 return externalPeerRouterStore.asJavaMap().get(ipAddress);
309 }
310
311 @Override
312 public Set<ExternalPeerRouter> externalPeerRouters() {
313 return new HashSet<>(externalPeerRouterStore.asJavaMap().values());
314 }
315
316 @Override
317 public void createExternalPeerRouter(ExternalPeerRouter peerRouter) {
318 externalPeerRouterStore.compute(
319 peerRouter.ipAddress().toString(), (id, existing) -> {
320 final String error = peerRouter.ipAddress().toString() + ERR_DUPLICATE;
321 checkArgument(existing == null, error);
322 return peerRouter;
323 });
324 }
325
326 @Override
327 public void updateExternalPeerRouter(ExternalPeerRouter peerRouter) {
328 externalPeerRouterStore.compute(
329 peerRouter.ipAddress().toString(), (id, existing) -> {
330 final String error = peerRouter.ipAddress() + ERR_NOT_FOUND;
331 checkArgument(existing != null, error);
332 return peerRouter;
333 });
334 }
335
336 @Override
337 public ExternalPeerRouter removeExternalPeerRouter(String ipAddress) {
338 Versioned<ExternalPeerRouter> peerRouter =
339 externalPeerRouterStore.remove(ipAddress);
340 return peerRouter == null ? null : peerRouter.value();
341 }
342
343 @Override
Hyunsun Moonc7219222017-03-27 11:05:59 +0900344 public void clear() {
345 osPortStore.clear();
346 osSubnetStore.clear();
347 osNetworkStore.clear();
Jian Lie6e609f2019-05-14 17:45:54 +0900348 externalPeerRouterStore.clear();
Hyunsun Moonc7219222017-03-27 11:05:59 +0900349 }
350
Jian Li5ecfd1a2018-12-10 11:41:03 +0900351 private class OpenstackNetworkMapListener
352 implements MapEventListener<String, Network> {
Hyunsun Moon44aac662017-02-18 02:07:01 +0900353
354 @Override
355 public void event(MapEvent<String, Network> event) {
356 switch (event.type()) {
357 case UPDATE:
Jian Li411bf2e2018-11-29 00:08:54 +0900358 eventExecutor.execute(() -> processNetworkMapUpdate(event));
Hyunsun Moon44aac662017-02-18 02:07:01 +0900359 break;
360 case INSERT:
Jian Li411bf2e2018-11-29 00:08:54 +0900361 eventExecutor.execute(() -> processNetworkMapInsertion(event));
Hyunsun Moon44aac662017-02-18 02:07:01 +0900362 break;
363 case REMOVE:
Jian Li411bf2e2018-11-29 00:08:54 +0900364 eventExecutor.execute(() -> processNetworkMapRemoval(event));
Hyunsun Moon44aac662017-02-18 02:07:01 +0900365 break;
366 default:
Jian Li78885a22018-03-02 11:33:02 +0900367 log.error("Unsupported openstack network event type");
Hyunsun Moon44aac662017-02-18 02:07:01 +0900368 break;
369 }
370 }
Jian Li411bf2e2018-11-29 00:08:54 +0900371
372 private void processNetworkMapUpdate(MapEvent<String, Network> event) {
373 log.debug("OpenStack network updated");
374 notifyDelegate(new OpenstackNetworkEvent(
375 OPENSTACK_NETWORK_UPDATED,
376 event.newValue().value()));
Jian Li00105802020-02-25 03:30:20 +0900377
378 Network oldValue = event.oldValue().value();
379 Network newValue = event.newValue().value();
380
381 // FIXME: before the network get removed eventually, neutron always
382 // issue network update event with removed (empty) segmentation ID
383 // this might be a bug of openstack or openstack4j, need to revisit later
384 if (oldValue.getProviderSegID() != null &&
385 newValue.getProviderSegID() == null) {
386 log.debug("OpenStack network pre-removed");
387 notifyDelegate(new OpenstackNetworkEvent(
388 OPENSTACK_NETWORK_PRE_REMOVED,
389 event.oldValue().value()));
390 }
Jian Li411bf2e2018-11-29 00:08:54 +0900391 }
392
393 private void processNetworkMapInsertion(MapEvent<String, Network> event) {
394 log.debug("OpenStack network created");
395 notifyDelegate(new OpenstackNetworkEvent(
396 OPENSTACK_NETWORK_CREATED,
397 event.newValue().value()));
398 }
399
400 private void processNetworkMapRemoval(MapEvent<String, Network> event) {
401 log.debug("OpenStack network removed");
402 notifyDelegate(new OpenstackNetworkEvent(
403 OPENSTACK_NETWORK_REMOVED,
404 event.oldValue().value()));
405 }
Hyunsun Moon44aac662017-02-18 02:07:01 +0900406 }
407
408 private class OpenstackSubnetMapListener implements MapEventListener<String, Subnet> {
409
410 @Override
411 public void event(MapEvent<String, Subnet> event) {
412 switch (event.type()) {
413 case UPDATE:
Jian Li411bf2e2018-11-29 00:08:54 +0900414 eventExecutor.execute(() -> processSubnetMapUpdate(event));
Hyunsun Moon44aac662017-02-18 02:07:01 +0900415 break;
416 case INSERT:
Jian Li411bf2e2018-11-29 00:08:54 +0900417 eventExecutor.execute(() -> processSubnetMapInsertion(event));
Hyunsun Moon44aac662017-02-18 02:07:01 +0900418 break;
419 case REMOVE:
Jian Li411bf2e2018-11-29 00:08:54 +0900420 eventExecutor.execute(() -> processSubnetMapRemoval(event));
Hyunsun Moon44aac662017-02-18 02:07:01 +0900421 break;
422 default:
Jian Li78885a22018-03-02 11:33:02 +0900423 log.error("Unsupported openstack subnet event type");
Hyunsun Moon44aac662017-02-18 02:07:01 +0900424 break;
425 }
426 }
Jian Li411bf2e2018-11-29 00:08:54 +0900427
428 private void processSubnetMapUpdate(MapEvent<String, Subnet> event) {
429 log.debug("OpenStack subnet updated");
430 notifyDelegate(new OpenstackNetworkEvent(
431 OPENSTACK_SUBNET_UPDATED,
432 network(event.newValue().value().getNetworkId()),
433 event.newValue().value()));
434 }
435
436 private void processSubnetMapInsertion(MapEvent<String, Subnet> event) {
437 log.debug("OpenStack subnet created");
438 notifyDelegate(new OpenstackNetworkEvent(
439 OPENSTACK_SUBNET_CREATED,
440 network(event.newValue().value().getNetworkId()),
441 event.newValue().value()));
442 }
443
444 private void processSubnetMapRemoval(MapEvent<String, Subnet> event) {
445 log.debug("OpenStack subnet removed");
446 notifyDelegate(new OpenstackNetworkEvent(
447 OPENSTACK_SUBNET_REMOVED,
448 network(event.oldValue().value().getNetworkId()),
449 event.oldValue().value()));
450 }
Hyunsun Moon44aac662017-02-18 02:07:01 +0900451 }
452
Jian Lie6e609f2019-05-14 17:45:54 +0900453 private class ExternalPeerRouterMapListener
454 implements MapEventListener<String, ExternalPeerRouter> {
455
456 @Override
457 public void event(MapEvent<String, ExternalPeerRouter> event) {
458 switch (event.type()) {
459 case UPDATE:
460 eventExecutor.execute(() -> processPeerRouterUpdate(event));
461 break;
462 case INSERT:
463 eventExecutor.execute(() -> processPeerRouterInsertion(event));
464 break;
465 case REMOVE:
466 eventExecutor.execute(() -> processPeerRouterRemoval(event));
467 break;
468 default:
469 log.error("Unsupported external peer router event type");
470 break;
471 }
472 }
473
474 private void processPeerRouterUpdate(
475 MapEvent<String, ExternalPeerRouter> event) {
476 log.debug("External peer router updated");
477 notifyDelegate(new OpenstackNetworkEvent(
478 EXTERNAL_PEER_ROUTER_UPDATED, event.newValue().value()));
479
480 processPeerRouterMacUpdated(event);
481 }
482
483 private void processPeerRouterInsertion(
484 MapEvent<String, ExternalPeerRouter> event) {
485 log.debug("External peer router inserted");
486 notifyDelegate(new OpenstackNetworkEvent(
487 EXTERNAL_PEER_ROUTER_CREATED, event.newValue().value()));
488 }
489
490 private void processPeerRouterRemoval(
491 MapEvent<String, ExternalPeerRouter> event) {
492 log.debug("External peer router removed");
493 notifyDelegate(new OpenstackNetworkEvent(
494 EXTERNAL_PEER_ROUTER_REMOVED, event.oldValue().value()));
495 }
496
497 private void processPeerRouterMacUpdated(
498 MapEvent<String, ExternalPeerRouter> event) {
499 ExternalPeerRouter oldPeerRouter = event.oldValue().value();
500 ExternalPeerRouter newPeerRouter = event.newValue().value();
501
502 if (!Objects.equals(oldPeerRouter.macAddress(), newPeerRouter.macAddress())) {
503 notifyDelegate(new OpenstackNetworkEvent(
504 EXTERNAL_PEER_ROUTER_MAC_UPDATED, newPeerRouter));
505 }
506 }
507 }
508
Hyunsun Moon44aac662017-02-18 02:07:01 +0900509 private class OpenstackPortMapListener implements MapEventListener<String, Port> {
510
511 @Override
512 public void event(MapEvent<String, Port> event) {
513 switch (event.type()) {
514 case UPDATE:
Jian Li411bf2e2018-11-29 00:08:54 +0900515 eventExecutor.execute(() -> processPortMapUpdate(event));
Hyunsun Moon44aac662017-02-18 02:07:01 +0900516 break;
517 case INSERT:
Jian Li411bf2e2018-11-29 00:08:54 +0900518 eventExecutor.execute(() -> processPortMapInsertion(event));
Hyunsun Moon44aac662017-02-18 02:07:01 +0900519 break;
520 case REMOVE:
Jian Li411bf2e2018-11-29 00:08:54 +0900521 eventExecutor.execute(() -> processPortMapRemoval(event));
Hyunsun Moon44aac662017-02-18 02:07:01 +0900522 break;
523 default:
Jian Li78885a22018-03-02 11:33:02 +0900524 log.error("Unsupported openstack port event type");
Hyunsun Moon44aac662017-02-18 02:07:01 +0900525 break;
526 }
527 }
Hyunsun Moonae51e732017-04-25 17:46:21 +0900528
Jian Li411bf2e2018-11-29 00:08:54 +0900529 private void processPortMapUpdate(MapEvent<String, Port> event) {
530 log.debug("OpenStack port updated");
531 Port oldPort = event.oldValue().value();
532 Port newPort = event.newValue().value();
533 notifyDelegate(new OpenstackNetworkEvent(
534 OPENSTACK_PORT_UPDATED,
535 network(event.newValue().value().getNetworkId()), newPort));
536 processSecurityGroupUpdate(oldPort, newPort);
537 }
538
539 private void processPortMapInsertion(MapEvent<String, Port> event) {
540 log.debug("OpenStack port created");
541 notifyDelegate(new OpenstackNetworkEvent(
542 OPENSTACK_PORT_CREATED,
543 network(event.newValue().value().getNetworkId()),
544 event.newValue().value()));
545 }
546
547 private void processPortMapRemoval(MapEvent<String, Port> event) {
548 log.debug("OpenStack port removed");
549 notifyDelegate(new OpenstackNetworkEvent(
550 OPENSTACK_PORT_PRE_REMOVE,
551 network(event.oldValue().value().getNetworkId()),
552 event.oldValue().value()));
553
554 notifyDelegate(new OpenstackNetworkEvent(
555 OPENSTACK_PORT_REMOVED,
556 network(event.oldValue().value().getNetworkId()),
557 event.oldValue().value()));
558 }
559
Hyunsun Moonae51e732017-04-25 17:46:21 +0900560 private void processSecurityGroupUpdate(Port oldPort, Port newPort) {
561 List<String> oldSecurityGroups = oldPort.getSecurityGroups() == null ?
562 ImmutableList.of() : oldPort.getSecurityGroups();
563 List<String> newSecurityGroups = newPort.getSecurityGroups() == null ?
564 ImmutableList.of() : newPort.getSecurityGroups();
565
566 oldSecurityGroups.stream()
Jian Li5ecfd1a2018-12-10 11:41:03 +0900567 .filter(sgId -> !Objects.requireNonNull(
568 newPort.getSecurityGroups()).contains(sgId))
Hyunsun Moonae51e732017-04-25 17:46:21 +0900569 .forEach(sgId -> notifyDelegate(new OpenstackNetworkEvent(
570 OPENSTACK_PORT_SECURITY_GROUP_REMOVED, newPort, sgId
571 )));
572
573 newSecurityGroups.stream()
574 .filter(sgId -> !oldPort.getSecurityGroups().contains(sgId))
575 .forEach(sgId -> notifyDelegate(new OpenstackNetworkEvent(
576 OPENSTACK_PORT_SECURITY_GROUP_ADDED, newPort, sgId
577 )));
578 }
Hyunsun Moon44aac662017-02-18 02:07:01 +0900579 }
580}