Remove host location when port down or device down
Also refactor Host Location Provider
Change-Id: I57d682ee51e80ddd7e141883521a12da705a336d
diff --git a/core/api/src/main/java/org/onosproject/net/host/HostProviderService.java b/core/api/src/main/java/org/onosproject/net/host/HostProviderService.java
index dfb0ac2..9125049 100644
--- a/core/api/src/main/java/org/onosproject/net/host/HostProviderService.java
+++ b/core/api/src/main/java/org/onosproject/net/host/HostProviderService.java
@@ -17,6 +17,7 @@
import org.onlab.packet.IpAddress;
import org.onosproject.net.HostId;
+import org.onosproject.net.HostLocation;
import org.onosproject.net.provider.ProviderService;
/**
@@ -49,4 +50,11 @@
*/
void removeIpFromHost(HostId hostId, IpAddress ipAddress);
+ /**
+ * Notifies the core when a location is no longer associated with a host.
+ *
+ * @param hostId id of the host
+ * @param location location of host that vanished
+ */
+ void removeLocationFromHost(HostId hostId, HostLocation location);
}
diff --git a/core/api/src/main/java/org/onosproject/net/host/HostStore.java b/core/api/src/main/java/org/onosproject/net/host/HostStore.java
index e73fbb7..e8a3e56 100644
--- a/core/api/src/main/java/org/onosproject/net/host/HostStore.java
+++ b/core/api/src/main/java/org/onosproject/net/host/HostStore.java
@@ -22,6 +22,7 @@
import org.onosproject.net.DeviceId;
import org.onosproject.net.Host;
import org.onosproject.net.HostId;
+import org.onosproject.net.HostLocation;
import org.onosproject.net.provider.ProviderId;
import org.onosproject.store.Store;
@@ -64,6 +65,14 @@
HostEvent removeIp(HostId hostId, IpAddress ipAddress);
/**
+ * Removes the specified location from the host entry.
+ *
+ * @param hostId host identification
+ * @param location location to be removed
+ */
+ void removeLocation(HostId hostId, HostLocation location);
+
+ /**
* Returns the number of hosts in the store.
*
* @return host count
diff --git a/core/common/src/test/java/org/onosproject/store/trivial/SimpleHostStore.java b/core/common/src/test/java/org/onosproject/store/trivial/SimpleHostStore.java
index 98a9252..89214e4 100644
--- a/core/common/src/test/java/org/onosproject/store/trivial/SimpleHostStore.java
+++ b/core/common/src/test/java/org/onosproject/store/trivial/SimpleHostStore.java
@@ -167,10 +167,16 @@
@Override
public HostEvent removeIp(HostId hostId, IpAddress ipAddress) {
+ // TODO implement this
return null;
}
@Override
+ public void removeLocation(HostId hostId, HostLocation location) {
+ hosts.get(hostId).locations().remove(location);
+ }
+
+ @Override
public int getHostCount() {
return hosts.size();
}
diff --git a/core/net/src/main/java/org/onosproject/net/host/impl/HostManager.java b/core/net/src/main/java/org/onosproject/net/host/impl/HostManager.java
index 06f3120..ee0fc4c 100644
--- a/core/net/src/main/java/org/onosproject/net/host/impl/HostManager.java
+++ b/core/net/src/main/java/org/onosproject/net/host/impl/HostManager.java
@@ -30,16 +30,18 @@
import org.onlab.util.Tools;
import org.onosproject.cfg.ComponentConfigService;
import org.onosproject.incubator.net.intf.InterfaceService;
-import org.onosproject.net.ConnectPoint;
-import org.onosproject.net.DeviceId;
-import org.onosproject.net.Host;
-import org.onosproject.net.HostId;
+import org.onosproject.net.HostLocation;
+import org.onosproject.net.edge.EdgePortService;
+import org.onosproject.net.provider.AbstractListenerProviderRegistry;
import org.onosproject.net.config.NetworkConfigEvent;
import org.onosproject.net.config.NetworkConfigListener;
import org.onosproject.net.config.NetworkConfigService;
import org.onosproject.net.config.basics.BasicHostConfig;
+import org.onosproject.net.ConnectPoint;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.Host;
+import org.onosproject.net.HostId;
import org.onosproject.net.device.DeviceService;
-import org.onosproject.net.edge.EdgePortService;
import org.onosproject.net.host.HostAdminService;
import org.onosproject.net.host.HostDescription;
import org.onosproject.net.host.HostEvent;
@@ -51,7 +53,6 @@
import org.onosproject.net.host.HostStore;
import org.onosproject.net.host.HostStoreDelegate;
import org.onosproject.net.packet.PacketService;
-import org.onosproject.net.provider.AbstractListenerProviderRegistry;
import org.onosproject.net.provider.AbstractProviderService;
import org.osgi.service.component.ComponentContext;
import org.slf4j.Logger;
@@ -413,8 +414,8 @@
checkValidity();
Host host = store.getHost(hostId);
- // Disallow removing inexistent host or host provided by others
- if (host == null || !host.providerId().equals(provider().id())) {
+ if (!allowedToChange(hostId)) {
+ log.info("Request to remove {} is ignored due to provider mismatch", hostId);
return;
}
@@ -430,8 +431,35 @@
public void removeIpFromHost(HostId hostId, IpAddress ipAddress) {
checkNotNull(hostId, HOST_ID_NULL);
checkValidity();
+
+ if (!allowedToChange(hostId)) {
+ log.info("Request to remove {} from {} is ignored due to provider mismatch",
+ ipAddress, hostId);
+ return;
+ }
+
store.removeIp(hostId, ipAddress);
}
+
+ @Override
+ public void removeLocationFromHost(HostId hostId, HostLocation location) {
+ checkNotNull(hostId, HOST_ID_NULL);
+ checkValidity();
+
+ if (!allowedToChange(hostId)) {
+ log.info("Request to remove {} from {} is ignored due to provider mismatch",
+ location, hostId);
+ return;
+ }
+
+ store.removeLocation(hostId, location);
+ }
+
+ private boolean allowedToChange(HostId hostId) {
+ // Disallow removing inexistent host or host provided by others
+ Host host = store.getHost(hostId);
+ return host != null && host.providerId().equals(provider().id());
+ }
}
// Store delegate to re-post events emitted from the store.
diff --git a/core/store/dist/src/main/java/org/onosproject/store/host/impl/DistributedHostStore.java b/core/store/dist/src/main/java/org/onosproject/store/host/impl/DistributedHostStore.java
index 64d24a7..76d14e7 100644
--- a/core/store/dist/src/main/java/org/onosproject/store/host/impl/DistributedHostStore.java
+++ b/core/store/dist/src/main/java/org/onosproject/store/host/impl/DistributedHostStore.java
@@ -266,6 +266,29 @@
}
@Override
+ public void removeLocation(HostId hostId, HostLocation location) {
+ hosts.compute(hostId, (id, existingHost) -> {
+ if (existingHost != null) {
+ checkState(Objects.equals(hostId.mac(), existingHost.mac()),
+ "Existing and new MAC addresses differ.");
+ checkState(Objects.equals(hostId.vlanId(), existingHost.vlan()),
+ "Existing and new VLANs differ.");
+
+ Set<HostLocation> locations = new HashSet<>(existingHost.locations());
+ locations.remove(location);
+
+ // Remove entire host if we are removing the last location
+ return locations.isEmpty() ? null :
+ new DefaultHost(existingHost.providerId(),
+ hostId, existingHost.mac(), existingHost.vlan(),
+ locations, existingHost.ipAddresses(),
+ existingHost.configured(), existingHost.annotations());
+ }
+ return null;
+ });
+ }
+
+ @Override
public int getHostCount() {
return hosts.size();
}