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