blob: 36498666188b59008987b7c803fa6a2167aa5d0e [file] [log] [blame]
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001/*
Brian O'Connor5ab426f2016-04-09 01:19:45 -07002 * Copyright 2015-present Open Networking Laboratory
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07003 *
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;
lishuai6c56f5e2015-11-17 16:38:19 +080027
Sho SHIMIZUe4efe452015-08-26 15:06:55 -070028import io.netty.channel.Channel;
lishuai6c56f5e2015-11-17 16:38:19 +080029
Sho SHIMIZUe4efe452015-08-26 15:06:55 -070030import org.onlab.packet.IpAddress;
andreaed976a42015-10-05 14:38:25 -070031import org.onosproject.net.DeviceId;
32import org.onosproject.net.behaviour.ControllerInfo;
Sho SHIMIZUe4efe452015-08-26 15:06:55 -070033import org.onosproject.ovsdb.controller.OvsdbBridge;
34import org.onosproject.ovsdb.controller.OvsdbBridgeName;
35import org.onosproject.ovsdb.controller.OvsdbClientService;
36import org.onosproject.ovsdb.controller.OvsdbConstant;
37import org.onosproject.ovsdb.controller.OvsdbDatapathId;
38import org.onosproject.ovsdb.controller.OvsdbNodeId;
39import org.onosproject.ovsdb.controller.OvsdbPort;
40import org.onosproject.ovsdb.controller.OvsdbPortName;
41import org.onosproject.ovsdb.controller.OvsdbPortNumber;
42import org.onosproject.ovsdb.controller.OvsdbRowStore;
43import org.onosproject.ovsdb.controller.OvsdbStore;
44import org.onosproject.ovsdb.controller.OvsdbTableStore;
45import org.onosproject.ovsdb.controller.OvsdbTunnel;
Satish Kebe203d2015-11-21 15:58:18 +053046import org.onosproject.ovsdb.rfc.exception.BridgeCreateException;
Sho SHIMIZUe4efe452015-08-26 15:06:55 -070047import org.onosproject.ovsdb.rfc.jsonrpc.Callback;
48import org.onosproject.ovsdb.rfc.message.OperationResult;
49import org.onosproject.ovsdb.rfc.message.TableUpdates;
50import org.onosproject.ovsdb.rfc.notation.Condition;
51import org.onosproject.ovsdb.rfc.notation.Mutation;
CNluciusa66c3972015-09-06 20:31:29 +080052import org.onosproject.ovsdb.rfc.notation.OvsdbMap;
Sho SHIMIZUe4efe452015-08-26 15:06:55 -070053import org.onosproject.ovsdb.rfc.notation.OvsdbSet;
54import org.onosproject.ovsdb.rfc.notation.Row;
Jonathan Hart51539b82015-10-29 09:53:04 -070055import org.onosproject.ovsdb.rfc.notation.Uuid;
Sho SHIMIZUe4efe452015-08-26 15:06:55 -070056import org.onosproject.ovsdb.rfc.operations.Delete;
57import org.onosproject.ovsdb.rfc.operations.Insert;
58import org.onosproject.ovsdb.rfc.operations.Mutate;
59import org.onosproject.ovsdb.rfc.operations.Operation;
60import org.onosproject.ovsdb.rfc.operations.Update;
61import org.onosproject.ovsdb.rfc.schema.ColumnSchema;
62import org.onosproject.ovsdb.rfc.schema.DatabaseSchema;
63import org.onosproject.ovsdb.rfc.schema.TableSchema;
64import org.onosproject.ovsdb.rfc.table.Bridge;
65import org.onosproject.ovsdb.rfc.table.Controller;
66import org.onosproject.ovsdb.rfc.table.Interface;
67import org.onosproject.ovsdb.rfc.table.OvsdbTable;
68import org.onosproject.ovsdb.rfc.table.Port;
69import org.onosproject.ovsdb.rfc.table.TableGenerator;
70import org.onosproject.ovsdb.rfc.utils.ConditionUtil;
71import org.onosproject.ovsdb.rfc.utils.FromJsonUtil;
72import org.onosproject.ovsdb.rfc.utils.JsonRpcWriterUtil;
73import org.onosproject.ovsdb.rfc.utils.MutationUtil;
74import org.slf4j.Logger;
75import org.slf4j.LoggerFactory;
76
andreaed976a42015-10-05 14:38:25 -070077import java.net.InetSocketAddress;
78import java.util.ArrayList;
Hyunsun Moon646d8c42015-10-08 20:32:44 -070079import java.util.Arrays;
80import java.util.HashMap;
andreaed976a42015-10-05 14:38:25 -070081import java.util.HashSet;
82import java.util.Iterator;
83import java.util.List;
84import java.util.Map;
85import java.util.Set;
86import java.util.concurrent.ConcurrentMap;
87import java.util.concurrent.ExecutionException;
88import java.util.concurrent.atomic.AtomicReference;
89import java.util.stream.Collectors;
Sho SHIMIZUe4efe452015-08-26 15:06:55 -070090
91/**
92 * An representation of an ovsdb client.
93 */
94public class DefaultOvsdbClient
95 implements OvsdbProviderService, OvsdbClientService {
96
97 private final Logger log = LoggerFactory
98 .getLogger(DefaultOvsdbClient.class);
99
100 private Channel channel;
101
102 private OvsdbAgent agent;
103 private boolean connected;
104 private OvsdbNodeId nodeId;
105 private Callback monitorCallBack;
106
107 private OvsdbStore ovsdbStore = new OvsdbStore();
108
109 private final Map<String, String> requestMethod = Maps.newHashMap();
110 private final Map<String, SettableFuture<? extends Object>> requestResult = Maps
111 .newHashMap();
112
113 private final Map<String, DatabaseSchema> schema = Maps.newHashMap();
114 private final Set<OvsdbTunnel> ovsdbTunnels = new HashSet<OvsdbTunnel>();
115
116 /**
117 * Creates an OvsdbClient.
118 *
119 * @param nodeId ovsdb node id
120 */
121 public DefaultOvsdbClient(OvsdbNodeId nodeId) {
122 this.nodeId = nodeId;
123 }
124
125 @Override
126 public OvsdbNodeId nodeId() {
127 return nodeId;
128 }
129
130 @Override
131 public void setAgent(OvsdbAgent agent) {
132 if (this.agent == null) {
133 this.agent = agent;
134 }
135 }
136
137 @Override
138 public void setChannel(Channel channel) {
139 this.channel = channel;
140 }
141
142 @Override
143 public void setConnection(boolean connected) {
144 this.connected = connected;
145 }
146
147 @Override
148 public boolean isConnected() {
149 return this.connected;
150 }
151
152 @Override
153 public void nodeAdded() {
154 this.agent.addConnectedNode(nodeId, this);
155 }
156
157 @Override
158 public void nodeRemoved() {
159 this.agent.removeConnectedNode(nodeId);
160 channel.disconnect();
161 }
162
163 /**
164 * Gets the ovsdb table store.
165 *
166 * @param dbName the ovsdb database name
167 * @return ovsTableStore, empty if table store is find
168 */
169 private OvsdbTableStore getTableStore(String dbName) {
170 if (ovsdbStore == null) {
171 return null;
172 }
173 return ovsdbStore.getOvsdbTableStore(dbName);
174 }
175
176 /**
177 * Gets the ovsdb row store.
178 *
andreaed976a42015-10-05 14:38:25 -0700179 * @param dbName the ovsdb database name
Sho SHIMIZUe4efe452015-08-26 15:06:55 -0700180 * @param tableName the ovsdb table name
Hyunsun Moon6125c612015-10-15 10:54:44 -0700181 * @return ovsRowStore, empty store if no rows exist in the table
Sho SHIMIZUe4efe452015-08-26 15:06:55 -0700182 */
183 private OvsdbRowStore getRowStore(String dbName, String tableName) {
184 OvsdbTableStore tableStore = getTableStore(dbName);
185 if (tableStore == null) {
186 return null;
187 }
Hyunsun Moon6125c612015-10-15 10:54:44 -0700188
189 OvsdbRowStore rowStore = tableStore.getRows(tableName);
190 if (rowStore == null) {
191 rowStore = new OvsdbRowStore();
192 }
193 return rowStore;
Sho SHIMIZUe4efe452015-08-26 15:06:55 -0700194 }
195
196 /**
197 * Gets the ovsdb row.
198 *
andreaed976a42015-10-05 14:38:25 -0700199 * @param dbName the ovsdb database name
Sho SHIMIZUe4efe452015-08-26 15:06:55 -0700200 * @param tableName the ovsdb table name
andreaed976a42015-10-05 14:38:25 -0700201 * @param uuid the key of the row
Sho SHIMIZUe4efe452015-08-26 15:06:55 -0700202 * @return row, empty if row is find
203 */
204 @Override
205 public Row getRow(String dbName, String tableName, String uuid) {
206 OvsdbTableStore tableStore = getTableStore(dbName);
207 if (tableStore == null) {
208 return null;
209 }
210 OvsdbRowStore rowStore = tableStore.getRows(tableName);
211 if (rowStore == null) {
212 return null;
213 }
214 return rowStore.getRow(uuid);
215 }
216
217 @Override
218 public void removeRow(String dbName, String tableName, String uuid) {
219 OvsdbTableStore tableStore = getTableStore(dbName);
220 if (tableStore == null) {
221 return;
222 }
223 OvsdbRowStore rowStore = tableStore.getRows(tableName);
224 if (rowStore == null) {
225 return;
226 }
227 rowStore.deleteRow(uuid);
228 }
229
230 @Override
231 public void updateOvsdbStore(String dbName, String tableName, String uuid,
232 Row row) {
233 OvsdbTableStore tableStore = ovsdbStore.getOvsdbTableStore(dbName);
234 if (tableStore == null) {
235 tableStore = new OvsdbTableStore();
236 }
237 OvsdbRowStore rowStore = tableStore.getRows(tableName);
238 if (rowStore == null) {
239 rowStore = new OvsdbRowStore();
240 }
241 rowStore.insertRow(uuid, row);
242 tableStore.createOrUpdateTable(tableName, rowStore);
243 ovsdbStore.createOrUpdateOvsdbStore(dbName, tableStore);
244 }
245
246 @Override
247 public String getPortUuid(String portName, String bridgeUuid) {
248 DatabaseSchema dbSchema = schema.get(OvsdbConstant.DATABASENAME);
249
250 Row bridgeRow = getRow(OvsdbConstant.DATABASENAME,
251 OvsdbConstant.BRIDGE, bridgeUuid);
252
253 Bridge bridge = (Bridge) TableGenerator.getTable(dbSchema, bridgeRow,
254 OvsdbTable.BRIDGE);
255 if (bridge != null) {
256 OvsdbSet setPorts = (OvsdbSet) bridge.getPortsColumn().data();
257 @SuppressWarnings("unchecked")
Jonathan Hart51539b82015-10-29 09:53:04 -0700258 Set<Uuid> ports = setPorts.set();
Sho SHIMIZUe4efe452015-08-26 15:06:55 -0700259 if (ports == null || ports.size() == 0) {
260 log.warn("The port uuid is null");
261 return null;
262 }
263
Jonathan Hart51539b82015-10-29 09:53:04 -0700264 for (Uuid uuid : ports) {
Sho SHIMIZUe4efe452015-08-26 15:06:55 -0700265 Row portRow = getRow(OvsdbConstant.DATABASENAME,
266 OvsdbConstant.PORT, uuid.value());
267 Port port = (Port) TableGenerator.getTable(dbSchema, portRow,
268 OvsdbTable.PORT);
269 if (port != null && portName.equalsIgnoreCase(port.getName())) {
270 return uuid.value();
271 }
272 }
273
274 }
275 return null;
276 }
277
278 @Override
279 public String getInterfaceUuid(String portUuid, String portName) {
280 DatabaseSchema dbSchema = schema.get(OvsdbConstant.DATABASENAME);
281
282 Row portRow = getRow(OvsdbConstant.DATABASENAME, OvsdbConstant.PORT,
283 portUuid);
284 Port port = (Port) TableGenerator.getTable(dbSchema, portRow,
285 OvsdbTable.PORT);
286
287 if (port != null) {
288 OvsdbSet setInterfaces = (OvsdbSet) port.getInterfacesColumn().data();
289 @SuppressWarnings("unchecked")
Jonathan Hart51539b82015-10-29 09:53:04 -0700290 Set<Uuid> interfaces = setInterfaces.set();
Sho SHIMIZUe4efe452015-08-26 15:06:55 -0700291
292 if (interfaces == null || interfaces.size() == 0) {
293 log.warn("The interface uuid is null");
294 return null;
295 }
296
Jonathan Hart51539b82015-10-29 09:53:04 -0700297 for (Uuid uuid : interfaces) {
Sho SHIMIZUe4efe452015-08-26 15:06:55 -0700298 Row intfRow = getRow(OvsdbConstant.DATABASENAME,
299 OvsdbConstant.INTERFACE, uuid.value());
300 Interface intf = (Interface) TableGenerator
301 .getTable(dbSchema, intfRow, OvsdbTable.INTERFACE);
302 if (intf != null && portName.equalsIgnoreCase(intf.getName())) {
303 return uuid.value();
304 }
305 }
306
307 }
308
309 return null;
310 }
311
312 @Override
313 public String getBridgeUuid(String bridgeName) {
314 DatabaseSchema dbSchema = schema.get(OvsdbConstant.DATABASENAME);
315
316 OvsdbRowStore rowStore = getRowStore(OvsdbConstant.DATABASENAME,
317 OvsdbConstant.BRIDGE);
318 if (rowStore == null) {
319 log.debug("The bridge uuid is null");
320 return null;
321 }
322
323 ConcurrentMap<String, Row> bridgeTableRows = rowStore.getRowStore();
324 if (bridgeTableRows == null) {
325 log.debug("The bridge uuid is null");
326 return null;
327 }
328
329 for (String uuid : bridgeTableRows.keySet()) {
330 Bridge bridge = (Bridge) TableGenerator
331 .getTable(dbSchema, bridgeTableRows.get(uuid),
332 OvsdbTable.BRIDGE);
333
334 if (bridge.getName().equals(bridgeName)) {
335 return uuid;
336 }
337
338 }
339 return null;
340 }
341
342 @Override
343 public String getControllerUuid(String controllerName,
344 String controllerTarget) {
345 DatabaseSchema dbSchema = schema.get(OvsdbConstant.DATABASENAME);
346 OvsdbRowStore rowStore = getRowStore(OvsdbConstant.DATABASENAME,
347 OvsdbConstant.CONTROLLER);
348 if (rowStore == null) {
349 log.debug("The controller uuid is null");
350 return null;
351 }
352
353 ConcurrentMap<String, Row> controllerTableRows = rowStore.getRowStore();
354 if (controllerTableRows != null) {
355 for (String uuid : controllerTableRows.keySet()) {
356
357 Controller controller = (Controller) TableGenerator
358 .getTable(dbSchema, controllerTableRows.get(uuid),
359 OvsdbTable.CONTROLLER);
360 String target = (String) controller.getTargetColumn().data();
361 if (target.equalsIgnoreCase(controllerTarget)) {
362 return uuid;
363 }
364
365 }
366 }
367 return null;
368 }
369
370 @Override
371 public String getOvsUuid(String dbName) {
372 OvsdbRowStore rowStore = getRowStore(OvsdbConstant.DATABASENAME,
373 OvsdbConstant.DATABASENAME);
374 if (rowStore == null) {
375 log.debug("The bridge uuid is null");
376 return null;
377 }
378 ConcurrentMap<String, Row> ovsTableRows = rowStore.getRowStore();
379 if (ovsTableRows != null) {
380 for (String uuid : ovsTableRows.keySet()) {
381 Row row = ovsTableRows.get(uuid);
382 String tableName = row.tableName();
383 if (tableName.equals(dbName)) {
384 return uuid;
385 }
386 }
387 }
388 return null;
389 }
390
391 @Override
392 public void createPort(String bridgeName, String portName) {
393 String bridgeUuid = getBridgeUuid(bridgeName);
394 if (bridgeUuid == null) {
395 log.error("Can't find bridge {} in {}", bridgeName,
396 nodeId.getIpAddress());
397 return;
398 }
399
400 DatabaseSchema dbSchema = schema.get(OvsdbConstant.DATABASENAME);
401 String portUuid = getPortUuid(portName, bridgeUuid);
402
403 Port port = (Port) TableGenerator
404 .createTable(dbSchema, OvsdbTable.PORT);
405
406 port.setName(portName);
407 if (portUuid == null) {
408 insertConfig(OvsdbConstant.PORT, "_uuid", OvsdbConstant.BRIDGE,
andreaed976a42015-10-05 14:38:25 -0700409 "ports", bridgeUuid, port.getRow());
Sho SHIMIZUe4efe452015-08-26 15:06:55 -0700410 } else {
411 updateConfig(OvsdbConstant.PORT, "_uuid", portUuid, port.getRow());
412 }
413
414 return;
415 }
416
417 @Override
418 public void dropPort(String bridgeName, String portName) {
419 String bridgeUuid = getBridgeUuid(bridgeName);
420 if (bridgeUuid == null) {
421 log.error("Could not find Bridge {} in {}", bridgeName, nodeId);
422 return;
423 }
424
425 String portUuid = getPortUuid(portName, bridgeUuid);
426 if (portUuid != null) {
427 log.info("Port {} delete", portName);
428 deleteConfig(OvsdbConstant.PORT, "_uuid", portUuid,
andreaed976a42015-10-05 14:38:25 -0700429 OvsdbConstant.BRIDGE, "ports");
Sho SHIMIZUe4efe452015-08-26 15:06:55 -0700430 }
431 }
432
433 @Override
434 public void createBridge(String bridgeName) {
435 log.debug("create bridge {}", bridgeName);
436
437 DatabaseSchema dbSchema = schema.get(OvsdbConstant.DATABASENAME);
438 if (dbSchema == null) {
439 log.warn("The schema is null");
440 return;
441 }
442
443 Bridge bridge = (Bridge) TableGenerator.createTable(dbSchema,
444 OvsdbTable.BRIDGE);
445 if (bridge == null) {
446 log.debug("Can not create bridge");
447 return;
448 }
449
450 Set<String> failModes = new HashSet<>();
451 failModes.add("secure");
452 bridge.setFailMode(failModes);
453
454 Set<String> protocols = new HashSet<>();
455 protocols.add(OvsdbConstant.OPENFLOW13);
456 bridge.setProtocols(protocols);
457
458 String ovsUuid = getOvsUuid(OvsdbConstant.DATABASENAME);
459 if (ovsUuid == null) {
460 log.warn("The Open_vSwitch is null");
461 return;
462 }
463
Bob zhoue9795fd2016-05-12 20:18:45 +0800464 Map<String, String> options = new HashMap<>();
465 options.put("disable-in-band", "true");
466 bridge.setOtherConfig(options);
467
Sho SHIMIZUe4efe452015-08-26 15:06:55 -0700468 String bridgeUuid = getBridgeUuid(bridgeName);
469 if (bridgeUuid == null) {
470 log.debug("Create a new bridge");
471
472 bridge.setName(bridgeName);
473 bridgeUuid = insertConfig(OvsdbConstant.BRIDGE, "_uuid",
andreaed976a42015-10-05 14:38:25 -0700474 OvsdbConstant.DATABASENAME, "bridges",
475 ovsUuid, bridge.getRow());
Sho SHIMIZUe4efe452015-08-26 15:06:55 -0700476
477 if (bridgeUuid != null) {
478 Port port = (Port) TableGenerator.createTable(dbSchema,
479 OvsdbTable.PORT);
480 if (port != null) {
481 log.debug("the port is not null");
482 port.setName(bridgeName);
483
484 insertConfig(OvsdbConstant.PORT, "_uuid", "Bridge", "ports", bridgeUuid,
andreaed976a42015-10-05 14:38:25 -0700485 port.getRow());
Sho SHIMIZUe4efe452015-08-26 15:06:55 -0700486 }
Satish Kebe203d2015-11-21 15:58:18 +0530487 } else {
488 String message = BridgeCreateException.createMessage(ovsUuid);
489 throw new BridgeCreateException(message);
Sho SHIMIZUe4efe452015-08-26 15:06:55 -0700490 }
491
492 } else {
493 log.info("Update a bridge");
494 updateConfig(OvsdbConstant.BRIDGE, "_uuid", bridgeUuid, bridge.getRow());
495 }
496
andreaed976a42015-10-05 14:38:25 -0700497 setControllerAuto(bridgeUuid);
Sho SHIMIZUe4efe452015-08-26 15:06:55 -0700498 log.info("Create bridge success");
499 }
500
Hyunsun Moon646d8c42015-10-08 20:32:44 -0700501 @Override
lishuai6c56f5e2015-11-17 16:38:19 +0800502 public void createBridge(String bridgeName, String dpid, String exPortName) {
503 log.debug("create bridge {}", bridgeName);
504
505 DatabaseSchema dbSchema = schema.get(OvsdbConstant.DATABASENAME);
506 if (dbSchema == null) {
507 log.warn("The schema is null");
508 return;
509 }
510
511 Bridge bridge = (Bridge) TableGenerator.createTable(dbSchema,
512 OvsdbTable.BRIDGE);
513 if (bridge == null) {
514 log.debug("Can not create bridge");
515 return;
516 }
517
518 Set<String> failModes = new HashSet<>();
519 failModes.add("secure");
520 bridge.setFailMode(failModes);
521
522 Set<String> protocols = new HashSet<>();
523 protocols.add(OvsdbConstant.OPENFLOW13);
524 bridge.setProtocols(protocols);
525
526 String ovsUuid = getOvsUuid(OvsdbConstant.DATABASENAME);
527 if (ovsUuid == null) {
528 log.warn("The Open_vSwitch is null");
529 return;
530 }
531
Bob zhoue9795fd2016-05-12 20:18:45 +0800532 Map<String, String> options = new HashMap<>();
533 options.put("disable-in-band", "true");
534 if (dpid != null) {
535 options.put("datapath-id", dpid);
536 }
537 bridge.setOtherConfig(options);
538
lishuai6c56f5e2015-11-17 16:38:19 +0800539 String bridgeUuid = getBridgeUuid(bridgeName);
540 if (bridgeUuid == null) {
541 log.debug("Create a new bridge");
542
543 bridge.setName(bridgeName);
lishuai6c56f5e2015-11-17 16:38:19 +0800544 bridgeUuid = insertConfig(OvsdbConstant.BRIDGE, "_uuid",
545 OvsdbConstant.DATABASENAME, "bridges",
546 ovsUuid, bridge.getRow());
547
548 if (bridgeUuid != null) {
549 Port port = (Port) TableGenerator.createTable(dbSchema,
550 OvsdbTable.PORT);
551 if (port != null) {
552 log.debug("the port is not null");
553 port.setName(bridgeName);
554
555 insertConfig(OvsdbConstant.PORT, "_uuid", "Bridge", "ports", bridgeUuid,
556 port.getRow());
557 }
Satish Kebe203d2015-11-21 15:58:18 +0530558 } else {
559 String message = BridgeCreateException.createMessage(ovsUuid);
560 throw new BridgeCreateException(message);
lishuai6c56f5e2015-11-17 16:38:19 +0800561 }
562
563 } else {
564 log.info("Update a bridge");
565 updateConfig(OvsdbConstant.BRIDGE, "_uuid", bridgeUuid, bridge.getRow());
566 }
567 // Create external port
568 if (exPortName != null) {
569 createPort(bridgeName, exPortName);
570 }
571
572 setControllerAuto(bridgeUuid);
573 log.info("Create bridge success");
574 }
575
576 @Override
Hyunsun Moon646d8c42015-10-08 20:32:44 -0700577 public boolean createBridge(String bridgeName, String dpid, List<ControllerInfo> controllers) {
578
579 DatabaseSchema dbSchema = schema.get(OvsdbConstant.DATABASENAME);
580 String ovsUuid = getOvsUuid(OvsdbConstant.DATABASENAME);
581
582 if (dbSchema == null || ovsUuid == null) {
583 log.warn("Couldn't find database Open_vSwitch");
584 return false;
585 }
586
Hyunsun Moon646d8c42015-10-08 20:32:44 -0700587 Bridge bridge = (Bridge) TableGenerator.createTable(dbSchema, OvsdbTable.BRIDGE);
Hyunsun Moon646d8c42015-10-08 20:32:44 -0700588 Set<String> failMode = new HashSet<>(Arrays.asList("secure"));
589 bridge.setFailMode(failMode);
590
591 Set<String> protocols = new HashSet<>(Arrays.asList(OvsdbConstant.OPENFLOW13));
592 bridge.setProtocols(protocols);
593
594 Map<String, String> options = new HashMap<>();
Bob zhoue9795fd2016-05-12 20:18:45 +0800595 options.put("disable-in-band", "true");
596 if (dpid != null) {
597 options.put("datapath-id", dpid);
598 }
Hyunsun Moon646d8c42015-10-08 20:32:44 -0700599 bridge.setOtherConfig(options);
600
Hyunsun Moon98025542016-03-08 04:36:02 -0800601 String bridgeUuid = getBridgeUuid(bridgeName);
602 if (bridgeUuid == null) {
603 bridge.setName(bridgeName);
604 bridgeUuid = insertConfig(OvsdbConstant.BRIDGE, "_uuid",
605 OvsdbConstant.DATABASENAME, "bridges",
606 ovsUuid, bridge.getRow());
607 } else {
608 updateConfig(OvsdbConstant.BRIDGE, "_uuid", bridgeUuid, bridge.getRow());
609 }
Hyunsun Moon646d8c42015-10-08 20:32:44 -0700610
611 if (bridgeUuid != null) {
612 createPort(bridgeName, bridgeName);
613 } else {
614 log.warn("Failed to create bridge {} on {}", bridgeName, nodeId.toString());
615 return false;
616 }
617
Jonathan Hart51539b82015-10-29 09:53:04 -0700618 setControllersWithUuid(Uuid.uuid(bridgeUuid), controllers);
Hyunsun Moon646d8c42015-10-08 20:32:44 -0700619 return true;
620 }
621
Sho SHIMIZUe4efe452015-08-26 15:06:55 -0700622 /**
Brian O'Connor6ee8aa32015-10-09 16:07:42 -0700623 * Sets the bridge's controller automatically.
624 * <p/>
625 * The connection is a TCP connection to the local ONOS instance's IP
626 * and the default OpenFlow port.
Sho SHIMIZUe4efe452015-08-26 15:06:55 -0700627 *
628 * @param bridgeUuid bridge uuid
629 */
andreaed976a42015-10-05 14:38:25 -0700630 private void setControllerAuto(String bridgeUuid) {
Brian O'Connor6ee8aa32015-10-09 16:07:42 -0700631 IpAddress ipAddress = IpAddress.valueOf(((InetSocketAddress) channel.localAddress()).getAddress());
632 ControllerInfo controllerInfo = new ControllerInfo(ipAddress, OvsdbConstant.OFPORT, "tcp");
633 log.debug("Automatically setting controller for bridge {} to {}",
634 bridgeUuid, controllerInfo.target());
Jonathan Hart51539b82015-10-29 09:53:04 -0700635 setControllersWithUuid(Uuid.uuid(bridgeUuid), ImmutableList.of(controllerInfo));
andreaed976a42015-10-05 14:38:25 -0700636 }
637
andreaed976a42015-10-05 14:38:25 -0700638 @Override
Jonathan Hart51539b82015-10-29 09:53:04 -0700639 public void setControllersWithUuid(Uuid bridgeUuid, List<ControllerInfo> controllers) {
andreaed976a42015-10-05 14:38:25 -0700640
Sho SHIMIZUe4efe452015-08-26 15:06:55 -0700641 DatabaseSchema dbSchema = schema.get(OvsdbConstant.DATABASENAME);
andreaed976a42015-10-05 14:38:25 -0700642 if (dbSchema == null) {
643 log.debug("There is no schema");
644 return;
645 }
646 List<Controller> oldControllers = getControllers(bridgeUuid);
647 if (oldControllers == null) {
648 log.warn("There are no controllers");
649 return;
650 }
651
Jonathan Hart51539b82015-10-29 09:53:04 -0700652 Set<Uuid> newControllerUuids = new HashSet<>();
andreaed976a42015-10-05 14:38:25 -0700653
654 Set<ControllerInfo> newControllers = new HashSet<>(controllers);
655 List<Controller> removeControllers = new ArrayList<>();
656 oldControllers.forEach(controller -> {
657 ControllerInfo controllerInfo = new ControllerInfo((String) controller.getTargetColumn().data());
658 if (newControllers.contains(controllerInfo)) {
659 newControllers.remove(controllerInfo);
660 newControllerUuids.add(controller.getRow().uuid());
661 } else {
662 removeControllers.add(controller);
663 }
664 });
665 OvsdbRowStore controllerRowStore = getRowStore(OvsdbConstant.DATABASENAME,
666 OvsdbConstant.CONTROLLER);
667 if (controllerRowStore == null) {
668 log.debug("There is no controller table");
669 return;
670 }
671
andreaed976a42015-10-05 14:38:25 -0700672 removeControllers.forEach(c -> deleteConfig(OvsdbConstant.CONTROLLER, "_uuid", c.getRow().uuid().value(),
673 OvsdbConstant.BRIDGE, "controller"));
674
675 newControllers.stream().map(c -> {
676 Controller controller = (Controller) TableGenerator
677 .createTable(dbSchema, OvsdbTable.CONTROLLER);
678 controller.setTarget(c.target());
679 return controller;
680 }).forEach(c -> {
andreaed976a42015-10-05 14:38:25 -0700681 String uuid = insertConfig(OvsdbConstant.CONTROLLER, "_uuid",
682 OvsdbConstant.BRIDGE, "controller", bridgeUuid.value(),
683 c.getRow());
Jonathan Hart51539b82015-10-29 09:53:04 -0700684 newControllerUuids.add(Uuid.uuid(uuid));
andreaed976a42015-10-05 14:38:25 -0700685
686 });
687
688 OvsdbRowStore rowStore = getRowStore(OvsdbConstant.DATABASENAME,
689 OvsdbConstant.BRIDGE);
690 if (rowStore == null) {
691 log.debug("There is no bridge table");
692 return;
693 }
694
695 Row bridgeRow = rowStore.getRow(bridgeUuid.value());
696 Bridge bridge = (Bridge) TableGenerator.getTable(dbSchema, bridgeRow, OvsdbTable.BRIDGE);
697 bridge.setController(OvsdbSet.ovsdbSet(newControllerUuids));
698 updateConfig(OvsdbConstant.BRIDGE, "_uuid", bridgeUuid.value(), bridge.getRow());
andreaed976a42015-10-05 14:38:25 -0700699 }
700
andreaed976a42015-10-05 14:38:25 -0700701 @Override
702 public void setControllersWithDeviceId(DeviceId deviceId, List<ControllerInfo> controllers) {
Jonathan Hart51539b82015-10-29 09:53:04 -0700703 setControllersWithUuid(getBridgeUuid(deviceId), controllers);
andreaed976a42015-10-05 14:38:25 -0700704 }
705
Sho SHIMIZUe4efe452015-08-26 15:06:55 -0700706 @Override
707 public void dropBridge(String bridgeName) {
Jonathan Hart51539b82015-10-29 09:53:04 -0700708 String bridgeUuid = getBridgeUuid(bridgeName);
709 if (bridgeUuid == null) {
Sho SHIMIZUe4efe452015-08-26 15:06:55 -0700710 log.warn("Could not find bridge in node", nodeId.getIpAddress());
711 return;
712 }
Jonathan Hart51539b82015-10-29 09:53:04 -0700713 deleteConfig(OvsdbConstant.BRIDGE, "_uuid", bridgeUuid,
andreaed976a42015-10-05 14:38:25 -0700714 OvsdbConstant.DATABASENAME, "bridges");
Sho SHIMIZUe4efe452015-08-26 15:06:55 -0700715 }
716
717 @Override
Hyunsun Moon646d8c42015-10-08 20:32:44 -0700718 public boolean createTunnel(String bridgeName, String portName, String tunnelType, Map<String, String> options) {
719
720 String bridgeUuid = getBridgeUuid(bridgeName);
721 if (bridgeUuid == null) {
722 log.warn("Couldn't find bridge {} in {}", bridgeName, nodeId.getIpAddress());
723 return false;
724 }
725
726 if (getPortUuid(portName, bridgeUuid) != null) {
727 log.warn("Port {} already exists", portName);
728 // remove existing one and re-create?
729 return false;
730 }
731
732 ArrayList<Operation> operations = Lists.newArrayList();
733 DatabaseSchema dbSchema = schema.get(OvsdbConstant.DATABASENAME);
734
735 // insert a new port to the port table
736 Port port = (Port) TableGenerator.createTable(dbSchema, OvsdbTable.PORT);
737 port.setName(portName);
738 Insert portInsert = new Insert(dbSchema.getTableSchema("Port"), "Port", port.getRow());
Jonathan Hart51539b82015-10-29 09:53:04 -0700739 portInsert.getRow().put("interfaces", Uuid.uuid("Interface"));
Hyunsun Moon646d8c42015-10-08 20:32:44 -0700740 operations.add(portInsert);
741
742 // update the bridge table
Jonathan Hart51539b82015-10-29 09:53:04 -0700743 Condition condition = ConditionUtil.isEqual("_uuid", Uuid.uuid(bridgeUuid));
744 Mutation mutation = MutationUtil.insert("ports", Uuid.uuid("Port"));
Hyunsun Moon646d8c42015-10-08 20:32:44 -0700745 List<Condition> conditions = new ArrayList<>(Arrays.asList(condition));
746 List<Mutation> mutations = new ArrayList<>(Arrays.asList(mutation));
747 operations.add(new Mutate(dbSchema.getTableSchema("Bridge"), conditions, mutations));
748
749 // insert a tunnel interface
750 Interface intf = (Interface) TableGenerator.createTable(dbSchema, OvsdbTable.INTERFACE);
751 intf.setName(portName);
752 intf.setType(tunnelType);
753 intf.setOptions(options);
754 Insert intfInsert = new Insert(dbSchema.getTableSchema("Interface"), "Interface", intf.getRow());
755 operations.add(intfInsert);
756
757 transactConfig(OvsdbConstant.DATABASENAME, operations);
758 return true;
759 }
760
761 @Override
Sho SHIMIZUe4efe452015-08-26 15:06:55 -0700762 public void dropTunnel(IpAddress srcIp, IpAddress dstIp) {
763 String bridgeName = OvsdbConstant.INTEGRATION_BRIDGE;
764 String portName = getTunnelName(OvsdbConstant.TYPEVXLAN, dstIp);
765 String bridgeUuid = getBridgeUuid(OvsdbConstant.INTEGRATION_BRIDGE);
766 if (bridgeUuid == null) {
767 log.warn("Could not find bridge {} in {}", bridgeName,
768 nodeId.getIpAddress());
769 return;
770 }
771
Jonathan Hart51539b82015-10-29 09:53:04 -0700772 String portUuid = getPortUuid(portName, bridgeUuid);
773 if (portUuid != null) {
Sho SHIMIZUe4efe452015-08-26 15:06:55 -0700774 log.info("Delete tunnel");
Jonathan Hart51539b82015-10-29 09:53:04 -0700775 deleteConfig(OvsdbConstant.PORT, "_uuid", portUuid,
andreaed976a42015-10-05 14:38:25 -0700776 OvsdbConstant.BRIDGE, "ports");
Sho SHIMIZUe4efe452015-08-26 15:06:55 -0700777 }
778
779 return;
780 }
781
782 /**
783 * Delete transact config.
784 *
andreaed976a42015-10-05 14:38:25 -0700785 * @param childTableName child table name
786 * @param childColumnName child column name
787 * @param childUuid child row uuid
788 * @param parentTableName parent table name
Sho SHIMIZUe4efe452015-08-26 15:06:55 -0700789 * @param parentColumnName parent column
Sho SHIMIZUe4efe452015-08-26 15:06:55 -0700790 */
791 private void deleteConfig(String childTableName, String childColumnName,
andreaed976a42015-10-05 14:38:25 -0700792 String childUuid, String parentTableName,
793 String parentColumnName) {
Sho SHIMIZUe4efe452015-08-26 15:06:55 -0700794 DatabaseSchema dbSchema = schema.get(OvsdbConstant.DATABASENAME);
795 TableSchema childTableSchema = dbSchema.getTableSchema(childTableName);
796
797 ArrayList<Operation> operations = Lists.newArrayList();
798 if (parentTableName != null && parentColumnName != null) {
799 TableSchema parentTableSchema = dbSchema
800 .getTableSchema(parentTableName);
801 ColumnSchema parentColumnSchema = parentTableSchema
802 .getColumnSchema(parentColumnName);
803 List<Mutation> mutations = Lists.newArrayList();
804 Mutation mutation = MutationUtil.delete(parentColumnSchema.name(),
Jonathan Hart51539b82015-10-29 09:53:04 -0700805 Uuid.uuid(childUuid));
Sho SHIMIZUe4efe452015-08-26 15:06:55 -0700806 mutations.add(mutation);
807 List<Condition> conditions = Lists.newArrayList();
808 Condition condition = ConditionUtil.includes(parentColumnName,
Jonathan Hart51539b82015-10-29 09:53:04 -0700809 Uuid.uuid(childUuid));
Sho SHIMIZUe4efe452015-08-26 15:06:55 -0700810 conditions.add(condition);
811 Mutate op = new Mutate(parentTableSchema, conditions, mutations);
812 operations.add(op);
813 }
814
815 List<Condition> conditions = Lists.newArrayList();
Jonathan Hart51539b82015-10-29 09:53:04 -0700816 Condition condition = ConditionUtil.isEqual(childColumnName, Uuid.uuid(childUuid));
Sho SHIMIZUe4efe452015-08-26 15:06:55 -0700817 conditions.add(condition);
818 Delete del = new Delete(childTableSchema, conditions);
819 operations.add(del);
820 transactConfig(OvsdbConstant.DATABASENAME, operations);
821
822 return;
823 }
824
825 /**
826 * Update transact config.
827 *
andreaed976a42015-10-05 14:38:25 -0700828 * @param tableName table name
Sho SHIMIZUe4efe452015-08-26 15:06:55 -0700829 * @param columnName column name
andreaed976a42015-10-05 14:38:25 -0700830 * @param uuid uuid
831 * @param row the config data
Sho SHIMIZUe4efe452015-08-26 15:06:55 -0700832 */
833 private void updateConfig(String tableName, String columnName, String uuid,
andreaed976a42015-10-05 14:38:25 -0700834 Row row) {
Sho SHIMIZUe4efe452015-08-26 15:06:55 -0700835 DatabaseSchema dbSchema = schema.get(OvsdbConstant.DATABASENAME);
836 TableSchema tableSchema = dbSchema.getTableSchema(tableName);
837
838 List<Condition> conditions = Lists.newArrayList();
Jonathan Hart51539b82015-10-29 09:53:04 -0700839 Condition condition = ConditionUtil.isEqual(columnName, Uuid.uuid(uuid));
Sho SHIMIZUe4efe452015-08-26 15:06:55 -0700840 conditions.add(condition);
841
842 Update update = new Update(tableSchema, row, conditions);
843
844 ArrayList<Operation> operations = Lists.newArrayList();
845 operations.add(update);
846
847 transactConfig(OvsdbConstant.DATABASENAME, operations);
848 }
849
850 /**
851 * Insert transact config.
852 *
andreaed976a42015-10-05 14:38:25 -0700853 * @param childTableName child table name
854 * @param childColumnName child column name
855 * @param parentTableName parent table name
Sho SHIMIZUe4efe452015-08-26 15:06:55 -0700856 * @param parentColumnName parent column
andreaed976a42015-10-05 14:38:25 -0700857 * @param parentUuid parent uuid
858 * @param row the config data
Sho SHIMIZUe4efe452015-08-26 15:06:55 -0700859 * @return uuid, empty if no uuid is find
860 */
861 private String insertConfig(String childTableName, String childColumnName,
andreaed976a42015-10-05 14:38:25 -0700862 String parentTableName, String parentColumnName,
863 String parentUuid, Row row) {
Sho SHIMIZUe4efe452015-08-26 15:06:55 -0700864 DatabaseSchema dbSchema = schema.get(OvsdbConstant.DATABASENAME);
865 TableSchema tableSchema = dbSchema.getTableSchema(childTableName);
866
Sho SHIMIZUff18f8c2016-03-11 14:43:53 -0800867 Insert insert = new Insert(tableSchema, childTableName, row);
Sho SHIMIZUe4efe452015-08-26 15:06:55 -0700868
869 ArrayList<Operation> operations = Lists.newArrayList();
870 operations.add(insert);
871
872 if (parentTableName != null && parentColumnName != null) {
873 TableSchema parentTableSchema = dbSchema
874 .getTableSchema(parentTableName);
875 ColumnSchema parentColumnSchema = parentTableSchema
876 .getColumnSchema(parentColumnName);
877
878 List<Mutation> mutations = Lists.newArrayList();
879 Mutation mutation = MutationUtil.insert(parentColumnSchema.name(),
Sho SHIMIZUff18f8c2016-03-11 14:43:53 -0800880 Uuid.uuid(childTableName));
Sho SHIMIZUe4efe452015-08-26 15:06:55 -0700881 mutations.add(mutation);
882
883 List<Condition> conditions = Lists.newArrayList();
Ray Milkey676249c2015-12-18 09:27:03 -0800884 Condition condition = ConditionUtil.isEqual("_uuid",
Jonathan Hart51539b82015-10-29 09:53:04 -0700885 Uuid.uuid(parentUuid));
Sho SHIMIZUe4efe452015-08-26 15:06:55 -0700886 conditions.add(condition);
887
888 Mutate op = new Mutate(parentTableSchema, conditions, mutations);
889 operations.add(op);
890 }
891 if (childTableName.equalsIgnoreCase(OvsdbConstant.PORT)) {
892 log.info("Handle port insert");
893 Insert intfInsert = handlePortInsertTable(OvsdbConstant.INTERFACE,
andreaed976a42015-10-05 14:38:25 -0700894 row);
Sho SHIMIZUe4efe452015-08-26 15:06:55 -0700895
896 if (intfInsert != null) {
897 operations.add(intfInsert);
898 }
899
900 Insert ins = (Insert) operations.get(0);
901 ins.getRow().put("interfaces",
Jonathan Hart51539b82015-10-29 09:53:04 -0700902 Uuid.uuid(OvsdbConstant.INTERFACE));
Sho SHIMIZUe4efe452015-08-26 15:06:55 -0700903 }
904
905 List<OperationResult> results;
906 try {
907 results = transactConfig(OvsdbConstant.DATABASENAME, operations)
908 .get();
909
910 return results.get(0).getUuid().value();
911 } catch (InterruptedException e) {
912 log.warn("Interrupted while waiting to get result");
913 Thread.currentThread().interrupt();
914 } catch (ExecutionException e) {
915 log.error("Exception thrown while to get result");
916 }
917
918 return null;
919 }
920
921 /**
922 * Handles port insert.
923 *
924 * @param tableName ovsdb table interface
andreaed976a42015-10-05 14:38:25 -0700925 * @param portRow row of port
Sho SHIMIZUe4efe452015-08-26 15:06:55 -0700926 * @return insert, empty if null
927 */
928 private Insert handlePortInsertTable(String tableName, Row portRow) {
929 DatabaseSchema dbSchema = schema.get(OvsdbConstant.DATABASENAME);
930
931 TableSchema portTableSchema = dbSchema
932 .getTableSchema(OvsdbConstant.PORT);
933 ColumnSchema portColumnSchema = portTableSchema.getColumnSchema("name");
934
935 String portName = (String) portRow.getColumn(portColumnSchema.name()).data();
936
937 Interface inf = (Interface) TableGenerator
938 .createTable(dbSchema, OvsdbTable.INTERFACE);
939
940 inf.setName(portName);
941
942 TableSchema intfTableSchema = dbSchema
943 .getTableSchema(OvsdbConstant.INTERFACE);
944 Insert insert = new Insert(intfTableSchema, OvsdbConstant.INTERFACE,
945 inf.getRow());
946 return insert;
947 }
948
949 /**
950 * Gets tunnel name.
951 *
952 * @param tunnelType
andreaed976a42015-10-05 14:38:25 -0700953 * @param dstIp the remote ip address
Sho SHIMIZUe4efe452015-08-26 15:06:55 -0700954 * @return tunnel name
955 */
956 private String getTunnelName(String tunnelType, IpAddress dstIp) {
957 return tunnelType + "-" + dstIp.toString();
958 }
959
960 @Override
961 public ListenableFuture<DatabaseSchema> getOvsdbSchema(String dbName) {
962 if (dbName == null) {
963 return null;
964 }
965 DatabaseSchema databaseSchema = schema.get(dbName);
966 if (databaseSchema == null) {
967 List<String> dbNames = new ArrayList<String>();
968 dbNames.add(dbName);
969 Function<JsonNode, DatabaseSchema> rowFunction = new Function<JsonNode, DatabaseSchema>() {
970 @Override
971 public DatabaseSchema apply(JsonNode input) {
Hyunsun Moon5fb20a52015-09-25 17:02:33 -0700972 log.info("Get ovsdb database schema {}", dbName);
Sho SHIMIZUe4efe452015-08-26 15:06:55 -0700973 DatabaseSchema dbSchema = FromJsonUtil
974 .jsonNodeToDbSchema(dbName, input);
975 if (dbSchema == null) {
976 log.debug("Get ovsdb database schema error");
977 return null;
978 }
979 schema.put(dbName, dbSchema);
980
981 return dbSchema;
982 }
983 };
984
985 ListenableFuture<JsonNode> input = getSchema(dbNames);
986 if (input != null) {
987 return Futures.transform(input, rowFunction);
988 }
989 return null;
990 } else {
991 return Futures.immediateFuture(databaseSchema);
992 }
993 }
994
995 @Override
996 public ListenableFuture<TableUpdates> monitorTables(String dbName, String id) {
997 if (dbName == null) {
998 return null;
999 }
1000 DatabaseSchema dbSchema = schema.get(dbName);
1001 if (dbSchema != null) {
1002 Function<JsonNode, TableUpdates> rowFunction = new Function<JsonNode, TableUpdates>() {
1003 @Override
1004 public TableUpdates apply(JsonNode input) {
1005 log.info("Get table updates");
1006 TableUpdates updates = FromJsonUtil
1007 .jsonNodeToTableUpdates(input, dbSchema);
1008 if (updates == null) {
1009 log.debug("Get table updates error");
1010 return null;
1011 }
1012 return updates;
1013 }
1014 };
1015 return Futures.transform(monitor(dbSchema, id), rowFunction);
1016 }
1017 return null;
1018 }
1019
1020 @Override
1021 public ListenableFuture<List<OperationResult>> transactConfig(String dbName,
1022 List<Operation> operations) {
1023 if (dbName == null) {
1024 return null;
1025 }
1026 DatabaseSchema dbSchema = schema.get(dbName);
1027 if (dbSchema != null) {
andreaed976a42015-10-05 14:38:25 -07001028 Function<List<JsonNode>, List<OperationResult>> rowFunction = (input -> {
1029 log.info("Get ovsdb operation result");
1030 List<OperationResult> result = FromJsonUtil
1031 .jsonNodeToOperationResult(input, operations);
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001032
andreaed976a42015-10-05 14:38:25 -07001033 if (result == null) {
1034 log.debug("The operation result is null");
1035 return null;
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001036 }
andreaed976a42015-10-05 14:38:25 -07001037 return result;
1038 });
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001039 return Futures.transform(transact(dbSchema, operations),
1040 rowFunction);
1041 }
1042 return null;
1043 }
1044
1045 @Override
1046 public ListenableFuture<JsonNode> getSchema(List<String> dbnames) {
1047 String id = java.util.UUID.randomUUID().toString();
1048 String getSchemaString = JsonRpcWriterUtil.getSchemaStr(id, dbnames);
1049
1050 SettableFuture<JsonNode> sf = SettableFuture.create();
1051 requestResult.put(id, sf);
1052 requestMethod.put(id, "getSchema");
1053
1054 channel.writeAndFlush(getSchemaString);
1055 return sf;
1056
1057 }
1058
1059 @Override
1060 public ListenableFuture<List<String>> echo() {
1061 String id = java.util.UUID.randomUUID().toString();
1062 String echoString = JsonRpcWriterUtil.echoStr(id);
1063
1064 SettableFuture<List<String>> sf = SettableFuture.create();
1065 requestResult.put(id, sf);
1066 requestMethod.put(id, "echo");
1067
1068 channel.writeAndFlush(echoString);
1069 return sf;
1070
1071 }
1072
1073 @Override
1074 public ListenableFuture<JsonNode> monitor(DatabaseSchema dbSchema,
1075 String monitorId) {
1076 String id = java.util.UUID.randomUUID().toString();
1077 String monitorString = JsonRpcWriterUtil.monitorStr(id, monitorId,
1078 dbSchema);
1079
1080 SettableFuture<JsonNode> sf = SettableFuture.create();
1081 requestResult.put(id, sf);
1082 requestMethod.put(id, "monitor");
1083
1084 channel.writeAndFlush(monitorString);
1085 return sf;
1086
1087 }
1088
1089 @Override
1090 public ListenableFuture<List<String>> listDbs() {
1091 String id = java.util.UUID.randomUUID().toString();
1092 String listDbsString = JsonRpcWriterUtil.listDbsStr(id);
1093
1094 SettableFuture<List<String>> sf = SettableFuture.create();
1095 requestResult.put(id, sf);
1096 requestMethod.put(id, "listDbs");
1097
1098 channel.writeAndFlush(listDbsString);
1099 return sf;
1100
1101 }
1102
1103 @Override
1104 public ListenableFuture<List<JsonNode>> transact(DatabaseSchema dbSchema,
1105 List<Operation> operations) {
1106 String id = java.util.UUID.randomUUID().toString();
1107 String transactString = JsonRpcWriterUtil.transactStr(id, dbSchema,
1108 operations);
1109
1110 SettableFuture<List<JsonNode>> sf = SettableFuture.create();
1111 requestResult.put(id, sf);
1112 requestMethod.put(id, "transact");
1113
1114 channel.writeAndFlush(transactString);
1115 return sf;
1116
1117 }
1118
andreaed976a42015-10-05 14:38:25 -07001119 @SuppressWarnings({"rawtypes", "unchecked"})
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001120 @Override
1121 public void processResult(JsonNode response) {
1122 log.debug("Handle result");
1123 String requestId = response.get("id").asText();
1124 SettableFuture sf = requestResult.get(requestId);
1125 if (sf == null) {
1126 log.debug("No such future to process");
1127 return;
1128 }
1129 String methodName = requestMethod.get(requestId);
1130
1131 Object result;
1132 result = FromJsonUtil.jsonResultParser(response, methodName);
1133
1134 sf.set(result);
1135 return;
1136 }
1137
1138 @Override
1139 public void processRequest(JsonNode requestJson) {
1140 log.debug("Handle request");
1141 if (requestJson.get("method").asText().equalsIgnoreCase("echo")) {
1142 log.debug("handle echo request");
1143
1144 String replyString = FromJsonUtil.getEchoRequestStr(requestJson);
1145 channel.writeAndFlush(replyString);
1146
1147 return;
1148 } else {
1149 FromJsonUtil
1150 .jsonCallbackRequestParser(requestJson, monitorCallBack);
1151 return;
1152 }
1153 }
1154
1155 @Override
1156 public void setCallback(Callback monitorCallback) {
1157 this.monitorCallBack = monitorCallback;
1158 }
1159
1160 @Override
1161 public Set<OvsdbTunnel> getTunnels() {
1162 return ovsdbTunnels;
1163 }
1164
1165 @Override
1166 public Set<OvsdbBridge> getBridges() {
1167 Set<OvsdbBridge> ovsdbBridges = new HashSet<OvsdbBridge>();
1168 OvsdbTableStore tableStore = getTableStore(OvsdbConstant.DATABASENAME);
1169 if (tableStore == null) {
1170 return null;
1171 }
1172 OvsdbRowStore rowStore = tableStore.getRows(OvsdbConstant.BRIDGE);
1173 if (rowStore == null) {
1174 return null;
1175 }
1176 ConcurrentMap<String, Row> rows = rowStore.getRowStore();
1177 for (String uuid : rows.keySet()) {
1178 Row row = getRow(OvsdbConstant.DATABASENAME, OvsdbConstant.BRIDGE,
1179 uuid);
1180 OvsdbBridge ovsdbBridge = getOvsdbBridge(row);
1181 if (ovsdbBridge != null) {
1182 ovsdbBridges.add(ovsdbBridge);
1183 }
1184 }
1185 return ovsdbBridges;
1186 }
1187
1188 @Override
andreaed976a42015-10-05 14:38:25 -07001189 public Set<ControllerInfo> getControllers(DeviceId openflowDeviceId) {
Jonathan Hart51539b82015-10-29 09:53:04 -07001190 Uuid bridgeUuid = getBridgeUuid(openflowDeviceId);
andreaed976a42015-10-05 14:38:25 -07001191 if (bridgeUuid == null) {
1192 log.warn("bad bridge Uuid");
1193 return null;
1194 }
1195 List<Controller> controllers = getControllers(bridgeUuid);
1196 if (controllers == null) {
1197 log.warn("bad list of controllers");
1198 return null;
1199 }
1200 return controllers.stream().
1201 map(controller -> new ControllerInfo(
1202 (String) controller.getTargetColumn()
1203 .data())).collect(Collectors.toSet());
1204 }
1205
Jonathan Hart51539b82015-10-29 09:53:04 -07001206 private List<Controller> getControllers(Uuid bridgeUuid) {
andreaed976a42015-10-05 14:38:25 -07001207 DatabaseSchema dbSchema = schema.get(OvsdbConstant.DATABASENAME);
1208 if (dbSchema == null) {
1209 return null;
1210 }
1211 OvsdbRowStore rowStore = getRowStore(OvsdbConstant.DATABASENAME,
1212 OvsdbConstant.BRIDGE);
1213 if (rowStore == null) {
1214 log.debug("There is no bridge table");
1215 return null;
1216 }
1217
1218 Row bridgeRow = rowStore.getRow(bridgeUuid.value());
1219 Bridge bridge = (Bridge) TableGenerator.
1220 getTable(dbSchema, bridgeRow, OvsdbTable.BRIDGE);
1221
1222 //FIXME remove log
1223 log.warn("type of controller column", bridge.getControllerColumn()
1224 .data().getClass());
Jonathan Hart51539b82015-10-29 09:53:04 -07001225 Set<Uuid> controllerUuids = (Set<Uuid>) ((OvsdbSet) bridge
andreaed976a42015-10-05 14:38:25 -07001226 .getControllerColumn().data()).set();
1227// Set<String> controllerUuidStrings = (Set<String>) bridge.getControllerColumn().data();
1228
1229 OvsdbRowStore controllerRowStore = getRowStore(OvsdbConstant.DATABASENAME,
1230 OvsdbConstant.CONTROLLER);
1231 if (controllerRowStore == null) {
1232 log.debug("There is no controller table");
1233 return null;
1234 }
1235
1236 List<Controller> ovsdbControllers = new ArrayList<>();
1237 ConcurrentMap<String, Row> controllerTableRows = controllerRowStore.getRowStore();
1238 controllerTableRows.forEach((key, row) -> {
Jonathan Hart51539b82015-10-29 09:53:04 -07001239 if (!controllerUuids.contains(Uuid.uuid(key))) {
andreaed976a42015-10-05 14:38:25 -07001240 return;
1241 }
1242 Controller controller = (Controller) TableGenerator
1243 .getTable(dbSchema, row, OvsdbTable.CONTROLLER);
1244 ovsdbControllers.add(controller);
1245 });
1246 return ovsdbControllers;
1247 }
1248
1249
Jonathan Hart51539b82015-10-29 09:53:04 -07001250 private Uuid getBridgeUuid(DeviceId openflowDeviceId) {
andreaed976a42015-10-05 14:38:25 -07001251 DatabaseSchema dbSchema = schema.get(OvsdbConstant.DATABASENAME);
1252 if (dbSchema == null) {
1253 return null;
1254 }
1255 OvsdbRowStore rowStore = getRowStore(OvsdbConstant.DATABASENAME,
1256 OvsdbConstant.BRIDGE);
1257 if (rowStore == null) {
1258 log.debug("There is no bridge table");
1259 return null;
1260 }
1261
1262 ConcurrentMap<String, Row> bridgeTableRows = rowStore.getRowStore();
Jonathan Hart51539b82015-10-29 09:53:04 -07001263 final AtomicReference<Uuid> uuid = new AtomicReference<>();
andreaed976a42015-10-05 14:38:25 -07001264 for (Map.Entry<String, Row> entry : bridgeTableRows.entrySet()) {
1265 Bridge b = (Bridge) TableGenerator.getTable(dbSchema,
1266 entry.getValue(),
1267 OvsdbTable.BRIDGE);
1268 if (matchesDpid(b, openflowDeviceId)) {
Jonathan Hart51539b82015-10-29 09:53:04 -07001269 uuid.set(Uuid.uuid(entry.getKey()));
andreaed976a42015-10-05 14:38:25 -07001270 break;
1271 }
1272 }
1273 if (uuid.get() == null) {
1274 log.debug("There is no bridge for {}", openflowDeviceId);
1275 }
1276 return uuid.get();
1277
1278 }
1279
1280 private static boolean matchesDpid(Bridge b, DeviceId deviceId) {
1281 String ofDpid = deviceId.toString().replace("of:", "");
1282 Set ofDeviceIds = ((OvsdbSet) b.getDatapathIdColumn().data()).set();
1283 //TODO Set<String>
1284 return ofDeviceIds.contains(ofDpid);
1285 }
1286
1287 @Override
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001288 public Set<OvsdbPort> getPorts() {
1289 Set<OvsdbPort> ovsdbPorts = new HashSet<OvsdbPort>();
1290 OvsdbTableStore tableStore = getTableStore(OvsdbConstant.DATABASENAME);
1291 if (tableStore == null) {
1292 return null;
1293 }
1294 OvsdbRowStore rowStore = tableStore.getRows(OvsdbConstant.INTERFACE);
1295 if (rowStore == null) {
1296 return null;
1297 }
1298 ConcurrentMap<String, Row> rows = rowStore.getRowStore();
1299 for (String uuid : rows.keySet()) {
1300 Row row = getRow(OvsdbConstant.DATABASENAME,
1301 OvsdbConstant.INTERFACE, uuid);
1302 OvsdbPort ovsdbPort = getOvsdbPort(row);
1303 if (ovsdbPort != null) {
1304 ovsdbPorts.add(ovsdbPort);
1305 }
1306 }
1307 return ovsdbPorts;
1308 }
1309
1310 @Override
1311 public DatabaseSchema getDatabaseSchema(String dbName) {
1312 return schema.get(dbName);
1313 }
1314
1315 //Gets ovsdb port.
1316 private OvsdbPort getOvsdbPort(Row row) {
1317 DatabaseSchema dbSchema = getDatabaseSchema(OvsdbConstant.DATABASENAME);
1318 Interface intf = (Interface) TableGenerator
1319 .getTable(dbSchema, row, OvsdbTable.INTERFACE);
1320 if (intf == null) {
1321 return null;
1322 }
1323 long ofPort = getOfPort(intf);
1324 String portName = intf.getName();
1325 if ((ofPort < 0) || (portName == null)) {
1326 return null;
1327 }
1328
1329 OvsdbPort ovsdbPort = new OvsdbPort(new OvsdbPortNumber(ofPort),
1330 new OvsdbPortName(portName));
1331 return ovsdbPort;
1332 }
1333
1334 ////Gets ovsdb bridge.
1335 private OvsdbBridge getOvsdbBridge(Row row) {
1336 DatabaseSchema dbSchema = getDatabaseSchema(OvsdbConstant.DATABASENAME);
1337 Bridge bridge = (Bridge) TableGenerator.getTable(dbSchema, row,
1338 OvsdbTable.BRIDGE);
1339 if (bridge == null) {
1340 return null;
1341 }
1342
1343 OvsdbSet datapathIdSet = (OvsdbSet) bridge.getDatapathIdColumn().data();
1344 @SuppressWarnings("unchecked")
1345 Set<String> datapathIds = datapathIdSet.set();
1346 if (datapathIds == null || datapathIds.size() == 0) {
1347 return null;
1348 }
1349 String datapathId = (String) datapathIds.toArray()[0];
1350 String bridgeName = bridge.getName();
1351 if ((datapathId == null) || (bridgeName == null)) {
1352 return null;
1353 }
1354
1355 OvsdbBridge ovsdbBridge = new OvsdbBridge(new OvsdbBridgeName(bridgeName),
1356 new OvsdbDatapathId(datapathId));
1357 return ovsdbBridge;
1358 }
1359
1360 //Gets ofPort in the interface.
1361 private long getOfPort(Interface intf) {
1362 OvsdbSet ofPortSet = (OvsdbSet) intf.getOpenFlowPortColumn().data();
1363 @SuppressWarnings("unchecked")
1364 Set<Integer> ofPorts = ofPortSet.set();
1365 while (ofPorts == null || ofPorts.size() <= 0) {
1366 log.debug("The ofport is null in {}", intf.getName());
1367 return -1;
1368 }
1369 // return (long) ofPorts.toArray()[0];
1370 Iterator<Integer> it = ofPorts.iterator();
1371 return Long.parseLong(it.next().toString());
1372 }
CNluciusa66c3972015-09-06 20:31:29 +08001373
1374 @Override
1375 public Set<OvsdbPort> getLocalPorts(Iterable<String> ifaceids) {
1376 Set<OvsdbPort> ovsdbPorts = new HashSet<OvsdbPort>();
1377 OvsdbTableStore tableStore = getTableStore(OvsdbConstant.DATABASENAME);
1378 if (tableStore == null) {
1379 return null;
1380 }
1381 OvsdbRowStore rowStore = tableStore.getRows(OvsdbConstant.INTERFACE);
1382 if (rowStore == null) {
1383 return null;
1384 }
1385 ConcurrentMap<String, Row> rows = rowStore.getRowStore();
1386 for (String uuid : rows.keySet()) {
1387 Row row = getRow(OvsdbConstant.DATABASENAME,
1388 OvsdbConstant.INTERFACE, uuid);
1389 DatabaseSchema dbSchema = getDatabaseSchema(OvsdbConstant.DATABASENAME);
1390 Interface intf = (Interface) TableGenerator
1391 .getTable(dbSchema, row, OvsdbTable.INTERFACE);
1392 if (intf == null || getIfaceid(intf) == null) {
1393 continue;
1394 }
1395 String portName = intf.getName();
1396 Set<String> ifaceidSet = Sets.newHashSet(ifaceids);
1397 if (portName.startsWith("vxlan")
1398 || !ifaceidSet.contains(getIfaceid(intf))) {
1399 continue;
1400 }
1401 long ofPort = getOfPort(intf);
1402 if ((ofPort < 0) || (portName == null)) {
1403 continue;
1404 }
1405
1406 OvsdbPort ovsdbPort = new OvsdbPort(new OvsdbPortNumber(ofPort),
1407 new OvsdbPortName(portName));
1408 if (ovsdbPort != null) {
1409 ovsdbPorts.add(ovsdbPort);
1410 }
1411 }
1412 return ovsdbPorts;
1413 }
1414
1415 private String getIfaceid(Interface intf) {
1416 OvsdbMap ovsdbMap = (OvsdbMap) intf.getExternalIdsColumn().data();
1417 @SuppressWarnings("unchecked")
1418 Map<String, String> externalIds = ovsdbMap.map();
1419 if (externalIds.isEmpty()) {
1420 log.warn("The external_ids is null");
1421 return null;
1422 }
1423 String ifaceid = externalIds
1424 .get(OvsdbConstant.EXTERNAL_ID_INTERFACE_ID);
1425 if (ifaceid == null) {
1426 log.warn("The ifaceid is null");
1427 return null;
1428 }
1429 return ifaceid;
1430 }
Hyunsun Moon5fb20a52015-09-25 17:02:33 -07001431
1432 @Override
1433 public void disconnect() {
1434 channel.disconnect();
1435 this.agent.removeConnectedNode(nodeId);
1436 }
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001437}