3a84d00044cc63147bd9eb8e1c4a1128f5a26052
[onosfw.git] /
1 /*
2  * Copyright 2015 Open Networking Laboratory
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 package org.onosproject.ovsdb.controller.driver;
17
18 import com.fasterxml.jackson.databind.JsonNode;
19 import com.google.common.base.Function;
20 import com.google.common.collect.ImmutableList;
21 import com.google.common.collect.Lists;
22 import com.google.common.collect.Maps;
23 import com.google.common.collect.Sets;
24 import com.google.common.util.concurrent.Futures;
25 import com.google.common.util.concurrent.ListenableFuture;
26 import com.google.common.util.concurrent.SettableFuture;
27 import io.netty.channel.Channel;
28 import org.onlab.packet.IpAddress;
29 import org.onosproject.net.DeviceId;
30 import org.onosproject.net.behaviour.ControllerInfo;
31 import org.onosproject.ovsdb.controller.OvsdbBridge;
32 import org.onosproject.ovsdb.controller.OvsdbBridgeName;
33 import org.onosproject.ovsdb.controller.OvsdbClientService;
34 import org.onosproject.ovsdb.controller.OvsdbConstant;
35 import org.onosproject.ovsdb.controller.OvsdbDatapathId;
36 import org.onosproject.ovsdb.controller.OvsdbNodeId;
37 import org.onosproject.ovsdb.controller.OvsdbPort;
38 import org.onosproject.ovsdb.controller.OvsdbPortName;
39 import org.onosproject.ovsdb.controller.OvsdbPortNumber;
40 import org.onosproject.ovsdb.controller.OvsdbRowStore;
41 import org.onosproject.ovsdb.controller.OvsdbStore;
42 import org.onosproject.ovsdb.controller.OvsdbTableStore;
43 import org.onosproject.ovsdb.controller.OvsdbTunnel;
44 import org.onosproject.ovsdb.rfc.jsonrpc.Callback;
45 import org.onosproject.ovsdb.rfc.message.OperationResult;
46 import org.onosproject.ovsdb.rfc.message.TableUpdates;
47 import org.onosproject.ovsdb.rfc.notation.Condition;
48 import org.onosproject.ovsdb.rfc.notation.Mutation;
49 import org.onosproject.ovsdb.rfc.notation.OvsdbMap;
50 import org.onosproject.ovsdb.rfc.notation.OvsdbSet;
51 import org.onosproject.ovsdb.rfc.notation.Row;
52 import org.onosproject.ovsdb.rfc.notation.UUID;
53 import org.onosproject.ovsdb.rfc.operations.Delete;
54 import org.onosproject.ovsdb.rfc.operations.Insert;
55 import org.onosproject.ovsdb.rfc.operations.Mutate;
56 import org.onosproject.ovsdb.rfc.operations.Operation;
57 import org.onosproject.ovsdb.rfc.operations.Update;
58 import org.onosproject.ovsdb.rfc.schema.ColumnSchema;
59 import org.onosproject.ovsdb.rfc.schema.DatabaseSchema;
60 import org.onosproject.ovsdb.rfc.schema.TableSchema;
61 import org.onosproject.ovsdb.rfc.table.Bridge;
62 import org.onosproject.ovsdb.rfc.table.Controller;
63 import org.onosproject.ovsdb.rfc.table.Interface;
64 import org.onosproject.ovsdb.rfc.table.OvsdbTable;
65 import org.onosproject.ovsdb.rfc.table.Port;
66 import org.onosproject.ovsdb.rfc.table.TableGenerator;
67 import org.onosproject.ovsdb.rfc.utils.ConditionUtil;
68 import org.onosproject.ovsdb.rfc.utils.FromJsonUtil;
69 import org.onosproject.ovsdb.rfc.utils.JsonRpcWriterUtil;
70 import org.onosproject.ovsdb.rfc.utils.MutationUtil;
71 import org.slf4j.Logger;
72 import org.slf4j.LoggerFactory;
73
74 import java.net.InetSocketAddress;
75 import java.util.ArrayList;
76 import java.util.HashSet;
77 import java.util.Iterator;
78 import java.util.List;
79 import java.util.Map;
80 import java.util.Set;
81 import java.util.concurrent.ConcurrentMap;
82 import java.util.concurrent.ExecutionException;
83 import java.util.concurrent.atomic.AtomicReference;
84 import java.util.stream.Collectors;
85
86 /**
87  * An representation of an ovsdb client.
88  */
89 public class DefaultOvsdbClient
90         implements OvsdbProviderService, OvsdbClientService {
91
92     private final Logger log = LoggerFactory
93             .getLogger(DefaultOvsdbClient.class);
94
95     private Channel channel;
96
97     private OvsdbAgent agent;
98     private boolean connected;
99     private OvsdbNodeId nodeId;
100     private Callback monitorCallBack;
101
102     private OvsdbStore ovsdbStore = new OvsdbStore();
103
104     private final Map<String, String> requestMethod = Maps.newHashMap();
105     private final Map<String, SettableFuture<? extends Object>> requestResult = Maps
106             .newHashMap();
107
108     private final Map<String, DatabaseSchema> schema = Maps.newHashMap();
109     private final Set<OvsdbTunnel> ovsdbTunnels = new HashSet<OvsdbTunnel>();
110
111     /**
112      * Creates an OvsdbClient.
113      *
114      * @param nodeId ovsdb node id
115      */
116     public DefaultOvsdbClient(OvsdbNodeId nodeId) {
117         this.nodeId = nodeId;
118     }
119
120     @Override
121     public OvsdbNodeId nodeId() {
122         return nodeId;
123     }
124
125     @Override
126     public void setAgent(OvsdbAgent agent) {
127         if (this.agent == null) {
128             this.agent = agent;
129         }
130     }
131
132     @Override
133     public void setChannel(Channel channel) {
134         this.channel = channel;
135     }
136
137     @Override
138     public void setConnection(boolean connected) {
139         this.connected = connected;
140     }
141
142     @Override
143     public boolean isConnected() {
144         return this.connected;
145     }
146
147     @Override
148     public void nodeAdded() {
149         this.agent.addConnectedNode(nodeId, this);
150     }
151
152     @Override
153     public void nodeRemoved() {
154         this.agent.removeConnectedNode(nodeId);
155         channel.disconnect();
156     }
157
158     /**
159      * Gets the ovsdb table store.
160      *
161      * @param dbName the ovsdb database name
162      * @return ovsTableStore, empty if table store is find
163      */
164     private OvsdbTableStore getTableStore(String dbName) {
165         if (ovsdbStore == null) {
166             return null;
167         }
168         return ovsdbStore.getOvsdbTableStore(dbName);
169     }
170
171     /**
172      * Gets the ovsdb row store.
173      *
174      * @param dbName    the ovsdb database name
175      * @param tableName the ovsdb table name
176      * @return ovsRowStore, empty if row store is find
177      */
178     private OvsdbRowStore getRowStore(String dbName, String tableName) {
179         OvsdbTableStore tableStore = getTableStore(dbName);
180         if (tableStore == null) {
181             return null;
182         }
183         return tableStore.getRows(tableName);
184     }
185
186     /**
187      * Gets the ovsdb row.
188      *
189      * @param dbName    the ovsdb database name
190      * @param tableName the ovsdb table name
191      * @param uuid      the key of the row
192      * @return row, empty if row is find
193      */
194     @Override
195     public Row getRow(String dbName, String tableName, String uuid) {
196         OvsdbTableStore tableStore = getTableStore(dbName);
197         if (tableStore == null) {
198             return null;
199         }
200         OvsdbRowStore rowStore = tableStore.getRows(tableName);
201         if (rowStore == null) {
202             return null;
203         }
204         return rowStore.getRow(uuid);
205     }
206
207     @Override
208     public void removeRow(String dbName, String tableName, String uuid) {
209         OvsdbTableStore tableStore = getTableStore(dbName);
210         if (tableStore == null) {
211             return;
212         }
213         OvsdbRowStore rowStore = tableStore.getRows(tableName);
214         if (rowStore == null) {
215             return;
216         }
217         rowStore.deleteRow(uuid);
218     }
219
220     @Override
221     public void updateOvsdbStore(String dbName, String tableName, String uuid,
222                                  Row row) {
223         OvsdbTableStore tableStore = ovsdbStore.getOvsdbTableStore(dbName);
224         if (tableStore == null) {
225             tableStore = new OvsdbTableStore();
226         }
227         OvsdbRowStore rowStore = tableStore.getRows(tableName);
228         if (rowStore == null) {
229             rowStore = new OvsdbRowStore();
230         }
231         rowStore.insertRow(uuid, row);
232         tableStore.createOrUpdateTable(tableName, rowStore);
233         ovsdbStore.createOrUpdateOvsdbStore(dbName, tableStore);
234     }
235
236     @Override
237     public String getPortUuid(String portName, String bridgeUuid) {
238         DatabaseSchema dbSchema = schema.get(OvsdbConstant.DATABASENAME);
239
240         Row bridgeRow = getRow(OvsdbConstant.DATABASENAME,
241                                OvsdbConstant.BRIDGE, bridgeUuid);
242
243         Bridge bridge = (Bridge) TableGenerator.getTable(dbSchema, bridgeRow,
244                                                          OvsdbTable.BRIDGE);
245         if (bridge != null) {
246             OvsdbSet setPorts = (OvsdbSet) bridge.getPortsColumn().data();
247             @SuppressWarnings("unchecked")
248             Set<UUID> ports = setPorts.set();
249             if (ports == null || ports.size() == 0) {
250                 log.warn("The port uuid is null");
251                 return null;
252             }
253
254             for (UUID uuid : ports) {
255                 Row portRow = getRow(OvsdbConstant.DATABASENAME,
256                                      OvsdbConstant.PORT, uuid.value());
257                 Port port = (Port) TableGenerator.getTable(dbSchema, portRow,
258                                                            OvsdbTable.PORT);
259                 if (port != null && portName.equalsIgnoreCase(port.getName())) {
260                     return uuid.value();
261                 }
262             }
263
264         }
265         return null;
266     }
267
268     @Override
269     public String getInterfaceUuid(String portUuid, String portName) {
270         DatabaseSchema dbSchema = schema.get(OvsdbConstant.DATABASENAME);
271
272         Row portRow = getRow(OvsdbConstant.DATABASENAME, OvsdbConstant.PORT,
273                              portUuid);
274         Port port = (Port) TableGenerator.getTable(dbSchema, portRow,
275                                                    OvsdbTable.PORT);
276
277         if (port != null) {
278             OvsdbSet setInterfaces = (OvsdbSet) port.getInterfacesColumn().data();
279             @SuppressWarnings("unchecked")
280             Set<UUID> interfaces = setInterfaces.set();
281
282             if (interfaces == null || interfaces.size() == 0) {
283                 log.warn("The interface uuid is null");
284                 return null;
285             }
286
287             for (UUID uuid : interfaces) {
288                 Row intfRow = getRow(OvsdbConstant.DATABASENAME,
289                                      OvsdbConstant.INTERFACE, uuid.value());
290                 Interface intf = (Interface) TableGenerator
291                         .getTable(dbSchema, intfRow, OvsdbTable.INTERFACE);
292                 if (intf != null && portName.equalsIgnoreCase(intf.getName())) {
293                     return uuid.value();
294                 }
295             }
296
297         }
298
299         return null;
300     }
301
302     @Override
303     public String getBridgeUuid(String bridgeName) {
304         DatabaseSchema dbSchema = schema.get(OvsdbConstant.DATABASENAME);
305
306         OvsdbRowStore rowStore = getRowStore(OvsdbConstant.DATABASENAME,
307                                              OvsdbConstant.BRIDGE);
308         if (rowStore == null) {
309             log.debug("The bridge uuid is null");
310             return null;
311         }
312
313         ConcurrentMap<String, Row> bridgeTableRows = rowStore.getRowStore();
314         if (bridgeTableRows == null) {
315             log.debug("The bridge uuid is null");
316             return null;
317         }
318
319         for (String uuid : bridgeTableRows.keySet()) {
320             Bridge bridge = (Bridge) TableGenerator
321                     .getTable(dbSchema, bridgeTableRows.get(uuid),
322                               OvsdbTable.BRIDGE);
323
324             if (bridge.getName().equals(bridgeName)) {
325                 return uuid;
326             }
327
328         }
329         return null;
330     }
331
332     @Override
333     public String getControllerUuid(String controllerName,
334                                     String controllerTarget) {
335         DatabaseSchema dbSchema = schema.get(OvsdbConstant.DATABASENAME);
336         OvsdbRowStore rowStore = getRowStore(OvsdbConstant.DATABASENAME,
337                                              OvsdbConstant.CONTROLLER);
338         if (rowStore == null) {
339             log.debug("The controller uuid is null");
340             return null;
341         }
342
343         ConcurrentMap<String, Row> controllerTableRows = rowStore.getRowStore();
344         if (controllerTableRows != null) {
345             for (String uuid : controllerTableRows.keySet()) {
346
347                 Controller controller = (Controller) TableGenerator
348                         .getTable(dbSchema, controllerTableRows.get(uuid),
349                                   OvsdbTable.CONTROLLER);
350                 String target = (String) controller.getTargetColumn().data();
351                 if (target.equalsIgnoreCase(controllerTarget)) {
352                     return uuid;
353                 }
354
355             }
356         }
357         return null;
358     }
359
360     @Override
361     public String getOvsUuid(String dbName) {
362         OvsdbRowStore rowStore = getRowStore(OvsdbConstant.DATABASENAME,
363                                              OvsdbConstant.DATABASENAME);
364         if (rowStore == null) {
365             log.debug("The bridge uuid is null");
366             return null;
367         }
368         ConcurrentMap<String, Row> ovsTableRows = rowStore.getRowStore();
369         if (ovsTableRows != null) {
370             for (String uuid : ovsTableRows.keySet()) {
371                 Row row = ovsTableRows.get(uuid);
372                 String tableName = row.tableName();
373                 if (tableName.equals(dbName)) {
374                     return uuid;
375                 }
376             }
377         }
378         return null;
379     }
380
381     @Override
382     public void createPort(String bridgeName, String portName) {
383         String bridgeUuid = getBridgeUuid(bridgeName);
384         if (bridgeUuid == null) {
385             log.error("Can't find bridge {} in {}", bridgeName,
386                       nodeId.getIpAddress());
387             return;
388         }
389
390         DatabaseSchema dbSchema = schema.get(OvsdbConstant.DATABASENAME);
391         String portUuid = getPortUuid(portName, bridgeUuid);
392
393         Port port = (Port) TableGenerator
394                 .createTable(dbSchema, OvsdbTable.PORT);
395
396         port.setName(portName);
397         if (portUuid == null) {
398             insertConfig(OvsdbConstant.PORT, "_uuid", OvsdbConstant.BRIDGE,
399                          "ports", bridgeUuid, port.getRow());
400         } else {
401             updateConfig(OvsdbConstant.PORT, "_uuid", portUuid, port.getRow());
402         }
403
404         return;
405     }
406
407     @Override
408     public void dropPort(String bridgeName, String portName) {
409         String bridgeUuid = getBridgeUuid(bridgeName);
410         if (bridgeUuid == null) {
411             log.error("Could not find Bridge {} in {}", bridgeName, nodeId);
412             return;
413         }
414
415         String portUuid = getPortUuid(portName, bridgeUuid);
416         if (portUuid != null) {
417             log.info("Port {} delete", portName);
418             deleteConfig(OvsdbConstant.PORT, "_uuid", portUuid,
419                          OvsdbConstant.BRIDGE, "ports");
420         }
421     }
422
423     @Override
424     public void createBridge(String bridgeName) {
425         log.debug("create bridge {}", bridgeName);
426
427         DatabaseSchema dbSchema = schema.get(OvsdbConstant.DATABASENAME);
428         if (dbSchema == null) {
429             log.warn("The schema is null");
430             return;
431         }
432
433         Bridge bridge = (Bridge) TableGenerator.createTable(dbSchema,
434                                                             OvsdbTable.BRIDGE);
435         if (bridge == null) {
436             log.debug("Can not create bridge");
437             return;
438         }
439
440         Set<String> failModes = new HashSet<>();
441         failModes.add("secure");
442         bridge.setFailMode(failModes);
443
444         Set<String> protocols = new HashSet<>();
445         protocols.add(OvsdbConstant.OPENFLOW13);
446         bridge.setProtocols(protocols);
447
448         String ovsUuid = getOvsUuid(OvsdbConstant.DATABASENAME);
449         if (ovsUuid == null) {
450             log.warn("The Open_vSwitch is null");
451             return;
452         }
453
454         String bridgeUuid = getBridgeUuid(bridgeName);
455         if (bridgeUuid == null) {
456             log.debug("Create a new bridge");
457
458             bridge.setName(bridgeName);
459             bridgeUuid = insertConfig(OvsdbConstant.BRIDGE, "_uuid",
460                                       OvsdbConstant.DATABASENAME, "bridges",
461                                       ovsUuid, bridge.getRow());
462
463             if (bridgeUuid != null) {
464                 Port port = (Port) TableGenerator.createTable(dbSchema,
465                                                               OvsdbTable.PORT);
466                 if (port != null) {
467                     log.debug("the port is not null");
468                     port.setName(bridgeName);
469
470                     insertConfig(OvsdbConstant.PORT, "_uuid", "Bridge", "ports", bridgeUuid,
471                                  port.getRow());
472                 }
473             }
474
475         } else {
476             log.info("Update a bridge");
477             updateConfig(OvsdbConstant.BRIDGE, "_uuid", bridgeUuid, bridge.getRow());
478         }
479
480         setControllerAuto(bridgeUuid);
481         log.info("Create bridge success");
482     }
483
484     /**
485      * Sets the bridge's controller automatically.
486      * <p/>
487      * The connection is a TCP connection to the local ONOS instance's IP
488      * and the default OpenFlow port.
489      *
490      * @param bridgeUuid bridge uuid
491      */
492     private void setControllerAuto(String bridgeUuid) {
493         IpAddress ipAddress = IpAddress.valueOf(((InetSocketAddress) channel.localAddress()).getAddress());
494         ControllerInfo controllerInfo = new ControllerInfo(ipAddress, OvsdbConstant.OFPORT, "tcp");
495         log.debug("Automatically setting controller for bridge {} to {}",
496                   bridgeUuid, controllerInfo.target());
497         setControllersWithUUID(UUID.uuid(bridgeUuid), ImmutableList.of(controllerInfo));
498     }
499
500     @Override
501     public void setControllersWithUUID(UUID bridgeUuid, List<ControllerInfo> controllers) {
502
503         DatabaseSchema dbSchema = schema.get(OvsdbConstant.DATABASENAME);
504         if (dbSchema == null) {
505             log.debug("There is no schema");
506             return;
507         }
508         List<Controller> oldControllers = getControllers(bridgeUuid);
509         if (oldControllers == null) {
510             log.warn("There are no controllers");
511             return;
512         }
513
514         Set<UUID> newControllerUuids = new HashSet<>();
515
516         Set<ControllerInfo> newControllers = new HashSet<>(controllers);
517         List<Controller> removeControllers = new ArrayList<>();
518         oldControllers.forEach(controller -> {
519             ControllerInfo controllerInfo = new ControllerInfo((String) controller.getTargetColumn().data());
520             if (newControllers.contains(controllerInfo)) {
521                 newControllers.remove(controllerInfo);
522                 newControllerUuids.add(controller.getRow().uuid());
523             } else {
524                 removeControllers.add(controller);
525             }
526         });
527         OvsdbRowStore controllerRowStore = getRowStore(OvsdbConstant.DATABASENAME,
528                                                        OvsdbConstant.CONTROLLER);
529         if (controllerRowStore == null) {
530             log.debug("There is no controller table");
531             return;
532         }
533
534         removeControllers.forEach(c -> deleteConfig(OvsdbConstant.CONTROLLER, "_uuid", c.getRow().uuid().value(),
535                                                     OvsdbConstant.BRIDGE, "controller"));
536
537         newControllers.stream().map(c -> {
538             Controller controller = (Controller) TableGenerator
539                     .createTable(dbSchema, OvsdbTable.CONTROLLER);
540             controller.setTarget(c.target());
541             return controller;
542         }).forEach(c -> {
543             String uuid = insertConfig(OvsdbConstant.CONTROLLER, "_uuid",
544                                        OvsdbConstant.BRIDGE, "controller", bridgeUuid.value(),
545                                        c.getRow());
546             newControllerUuids.add(UUID.uuid(uuid));
547
548         });
549
550         OvsdbRowStore rowStore = getRowStore(OvsdbConstant.DATABASENAME,
551                                              OvsdbConstant.BRIDGE);
552         if (rowStore == null) {
553             log.debug("There is no bridge table");
554             return;
555         }
556
557         Row bridgeRow = rowStore.getRow(bridgeUuid.value());
558         Bridge bridge = (Bridge) TableGenerator.getTable(dbSchema, bridgeRow, OvsdbTable.BRIDGE);
559         bridge.setController(OvsdbSet.ovsdbSet(newControllerUuids));
560         updateConfig(OvsdbConstant.BRIDGE, "_uuid", bridgeUuid.value(), bridge.getRow());
561     }
562
563     @Override
564     public void setControllersWithDeviceId(DeviceId deviceId, List<ControllerInfo> controllers) {
565         setControllersWithUUID(getBridgeUUID(deviceId), controllers);
566     }
567
568     @Override
569     public void dropBridge(String bridgeName) {
570         String bridgeUUID = getBridgeUuid(bridgeName);
571         if (bridgeUUID == null) {
572             log.warn("Could not find bridge in node", nodeId.getIpAddress());
573             return;
574         }
575         deleteConfig(OvsdbConstant.BRIDGE, "_uuid", bridgeUUID,
576                      OvsdbConstant.DATABASENAME, "bridges");
577     }
578
579     @Override
580     public void createTunnel(IpAddress srcIp, IpAddress dstIp) {
581         String bridgeUuid = getBridgeUuid(OvsdbConstant.INTEGRATION_BRIDGE);
582         if (bridgeUuid == null) {
583             log.warn("Could not find bridge {} and Could not create tunnel. ",
584                      OvsdbConstant.INTEGRATION_BRIDGE);
585             return;
586         }
587
588         DatabaseSchema dbSchema = schema.get(OvsdbConstant.DATABASENAME);
589         String portName = getTunnelName(OvsdbConstant.TYPEVXLAN, dstIp);
590         String portUuid = getPortUuid(portName, bridgeUuid);
591
592         Port port = (Port) TableGenerator
593                 .createTable(dbSchema, OvsdbTable.PORT);
594         if (port != null) {
595             port.setName(portName);
596         }
597
598         if (portUuid == null) {
599             portUuid = insertConfig(OvsdbConstant.PORT, "_uuid", OvsdbConstant.BRIDGE,
600                                     "ports", bridgeUuid, port.getRow());
601         } else {
602             updateConfig(OvsdbConstant.PORT, "_uuid", portUuid, port.getRow());
603         }
604
605         // When a tunnel is created, A row is inserted into port table and
606         // interface table of the ovsdb node.
607         // and the following step is to get the interface uuid from local store
608         // in controller node.
609         // but it need spend some time synchronising data between node and
610         // controller.
611         // so loop to judge if interfaceUUid is null is necessary.
612         String interfaceUuid = null;
613         for (int i = 0; i < 10; i++) {
614             interfaceUuid = getInterfaceUuid(portUuid, portName);
615             if (interfaceUuid == null) {
616                 try {
617                     Thread.sleep(500);
618                 } catch (InterruptedException e) {
619                     log.warn("Interrupted while waiting to get interfaceUuid");
620                     Thread.currentThread().interrupt();
621                 }
622             } else {
623                 break;
624             }
625         }
626
627         if (interfaceUuid != null) {
628
629             Interface tunInterface = (Interface) TableGenerator
630                     .createTable(dbSchema, OvsdbTable.INTERFACE);
631
632             if (tunInterface != null) {
633
634                 tunInterface.setType(OvsdbConstant.TYPEVXLAN);
635                 Map<String, String> options = Maps.newHashMap();
636                 options.put("key", "flow");
637                 options.put("local_ip", srcIp.toString());
638                 options.put("remote_ip", dstIp.toString());
639                 tunInterface.setOptions(options);
640                 updateConfig(OvsdbConstant.INTERFACE, "_uuid", interfaceUuid,
641                              tunInterface.getRow());
642                 log.info("Tunnel added success", tunInterface);
643
644             }
645         }
646
647         return;
648     }
649
650     @Override
651     public void dropTunnel(IpAddress srcIp, IpAddress dstIp) {
652         String bridgeName = OvsdbConstant.INTEGRATION_BRIDGE;
653         String portName = getTunnelName(OvsdbConstant.TYPEVXLAN, dstIp);
654         String bridgeUuid = getBridgeUuid(OvsdbConstant.INTEGRATION_BRIDGE);
655         if (bridgeUuid == null) {
656             log.warn("Could not find bridge {} in {}", bridgeName,
657                      nodeId.getIpAddress());
658             return;
659         }
660
661         String portUUID = getPortUuid(portName, bridgeUuid);
662         if (portUUID != null) {
663             log.info("Delete tunnel");
664             deleteConfig(OvsdbConstant.PORT, "_uuid", portUUID,
665                          OvsdbConstant.BRIDGE, "ports");
666         }
667
668         return;
669     }
670
671     /**
672      * Delete transact config.
673      *
674      * @param childTableName   child table name
675      * @param childColumnName  child column name
676      * @param childUuid        child row uuid
677      * @param parentTableName  parent table name
678      * @param parentColumnName parent column
679      */
680     private void deleteConfig(String childTableName, String childColumnName,
681                               String childUuid, String parentTableName,
682                               String parentColumnName) {
683         DatabaseSchema dbSchema = schema.get(OvsdbConstant.DATABASENAME);
684         TableSchema childTableSchema = dbSchema.getTableSchema(childTableName);
685
686         ArrayList<Operation> operations = Lists.newArrayList();
687         if (parentTableName != null && parentColumnName != null) {
688             TableSchema parentTableSchema = dbSchema
689                     .getTableSchema(parentTableName);
690             ColumnSchema parentColumnSchema = parentTableSchema
691                     .getColumnSchema(parentColumnName);
692             List<Mutation> mutations = Lists.newArrayList();
693             Mutation mutation = MutationUtil.delete(parentColumnSchema.name(),
694                                                     UUID.uuid(childUuid));
695             mutations.add(mutation);
696             List<Condition> conditions = Lists.newArrayList();
697             Condition condition = ConditionUtil.includes(parentColumnName,
698                                                          UUID.uuid(childUuid));
699             conditions.add(condition);
700             Mutate op = new Mutate(parentTableSchema, conditions, mutations);
701             operations.add(op);
702         }
703
704         List<Condition> conditions = Lists.newArrayList();
705         Condition condition = ConditionUtil.equals(childColumnName, UUID.uuid(childUuid));
706         conditions.add(condition);
707         Delete del = new Delete(childTableSchema, conditions);
708         operations.add(del);
709         transactConfig(OvsdbConstant.DATABASENAME, operations);
710
711         return;
712     }
713
714     /**
715      * Update transact config.
716      *
717      * @param tableName  table name
718      * @param columnName column name
719      * @param uuid       uuid
720      * @param row        the config data
721      */
722     private void updateConfig(String tableName, String columnName, String uuid,
723                               Row row) {
724         DatabaseSchema dbSchema = schema.get(OvsdbConstant.DATABASENAME);
725         TableSchema tableSchema = dbSchema.getTableSchema(tableName);
726
727         List<Condition> conditions = Lists.newArrayList();
728         Condition condition = ConditionUtil.equals(columnName, UUID.uuid(uuid));
729         conditions.add(condition);
730
731         Update update = new Update(tableSchema, row, conditions);
732
733         ArrayList<Operation> operations = Lists.newArrayList();
734         operations.add(update);
735
736         transactConfig(OvsdbConstant.DATABASENAME, operations);
737     }
738
739     /**
740      * Insert transact config.
741      *
742      * @param childTableName   child table name
743      * @param childColumnName  child column name
744      * @param parentTableName  parent table name
745      * @param parentColumnName parent column
746      * @param parentUuid       parent uuid
747      * @param row              the config data
748      * @return uuid, empty if no uuid is find
749      */
750     private String insertConfig(String childTableName, String childColumnName,
751                                 String parentTableName, String parentColumnName,
752                                 String parentUuid, Row row) {
753         DatabaseSchema dbSchema = schema.get(OvsdbConstant.DATABASENAME);
754         TableSchema tableSchema = dbSchema.getTableSchema(childTableName);
755
756         String namedUuid = childTableName;
757         Insert insert = new Insert(tableSchema, namedUuid, row);
758
759         ArrayList<Operation> operations = Lists.newArrayList();
760         operations.add(insert);
761
762         if (parentTableName != null && parentColumnName != null) {
763             TableSchema parentTableSchema = dbSchema
764                     .getTableSchema(parentTableName);
765             ColumnSchema parentColumnSchema = parentTableSchema
766                     .getColumnSchema(parentColumnName);
767
768             List<Mutation> mutations = Lists.newArrayList();
769             Mutation mutation = MutationUtil.insert(parentColumnSchema.name(),
770                                                     UUID.uuid(namedUuid));
771             mutations.add(mutation);
772
773             List<Condition> conditions = Lists.newArrayList();
774             Condition condition = ConditionUtil.equals("_uuid",
775                                                        UUID.uuid(parentUuid));
776             conditions.add(condition);
777
778             Mutate op = new Mutate(parentTableSchema, conditions, mutations);
779             operations.add(op);
780         }
781         if (childTableName.equalsIgnoreCase(OvsdbConstant.PORT)) {
782             log.info("Handle port insert");
783             Insert intfInsert = handlePortInsertTable(OvsdbConstant.INTERFACE,
784                                                       row);
785
786             if (intfInsert != null) {
787                 operations.add(intfInsert);
788             }
789
790             Insert ins = (Insert) operations.get(0);
791             ins.getRow().put("interfaces",
792                              UUID.uuid(OvsdbConstant.INTERFACE));
793         }
794
795         List<OperationResult> results;
796         try {
797             results = transactConfig(OvsdbConstant.DATABASENAME, operations)
798                     .get();
799
800             return results.get(0).getUuid().value();
801         } catch (InterruptedException e) {
802             log.warn("Interrupted while waiting to get result");
803             Thread.currentThread().interrupt();
804         } catch (ExecutionException e) {
805             log.error("Exception thrown while to get result");
806         }
807
808         return null;
809     }
810
811     /**
812      * Handles port insert.
813      *
814      * @param tableName ovsdb table interface
815      * @param portRow   row of port
816      * @return insert, empty if null
817      */
818     private Insert handlePortInsertTable(String tableName, Row portRow) {
819         DatabaseSchema dbSchema = schema.get(OvsdbConstant.DATABASENAME);
820
821         TableSchema portTableSchema = dbSchema
822                 .getTableSchema(OvsdbConstant.PORT);
823         ColumnSchema portColumnSchema = portTableSchema.getColumnSchema("name");
824
825         String portName = (String) portRow.getColumn(portColumnSchema.name()).data();
826
827         Interface inf = (Interface) TableGenerator
828                 .createTable(dbSchema, OvsdbTable.INTERFACE);
829
830         inf.setName(portName);
831
832         TableSchema intfTableSchema = dbSchema
833                 .getTableSchema(OvsdbConstant.INTERFACE);
834         Insert insert = new Insert(intfTableSchema, OvsdbConstant.INTERFACE,
835                                    inf.getRow());
836         return insert;
837     }
838
839     /**
840      * Gets tunnel name.
841      *
842      * @param tunnelType
843      * @param dstIp      the remote ip address
844      * @return tunnel name
845      */
846     private String getTunnelName(String tunnelType, IpAddress dstIp) {
847         return tunnelType + "-" + dstIp.toString();
848     }
849
850     @Override
851     public ListenableFuture<DatabaseSchema> getOvsdbSchema(String dbName) {
852         if (dbName == null) {
853             return null;
854         }
855         DatabaseSchema databaseSchema = schema.get(dbName);
856         if (databaseSchema == null) {
857             List<String> dbNames = new ArrayList<String>();
858             dbNames.add(dbName);
859             Function<JsonNode, DatabaseSchema> rowFunction = new Function<JsonNode, DatabaseSchema>() {
860                 @Override
861                 public DatabaseSchema apply(JsonNode input) {
862                     log.info("Get ovsdb database schema {}", dbName);
863                     DatabaseSchema dbSchema = FromJsonUtil
864                             .jsonNodeToDbSchema(dbName, input);
865                     if (dbSchema == null) {
866                         log.debug("Get ovsdb database schema error");
867                         return null;
868                     }
869                     schema.put(dbName, dbSchema);
870
871                     return dbSchema;
872                 }
873             };
874
875             ListenableFuture<JsonNode> input = getSchema(dbNames);
876             if (input != null) {
877                 return Futures.transform(input, rowFunction);
878             }
879             return null;
880         } else {
881             return Futures.immediateFuture(databaseSchema);
882         }
883     }
884
885     @Override
886     public ListenableFuture<TableUpdates> monitorTables(String dbName, String id) {
887         if (dbName == null) {
888             return null;
889         }
890         DatabaseSchema dbSchema = schema.get(dbName);
891         if (dbSchema != null) {
892             Function<JsonNode, TableUpdates> rowFunction = new Function<JsonNode, TableUpdates>() {
893                 @Override
894                 public TableUpdates apply(JsonNode input) {
895                     log.info("Get table updates");
896                     TableUpdates updates = FromJsonUtil
897                             .jsonNodeToTableUpdates(input, dbSchema);
898                     if (updates == null) {
899                         log.debug("Get table updates error");
900                         return null;
901                     }
902                     return updates;
903                 }
904             };
905             return Futures.transform(monitor(dbSchema, id), rowFunction);
906         }
907         return null;
908     }
909
910     @Override
911     public ListenableFuture<List<OperationResult>> transactConfig(String dbName,
912                                                                   List<Operation> operations) {
913         if (dbName == null) {
914             return null;
915         }
916         DatabaseSchema dbSchema = schema.get(dbName);
917         if (dbSchema != null) {
918             Function<List<JsonNode>, List<OperationResult>> rowFunction = (input -> {
919                 log.info("Get ovsdb operation result");
920                 List<OperationResult> result = FromJsonUtil
921                         .jsonNodeToOperationResult(input, operations);
922
923                 if (result == null) {
924                     log.debug("The operation result is null");
925                     return null;
926                 }
927                 return result;
928             });
929             return Futures.transform(transact(dbSchema, operations),
930                                      rowFunction);
931         }
932         return null;
933     }
934
935     @Override
936     public ListenableFuture<JsonNode> getSchema(List<String> dbnames) {
937         String id = java.util.UUID.randomUUID().toString();
938         String getSchemaString = JsonRpcWriterUtil.getSchemaStr(id, dbnames);
939
940         SettableFuture<JsonNode> sf = SettableFuture.create();
941         requestResult.put(id, sf);
942         requestMethod.put(id, "getSchema");
943
944         channel.writeAndFlush(getSchemaString);
945         return sf;
946
947     }
948
949     @Override
950     public ListenableFuture<List<String>> echo() {
951         String id = java.util.UUID.randomUUID().toString();
952         String echoString = JsonRpcWriterUtil.echoStr(id);
953
954         SettableFuture<List<String>> sf = SettableFuture.create();
955         requestResult.put(id, sf);
956         requestMethod.put(id, "echo");
957
958         channel.writeAndFlush(echoString);
959         return sf;
960
961     }
962
963     @Override
964     public ListenableFuture<JsonNode> monitor(DatabaseSchema dbSchema,
965                                               String monitorId) {
966         String id = java.util.UUID.randomUUID().toString();
967         String monitorString = JsonRpcWriterUtil.monitorStr(id, monitorId,
968                                                             dbSchema);
969
970         SettableFuture<JsonNode> sf = SettableFuture.create();
971         requestResult.put(id, sf);
972         requestMethod.put(id, "monitor");
973
974         channel.writeAndFlush(monitorString);
975         return sf;
976
977     }
978
979     @Override
980     public ListenableFuture<List<String>> listDbs() {
981         String id = java.util.UUID.randomUUID().toString();
982         String listDbsString = JsonRpcWriterUtil.listDbsStr(id);
983
984         SettableFuture<List<String>> sf = SettableFuture.create();
985         requestResult.put(id, sf);
986         requestMethod.put(id, "listDbs");
987
988         channel.writeAndFlush(listDbsString);
989         return sf;
990
991     }
992
993     @Override
994     public ListenableFuture<List<JsonNode>> transact(DatabaseSchema dbSchema,
995                                                      List<Operation> operations) {
996         String id = java.util.UUID.randomUUID().toString();
997         String transactString = JsonRpcWriterUtil.transactStr(id, dbSchema,
998                                                               operations);
999
1000         SettableFuture<List<JsonNode>> sf = SettableFuture.create();
1001         requestResult.put(id, sf);
1002         requestMethod.put(id, "transact");
1003
1004         channel.writeAndFlush(transactString);
1005         return sf;
1006
1007     }
1008
1009     @SuppressWarnings({"rawtypes", "unchecked"})
1010     @Override
1011     public void processResult(JsonNode response) {
1012         log.debug("Handle result");
1013         String requestId = response.get("id").asText();
1014         SettableFuture sf = requestResult.get(requestId);
1015         if (sf == null) {
1016             log.debug("No such future to process");
1017             return;
1018         }
1019         String methodName = requestMethod.get(requestId);
1020
1021         Object result;
1022         result = FromJsonUtil.jsonResultParser(response, methodName);
1023
1024         sf.set(result);
1025         return;
1026     }
1027
1028     @Override
1029     public void processRequest(JsonNode requestJson) {
1030         log.debug("Handle request");
1031         if (requestJson.get("method").asText().equalsIgnoreCase("echo")) {
1032             log.debug("handle echo request");
1033
1034             String replyString = FromJsonUtil.getEchoRequestStr(requestJson);
1035             channel.writeAndFlush(replyString);
1036
1037             return;
1038         } else {
1039             FromJsonUtil
1040                     .jsonCallbackRequestParser(requestJson, monitorCallBack);
1041             return;
1042         }
1043     }
1044
1045     @Override
1046     public void setCallback(Callback monitorCallback) {
1047         this.monitorCallBack = monitorCallback;
1048     }
1049
1050     @Override
1051     public Set<OvsdbTunnel> getTunnels() {
1052         return ovsdbTunnels;
1053     }
1054
1055     @Override
1056     public Set<OvsdbBridge> getBridges() {
1057         Set<OvsdbBridge> ovsdbBridges = new HashSet<OvsdbBridge>();
1058         OvsdbTableStore tableStore = getTableStore(OvsdbConstant.DATABASENAME);
1059         if (tableStore == null) {
1060             return null;
1061         }
1062         OvsdbRowStore rowStore = tableStore.getRows(OvsdbConstant.BRIDGE);
1063         if (rowStore == null) {
1064             return null;
1065         }
1066         ConcurrentMap<String, Row> rows = rowStore.getRowStore();
1067         for (String uuid : rows.keySet()) {
1068             Row row = getRow(OvsdbConstant.DATABASENAME, OvsdbConstant.BRIDGE,
1069                              uuid);
1070             OvsdbBridge ovsdbBridge = getOvsdbBridge(row);
1071             if (ovsdbBridge != null) {
1072                 ovsdbBridges.add(ovsdbBridge);
1073             }
1074         }
1075         return ovsdbBridges;
1076     }
1077
1078     @Override
1079     public Set<ControllerInfo> getControllers(DeviceId openflowDeviceId) {
1080         UUID bridgeUuid = getBridgeUUID(openflowDeviceId);
1081         if (bridgeUuid == null) {
1082             log.warn("bad bridge Uuid");
1083             return null;
1084         }
1085         List<Controller> controllers = getControllers(bridgeUuid);
1086         if (controllers == null) {
1087             log.warn("bad list of controllers");
1088             return null;
1089         }
1090         return controllers.stream().
1091                 map(controller -> new ControllerInfo(
1092                         (String) controller.getTargetColumn()
1093                                 .data())).collect(Collectors.toSet());
1094     }
1095
1096     private List<Controller> getControllers(UUID bridgeUuid) {
1097         DatabaseSchema dbSchema = schema.get(OvsdbConstant.DATABASENAME);
1098         if (dbSchema == null) {
1099             return null;
1100         }
1101         OvsdbRowStore rowStore = getRowStore(OvsdbConstant.DATABASENAME,
1102                                              OvsdbConstant.BRIDGE);
1103         if (rowStore == null) {
1104             log.debug("There is no bridge table");
1105             return null;
1106         }
1107
1108         Row bridgeRow = rowStore.getRow(bridgeUuid.value());
1109         Bridge bridge = (Bridge) TableGenerator.
1110                 getTable(dbSchema, bridgeRow, OvsdbTable.BRIDGE);
1111
1112         //FIXME remove log
1113         log.warn("type of controller column", bridge.getControllerColumn()
1114                 .data().getClass());
1115         Set<UUID> controllerUuids = (Set<UUID>) ((OvsdbSet) bridge
1116                 .getControllerColumn().data()).set();
1117 //        Set<String> controllerUuidStrings = (Set<String>) bridge.getControllerColumn().data();
1118
1119         OvsdbRowStore controllerRowStore = getRowStore(OvsdbConstant.DATABASENAME,
1120                                                        OvsdbConstant.CONTROLLER);
1121         if (controllerRowStore == null) {
1122             log.debug("There is no controller table");
1123             return null;
1124         }
1125
1126         List<Controller> ovsdbControllers = new ArrayList<>();
1127         ConcurrentMap<String, Row> controllerTableRows = controllerRowStore.getRowStore();
1128         controllerTableRows.forEach((key, row) -> {
1129             if (!controllerUuids.contains(UUID.uuid(key))) {
1130                 return;
1131             }
1132             Controller controller = (Controller) TableGenerator
1133                     .getTable(dbSchema, row, OvsdbTable.CONTROLLER);
1134             ovsdbControllers.add(controller);
1135         });
1136         return ovsdbControllers;
1137     }
1138
1139
1140     private UUID getBridgeUUID(DeviceId openflowDeviceId) {
1141         DatabaseSchema dbSchema = schema.get(OvsdbConstant.DATABASENAME);
1142         if (dbSchema == null) {
1143             return null;
1144         }
1145         OvsdbRowStore rowStore = getRowStore(OvsdbConstant.DATABASENAME,
1146                                              OvsdbConstant.BRIDGE);
1147         if (rowStore == null) {
1148             log.debug("There is no bridge table");
1149             return null;
1150         }
1151
1152         ConcurrentMap<String, Row> bridgeTableRows = rowStore.getRowStore();
1153         final AtomicReference<UUID> uuid = new AtomicReference<>();
1154         for (Map.Entry<String, Row> entry : bridgeTableRows.entrySet()) {
1155             Bridge b = (Bridge) TableGenerator.getTable(dbSchema,
1156                                                         entry.getValue(),
1157                                                         OvsdbTable.BRIDGE);
1158             if (matchesDpid(b, openflowDeviceId)) {
1159                 uuid.set(UUID.uuid(entry.getKey()));
1160                 break;
1161             }
1162         }
1163         if (uuid.get() == null) {
1164             log.debug("There is no bridge for {}", openflowDeviceId);
1165         }
1166         return uuid.get();
1167
1168     }
1169
1170     private static boolean matchesDpid(Bridge b, DeviceId deviceId) {
1171         String ofDpid = deviceId.toString().replace("of:", "");
1172         Set ofDeviceIds = ((OvsdbSet) b.getDatapathIdColumn().data()).set();
1173         //TODO Set<String>
1174         return ofDeviceIds.contains(ofDpid);
1175     }
1176
1177     @Override
1178     public Set<OvsdbPort> getPorts() {
1179         Set<OvsdbPort> ovsdbPorts = new HashSet<OvsdbPort>();
1180         OvsdbTableStore tableStore = getTableStore(OvsdbConstant.DATABASENAME);
1181         if (tableStore == null) {
1182             return null;
1183         }
1184         OvsdbRowStore rowStore = tableStore.getRows(OvsdbConstant.INTERFACE);
1185         if (rowStore == null) {
1186             return null;
1187         }
1188         ConcurrentMap<String, Row> rows = rowStore.getRowStore();
1189         for (String uuid : rows.keySet()) {
1190             Row row = getRow(OvsdbConstant.DATABASENAME,
1191                              OvsdbConstant.INTERFACE, uuid);
1192             OvsdbPort ovsdbPort = getOvsdbPort(row);
1193             if (ovsdbPort != null) {
1194                 ovsdbPorts.add(ovsdbPort);
1195             }
1196         }
1197         return ovsdbPorts;
1198     }
1199
1200     @Override
1201     public DatabaseSchema getDatabaseSchema(String dbName) {
1202         return schema.get(dbName);
1203     }
1204
1205     //Gets ovsdb port.
1206     private OvsdbPort getOvsdbPort(Row row) {
1207         DatabaseSchema dbSchema = getDatabaseSchema(OvsdbConstant.DATABASENAME);
1208         Interface intf = (Interface) TableGenerator
1209                 .getTable(dbSchema, row, OvsdbTable.INTERFACE);
1210         if (intf == null) {
1211             return null;
1212         }
1213         long ofPort = getOfPort(intf);
1214         String portName = intf.getName();
1215         if ((ofPort < 0) || (portName == null)) {
1216             return null;
1217         }
1218
1219         OvsdbPort ovsdbPort = new OvsdbPort(new OvsdbPortNumber(ofPort),
1220                                             new OvsdbPortName(portName));
1221         return ovsdbPort;
1222     }
1223
1224     ////Gets ovsdb bridge.
1225     private OvsdbBridge getOvsdbBridge(Row row) {
1226         DatabaseSchema dbSchema = getDatabaseSchema(OvsdbConstant.DATABASENAME);
1227         Bridge bridge = (Bridge) TableGenerator.getTable(dbSchema, row,
1228                                                          OvsdbTable.BRIDGE);
1229         if (bridge == null) {
1230             return null;
1231         }
1232
1233         OvsdbSet datapathIdSet = (OvsdbSet) bridge.getDatapathIdColumn().data();
1234         @SuppressWarnings("unchecked")
1235         Set<String> datapathIds = datapathIdSet.set();
1236         if (datapathIds == null || datapathIds.size() == 0) {
1237             return null;
1238         }
1239         String datapathId = (String) datapathIds.toArray()[0];
1240         String bridgeName = bridge.getName();
1241         if ((datapathId == null) || (bridgeName == null)) {
1242             return null;
1243         }
1244
1245         OvsdbBridge ovsdbBridge = new OvsdbBridge(new OvsdbBridgeName(bridgeName),
1246                                                   new OvsdbDatapathId(datapathId));
1247         return ovsdbBridge;
1248     }
1249
1250     //Gets ofPort in the interface.
1251     private long getOfPort(Interface intf) {
1252         OvsdbSet ofPortSet = (OvsdbSet) intf.getOpenFlowPortColumn().data();
1253         @SuppressWarnings("unchecked")
1254         Set<Integer> ofPorts = ofPortSet.set();
1255         while (ofPorts == null || ofPorts.size() <= 0) {
1256             log.debug("The ofport is null in {}", intf.getName());
1257             return -1;
1258         }
1259         // return (long) ofPorts.toArray()[0];
1260         Iterator<Integer> it = ofPorts.iterator();
1261         return Long.parseLong(it.next().toString());
1262     }
1263
1264     @Override
1265     public Set<OvsdbPort> getLocalPorts(Iterable<String> ifaceids) {
1266         Set<OvsdbPort> ovsdbPorts = new HashSet<OvsdbPort>();
1267         OvsdbTableStore tableStore = getTableStore(OvsdbConstant.DATABASENAME);
1268         if (tableStore == null) {
1269             return null;
1270         }
1271         OvsdbRowStore rowStore = tableStore.getRows(OvsdbConstant.INTERFACE);
1272         if (rowStore == null) {
1273             return null;
1274         }
1275         ConcurrentMap<String, Row> rows = rowStore.getRowStore();
1276         for (String uuid : rows.keySet()) {
1277             Row row = getRow(OvsdbConstant.DATABASENAME,
1278                              OvsdbConstant.INTERFACE, uuid);
1279             DatabaseSchema dbSchema = getDatabaseSchema(OvsdbConstant.DATABASENAME);
1280             Interface intf = (Interface) TableGenerator
1281                     .getTable(dbSchema, row, OvsdbTable.INTERFACE);
1282             if (intf == null || getIfaceid(intf) == null) {
1283                 continue;
1284             }
1285             String portName = intf.getName();
1286             Set<String> ifaceidSet = Sets.newHashSet(ifaceids);
1287             if (portName.startsWith("vxlan")
1288                     || !ifaceidSet.contains(getIfaceid(intf))) {
1289                 continue;
1290             }
1291             long ofPort = getOfPort(intf);
1292             if ((ofPort < 0) || (portName == null)) {
1293                 continue;
1294             }
1295
1296             OvsdbPort ovsdbPort = new OvsdbPort(new OvsdbPortNumber(ofPort),
1297                                                 new OvsdbPortName(portName));
1298             if (ovsdbPort != null) {
1299                 ovsdbPorts.add(ovsdbPort);
1300             }
1301         }
1302         return ovsdbPorts;
1303     }
1304
1305     private String getIfaceid(Interface intf) {
1306         OvsdbMap ovsdbMap = (OvsdbMap) intf.getExternalIdsColumn().data();
1307         @SuppressWarnings("unchecked")
1308         Map<String, String> externalIds = ovsdbMap.map();
1309         if (externalIds.isEmpty()) {
1310             log.warn("The external_ids is null");
1311             return null;
1312         }
1313         String ifaceid = externalIds
1314                 .get(OvsdbConstant.EXTERNAL_ID_INTERFACE_ID);
1315         if (ifaceid == null) {
1316             log.warn("The ifaceid is null");
1317             return null;
1318         }
1319         return ifaceid;
1320     }
1321
1322     @Override
1323     public void disconnect() {
1324         channel.disconnect();
1325         this.agent.removeConnectedNode(nodeId);
1326     }
1327 }