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