1 package org.opendaylight.ovsdb.neutron;
5 import java.util.concurrent.BlockingQueue;
6 import java.util.concurrent.LinkedBlockingQueue;
8 import org.opendaylight.controller.networkconfig.neutron.NeutronNetwork;
9 import org.opendaylight.controller.sal.core.Node;
10 import org.opendaylight.ovsdb.lib.notation.UUID;
11 import org.opendaylight.ovsdb.lib.table.Interface;
12 import org.opendaylight.ovsdb.lib.table.Open_vSwitch;
13 import org.opendaylight.ovsdb.lib.table.Port;
14 import org.opendaylight.ovsdb.lib.table.internal.Table;
15 import org.opendaylight.ovsdb.neutron.provider.ProviderNetworkManager;
16 import org.opendaylight.ovsdb.plugin.OVSDBInventoryListener;
17 import org.slf4j.Logger;
18 import org.slf4j.LoggerFactory;
20 public class SouthboundHandler extends BaseHandler implements OVSDBInventoryListener {
21 static final Logger logger = LoggerFactory.getLogger(SouthboundHandler.class);
22 private Thread eventThread;
23 private BlockingQueue<SouthboundEvent> events;
26 eventThread = new Thread(new EventHandler(), "SouthBound Event Thread");
27 this.events = new LinkedBlockingQueue<SouthboundEvent>();
35 eventThread.interrupt();
38 public void nodeAdded(Node node) {
39 this.enqueueEvent(new SouthboundEvent(node, SouthboundEvent.Action.ADD));
43 public void nodeRemoved(Node node) {
44 this.enqueueEvent(new SouthboundEvent(node, SouthboundEvent.Action.DELETE));
48 public void rowAdded(Node node, String tableName, String uuid, Table<?> row) {
49 this.enqueueEvent(new SouthboundEvent(node, tableName, uuid, row, SouthboundEvent.Action.ADD));
53 public void rowUpdated(Node node, String tableName, String uuid, Table<?> row) {
54 this.enqueueEvent(new SouthboundEvent(node, tableName, uuid, row, SouthboundEvent.Action.UPDATE));
58 public void rowRemoved(Node node, String tableName, String uuid, Table<?> row) {
59 this.enqueueEvent(new SouthboundEvent(node, tableName, uuid, row, SouthboundEvent.Action.DELETE));
62 private void enqueueEvent (SouthboundEvent event) {
65 } catch (InterruptedException e) {
66 logger.error("Thread was interrupted while trying to enqueue event ", e);
70 private class EventHandler implements Runnable {
75 SouthboundEvent ev = events.take();
76 switch (ev.getType()) {
78 ProcessNodeUpdate(ev.getNode(), ev.getAction());
80 ProcessRowUpdate(ev.getNode(), ev.getTableName(), ev.getUuid(), ev.getRow(), ev.getAction());
83 } catch (InterruptedException e) {
84 logger.error("Thread was interrupted while taking an evet from the queue", e);
90 public void ProcessNodeUpdate(Node node, SouthboundEvent.Action action) {
91 if (action == SouthboundEvent.Action.DELETE) return;
92 logger.trace("Process Node added {}", node);
93 InternalNetworkManager.getManager().prepareInternalNetwork(node);
96 private void ProcessRowUpdate(Node node, String tableName, String uuid, Table<?> row,
97 SouthboundEvent.Action action) {
98 if (action == SouthboundEvent.Action.DELETE) return;
100 if (Interface.NAME.getName().equalsIgnoreCase(tableName)) {
101 logger.debug("trace {} Added / Updated {} , {}, {}", tableName, node, uuid, row);
102 Interface intf = (Interface)row;
103 NeutronNetwork network = TenantNetworkManager.getManager().getTenantNetworkForInterface(intf);
104 if (network != null) {
105 int vlan = TenantNetworkManager.getManager().networkCreated(network.getID());
106 logger.trace("Neutron Network {} Created with Internal Vlan : {}", network.toString(), vlan);
108 String portUUID = this.getPortIdForInterface(node, uuid, intf);
109 if (portUUID != null) {
110 TenantNetworkManager.getManager().programTenantNetworkInternalVlan(node, portUUID, network);
112 this.createTunnels(node, uuid, intf);
114 } else if (Port.NAME.getName().equalsIgnoreCase(tableName)) {
115 logger.debug("trace {} Added / Updated {} , {}, {}", tableName, node, uuid, row);
116 Port port = (Port)row;
117 Set<UUID> interfaceUUIDs = port.getInterfaces();
118 for (UUID intfUUID : interfaceUUIDs) {
119 logger.trace("Scanning interface "+intfUUID);
121 Interface intf = (Interface)this.ovsdbConfigService.getRow(node, Interface.NAME.getName(), intfUUID.toString());
122 NeutronNetwork network = TenantNetworkManager.getManager().getTenantNetworkForInterface(intf);
123 if (network != null) {
124 TenantNetworkManager.getManager().programTenantNetworkInternalVlan(node, uuid, network);
126 } catch (Exception e) {
127 logger.error("Failed to process row update", e);
130 } else if (Open_vSwitch.NAME.getName().equalsIgnoreCase(tableName)) {
131 logger.debug("trace {} Added / Updated {} , {}, {}", tableName, node, uuid, row);
132 AdminConfigManager.getManager().populateTunnelEndpoint(node);
134 Map<String, Table<?>> interfaces = this.ovsdbConfigService.getRows(node, Interface.NAME.getName());
135 if (interfaces != null) {
136 for (String intfUUID : interfaces.keySet()) {
137 Interface intf = (Interface) interfaces.get(intfUUID);
138 createTunnels(node, intfUUID, intf);
141 } catch (Exception e) {
142 logger.error("Error fetching Interface Rows for node " + node, e);
147 private void createTunnels (Node node, String uuid, Interface intf) {
148 if (AdminConfigManager.getManager().getTunnelEndPoint(node) == null) {
149 logger.error("Tunnel end-point configuration missing. Please configure it in Open_vSwitch Table");
152 NeutronNetwork network = TenantNetworkManager.getManager().getTenantNetworkForInterface(intf);
153 if (network != null) {
154 ProviderNetworkManager.getManager().createTunnels(network.getProviderNetworkType(),
155 network.getProviderSegmentationID(), node, intf);
159 private String getPortIdForInterface (Node node, String uuid, Interface intf) {
161 Map<String, Table<?>> ports = this.ovsdbConfigService.getRows(node, Port.NAME.getName());
162 if (ports == null) return null;
163 for (String portUUID : ports.keySet()) {
164 Port port = (Port)ports.get(portUUID);
165 Set<UUID> interfaceUUIDs = port.getInterfaces();
166 logger.trace("Scanning Port {} to identify interface : {} ",port, uuid);
167 for (UUID intfUUID : interfaceUUIDs) {
168 if (intfUUID.toString().equalsIgnoreCase(uuid)) {
169 logger.trace("Found Interafce {} -> {}", uuid, portUUID);
174 } catch (Exception e) {
175 logger.debug("Failed to add Port tag for for Intf {}",intf, e);