2 * Copyright 2015 Open Networking Laboratory
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
16 package org.onosproject.ovsdb.controller.driver;
18 import io.netty.channel.Channel;
20 import java.net.InetSocketAddress;
21 import java.util.ArrayList;
22 import java.util.HashSet;
23 import java.util.Iterator;
24 import java.util.List;
27 import java.util.concurrent.ConcurrentMap;
28 import java.util.concurrent.ExecutionException;
30 import org.onlab.packet.IpAddress;
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;
74 import com.fasterxml.jackson.databind.JsonNode;
75 import com.google.common.base.Function;
76 import com.google.common.collect.Lists;
77 import com.google.common.collect.Maps;
78 import com.google.common.collect.Sets;
79 import com.google.common.util.concurrent.Futures;
80 import com.google.common.util.concurrent.ListenableFuture;
81 import com.google.common.util.concurrent.SettableFuture;
84 * An representation of an ovsdb client.
86 public class DefaultOvsdbClient
87 implements OvsdbProviderService, OvsdbClientService {
89 private final Logger log = LoggerFactory
90 .getLogger(DefaultOvsdbClient.class);
92 private Channel channel;
94 private OvsdbAgent agent;
95 private boolean connected;
96 private OvsdbNodeId nodeId;
97 private Callback monitorCallBack;
99 private OvsdbStore ovsdbStore = new OvsdbStore();
101 private final Map<String, String> requestMethod = Maps.newHashMap();
102 private final Map<String, SettableFuture<? extends Object>> requestResult = Maps
105 private final Map<String, DatabaseSchema> schema = Maps.newHashMap();
106 private final Set<OvsdbTunnel> ovsdbTunnels = new HashSet<OvsdbTunnel>();
109 * Creates an OvsdbClient.
111 * @param nodeId ovsdb node id
113 public DefaultOvsdbClient(OvsdbNodeId nodeId) {
114 this.nodeId = nodeId;
118 public OvsdbNodeId nodeId() {
123 public void setAgent(OvsdbAgent agent) {
124 if (this.agent == null) {
130 public void setChannel(Channel channel) {
131 this.channel = channel;
135 public void setConnection(boolean connected) {
136 this.connected = connected;
140 public boolean isConnected() {
141 return this.connected;
145 public void nodeAdded() {
146 this.agent.addConnectedNode(nodeId, this);
150 public void nodeRemoved() {
151 this.agent.removeConnectedNode(nodeId);
152 channel.disconnect();
156 * Gets the ovsdb table store.
158 * @param dbName the ovsdb database name
159 * @return ovsTableStore, empty if table store is find
161 private OvsdbTableStore getTableStore(String dbName) {
162 if (ovsdbStore == null) {
165 return ovsdbStore.getOvsdbTableStore(dbName);
169 * Gets the ovsdb row store.
171 * @param dbName the ovsdb database name
172 * @param tableName the ovsdb table name
174 * @return ovsRowStore, empty if row store is find
176 private OvsdbRowStore getRowStore(String dbName, String tableName) {
177 OvsdbTableStore tableStore = getTableStore(dbName);
178 if (tableStore == null) {
181 return tableStore.getRows(tableName);
185 * Gets the ovsdb row.
187 * @param dbName the ovsdb database name
188 * @param tableName the ovsdb table name
189 * @param uuid the key of the row
190 * @return row, empty if row is find
193 public Row getRow(String dbName, String tableName, String uuid) {
194 OvsdbTableStore tableStore = getTableStore(dbName);
195 if (tableStore == null) {
198 OvsdbRowStore rowStore = tableStore.getRows(tableName);
199 if (rowStore == null) {
202 return rowStore.getRow(uuid);
206 public void removeRow(String dbName, String tableName, String uuid) {
207 OvsdbTableStore tableStore = getTableStore(dbName);
208 if (tableStore == null) {
211 OvsdbRowStore rowStore = tableStore.getRows(tableName);
212 if (rowStore == null) {
215 rowStore.deleteRow(uuid);
219 public void updateOvsdbStore(String dbName, String tableName, String uuid,
221 OvsdbTableStore tableStore = ovsdbStore.getOvsdbTableStore(dbName);
222 if (tableStore == null) {
223 tableStore = new OvsdbTableStore();
225 OvsdbRowStore rowStore = tableStore.getRows(tableName);
226 if (rowStore == null) {
227 rowStore = new OvsdbRowStore();
229 rowStore.insertRow(uuid, row);
230 tableStore.createOrUpdateTable(tableName, rowStore);
231 ovsdbStore.createOrUpdateOvsdbStore(dbName, tableStore);
235 public String getPortUuid(String portName, String bridgeUuid) {
236 DatabaseSchema dbSchema = schema.get(OvsdbConstant.DATABASENAME);
238 Row bridgeRow = getRow(OvsdbConstant.DATABASENAME,
239 OvsdbConstant.BRIDGE, bridgeUuid);
241 Bridge bridge = (Bridge) TableGenerator.getTable(dbSchema, bridgeRow,
243 if (bridge != null) {
244 OvsdbSet setPorts = (OvsdbSet) bridge.getPortsColumn().data();
245 @SuppressWarnings("unchecked")
246 Set<UUID> ports = setPorts.set();
247 if (ports == null || ports.size() == 0) {
248 log.warn("The port uuid is null");
252 for (UUID uuid : ports) {
253 Row portRow = getRow(OvsdbConstant.DATABASENAME,
254 OvsdbConstant.PORT, uuid.value());
255 Port port = (Port) TableGenerator.getTable(dbSchema, portRow,
257 if (port != null && portName.equalsIgnoreCase(port.getName())) {
267 public String getInterfaceUuid(String portUuid, String portName) {
268 DatabaseSchema dbSchema = schema.get(OvsdbConstant.DATABASENAME);
270 Row portRow = getRow(OvsdbConstant.DATABASENAME, OvsdbConstant.PORT,
272 Port port = (Port) TableGenerator.getTable(dbSchema, portRow,
276 OvsdbSet setInterfaces = (OvsdbSet) port.getInterfacesColumn().data();
277 @SuppressWarnings("unchecked")
278 Set<UUID> interfaces = setInterfaces.set();
280 if (interfaces == null || interfaces.size() == 0) {
281 log.warn("The interface uuid is null");
285 for (UUID uuid : interfaces) {
286 Row intfRow = getRow(OvsdbConstant.DATABASENAME,
287 OvsdbConstant.INTERFACE, uuid.value());
288 Interface intf = (Interface) TableGenerator
289 .getTable(dbSchema, intfRow, OvsdbTable.INTERFACE);
290 if (intf != null && portName.equalsIgnoreCase(intf.getName())) {
301 public String getBridgeUuid(String bridgeName) {
302 DatabaseSchema dbSchema = schema.get(OvsdbConstant.DATABASENAME);
304 OvsdbRowStore rowStore = getRowStore(OvsdbConstant.DATABASENAME,
305 OvsdbConstant.BRIDGE);
306 if (rowStore == null) {
307 log.debug("The bridge uuid is null");
311 ConcurrentMap<String, Row> bridgeTableRows = rowStore.getRowStore();
312 if (bridgeTableRows == null) {
313 log.debug("The bridge uuid is null");
317 for (String uuid : bridgeTableRows.keySet()) {
318 Bridge bridge = (Bridge) TableGenerator
319 .getTable(dbSchema, bridgeTableRows.get(uuid),
322 if (bridge.getName().equals(bridgeName)) {
331 public String getControllerUuid(String controllerName,
332 String controllerTarget) {
333 DatabaseSchema dbSchema = schema.get(OvsdbConstant.DATABASENAME);
334 OvsdbRowStore rowStore = getRowStore(OvsdbConstant.DATABASENAME,
335 OvsdbConstant.CONTROLLER);
336 if (rowStore == null) {
337 log.debug("The controller uuid is null");
341 ConcurrentMap<String, Row> controllerTableRows = rowStore.getRowStore();
342 if (controllerTableRows != null) {
343 for (String uuid : controllerTableRows.keySet()) {
345 Controller controller = (Controller) TableGenerator
346 .getTable(dbSchema, controllerTableRows.get(uuid),
347 OvsdbTable.CONTROLLER);
348 String target = (String) controller.getTargetColumn().data();
349 if (target.equalsIgnoreCase(controllerTarget)) {
359 public String getOvsUuid(String dbName) {
360 OvsdbRowStore rowStore = getRowStore(OvsdbConstant.DATABASENAME,
361 OvsdbConstant.DATABASENAME);
362 if (rowStore == null) {
363 log.debug("The bridge uuid is null");
366 ConcurrentMap<String, Row> ovsTableRows = rowStore.getRowStore();
367 if (ovsTableRows != null) {
368 for (String uuid : ovsTableRows.keySet()) {
369 Row row = ovsTableRows.get(uuid);
370 String tableName = row.tableName();
371 if (tableName.equals(dbName)) {
380 public void createPort(String bridgeName, String portName) {
381 String bridgeUuid = getBridgeUuid(bridgeName);
382 if (bridgeUuid == null) {
383 log.error("Can't find bridge {} in {}", bridgeName,
384 nodeId.getIpAddress());
388 DatabaseSchema dbSchema = schema.get(OvsdbConstant.DATABASENAME);
389 String portUuid = getPortUuid(portName, bridgeUuid);
391 Port port = (Port) TableGenerator
392 .createTable(dbSchema, OvsdbTable.PORT);
394 port.setName(portName);
395 if (portUuid == null) {
396 insertConfig(OvsdbConstant.PORT, "_uuid", OvsdbConstant.BRIDGE,
397 "ports", bridgeUuid, port.getRow());
399 updateConfig(OvsdbConstant.PORT, "_uuid", portUuid, port.getRow());
406 public void dropPort(String bridgeName, String portName) {
407 String bridgeUuid = getBridgeUuid(bridgeName);
408 if (bridgeUuid == null) {
409 log.error("Could not find Bridge {} in {}", bridgeName, nodeId);
413 String portUuid = getPortUuid(portName, bridgeUuid);
414 if (portUuid != null) {
415 log.info("Port {} delete", portName);
416 deleteConfig(OvsdbConstant.PORT, "_uuid", portUuid,
417 OvsdbConstant.BRIDGE, "ports");
422 public void createBridge(String bridgeName) {
423 log.debug("create bridge {}", bridgeName);
425 DatabaseSchema dbSchema = schema.get(OvsdbConstant.DATABASENAME);
426 if (dbSchema == null) {
427 log.warn("The schema is null");
431 Bridge bridge = (Bridge) TableGenerator.createTable(dbSchema,
433 if (bridge == null) {
434 log.debug("Can not create bridge");
438 Set<String> failModes = new HashSet<>();
439 failModes.add("secure");
440 bridge.setFailMode(failModes);
442 Set<String> protocols = new HashSet<>();
443 protocols.add(OvsdbConstant.OPENFLOW13);
444 bridge.setProtocols(protocols);
446 String ovsUuid = getOvsUuid(OvsdbConstant.DATABASENAME);
447 if (ovsUuid == null) {
448 log.warn("The Open_vSwitch is null");
452 String bridgeUuid = getBridgeUuid(bridgeName);
453 if (bridgeUuid == null) {
454 log.debug("Create a new bridge");
456 bridge.setName(bridgeName);
457 bridgeUuid = insertConfig(OvsdbConstant.BRIDGE, "_uuid",
458 OvsdbConstant.DATABASENAME, "bridges",
459 ovsUuid, bridge.getRow());
461 if (bridgeUuid != null) {
462 Port port = (Port) TableGenerator.createTable(dbSchema,
465 log.debug("the port is not null");
466 port.setName(bridgeName);
468 insertConfig(OvsdbConstant.PORT, "_uuid", "Bridge", "ports", bridgeUuid,
474 log.info("Update a bridge");
475 updateConfig(OvsdbConstant.BRIDGE, "_uuid", bridgeUuid, bridge.getRow());
478 setController(bridgeUuid);
479 log.info("Create bridge success");
483 * Sets the Controller.
485 * @param bridgeUuid bridge uuid
487 private void setController(String bridgeUuid) {
488 String controllerUuid = null;
489 String iPAddress = IpAddress.valueOf(((InetSocketAddress) channel
495 String target = "tcp:" + iPAddress + ":" + OvsdbConstant.OFPORT;
496 log.debug("controller IP {}: port {}", iPAddress, OvsdbConstant.OFPORT);
498 DatabaseSchema dbSchema = schema.get(OvsdbConstant.DATABASENAME);
499 Controller controller = (Controller) TableGenerator
500 .createTable(dbSchema, OvsdbTable.CONTROLLER);
502 if (controller != null) {
503 controller.setTarget(target);
504 controllerUuid = getControllerUuid(OvsdbConstant.CONTROLLER, target);
505 if (controllerUuid == null) {
507 insertConfig(OvsdbConstant.CONTROLLER, "_uuid",
508 OvsdbConstant.BRIDGE, "controller", bridgeUuid,
509 controller.getRow());
513 Bridge bridge = (Bridge) TableGenerator
514 .createTable(dbSchema, OvsdbTable.BRIDGE);
515 Set<UUID> controllerUuids = new HashSet<>();
516 controllerUuids.add(UUID.uuid(controllerUuid));
517 bridge.setController(controllerUuids);
518 updateConfig(OvsdbConstant.CONTROLLER, "_uuid", bridgeUuid, bridge.getRow());
526 public void dropBridge(String bridgeName) {
527 String bridgeUUID = getBridgeUuid(bridgeName);
528 if (bridgeUUID == null) {
529 log.warn("Could not find bridge in node", nodeId.getIpAddress());
532 deleteConfig(OvsdbConstant.BRIDGE, "_uuid", bridgeUUID,
533 OvsdbConstant.DATABASENAME, "bridges");
537 public void createTunnel(IpAddress srcIp, IpAddress dstIp) {
538 String bridgeUuid = getBridgeUuid(OvsdbConstant.INTEGRATION_BRIDGE);
539 if (bridgeUuid == null) {
540 log.warn("Could not find bridge {} and Could not create tunnel. ",
541 OvsdbConstant.INTEGRATION_BRIDGE);
545 DatabaseSchema dbSchema = schema.get(OvsdbConstant.DATABASENAME);
546 String portName = getTunnelName(OvsdbConstant.TYPEVXLAN, dstIp);
547 String portUuid = getPortUuid(portName, bridgeUuid);
549 Port port = (Port) TableGenerator
550 .createTable(dbSchema, OvsdbTable.PORT);
552 port.setName(portName);
555 if (portUuid == null) {
556 portUuid = insertConfig(OvsdbConstant.PORT, "_uuid", OvsdbConstant.BRIDGE,
557 "ports", bridgeUuid, port.getRow());
559 updateConfig(OvsdbConstant.PORT, "_uuid", portUuid, port.getRow());
562 // When a tunnel is created, A row is inserted into port table and
563 // interface table of the ovsdb node.
564 // and the following step is to get the interface uuid from local store
565 // in controller node.
566 // but it need spend some time synchronising data between node and
568 // so loop to judge if interfaceUUid is null is necessary.
569 String interfaceUuid = null;
570 for (int i = 0; i < 10; i++) {
571 interfaceUuid = getInterfaceUuid(portUuid, portName);
572 if (interfaceUuid == null) {
575 } catch (InterruptedException e) {
576 log.warn("Interrupted while waiting to get interfaceUuid");
577 Thread.currentThread().interrupt();
584 if (interfaceUuid != null) {
586 Interface tunInterface = (Interface) TableGenerator
587 .createTable(dbSchema, OvsdbTable.INTERFACE);
589 if (tunInterface != null) {
591 tunInterface.setType(OvsdbConstant.TYPEVXLAN);
592 Map<String, String> options = Maps.newHashMap();
593 options.put("key", "flow");
594 options.put("local_ip", srcIp.toString());
595 options.put("remote_ip", dstIp.toString());
596 tunInterface.setOptions(options);
597 updateConfig(OvsdbConstant.INTERFACE, "_uuid", interfaceUuid,
598 tunInterface.getRow());
599 log.info("Tunnel added success", tunInterface);
608 public void dropTunnel(IpAddress srcIp, IpAddress dstIp) {
609 String bridgeName = OvsdbConstant.INTEGRATION_BRIDGE;
610 String portName = getTunnelName(OvsdbConstant.TYPEVXLAN, dstIp);
611 String bridgeUuid = getBridgeUuid(OvsdbConstant.INTEGRATION_BRIDGE);
612 if (bridgeUuid == null) {
613 log.warn("Could not find bridge {} in {}", bridgeName,
614 nodeId.getIpAddress());
618 String portUUID = getPortUuid(portName, bridgeUuid);
619 if (portUUID != null) {
620 log.info("Delete tunnel");
621 deleteConfig(OvsdbConstant.PORT, "_uuid", portUUID,
622 OvsdbConstant.BRIDGE, "ports");
629 * Delete transact config.
631 * @param childTableName child table name
632 * @param childColumnName child column name
633 * @param childUuid child row uuid
634 * @param parentTableName parent table name
635 * @param parentColumnName parent column
638 private void deleteConfig(String childTableName, String childColumnName,
639 String childUuid, String parentTableName,
640 String parentColumnName) {
641 DatabaseSchema dbSchema = schema.get(OvsdbConstant.DATABASENAME);
642 TableSchema childTableSchema = dbSchema.getTableSchema(childTableName);
644 ArrayList<Operation> operations = Lists.newArrayList();
645 if (parentTableName != null && parentColumnName != null) {
646 TableSchema parentTableSchema = dbSchema
647 .getTableSchema(parentTableName);
648 ColumnSchema parentColumnSchema = parentTableSchema
649 .getColumnSchema(parentColumnName);
650 List<Mutation> mutations = Lists.newArrayList();
651 Mutation mutation = MutationUtil.delete(parentColumnSchema.name(),
652 UUID.uuid(childUuid));
653 mutations.add(mutation);
654 List<Condition> conditions = Lists.newArrayList();
655 Condition condition = ConditionUtil.includes(parentColumnName,
656 UUID.uuid(childUuid));
657 conditions.add(condition);
658 Mutate op = new Mutate(parentTableSchema, conditions, mutations);
662 List<Condition> conditions = Lists.newArrayList();
663 Condition condition = ConditionUtil.equals(childColumnName, UUID.uuid(childUuid));
664 conditions.add(condition);
665 Delete del = new Delete(childTableSchema, conditions);
667 transactConfig(OvsdbConstant.DATABASENAME, operations);
673 * Update transact config.
675 * @param tableName table name
676 * @param columnName column name
678 * @param row the config data
681 private void updateConfig(String tableName, String columnName, String uuid,
683 DatabaseSchema dbSchema = schema.get(OvsdbConstant.DATABASENAME);
684 TableSchema tableSchema = dbSchema.getTableSchema(tableName);
686 List<Condition> conditions = Lists.newArrayList();
687 Condition condition = ConditionUtil.equals(columnName, UUID.uuid(uuid));
688 conditions.add(condition);
690 Update update = new Update(tableSchema, row, conditions);
692 ArrayList<Operation> operations = Lists.newArrayList();
693 operations.add(update);
695 transactConfig(OvsdbConstant.DATABASENAME, operations);
699 * Insert transact config.
701 * @param childTableName child table name
702 * @param childColumnName child column name
703 * @param parentTableName parent table name
704 * @param parentColumnName parent column
705 * @param parentUuid parent uuid
706 * @param row the config data
708 * @return uuid, empty if no uuid is find
710 private String insertConfig(String childTableName, String childColumnName,
711 String parentTableName, String parentColumnName,
712 String parentUuid, Row row) {
713 DatabaseSchema dbSchema = schema.get(OvsdbConstant.DATABASENAME);
714 TableSchema tableSchema = dbSchema.getTableSchema(childTableName);
716 String namedUuid = childTableName;
717 Insert insert = new Insert(tableSchema, namedUuid, row);
719 ArrayList<Operation> operations = Lists.newArrayList();
720 operations.add(insert);
722 if (parentTableName != null && parentColumnName != null) {
723 TableSchema parentTableSchema = dbSchema
724 .getTableSchema(parentTableName);
725 ColumnSchema parentColumnSchema = parentTableSchema
726 .getColumnSchema(parentColumnName);
728 List<Mutation> mutations = Lists.newArrayList();
729 Mutation mutation = MutationUtil.insert(parentColumnSchema.name(),
730 UUID.uuid(namedUuid));
731 mutations.add(mutation);
733 List<Condition> conditions = Lists.newArrayList();
734 Condition condition = ConditionUtil.equals("_uuid",
735 UUID.uuid(parentUuid));
736 conditions.add(condition);
738 Mutate op = new Mutate(parentTableSchema, conditions, mutations);
741 if (childTableName.equalsIgnoreCase(OvsdbConstant.PORT)) {
742 log.info("Handle port insert");
743 Insert intfInsert = handlePortInsertTable(OvsdbConstant.INTERFACE,
746 if (intfInsert != null) {
747 operations.add(intfInsert);
750 Insert ins = (Insert) operations.get(0);
751 ins.getRow().put("interfaces",
752 UUID.uuid(OvsdbConstant.INTERFACE));
755 List<OperationResult> results;
757 results = transactConfig(OvsdbConstant.DATABASENAME, operations)
760 return results.get(0).getUuid().value();
761 } catch (InterruptedException e) {
762 log.warn("Interrupted while waiting to get result");
763 Thread.currentThread().interrupt();
764 } catch (ExecutionException e) {
765 log.error("Exception thrown while to get result");
772 * Handles port insert.
774 * @param tableName ovsdb table interface
775 * @param portRow row of port
777 * @return insert, empty if null
779 private Insert handlePortInsertTable(String tableName, Row portRow) {
780 DatabaseSchema dbSchema = schema.get(OvsdbConstant.DATABASENAME);
782 TableSchema portTableSchema = dbSchema
783 .getTableSchema(OvsdbConstant.PORT);
784 ColumnSchema portColumnSchema = portTableSchema.getColumnSchema("name");
786 String portName = (String) portRow.getColumn(portColumnSchema.name()).data();
788 Interface inf = (Interface) TableGenerator
789 .createTable(dbSchema, OvsdbTable.INTERFACE);
791 inf.setName(portName);
793 TableSchema intfTableSchema = dbSchema
794 .getTableSchema(OvsdbConstant.INTERFACE);
795 Insert insert = new Insert(intfTableSchema, OvsdbConstant.INTERFACE,
804 * @param dstIp the remote ip address
806 * @return tunnel name
808 private String getTunnelName(String tunnelType, IpAddress dstIp) {
809 return tunnelType + "-" + dstIp.toString();
813 public ListenableFuture<DatabaseSchema> getOvsdbSchema(String dbName) {
814 if (dbName == null) {
817 DatabaseSchema databaseSchema = schema.get(dbName);
818 if (databaseSchema == null) {
819 List<String> dbNames = new ArrayList<String>();
821 Function<JsonNode, DatabaseSchema> rowFunction = new Function<JsonNode, DatabaseSchema>() {
823 public DatabaseSchema apply(JsonNode input) {
824 log.info("Get ovsdb database schema", dbName);
825 DatabaseSchema dbSchema = FromJsonUtil
826 .jsonNodeToDbSchema(dbName, input);
827 if (dbSchema == null) {
828 log.debug("Get ovsdb database schema error");
831 schema.put(dbName, dbSchema);
837 ListenableFuture<JsonNode> input = getSchema(dbNames);
839 return Futures.transform(input, rowFunction);
843 return Futures.immediateFuture(databaseSchema);
848 public ListenableFuture<TableUpdates> monitorTables(String dbName, String id) {
849 if (dbName == null) {
852 DatabaseSchema dbSchema = schema.get(dbName);
853 if (dbSchema != null) {
854 Function<JsonNode, TableUpdates> rowFunction = new Function<JsonNode, TableUpdates>() {
856 public TableUpdates apply(JsonNode input) {
857 log.info("Get table updates");
858 TableUpdates updates = FromJsonUtil
859 .jsonNodeToTableUpdates(input, dbSchema);
860 if (updates == null) {
861 log.debug("Get table updates error");
867 return Futures.transform(monitor(dbSchema, id), rowFunction);
873 public ListenableFuture<List<OperationResult>> transactConfig(String dbName,
874 List<Operation> operations) {
875 if (dbName == null) {
878 DatabaseSchema dbSchema = schema.get(dbName);
879 if (dbSchema != null) {
880 Function<List<JsonNode>, List<OperationResult>> rowFunction =
881 new Function<List<JsonNode>, List<OperationResult>>() {
883 public List<OperationResult> apply(List<JsonNode> input) {
884 log.info("Get ovsdb operation result");
885 List<OperationResult> result = FromJsonUtil
886 .jsonNodeToOperationResult(input, operations);
888 if (result == null) {
889 log.debug("The operation result is null");
895 return Futures.transform(transact(dbSchema, operations),
902 public ListenableFuture<JsonNode> getSchema(List<String> dbnames) {
903 String id = java.util.UUID.randomUUID().toString();
904 String getSchemaString = JsonRpcWriterUtil.getSchemaStr(id, dbnames);
906 SettableFuture<JsonNode> sf = SettableFuture.create();
907 requestResult.put(id, sf);
908 requestMethod.put(id, "getSchema");
910 channel.writeAndFlush(getSchemaString);
916 public ListenableFuture<List<String>> echo() {
917 String id = java.util.UUID.randomUUID().toString();
918 String echoString = JsonRpcWriterUtil.echoStr(id);
920 SettableFuture<List<String>> sf = SettableFuture.create();
921 requestResult.put(id, sf);
922 requestMethod.put(id, "echo");
924 channel.writeAndFlush(echoString);
930 public ListenableFuture<JsonNode> monitor(DatabaseSchema dbSchema,
932 String id = java.util.UUID.randomUUID().toString();
933 String monitorString = JsonRpcWriterUtil.monitorStr(id, monitorId,
936 SettableFuture<JsonNode> sf = SettableFuture.create();
937 requestResult.put(id, sf);
938 requestMethod.put(id, "monitor");
940 channel.writeAndFlush(monitorString);
946 public ListenableFuture<List<String>> listDbs() {
947 String id = java.util.UUID.randomUUID().toString();
948 String listDbsString = JsonRpcWriterUtil.listDbsStr(id);
950 SettableFuture<List<String>> sf = SettableFuture.create();
951 requestResult.put(id, sf);
952 requestMethod.put(id, "listDbs");
954 channel.writeAndFlush(listDbsString);
960 public ListenableFuture<List<JsonNode>> transact(DatabaseSchema dbSchema,
961 List<Operation> operations) {
962 String id = java.util.UUID.randomUUID().toString();
963 String transactString = JsonRpcWriterUtil.transactStr(id, dbSchema,
966 SettableFuture<List<JsonNode>> sf = SettableFuture.create();
967 requestResult.put(id, sf);
968 requestMethod.put(id, "transact");
970 channel.writeAndFlush(transactString);
975 @SuppressWarnings({ "rawtypes", "unchecked" })
977 public void processResult(JsonNode response) {
978 log.debug("Handle result");
979 String requestId = response.get("id").asText();
980 SettableFuture sf = requestResult.get(requestId);
982 log.debug("No such future to process");
985 String methodName = requestMethod.get(requestId);
988 result = FromJsonUtil.jsonResultParser(response, methodName);
995 public void processRequest(JsonNode requestJson) {
996 log.debug("Handle request");
997 if (requestJson.get("method").asText().equalsIgnoreCase("echo")) {
998 log.debug("handle echo request");
1000 String replyString = FromJsonUtil.getEchoRequestStr(requestJson);
1001 channel.writeAndFlush(replyString);
1006 .jsonCallbackRequestParser(requestJson, monitorCallBack);
1012 public void setCallback(Callback monitorCallback) {
1013 this.monitorCallBack = monitorCallback;
1017 public Set<OvsdbTunnel> getTunnels() {
1018 return ovsdbTunnels;
1022 public Set<OvsdbBridge> getBridges() {
1023 Set<OvsdbBridge> ovsdbBridges = new HashSet<OvsdbBridge>();
1024 OvsdbTableStore tableStore = getTableStore(OvsdbConstant.DATABASENAME);
1025 if (tableStore == null) {
1028 OvsdbRowStore rowStore = tableStore.getRows(OvsdbConstant.BRIDGE);
1029 if (rowStore == null) {
1032 ConcurrentMap<String, Row> rows = rowStore.getRowStore();
1033 for (String uuid : rows.keySet()) {
1034 Row row = getRow(OvsdbConstant.DATABASENAME, OvsdbConstant.BRIDGE,
1036 OvsdbBridge ovsdbBridge = getOvsdbBridge(row);
1037 if (ovsdbBridge != null) {
1038 ovsdbBridges.add(ovsdbBridge);
1041 return ovsdbBridges;
1045 public Set<OvsdbPort> getPorts() {
1046 Set<OvsdbPort> ovsdbPorts = new HashSet<OvsdbPort>();
1047 OvsdbTableStore tableStore = getTableStore(OvsdbConstant.DATABASENAME);
1048 if (tableStore == null) {
1051 OvsdbRowStore rowStore = tableStore.getRows(OvsdbConstant.INTERFACE);
1052 if (rowStore == null) {
1055 ConcurrentMap<String, Row> rows = rowStore.getRowStore();
1056 for (String uuid : rows.keySet()) {
1057 Row row = getRow(OvsdbConstant.DATABASENAME,
1058 OvsdbConstant.INTERFACE, uuid);
1059 OvsdbPort ovsdbPort = getOvsdbPort(row);
1060 if (ovsdbPort != null) {
1061 ovsdbPorts.add(ovsdbPort);
1068 public DatabaseSchema getDatabaseSchema(String dbName) {
1069 return schema.get(dbName);
1073 private OvsdbPort getOvsdbPort(Row row) {
1074 DatabaseSchema dbSchema = getDatabaseSchema(OvsdbConstant.DATABASENAME);
1075 Interface intf = (Interface) TableGenerator
1076 .getTable(dbSchema, row, OvsdbTable.INTERFACE);
1080 long ofPort = getOfPort(intf);
1081 String portName = intf.getName();
1082 if ((ofPort < 0) || (portName == null)) {
1086 OvsdbPort ovsdbPort = new OvsdbPort(new OvsdbPortNumber(ofPort),
1087 new OvsdbPortName(portName));
1091 ////Gets ovsdb bridge.
1092 private OvsdbBridge getOvsdbBridge(Row row) {
1093 DatabaseSchema dbSchema = getDatabaseSchema(OvsdbConstant.DATABASENAME);
1094 Bridge bridge = (Bridge) TableGenerator.getTable(dbSchema, row,
1096 if (bridge == null) {
1100 OvsdbSet datapathIdSet = (OvsdbSet) bridge.getDatapathIdColumn().data();
1101 @SuppressWarnings("unchecked")
1102 Set<String> datapathIds = datapathIdSet.set();
1103 if (datapathIds == null || datapathIds.size() == 0) {
1106 String datapathId = (String) datapathIds.toArray()[0];
1107 String bridgeName = bridge.getName();
1108 if ((datapathId == null) || (bridgeName == null)) {
1112 OvsdbBridge ovsdbBridge = new OvsdbBridge(new OvsdbBridgeName(bridgeName),
1113 new OvsdbDatapathId(datapathId));
1117 //Gets ofPort in the interface.
1118 private long getOfPort(Interface intf) {
1119 OvsdbSet ofPortSet = (OvsdbSet) intf.getOpenFlowPortColumn().data();
1120 @SuppressWarnings("unchecked")
1121 Set<Integer> ofPorts = ofPortSet.set();
1122 while (ofPorts == null || ofPorts.size() <= 0) {
1123 log.debug("The ofport is null in {}", intf.getName());
1126 // return (long) ofPorts.toArray()[0];
1127 Iterator<Integer> it = ofPorts.iterator();
1128 return Long.parseLong(it.next().toString());
1132 public Set<OvsdbPort> getLocalPorts(Iterable<String> ifaceids) {
1133 Set<OvsdbPort> ovsdbPorts = new HashSet<OvsdbPort>();
1134 OvsdbTableStore tableStore = getTableStore(OvsdbConstant.DATABASENAME);
1135 if (tableStore == null) {
1138 OvsdbRowStore rowStore = tableStore.getRows(OvsdbConstant.INTERFACE);
1139 if (rowStore == null) {
1142 ConcurrentMap<String, Row> rows = rowStore.getRowStore();
1143 for (String uuid : rows.keySet()) {
1144 Row row = getRow(OvsdbConstant.DATABASENAME,
1145 OvsdbConstant.INTERFACE, uuid);
1146 DatabaseSchema dbSchema = getDatabaseSchema(OvsdbConstant.DATABASENAME);
1147 Interface intf = (Interface) TableGenerator
1148 .getTable(dbSchema, row, OvsdbTable.INTERFACE);
1149 if (intf == null || getIfaceid(intf) == null) {
1152 String portName = intf.getName();
1153 Set<String> ifaceidSet = Sets.newHashSet(ifaceids);
1154 if (portName.startsWith("vxlan")
1155 || !ifaceidSet.contains(getIfaceid(intf))) {
1158 long ofPort = getOfPort(intf);
1159 if ((ofPort < 0) || (portName == null)) {
1163 OvsdbPort ovsdbPort = new OvsdbPort(new OvsdbPortNumber(ofPort),
1164 new OvsdbPortName(portName));
1165 if (ovsdbPort != null) {
1166 ovsdbPorts.add(ovsdbPort);
1172 private String getIfaceid(Interface intf) {
1173 OvsdbMap ovsdbMap = (OvsdbMap) intf.getExternalIdsColumn().data();
1174 @SuppressWarnings("unchecked")
1175 Map<String, String> externalIds = ovsdbMap.map();
1176 if (externalIds.isEmpty()) {
1177 log.warn("The external_ids is null");
1180 String ifaceid = externalIds
1181 .get(OvsdbConstant.EXTERNAL_ID_INTERFACE_ID);
1182 if (ifaceid == null) {
1183 log.warn("The ifaceid is null");