blob: 3a84d00044cc63147bd9eb8e1c4a1128f5a26052 [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;
76import java.util.HashSet;
77import java.util.Iterator;
78import java.util.List;
79import java.util.Map;
80import java.util.Set;
81import java.util.concurrent.ConcurrentMap;
82import java.util.concurrent.ExecutionException;
83import java.util.concurrent.atomic.AtomicReference;
84import java.util.stream.Collectors;
Sho SHIMIZUe4efe452015-08-26 15:06:55 -070085
86/**
87 * An representation of an ovsdb client.
88 */
89public 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 *
andreaed976a42015-10-05 14:38:25 -0700174 * @param dbName the ovsdb database name
Sho SHIMIZUe4efe452015-08-26 15:06:55 -0700175 * @param tableName the ovsdb table name
Sho SHIMIZUe4efe452015-08-26 15:06:55 -0700176 * @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 *
andreaed976a42015-10-05 14:38:25 -0700189 * @param dbName the ovsdb database name
Sho SHIMIZUe4efe452015-08-26 15:06:55 -0700190 * @param tableName the ovsdb table name
andreaed976a42015-10-05 14:38:25 -0700191 * @param uuid the key of the row
Sho SHIMIZUe4efe452015-08-26 15:06:55 -0700192 * @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,
andreaed976a42015-10-05 14:38:25 -0700399 "ports", bridgeUuid, port.getRow());
Sho SHIMIZUe4efe452015-08-26 15:06:55 -0700400 } 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,
andreaed976a42015-10-05 14:38:25 -0700419 OvsdbConstant.BRIDGE, "ports");
Sho SHIMIZUe4efe452015-08-26 15:06:55 -0700420 }
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",
andreaed976a42015-10-05 14:38:25 -0700460 OvsdbConstant.DATABASENAME, "bridges",
461 ovsUuid, bridge.getRow());
Sho SHIMIZUe4efe452015-08-26 15:06:55 -0700462
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,
andreaed976a42015-10-05 14:38:25 -0700471 port.getRow());
Sho SHIMIZUe4efe452015-08-26 15:06:55 -0700472 }
473 }
474
475 } else {
476 log.info("Update a bridge");
477 updateConfig(OvsdbConstant.BRIDGE, "_uuid", bridgeUuid, bridge.getRow());
478 }
479
andreaed976a42015-10-05 14:38:25 -0700480 setControllerAuto(bridgeUuid);
Sho SHIMIZUe4efe452015-08-26 15:06:55 -0700481 log.info("Create bridge success");
482 }
483
484 /**
Brian O'Connor6ee8aa32015-10-09 16:07:42 -0700485 * 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.
Sho SHIMIZUe4efe452015-08-26 15:06:55 -0700489 *
490 * @param bridgeUuid bridge uuid
491 */
andreaed976a42015-10-05 14:38:25 -0700492 private void setControllerAuto(String bridgeUuid) {
Brian O'Connor6ee8aa32015-10-09 16:07:42 -0700493 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));
andreaed976a42015-10-05 14:38:25 -0700498 }
499
andreaed976a42015-10-05 14:38:25 -0700500 @Override
501 public void setControllersWithUUID(UUID bridgeUuid, List<ControllerInfo> controllers) {
502
Sho SHIMIZUe4efe452015-08-26 15:06:55 -0700503 DatabaseSchema dbSchema = schema.get(OvsdbConstant.DATABASENAME);
andreaed976a42015-10-05 14:38:25 -0700504 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
andreaed976a42015-10-05 14:38:25 -0700534 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 -> {
andreaed976a42015-10-05 14:38:25 -0700543 String uuid = insertConfig(OvsdbConstant.CONTROLLER, "_uuid",
544 OvsdbConstant.BRIDGE, "controller", bridgeUuid.value(),
545 c.getRow());
andreaed976a42015-10-05 14:38:25 -0700546 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());
andreaed976a42015-10-05 14:38:25 -0700561 }
562
andreaed976a42015-10-05 14:38:25 -0700563 @Override
564 public void setControllersWithDeviceId(DeviceId deviceId, List<ControllerInfo> controllers) {
565 setControllersWithUUID(getBridgeUUID(deviceId), controllers);
566 }
567
Sho SHIMIZUe4efe452015-08-26 15:06:55 -0700568 @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,
andreaed976a42015-10-05 14:38:25 -0700576 OvsdbConstant.DATABASENAME, "bridges");
Sho SHIMIZUe4efe452015-08-26 15:06:55 -0700577 }
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,
andreaed976a42015-10-05 14:38:25 -0700600 "ports", bridgeUuid, port.getRow());
Sho SHIMIZUe4efe452015-08-26 15:06:55 -0700601 } 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,
andreaed976a42015-10-05 14:38:25 -0700641 tunInterface.getRow());
Sho SHIMIZUe4efe452015-08-26 15:06:55 -0700642 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,
andreaed976a42015-10-05 14:38:25 -0700665 OvsdbConstant.BRIDGE, "ports");
Sho SHIMIZUe4efe452015-08-26 15:06:55 -0700666 }
667
668 return;
669 }
670
671 /**
672 * Delete transact config.
673 *
andreaed976a42015-10-05 14:38:25 -0700674 * @param childTableName child table name
675 * @param childColumnName child column name
676 * @param childUuid child row uuid
677 * @param parentTableName parent table name
Sho SHIMIZUe4efe452015-08-26 15:06:55 -0700678 * @param parentColumnName parent column
Sho SHIMIZUe4efe452015-08-26 15:06:55 -0700679 */
680 private void deleteConfig(String childTableName, String childColumnName,
andreaed976a42015-10-05 14:38:25 -0700681 String childUuid, String parentTableName,
682 String parentColumnName) {
Sho SHIMIZUe4efe452015-08-26 15:06:55 -0700683 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 *
andreaed976a42015-10-05 14:38:25 -0700717 * @param tableName table name
Sho SHIMIZUe4efe452015-08-26 15:06:55 -0700718 * @param columnName column name
andreaed976a42015-10-05 14:38:25 -0700719 * @param uuid uuid
720 * @param row the config data
Sho SHIMIZUe4efe452015-08-26 15:06:55 -0700721 */
722 private void updateConfig(String tableName, String columnName, String uuid,
andreaed976a42015-10-05 14:38:25 -0700723 Row row) {
Sho SHIMIZUe4efe452015-08-26 15:06:55 -0700724 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 *
andreaed976a42015-10-05 14:38:25 -0700742 * @param childTableName child table name
743 * @param childColumnName child column name
744 * @param parentTableName parent table name
Sho SHIMIZUe4efe452015-08-26 15:06:55 -0700745 * @param parentColumnName parent column
andreaed976a42015-10-05 14:38:25 -0700746 * @param parentUuid parent uuid
747 * @param row the config data
Sho SHIMIZUe4efe452015-08-26 15:06:55 -0700748 * @return uuid, empty if no uuid is find
749 */
750 private String insertConfig(String childTableName, String childColumnName,
andreaed976a42015-10-05 14:38:25 -0700751 String parentTableName, String parentColumnName,
752 String parentUuid, Row row) {
Sho SHIMIZUe4efe452015-08-26 15:06:55 -0700753 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,
andreaed976a42015-10-05 14:38:25 -0700784 row);
Sho SHIMIZUe4efe452015-08-26 15:06:55 -0700785
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
andreaed976a42015-10-05 14:38:25 -0700815 * @param portRow row of port
Sho SHIMIZUe4efe452015-08-26 15:06:55 -0700816 * @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
andreaed976a42015-10-05 14:38:25 -0700843 * @param dstIp the remote ip address
Sho SHIMIZUe4efe452015-08-26 15:06:55 -0700844 * @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) {
Hyunsun Moon5fb20a52015-09-25 17:02:33 -0700862 log.info("Get ovsdb database schema {}", dbName);
Sho SHIMIZUe4efe452015-08-26 15:06:55 -0700863 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) {
andreaed976a42015-10-05 14:38:25 -0700918 Function<List<JsonNode>, List<OperationResult>> rowFunction = (input -> {
919 log.info("Get ovsdb operation result");
920 List<OperationResult> result = FromJsonUtil
921 .jsonNodeToOperationResult(input, operations);
Sho SHIMIZUe4efe452015-08-26 15:06:55 -0700922
andreaed976a42015-10-05 14:38:25 -0700923 if (result == null) {
924 log.debug("The operation result is null");
925 return null;
Sho SHIMIZUe4efe452015-08-26 15:06:55 -0700926 }
andreaed976a42015-10-05 14:38:25 -0700927 return result;
928 });
Sho SHIMIZUe4efe452015-08-26 15:06:55 -0700929 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
andreaed976a42015-10-05 14:38:25 -07001009 @SuppressWarnings({"rawtypes", "unchecked"})
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001010 @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
andreaed976a42015-10-05 14:38:25 -07001079 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
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001178 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 }
CNluciusa66c3972015-09-06 20:31:29 +08001263
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 }
Hyunsun Moon5fb20a52015-09-25 17:02:33 -07001321
1322 @Override
1323 public void disconnect() {
1324 channel.disconnect();
1325 this.agent.removeConnectedNode(nodeId);
1326 }
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001327}