blob: 58b89a662f0d37800d251a223bdcab359a92f843 [file] [log] [blame]
Hyunsun Moonb974fca2016-06-30 21:20:39 -07001/*
2 * Copyright 2016-present Open Networking Laboratory
3 *
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 */
Hyunsun Moonb3eb84d2016-07-27 19:10:52 -070016package org.onosproject.openstacknetworking;
Hyunsun Moonb974fca2016-06-30 21:20:39 -070017
18import org.onlab.osgi.DefaultServiceDirectory;
19import org.onlab.osgi.ServiceDirectory;
20import org.onlab.packet.Ip4Address;
21import org.onlab.util.Tools;
Hyunsun Moonb974fca2016-06-30 21:20:39 -070022import org.onosproject.core.CoreService;
23import org.onosproject.mastership.MastershipService;
24import org.onosproject.net.Host;
25import org.onosproject.net.host.HostEvent;
26import org.onosproject.net.host.HostListener;
27import org.onosproject.net.host.HostService;
28import org.slf4j.Logger;
29
30import java.util.Objects;
31import java.util.Optional;
32import java.util.Set;
33import java.util.concurrent.ExecutorService;
34import java.util.stream.Collectors;
35
36import static java.util.concurrent.Executors.newSingleThreadScheduledExecutor;
37import static org.onlab.util.Tools.groupedThreads;
sangho6032f342016-07-07 14:32:03 +090038import static org.onosproject.openstacknetworking.Constants.*;
Hyunsun Moonb974fca2016-06-30 21:20:39 -070039import static org.slf4j.LoggerFactory.getLogger;
40
41/**
42 * Provides abstract virtual machine handler.
43 */
44public abstract class AbstractVmHandler {
45 protected final Logger log = getLogger(getClass());
46
47 protected final ExecutorService eventExecutor = newSingleThreadScheduledExecutor(
48 groupedThreads(this.getClass().getSimpleName(), "event-handler"));
49
50 protected CoreService coreService;
51 protected MastershipService mastershipService;
52 protected HostService hostService;
53
Hyunsun Moonb974fca2016-06-30 21:20:39 -070054 protected HostListener hostListener = new InternalHostListener();
55
56 protected void activate() {
57 ServiceDirectory services = new DefaultServiceDirectory();
58 coreService = services.get(CoreService.class);
59 mastershipService = services.get(MastershipService.class);
60 hostService = services.get(HostService.class);
Hyunsun Moonb974fca2016-06-30 21:20:39 -070061 hostService.addListener(hostListener);
62
63 log.info("Started");
64 }
65
66 protected void deactivate() {
67 hostService.removeListener(hostListener);
68 eventExecutor.shutdown();
69
70 log.info("Stopped");
71 }
72
Hyunsun Moonb3eb84d2016-07-27 19:10:52 -070073 /**
74 * Performs any action when a host is detected.
75 *
76 * @param host detected host
77 */
78 protected abstract void hostDetected(Host host);
Hyunsun Moonb974fca2016-06-30 21:20:39 -070079
Hyunsun Moonb3eb84d2016-07-27 19:10:52 -070080 /**
81 * Performs any action when a host is removed.
82 *
83 * @param host removed host
84 */
85 protected abstract void hostRemoved(Host host);
Hyunsun Moonb974fca2016-06-30 21:20:39 -070086
87 protected boolean isValidHost(Host host) {
88 return !host.ipAddresses().isEmpty() &&
89 host.annotations().value(VXLAN_ID) != null &&
90 host.annotations().value(NETWORK_ID) != null &&
91 host.annotations().value(TENANT_ID) != null &&
92 host.annotations().value(PORT_ID) != null;
93 }
94
95 protected Set<Host> getVmsInDifferentCnode(Host host) {
96 return Tools.stream(hostService.getHosts())
97 .filter(h -> !h.location().deviceId().equals(host.location().deviceId()))
98 .filter(this::isValidHost)
99 .filter(h -> Objects.equals(getVni(h), getVni(host)))
100 .collect(Collectors.toSet());
101 }
102
103 protected Optional<Host> getVmByPortId(String portId) {
104 return Tools.stream(hostService.getHosts())
105 .filter(this::isValidHost)
106 .filter(host -> host.annotations().value(PORT_ID).equals(portId))
107 .findFirst();
108 }
109
110 protected Ip4Address getIp(Host host) {
111 return host.ipAddresses().stream().findFirst().get().getIp4Address();
112 }
113
114 protected String getVni(Host host) {
115 return host.annotations().value(VXLAN_ID);
116 }
117
118 protected String getTenantId(Host host) {
119 return host.annotations().value(TENANT_ID);
120 }
121
122 private class InternalHostListener implements HostListener {
123
124 @Override
125 public void event(HostEvent event) {
126 Host host = event.subject();
127 if (!mastershipService.isLocalMaster(host.location().deviceId())) {
128 // do not allow to proceed without mastership
129 return;
130 }
131
132 if (!isValidHost(host)) {
133 log.debug("Invalid host event, ignore it {}", host);
134 return;
135 }
136
137 switch (event.type()) {
138 case HOST_UPDATED:
139 case HOST_ADDED:
140 eventExecutor.execute(() -> hostDetected(host));
141 break;
142 case HOST_REMOVED:
143 eventExecutor.execute(() -> hostRemoved(host));
144 break;
145 default:
146 break;
147 }
148 }
149 }
150}