blob: 2f6ba528bcef342b4b46a6be8f8ccd6c26519d5c [file] [log] [blame]
Madan Jampani38a88212015-09-15 11:21:27 -07001/*
Brian O'Connora09fe5b2017-08-03 21:12:30 -07002 * Copyright 2015-present Open Networking Foundation
Madan Jampani38a88212015-09-15 11:21:27 -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 */
16package org.onosproject.store.host.impl;
17
alshabib8a4a6002015-11-25 14:31:16 -080018import com.google.common.collect.ImmutableSet;
19import com.google.common.collect.Sets;
Madan Jampani38a88212015-09-15 11:21:27 -070020import org.onlab.packet.IpAddress;
21import org.onlab.packet.MacAddress;
22import org.onlab.packet.VlanId;
23import org.onlab.util.KryoNamespace;
24import org.onosproject.net.Annotations;
25import org.onosproject.net.ConnectPoint;
26import org.onosproject.net.DefaultAnnotations;
27import org.onosproject.net.DefaultHost;
28import org.onosproject.net.DeviceId;
29import org.onosproject.net.Host;
30import org.onosproject.net.HostId;
Brian O'Connorf107bd72015-09-21 15:31:03 -070031import org.onosproject.net.HostLocation;
Madan Jampani38a88212015-09-15 11:21:27 -070032import org.onosproject.net.host.HostDescription;
33import org.onosproject.net.host.HostEvent;
34import org.onosproject.net.host.HostStore;
35import org.onosproject.net.host.HostStoreDelegate;
Madan Jampani38a88212015-09-15 11:21:27 -070036import org.onosproject.net.provider.ProviderId;
37import org.onosproject.store.AbstractStore;
38import org.onosproject.store.serializers.KryoNamespaces;
alshabib8a4a6002015-11-25 14:31:16 -080039import org.onosproject.store.service.ConsistentMap;
Ray Milkeyd84f89b2018-08-17 14:54:17 -070040import org.onosproject.store.service.DistributedPrimitive.Status;
alshabib8a4a6002015-11-25 14:31:16 -080041import org.onosproject.store.service.MapEvent;
42import org.onosproject.store.service.MapEventListener;
43import org.onosproject.store.service.Serializer;
Madan Jampani38a88212015-09-15 11:21:27 -070044import org.onosproject.store.service.StorageService;
Ray Milkeyd0f017f2018-09-21 12:52:34 -070045import org.onosproject.store.service.Versioned;
Ray Milkeyd84f89b2018-08-17 14:54:17 -070046import org.osgi.service.component.annotations.Activate;
47import org.osgi.service.component.annotations.Component;
48import org.osgi.service.component.annotations.Deactivate;
49import org.osgi.service.component.annotations.Reference;
50import org.osgi.service.component.annotations.ReferenceCardinality;
Madan Jampani38a88212015-09-15 11:21:27 -070051import org.slf4j.Logger;
52
alshabib8a4a6002015-11-25 14:31:16 -080053import java.util.Collection;
54import java.util.HashSet;
Deepa Vaddireddy0a71c8b2017-01-19 21:20:45 +053055import java.util.Iterator;
alshabib8a4a6002015-11-25 14:31:16 -080056import java.util.Map;
57import java.util.Objects;
58import java.util.Set;
Deepa Vaddireddy0a71c8b2017-01-19 21:20:45 +053059import java.util.concurrent.ConcurrentHashMap;
60import java.util.concurrent.ScheduledExecutorService;
61import java.util.function.Consumer;
alshabib8a4a6002015-11-25 14:31:16 -080062import java.util.function.Predicate;
63import java.util.stream.Collectors;
64
65import static com.google.common.base.Preconditions.checkNotNull;
66import static com.google.common.base.Preconditions.checkState;
Deepa Vaddireddy0a71c8b2017-01-19 21:20:45 +053067import static java.util.concurrent.Executors.newSingleThreadScheduledExecutor;
68import static org.onlab.util.Tools.groupedThreads;
alshabib8a4a6002015-11-25 14:31:16 -080069import static org.onosproject.net.DefaultAnnotations.merge;
Ray Milkeyd84f89b2018-08-17 14:54:17 -070070import static org.onosproject.net.host.HostEvent.Type.HOST_ADDED;
71import static org.onosproject.net.host.HostEvent.Type.HOST_MOVED;
72import static org.onosproject.net.host.HostEvent.Type.HOST_REMOVED;
73import static org.onosproject.net.host.HostEvent.Type.HOST_UPDATED;
alshabib8a4a6002015-11-25 14:31:16 -080074import static org.slf4j.LoggerFactory.getLogger;
Madan Jampani38a88212015-09-15 11:21:27 -070075
76/**
77 * Manages the inventory of hosts using a {@code EventuallyConsistentMap}.
78 */
Ray Milkeyd84f89b2018-08-17 14:54:17 -070079@Component(immediate = true, service = HostStore.class)
alshabib8a4a6002015-11-25 14:31:16 -080080public class DistributedHostStore
Madan Jampani38a88212015-09-15 11:21:27 -070081 extends AbstractStore<HostEvent, HostStoreDelegate>
82 implements HostStore {
83
84 private final Logger log = getLogger(getClass());
85
Ray Milkeyd84f89b2018-08-17 14:54:17 -070086 @Reference(cardinality = ReferenceCardinality.MANDATORY)
Madan Jampani38a88212015-09-15 11:21:27 -070087 protected StorageService storageService;
88
Madan Jampanic6371882016-06-03 21:30:17 -070089 private ConsistentMap<HostId, DefaultHost> hostsConsistentMap;
alshabib8a4a6002015-11-25 14:31:16 -080090 private Map<HostId, DefaultHost> hosts;
Deepa Vaddireddy0a71c8b2017-01-19 21:20:45 +053091 private Map<IpAddress, Set<Host>> hostsByIp;
alshabib8a4a6002015-11-25 14:31:16 -080092 private MapEventListener<HostId, DefaultHost> hostLocationTracker =
Madan Jampani38a88212015-09-15 11:21:27 -070093 new HostLocationTracker();
94
Deepa Vaddireddy0a71c8b2017-01-19 21:20:45 +053095 private ScheduledExecutorService executor;
96
97 private Consumer<Status> statusChangeListener;
98
Madan Jampani38a88212015-09-15 11:21:27 -070099 @Activate
100 public void activate() {
101 KryoNamespace.Builder hostSerializer = KryoNamespace.newBuilder()
Jonathan Hart38feb6e2016-08-29 22:54:16 +0000102 .register(KryoNamespaces.API);
Madan Jampanic6371882016-06-03 21:30:17 -0700103 hostsConsistentMap = storageService.<HostId, DefaultHost>consistentMapBuilder()
Madan Jampani38a88212015-09-15 11:21:27 -0700104 .withName("onos-hosts")
alshabib8a4a6002015-11-25 14:31:16 -0800105 .withRelaxedReadConsistency()
106 .withSerializer(Serializer.using(hostSerializer.build()))
Madan Jampani38a88212015-09-15 11:21:27 -0700107 .build();
Charles Chan35a32322017-08-14 11:42:11 -0700108 hostsConsistentMap.addListener(hostLocationTracker);
Madan Jampanic6371882016-06-03 21:30:17 -0700109 hosts = hostsConsistentMap.asJavaMap();
alshabib8a4a6002015-11-25 14:31:16 -0800110
Charles Chan35c06ac2018-04-19 15:11:23 -0700111 executor = newSingleThreadScheduledExecutor(groupedThreads("onos/hosts", "status-listener", log));
Deepa Vaddireddy0a71c8b2017-01-19 21:20:45 +0530112 statusChangeListener = status -> {
113 if (status == Status.ACTIVE) {
114 executor.execute(this::loadHostsByIp);
115 }
116 };
117 hostsConsistentMap.addStatusChangeListener(statusChangeListener);
118 loadHostsByIp();
Madan Jampani38a88212015-09-15 11:21:27 -0700119 log.info("Started");
120 }
121
122 @Deactivate
123 public void deactivate() {
Madan Jampanic6371882016-06-03 21:30:17 -0700124 hostsConsistentMap.removeListener(hostLocationTracker);
Charles Chan35c06ac2018-04-19 15:11:23 -0700125 executor.shutdown();
Charles Chan35a32322017-08-14 11:42:11 -0700126
Madan Jampani38a88212015-09-15 11:21:27 -0700127 log.info("Stopped");
128 }
129
Deepa Vaddireddy0a71c8b2017-01-19 21:20:45 +0530130 private void loadHostsByIp() {
131 hostsByIp = new ConcurrentHashMap<IpAddress, Set<Host>>();
132 hostsConsistentMap.asJavaMap().values().forEach(host -> {
133 host.ipAddresses().forEach(ip -> {
134 Set<Host> existingHosts = hostsByIp.get(ip);
135 if (existingHosts == null) {
136 hostsByIp.put(ip, addHosts(host));
137 } else {
138 existingHosts.add(host);
139 }
140 });
141 });
142 }
143
Brian O'Connordab09742015-12-07 20:06:29 -0800144 private boolean shouldUpdate(DefaultHost existingHost,
145 ProviderId providerId,
Brian O'Connordab09742015-12-07 20:06:29 -0800146 HostDescription hostDescription,
147 boolean replaceIPs) {
148 if (existingHost == null) {
149 return true;
150 }
151
Charles Chan69ebcbb2017-04-27 14:33:21 -0700152 // Avoid overriding configured host with learnt host
153 if (existingHost.configured() && !hostDescription.configured()) {
Charles Chan29ecdee2017-02-22 18:46:56 -0800154 return false;
155 }
156
Brian O'Connordab09742015-12-07 20:06:29 -0800157 if (!Objects.equals(existingHost.providerId(), providerId) ||
158 !Objects.equals(existingHost.mac(), hostDescription.hwAddress()) ||
159 !Objects.equals(existingHost.vlan(), hostDescription.vlan()) ||
Jonghwan Hyun2c95acf2018-03-14 16:47:34 -0700160 !Objects.equals(existingHost.innerVlan(), hostDescription.innerVlan()) ||
161 !Objects.equals(existingHost.tpid(), hostDescription.tpid()) ||
Charles Chancd06c692017-04-27 20:46:06 -0700162 !Objects.equals(existingHost.locations(), hostDescription.locations())) {
Brian O'Connordab09742015-12-07 20:06:29 -0800163 return true;
164 }
165
166 if (replaceIPs) {
167 if (!Objects.equals(hostDescription.ipAddress(),
168 existingHost.ipAddresses())) {
169 return true;
170 }
171 } else {
172 if (!existingHost.ipAddresses().containsAll(hostDescription.ipAddress())) {
173 return true;
174 }
175 }
176
177 // check to see if any of the annotations provided by hostDescription
178 // differ from those in the existing host
179 return hostDescription.annotations().keys().stream()
Deepa Vaddireddy0a71c8b2017-01-19 21:20:45 +0530180 .anyMatch(k -> !Objects.equals(hostDescription.annotations().value(k),
181 existingHost.annotations().value(k)));
Brian O'Connordab09742015-12-07 20:06:29 -0800182
183
184 }
185
Charles Chan009c3082015-11-10 14:18:04 -0800186 // TODO No longer need to return HostEvent
Madan Jampani38a88212015-09-15 11:21:27 -0700187 @Override
188 public HostEvent createOrUpdateHost(ProviderId providerId,
Brian O'Connorf107bd72015-09-21 15:31:03 -0700189 HostId hostId,
190 HostDescription hostDescription,
191 boolean replaceIPs) {
Madan Jampanic6371882016-06-03 21:30:17 -0700192 hostsConsistentMap.computeIf(hostId,
Charles Chan69ebcbb2017-04-27 14:33:21 -0700193 existingHost -> shouldUpdate(existingHost, providerId,
Brian O'Connordab09742015-12-07 20:06:29 -0800194 hostDescription, replaceIPs),
195 (id, existingHost) -> {
Brian O'Connorf107bd72015-09-21 15:31:03 -0700196
Madan Jampanic7f49f92015-12-10 11:35:06 -0800197 final Set<IpAddress> addresses;
198 if (existingHost == null || replaceIPs) {
199 addresses = ImmutableSet.copyOf(hostDescription.ipAddress());
200 } else {
201 addresses = Sets.newHashSet(existingHost.ipAddresses());
202 addresses.addAll(hostDescription.ipAddress());
203 }
Brian O'Connorf107bd72015-09-21 15:31:03 -0700204
Madan Jampanic7f49f92015-12-10 11:35:06 -0800205 final Annotations annotations;
206 if (existingHost != null) {
207 annotations = merge((DefaultAnnotations) existingHost.annotations(),
208 hostDescription.annotations());
209 } else {
210 annotations = hostDescription.annotations();
211 }
Jonathan Hart38feb6e2016-08-29 22:54:16 +0000212
Madan Jampanic7f49f92015-12-10 11:35:06 -0800213 return new DefaultHost(providerId,
214 hostId,
215 hostDescription.hwAddress(),
216 hostDescription.vlan(),
Charles Chancd06c692017-04-27 20:46:06 -0700217 hostDescription.locations(),
Madan Jampanic7f49f92015-12-10 11:35:06 -0800218 addresses,
Jonghwan Hyun2c95acf2018-03-14 16:47:34 -0700219 hostDescription.innerVlan(),
220 hostDescription.tpid(),
Charles Chanb1e99242017-07-07 14:11:09 -0700221 hostDescription.configured(),
Madan Jampanic7f49f92015-12-10 11:35:06 -0800222 annotations);
223 });
Charles Chan009c3082015-11-10 14:18:04 -0800224 return null;
Madan Jampani38a88212015-09-15 11:21:27 -0700225 }
226
Charles Chan009c3082015-11-10 14:18:04 -0800227 // TODO No longer need to return HostEvent
Madan Jampani38a88212015-09-15 11:21:27 -0700228 @Override
229 public HostEvent removeHost(HostId hostId) {
Charles Chan009c3082015-11-10 14:18:04 -0800230 hosts.remove(hostId);
231 return null;
Madan Jampani38a88212015-09-15 11:21:27 -0700232 }
233
Charles Chan009c3082015-11-10 14:18:04 -0800234 // TODO No longer need to return HostEvent
Madan Jampani38a88212015-09-15 11:21:27 -0700235 @Override
samanwita palc40e5ed2015-09-24 11:01:51 -0700236 public HostEvent removeIp(HostId hostId, IpAddress ipAddress) {
Charles Chan009c3082015-11-10 14:18:04 -0800237 hosts.compute(hostId, (id, existingHost) -> {
samanwita palc40e5ed2015-09-24 11:01:51 -0700238 if (existingHost != null) {
239 checkState(Objects.equals(hostId.mac(), existingHost.mac()),
240 "Existing and new MAC addresses differ.");
241 checkState(Objects.equals(hostId.vlanId(), existingHost.vlan()),
242 "Existing and new VLANs differ.");
243
samanwita pale7c08de2015-09-24 21:59:49 -0700244 Set<IpAddress> addresses = existingHost.ipAddresses();
samanwita palc40e5ed2015-09-24 11:01:51 -0700245 if (addresses != null && addresses.contains(ipAddress)) {
samanwita pale7c08de2015-09-24 21:59:49 -0700246 addresses = new HashSet<>(existingHost.ipAddresses());
samanwita palc40e5ed2015-09-24 11:01:51 -0700247 addresses.remove(ipAddress);
Deepa Vaddireddy0a71c8b2017-01-19 21:20:45 +0530248 removeIpFromHostsByIp(existingHost, ipAddress);
samanwita palc40e5ed2015-09-24 11:01:51 -0700249 return new DefaultHost(existingHost.providerId(),
250 hostId,
251 existingHost.mac(),
252 existingHost.vlan(),
Charles Chancd06c692017-04-27 20:46:06 -0700253 existingHost.locations(),
samanwita palc40e5ed2015-09-24 11:01:51 -0700254 ImmutableSet.copyOf(addresses),
Charles Chancd06c692017-04-27 20:46:06 -0700255 existingHost.configured(),
samanwita palc40e5ed2015-09-24 11:01:51 -0700256 existingHost.annotations());
257 } else {
258 return existingHost;
259 }
260 }
261 return null;
262 });
Charles Chan009c3082015-11-10 14:18:04 -0800263 return null;
samanwita palc40e5ed2015-09-24 11:01:51 -0700264 }
265
266 @Override
Charles Chan47933752017-11-30 15:37:50 -0800267 public void appendLocation(HostId hostId, HostLocation location) {
268 log.debug("Appending location {} to host {}", location, hostId);
269 hosts.compute(hostId, (id, existingHost) -> {
270 if (existingHost != null) {
271 checkState(Objects.equals(hostId.mac(), existingHost.mac()),
272 "Existing and new MAC addresses differ.");
273 checkState(Objects.equals(hostId.vlanId(), existingHost.vlan()),
274 "Existing and new VLANs differ.");
275
Charles Chan9bd0e5a2018-04-25 18:51:46 -0400276 // Move within the same switch
277 // Simply replace old location that is on the same device
278 Set<HostLocation> newLocations = Sets.newHashSet(location);
279 existingHost.locations().stream().filter(loc -> !loc.deviceId().equals(location.deviceId()))
280 .forEach(newLocations::add);
Charles Chan47933752017-11-30 15:37:50 -0800281
282 return new DefaultHost(existingHost.providerId(),
283 hostId, existingHost.mac(), existingHost.vlan(),
Charles Chan9bd0e5a2018-04-25 18:51:46 -0400284 newLocations, existingHost.ipAddresses(),
Charles Chan47933752017-11-30 15:37:50 -0800285 existingHost.configured(), existingHost.annotations());
286 }
287 return null;
288 });
289 }
290
291 @Override
Charles Chan888e20a2017-05-01 15:44:23 -0700292 public void removeLocation(HostId hostId, HostLocation location) {
Charles Chan47933752017-11-30 15:37:50 -0800293 log.debug("Removing location {} from host {}", location, hostId);
Charles Chan888e20a2017-05-01 15:44:23 -0700294 hosts.compute(hostId, (id, existingHost) -> {
295 if (existingHost != null) {
296 checkState(Objects.equals(hostId.mac(), existingHost.mac()),
297 "Existing and new MAC addresses differ.");
298 checkState(Objects.equals(hostId.vlanId(), existingHost.vlan()),
299 "Existing and new VLANs differ.");
300
301 Set<HostLocation> locations = new HashSet<>(existingHost.locations());
302 locations.remove(location);
303
304 // Remove entire host if we are removing the last location
305 return locations.isEmpty() ? null :
306 new DefaultHost(existingHost.providerId(),
307 hostId, existingHost.mac(), existingHost.vlan(),
308 locations, existingHost.ipAddresses(),
309 existingHost.configured(), existingHost.annotations());
310 }
311 return null;
312 });
313 }
314
315 @Override
Madan Jampani38a88212015-09-15 11:21:27 -0700316 public int getHostCount() {
317 return hosts.size();
318 }
319
320 @Override
321 public Iterable<Host> getHosts() {
322 return ImmutableSet.copyOf(hosts.values());
323 }
324
325 @Override
326 public Host getHost(HostId hostId) {
327 return hosts.get(hostId);
328 }
329
330 @Override
331 public Set<Host> getHosts(VlanId vlanId) {
332 return filter(hosts.values(), host -> Objects.equals(host.vlan(), vlanId));
333 }
334
335 @Override
336 public Set<Host> getHosts(MacAddress mac) {
337 return filter(hosts.values(), host -> Objects.equals(host.mac(), mac));
338 }
339
340 @Override
341 public Set<Host> getHosts(IpAddress ip) {
Deepa Vaddireddy0a71c8b2017-01-19 21:20:45 +0530342 Set<Host> hosts = hostsByIp.get(ip);
343 return hosts != null ? ImmutableSet.copyOf(hosts) : ImmutableSet.of();
Madan Jampani38a88212015-09-15 11:21:27 -0700344 }
345
346 @Override
347 public Set<Host> getConnectedHosts(ConnectPoint connectPoint) {
Charles Chan009c3082015-11-10 14:18:04 -0800348 Set<Host> filtered = hosts.entrySet().stream()
Charles Chancd06c692017-04-27 20:46:06 -0700349 .filter(entry -> entry.getValue().locations().contains(connectPoint))
Charles Chan009c3082015-11-10 14:18:04 -0800350 .map(Map.Entry::getValue)
351 .collect(Collectors.toSet());
352 return ImmutableSet.copyOf(filtered);
Madan Jampani38a88212015-09-15 11:21:27 -0700353 }
354
355 @Override
356 public Set<Host> getConnectedHosts(DeviceId deviceId) {
Charles Chan009c3082015-11-10 14:18:04 -0800357 Set<Host> filtered = hosts.entrySet().stream()
Charles Chancd06c692017-04-27 20:46:06 -0700358 .filter(entry -> entry.getValue().locations().stream()
359 .map(HostLocation::deviceId).anyMatch(dpid -> dpid.equals(deviceId)))
Charles Chan009c3082015-11-10 14:18:04 -0800360 .map(Map.Entry::getValue)
361 .collect(Collectors.toSet());
HIGUCHI Yutafe2122c2015-09-30 13:46:22 -0700362 return ImmutableSet.copyOf(filtered);
Madan Jampani38a88212015-09-15 11:21:27 -0700363 }
364
Madan Jampani38a88212015-09-15 11:21:27 -0700365 private Set<Host> filter(Collection<DefaultHost> collection, Predicate<DefaultHost> predicate) {
366 return collection.stream().filter(predicate).collect(Collectors.toSet());
367 }
368
Deepa Vaddireddy0a71c8b2017-01-19 21:20:45 +0530369 private Set<Host> addHosts(Host host) {
370 Set<Host> hosts = Sets.newConcurrentHashSet();
371 hosts.add(host);
372 return hosts;
373 }
374
375 private Set<Host> updateHosts(Set<Host> existingHosts, Host host) {
376 Iterator<Host> iterator = existingHosts.iterator();
377 while (iterator.hasNext()) {
378 Host existingHost = iterator.next();
379 if (existingHost.id().equals(host.id())) {
380 iterator.remove();
381 }
382 }
383 existingHosts.add(host);
384 return existingHosts;
385 }
386
387 private Set<Host> removeHosts(Set<Host> existingHosts, Host host) {
388 if (existingHosts != null) {
389 Iterator<Host> iterator = existingHosts.iterator();
390 while (iterator.hasNext()) {
391 Host existingHost = iterator.next();
392 if (existingHost.id().equals(host.id())) {
393 iterator.remove();
394 }
395 }
396 }
397
Ray Milkey74e59132018-01-17 15:24:52 -0800398 if (existingHosts == null || existingHosts.isEmpty()) {
Deepa Vaddireddy0a71c8b2017-01-19 21:20:45 +0530399 return null;
400 }
401 return existingHosts;
402 }
403
404 private void updateHostsByIp(DefaultHost host) {
405 host.ipAddresses().forEach(ip -> {
406 hostsByIp.compute(ip, (k, v) -> v == null ? addHosts(host)
407 : updateHosts(v, host));
408 });
409 }
410
411 private void removeHostsByIp(DefaultHost host) {
412 host.ipAddresses().forEach(ip -> {
413 hostsByIp.computeIfPresent(ip, (k, v) -> removeHosts(v, host));
414 });
415 }
416
417 private void removeIpFromHostsByIp(DefaultHost host, IpAddress ip) {
418 hostsByIp.computeIfPresent(ip, (k, v) -> removeHosts(v, host));
419 }
420
alshabib8a4a6002015-11-25 14:31:16 -0800421 private class HostLocationTracker implements MapEventListener<HostId, DefaultHost> {
Madan Jampani38a88212015-09-15 11:21:27 -0700422 @Override
alshabib8a4a6002015-11-25 14:31:16 -0800423 public void event(MapEvent<HostId, DefaultHost> event) {
Ray Milkeyd0f017f2018-09-21 12:52:34 -0700424 Versioned<DefaultHost> value = event.type() == MapEvent.Type.REMOVE ? event.oldValue() : event.newValue();
425 DefaultHost host = checkNotNull(value.value());
alshabib1400ce92015-12-16 15:05:47 -0800426 switch (event.type()) {
427 case INSERT:
Deepa Vaddireddy0a71c8b2017-01-19 21:20:45 +0530428 updateHostsByIp(host);
Charles Chan009c3082015-11-10 14:18:04 -0800429 notifyDelegate(new HostEvent(HOST_ADDED, host));
alshabib1400ce92015-12-16 15:05:47 -0800430 break;
431 case UPDATE:
Deepa Vaddireddy0a71c8b2017-01-19 21:20:45 +0530432 updateHostsByIp(host);
433 DefaultHost prevHost = checkNotNull(event.oldValue().value());
Charles Chancd06c692017-04-27 20:46:06 -0700434 if (!Objects.equals(prevHost.locations(), host.locations())) {
alshabib1400ce92015-12-16 15:05:47 -0800435 notifyDelegate(new HostEvent(HOST_MOVED, host, prevHost));
436 } else if (!Objects.equals(prevHost, host)) {
437 notifyDelegate(new HostEvent(HOST_UPDATED, host, prevHost));
438 }
439 break;
440 case REMOVE:
Charles Chan21720342017-05-13 00:19:09 -0700441 removeHostsByIp(host);
Yuta HIGUCHI215a7e42016-07-20 19:54:06 -0700442 notifyDelegate(new HostEvent(HOST_REMOVED, host));
alshabib1400ce92015-12-16 15:05:47 -0800443 break;
444 default:
445 log.warn("Unknown map event type: {}", event.type());
Madan Jampani38a88212015-09-15 11:21:27 -0700446 }
447 }
448 }
449}