Listen on openstack's port event to create instance port and host
Change-Id: I3ef48dea08bf26bb61ed05d19b47d2bbade181e6
(cherry picked from commit 46276ef4b8a6c4670a65d0c91a9773f16175a0e1)
diff --git a/apps/openstacknetworking/api/src/main/java/org/onosproject/openstacknetworking/api/Constants.java b/apps/openstacknetworking/api/src/main/java/org/onosproject/openstacknetworking/api/Constants.java
index 897f473..e05c0d4 100644
--- a/apps/openstacknetworking/api/src/main/java/org/onosproject/openstacknetworking/api/Constants.java
+++ b/apps/openstacknetworking/api/src/main/java/org/onosproject/openstacknetworking/api/Constants.java
@@ -16,11 +16,13 @@
package org.onosproject.openstacknetworking.api;
import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.ImmutableSet;
import org.onlab.packet.IpAddress;
import org.onlab.packet.MacAddress;
import java.nio.charset.StandardCharsets;
import java.util.Map;
+import java.util.Set;
/**
* Provides constants used in OpenStackSwitching.
@@ -133,6 +135,8 @@
public static final String GRE = "GRE";
public static final String GENEVE = "GENEVE";
+ public static final Set<String> TUNNEL_TYPE = ImmutableSet.of(VXLAN, GRE, GENEVE);
+
public static Map<String, String> portNamePrefixMap() {
return PORT_NAME_PREFIX_MAP;
}
diff --git a/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/impl/OpenstackSwitchingHostProvider.java b/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/impl/OpenstackSwitchingHostProvider.java
index 1b42ccf..04ec1e7 100644
--- a/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/impl/OpenstackSwitchingHostProvider.java
+++ b/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/impl/OpenstackSwitchingHostProvider.java
@@ -42,6 +42,8 @@
import org.onosproject.net.provider.ProviderId;
import org.onosproject.openstacknetworking.api.Constants;
import org.onosproject.openstacknetworking.api.OpenstackNetwork.Type;
+import org.onosproject.openstacknetworking.api.OpenstackNetworkEvent;
+import org.onosproject.openstacknetworking.api.OpenstackNetworkListener;
import org.onosproject.openstacknetworking.api.OpenstackNetworkService;
import org.onosproject.openstacknode.api.OpenstackNode;
import org.onosproject.openstacknode.api.OpenstackNodeEvent;
@@ -71,6 +73,7 @@
import static org.onosproject.openstacknetworking.api.Constants.OPENSTACK_NETWORKING_APP_ID;
import static org.onosproject.openstacknetworking.api.Constants.PORT_NAME_PREFIX_VM;
import static org.onosproject.openstacknetworking.api.Constants.PORT_NAME_VHOST_USER_PREFIX_VM;
+import static org.onosproject.openstacknetworking.api.Constants.TUNNEL_TYPE;
import static org.onosproject.openstacknetworking.api.Constants.portNamePrefixMap;
import static org.onosproject.openstacknetworking.api.OpenstackNetwork.Type.FLAT;
import static org.onosproject.openstacknetworking.util.OpenstackNetworkingUtil.vnicType;
@@ -112,6 +115,8 @@
groupedThreads(this.getClass().getSimpleName(), "device-event"));
private final InternalDeviceListener internalDeviceListener =
new InternalDeviceListener();
+ private final InternalNetworkListener internalNetworkListener =
+ new InternalNetworkListener();
private final InternalOpenstackNodeListener internalNodeListener =
new InternalOpenstackNodeListener();
@@ -127,6 +132,7 @@
coreService.registerApplication(OPENSTACK_NETWORKING_APP_ID);
deviceService.addListener(internalDeviceListener);
osNodeService.addListener(internalNodeListener);
+ osNetworkService.addListener(internalNetworkListener);
hostProviderService = hostProviderRegistry.register(this);
log.info("Started");
@@ -136,6 +142,7 @@
protected void deactivate() {
hostProviderRegistry.unregister(this);
osNodeService.removeListener(internalNodeListener);
+ osNetworkService.removeListener(internalNetworkListener);
deviceService.removeListener(internalDeviceListener);
executor.shutdown();
@@ -158,7 +165,11 @@
log.debug("Instance port {} is detected from {}",
event.port().annotations().value(PORT_NAME),
event.subject().id());
- processPortAdded(event.port());
+ // we check the existence of openstack port, in case VM creation
+ // event comes before port creation
+ if (osNetworkService.port(event.port()) != null) {
+ processPortAdded(event.port());
+ }
}
/**
@@ -171,7 +182,11 @@
log.debug("Instance port {} is removed from {}",
event.port().annotations().value(PORT_NAME),
event.subject().id());
- processPortRemoved(event.port());
+ // we check the existence of openstack port, will not remove any hosts
+ // or instance ports with non-exist openstack port
+ if (osNetworkService.port(event.port()) != null) {
+ processPortRemoved(event.port());
+ }
}
/**
@@ -441,4 +456,30 @@
});
}
}
+
+ private class InternalNetworkListener implements OpenstackNetworkListener {
+
+ @Override
+ public void event(OpenstackNetworkEvent event) {
+ switch (event.type()) {
+ case OPENSTACK_PORT_CREATED:
+ executor.execute(() -> processOpenstackPortAddition(event));
+ break;
+ default:
+ break;
+ }
+ }
+
+ private void processOpenstackPortAddition(OpenstackNetworkEvent event) {
+ String portId = event.port().getId();
+ deviceService.getDevices().forEach(device -> {
+ deviceService.getPorts(device.id()).stream()
+ .filter(Port::isEnabled)
+ .filter(p -> p.annotations().value(PORT_NAME) != null)
+ .filter(p -> portId.contains(p.annotations().value(PORT_NAME).substring(3)))
+ .filter(p -> !TUNNEL_TYPE.contains(p.annotations().value(PORT_NAME).toUpperCase()))
+ .findAny().ifPresent(OpenstackSwitchingHostProvider.this::processPortAdded);
+ });
+ }
+ }
}