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