Get rid of all e.printStackTrace() statements and cleanup some exception handling.
[netvirt.git] / neutron / src / main / java / org / opendaylight / ovsdb / neutron / SouthboundHandler.java
1 package org.opendaylight.ovsdb.neutron;
2
3 import java.util.Map;
4 import java.util.Set;
5 import java.util.concurrent.BlockingQueue;
6 import java.util.concurrent.LinkedBlockingQueue;
7
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;
19
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;
24
25     void init() {
26         eventThread = new Thread(new EventHandler(), "SouthBound Event Thread");
27         this.events = new LinkedBlockingQueue<SouthboundEvent>();
28     }
29
30     void start() {
31         eventThread.start();
32     }
33
34     void stop() {
35         eventThread.interrupt();
36     }
37     @Override
38     public void nodeAdded(Node node) {
39         this.enqueueEvent(new SouthboundEvent(node, SouthboundEvent.Action.ADD));
40     }
41
42     @Override
43     public void nodeRemoved(Node node) {
44         this.enqueueEvent(new SouthboundEvent(node, SouthboundEvent.Action.DELETE));
45     }
46
47     @Override
48     public void rowAdded(Node node, String tableName, String uuid, Table<?> row) {
49         this.enqueueEvent(new SouthboundEvent(node, tableName, uuid, row, SouthboundEvent.Action.ADD));
50     }
51
52     @Override
53     public void rowUpdated(Node node, String tableName, String uuid, Table<?> row) {
54         this.enqueueEvent(new SouthboundEvent(node, tableName, uuid, row, SouthboundEvent.Action.UPDATE));
55     }
56
57     @Override
58     public void rowRemoved(Node node, String tableName, String uuid, Table<?> row) {
59         this.enqueueEvent(new SouthboundEvent(node, tableName, uuid, row, SouthboundEvent.Action.DELETE));
60     }
61
62     private void enqueueEvent (SouthboundEvent event) {
63         try {
64             events.put(event);
65         } catch (InterruptedException e) {
66             logger.error("Thread was interrupted while trying to enqueue event ", e);
67         }
68
69     }
70     private class EventHandler implements Runnable {
71         @Override
72         public void run() {
73             while (true) {
74                 try {
75                     SouthboundEvent ev = events.take();
76                     switch (ev.getType()) {
77                     case NODE:
78                         ProcessNodeUpdate(ev.getNode(), ev.getAction());
79                     case ROW:
80                         ProcessRowUpdate(ev.getNode(), ev.getTableName(), ev.getUuid(), ev.getRow(), ev.getAction());
81                         break;
82                     }
83                 } catch (InterruptedException e) {
84                     logger.error("Thread was interrupted while taking an evet from the queue", e);
85                 }
86             }
87         }
88     }
89
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);
94     }
95
96     private void ProcessRowUpdate(Node node, String tableName, String uuid, Table<?> row,
97                                   SouthboundEvent.Action action) {
98         if (action == SouthboundEvent.Action.DELETE) return;
99
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);
107
108                 String portUUID = this.getPortIdForInterface(node, uuid, intf);
109                 if (portUUID != null) {
110                     TenantNetworkManager.getManager().programTenantNetworkInternalVlan(node, portUUID, network);
111                 }
112                 this.createTunnels(node, uuid, intf);
113             }
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);
120                 try {
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);
125                     }
126                 } catch (Exception e) {
127                     logger.error("Failed to process row update", e);
128                 }
129             }
130         } else if (Open_vSwitch.NAME.getName().equalsIgnoreCase(tableName)) {
131             logger.debug("trace {} Added / Updated {} , {}, {}", tableName, node, uuid, row);
132             AdminConfigManager.getManager().populateTunnelEndpoint(node);
133             try {
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);
139                     }
140                 }
141             } catch (Exception e) {
142                 logger.error("Error fetching Interface Rows for node " + node, e);
143             }
144         }
145     }
146
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");
150             return;
151         }
152         NeutronNetwork network = TenantNetworkManager.getManager().getTenantNetworkForInterface(intf);
153         if (network != null) {
154             ProviderNetworkManager.getManager().createTunnels(network.getProviderNetworkType(),
155                     network.getProviderSegmentationID(), node, intf);
156         }
157     }
158
159     private String getPortIdForInterface (Node node, String uuid, Interface intf) {
160         try {
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);
170                         return portUUID;
171                     }
172                 }
173             }
174         } catch (Exception e) {
175             logger.debug("Failed to add Port tag for for Intf {}",intf, e);
176         }
177         return null;
178     }
179 }