X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?a=blobdiff_plain;f=neutron%2Fsrc%2Fmain%2Fjava%2Forg%2Fopendaylight%2Fovsdb%2Fneutron%2FSouthboundHandler.java;h=281aecf3d14787fb2de1651f4b88761d6e9b2a2c;hb=d5991ce7e27da12b9dcfc60beebb738e1ff0f21a;hp=321c72c48d416532e6ded947cab7876ba4f5df2a;hpb=def4434e659cc054df664fe512f6e5b5e4f586d3;p=netvirt.git diff --git a/neutron/src/main/java/org/opendaylight/ovsdb/neutron/SouthboundHandler.java b/neutron/src/main/java/org/opendaylight/ovsdb/neutron/SouthboundHandler.java index 321c72c48d..281aecf3d1 100644 --- a/neutron/src/main/java/org/opendaylight/ovsdb/neutron/SouthboundHandler.java +++ b/neutron/src/main/java/org/opendaylight/ovsdb/neutron/SouthboundHandler.java @@ -1,39 +1,179 @@ package org.opendaylight.ovsdb.neutron; +import java.util.Map; +import java.util.Set; +import java.util.concurrent.BlockingQueue; +import java.util.concurrent.LinkedBlockingQueue; + +import org.opendaylight.controller.networkconfig.neutron.NeutronNetwork; import org.opendaylight.controller.sal.core.Node; +import org.opendaylight.ovsdb.lib.notation.UUID; +import org.opendaylight.ovsdb.lib.table.Interface; +import org.opendaylight.ovsdb.lib.table.Open_vSwitch; +import org.opendaylight.ovsdb.lib.table.Port; import org.opendaylight.ovsdb.lib.table.internal.Table; +import org.opendaylight.ovsdb.neutron.provider.ProviderNetworkManager; import org.opendaylight.ovsdb.plugin.OVSDBInventoryListener; import org.slf4j.Logger; import org.slf4j.LoggerFactory; public class SouthboundHandler extends BaseHandler implements OVSDBInventoryListener { static final Logger logger = LoggerFactory.getLogger(SouthboundHandler.class); + private Thread eventThread; + private BlockingQueue events; + + void init() { + eventThread = new Thread(new EventHandler(), "SouthBound Event Thread"); + this.events = new LinkedBlockingQueue(); + } + + void start() { + eventThread.start(); + } + + void stop() { + eventThread.interrupt(); + } @Override public void nodeAdded(Node node) { - logger.debug("NODE ADDED {}", node); - AdminConfigManager.getManager().populateTunnelEndpoint(node); - InternalNetworkManager.getManager().prepareInternalNetwork(node); + this.enqueueEvent(new SouthboundEvent(node, SouthboundEvent.Action.ADD)); } @Override public void nodeRemoved(Node node) { - logger.debug("NODE REMOVED {}", node); + this.enqueueEvent(new SouthboundEvent(node, SouthboundEvent.Action.DELETE)); } @Override - public void rowAdded(Node node, String tableName, Table row) { - logger.debug("ROW ADDED {} , {}", node, row); - /* - * Should we support dynamic update of the Tunnel endpoint configuration ? - * - if (AdminConfigManager.getManager().isInterested(tableName)) { - AdminConfigManager.getManager().populateTunnelEndpoint(node, tableName, row); - } - */ + public void rowAdded(Node node, String tableName, String uuid, Table row) { + this.enqueueEvent(new SouthboundEvent(node, tableName, uuid, row, SouthboundEvent.Action.ADD)); } @Override - public void rowRemoved(Node node, String tableName, Table row) { - logger.debug("ROW REMOVED {} , {}", node, row); + public void rowUpdated(Node node, String tableName, String uuid, Table row) { + this.enqueueEvent(new SouthboundEvent(node, tableName, uuid, row, SouthboundEvent.Action.UPDATE)); + } + + @Override + public void rowRemoved(Node node, String tableName, String uuid, Table row) { + this.enqueueEvent(new SouthboundEvent(node, tableName, uuid, row, SouthboundEvent.Action.DELETE)); + } + + private void enqueueEvent (SouthboundEvent event) { + try { + events.put(event); + } catch (InterruptedException e) { + e.printStackTrace(); + } + + } + private class EventHandler implements Runnable { + @Override + public void run() { + while (true) { + try { + SouthboundEvent ev = events.take(); + switch (ev.getType()) { + case NODE: + ProcessNodeUpdate(ev.getNode(), ev.getAction()); + case ROW: + ProcessRowUpdate(ev.getNode(), ev.getTableName(), ev.getUuid(), ev.getRow(), ev.getAction()); + break; + } + } catch (Exception e) { + e.printStackTrace(); + } + } + } + } + + public void ProcessNodeUpdate(Node node, SouthboundEvent.Action action) { + if (action == SouthboundEvent.Action.DELETE) return; + logger.trace("Process Node added {}", node); + InternalNetworkManager.getManager().prepareInternalNetwork(node); + } + + private void ProcessRowUpdate(Node node, String tableName, String uuid, Table row, + SouthboundEvent.Action action) { + if (action == SouthboundEvent.Action.DELETE) return; + + if (Interface.NAME.getName().equalsIgnoreCase(tableName)) { + logger.debug("trace {} Added / Updated {} , {}, {}", tableName, node, uuid, row); + Interface intf = (Interface)row; + NeutronNetwork network = TenantNetworkManager.getManager().getTenantNetworkForInterface(intf); + if (network != null) { + int vlan = TenantNetworkManager.getManager().networkCreated(network.getID()); + logger.trace("Neutron Network {} Created with Internal Vlan : {}", network.toString(), vlan); + + String portUUID = this.getPortIdForInterface(node, uuid, intf); + if (portUUID != null) { + TenantNetworkManager.getManager().programTenantNetworkInternalVlan(node, portUUID, network); + } + this.createTunnels(node, uuid, intf); + } + } else if (Port.NAME.getName().equalsIgnoreCase(tableName)) { + logger.debug("trace {} Added / Updated {} , {}, {}", tableName, node, uuid, row); + Port port = (Port)row; + Set interfaceUUIDs = port.getInterfaces(); + for (UUID intfUUID : interfaceUUIDs) { + logger.trace("Scanning interface "+intfUUID); + try { + Interface intf = (Interface)this.ovsdbConfigService.getRow(node, Interface.NAME.getName(), intfUUID.toString()); + NeutronNetwork network = TenantNetworkManager.getManager().getTenantNetworkForInterface(intf); + if (network != null) { + TenantNetworkManager.getManager().programTenantNetworkInternalVlan(node, uuid, network); + } + } catch (Exception e) { + e.printStackTrace(); + } + } + } else if (Open_vSwitch.NAME.getName().equalsIgnoreCase(tableName)) { + logger.debug("trace {} Added / Updated {} , {}, {}", tableName, node, uuid, row); + AdminConfigManager.getManager().populateTunnelEndpoint(node); + try { + Map> interfaces = this.ovsdbConfigService.getRows(node, Interface.NAME.getName()); + if (interfaces != null) { + for (String intfUUID : interfaces.keySet()) { + Interface intf = (Interface) interfaces.get(intfUUID); + createTunnels(node, intfUUID, intf); + } + } + } catch (Exception e) { + logger.error("Error fetching Interface Rows for node {}", node); + } + } + } + + private void createTunnels (Node node, String uuid, Interface intf) { + if (AdminConfigManager.getManager().getTunnelEndPoint(node) == null) { + logger.error("Tunnel end-point configuration missing. Please configure it in Open_vSwitch Table"); + return; + } + NeutronNetwork network = TenantNetworkManager.getManager().getTenantNetworkForInterface(intf); + if (network != null) { + ProviderNetworkManager.getManager().createTunnels(network.getProviderNetworkType(), + network.getProviderSegmentationID()); + } + } + + private String getPortIdForInterface (Node node, String uuid, Interface intf) { + try { + Map> ports = this.ovsdbConfigService.getRows(node, Port.NAME.getName()); + if (ports == null) return null; + for (String portUUID : ports.keySet()) { + Port port = (Port)ports.get(portUUID); + Set interfaceUUIDs = port.getInterfaces(); + logger.trace("Scanning Port {} to identify interface : {} ",port, uuid); + for (UUID intfUUID : interfaceUUIDs) { + if (intfUUID.toString().equalsIgnoreCase(uuid)) { + logger.trace("Found Interafce {} -> {}", uuid, portUUID); + return portUUID; + } + } + } + } catch (Exception e) { + logger.debug("Failed to add Port tag for for Intf {}",intf, e); + } + return null; } }