blob: c60386324f57df85324a2e62edb71a88fc559229 [file] [log] [blame]
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001/*
2 * Copyright 2015 Open Networking Laboratory
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16package org.onosproject.ovsdb.controller.driver;
17
andreaed976a42015-10-05 14:38:25 -070018import com.fasterxml.jackson.databind.JsonNode;
19import com.google.common.base.Function;
Brian O'Connor6ee8aa32015-10-09 16:07:42 -070020import com.google.common.collect.ImmutableList;
andreaed976a42015-10-05 14:38:25 -070021import com.google.common.collect.Lists;
22import com.google.common.collect.Maps;
23import com.google.common.collect.Sets;
24import com.google.common.util.concurrent.Futures;
25import com.google.common.util.concurrent.ListenableFuture;
26import com.google.common.util.concurrent.SettableFuture;
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;
46import org.onosproject.ovsdb.rfc.jsonrpc.Callback;
47import org.onosproject.ovsdb.rfc.message.OperationResult;
48import org.onosproject.ovsdb.rfc.message.TableUpdates;
49import org.onosproject.ovsdb.rfc.notation.Condition;
50import org.onosproject.ovsdb.rfc.notation.Mutation;
CNluciusa66c3972015-09-06 20:31:29 +080051import org.onosproject.ovsdb.rfc.notation.OvsdbMap;
Sho SHIMIZUe4efe452015-08-26 15:06:55 -070052import org.onosproject.ovsdb.rfc.notation.OvsdbSet;
53import org.onosproject.ovsdb.rfc.notation.Row;
54import org.onosproject.ovsdb.rfc.notation.UUID;
55import org.onosproject.ovsdb.rfc.operations.Delete;
56import org.onosproject.ovsdb.rfc.operations.Insert;
57import org.onosproject.ovsdb.rfc.operations.Mutate;
58import org.onosproject.ovsdb.rfc.operations.Operation;
59import org.onosproject.ovsdb.rfc.operations.Update;
60import org.onosproject.ovsdb.rfc.schema.ColumnSchema;
61import org.onosproject.ovsdb.rfc.schema.DatabaseSchema;
62import org.onosproject.ovsdb.rfc.schema.TableSchema;
63import org.onosproject.ovsdb.rfc.table.Bridge;
64import org.onosproject.ovsdb.rfc.table.Controller;
65import org.onosproject.ovsdb.rfc.table.Interface;
66import org.onosproject.ovsdb.rfc.table.OvsdbTable;
67import org.onosproject.ovsdb.rfc.table.Port;
68import org.onosproject.ovsdb.rfc.table.TableGenerator;
69import org.onosproject.ovsdb.rfc.utils.ConditionUtil;
70import org.onosproject.ovsdb.rfc.utils.FromJsonUtil;
71import org.onosproject.ovsdb.rfc.utils.JsonRpcWriterUtil;
72import org.onosproject.ovsdb.rfc.utils.MutationUtil;
73import org.slf4j.Logger;
74import org.slf4j.LoggerFactory;
75
andreaed976a42015-10-05 14:38:25 -070076import java.net.InetSocketAddress;
77import java.util.ArrayList;
Hyunsun Moon646d8c42015-10-08 20:32:44 -070078import java.util.Arrays;
79import java.util.HashMap;
andreaed976a42015-10-05 14:38:25 -070080import java.util.HashSet;
81import java.util.Iterator;
82import java.util.List;
83import java.util.Map;
84import java.util.Set;
85import java.util.concurrent.ConcurrentMap;
86import java.util.concurrent.ExecutionException;
87import java.util.concurrent.atomic.AtomicReference;
88import java.util.stream.Collectors;
Sho SHIMIZUe4efe452015-08-26 15:06:55 -070089
90/**
91 * An representation of an ovsdb client.
92 */
93public class DefaultOvsdbClient
94 implements OvsdbProviderService, OvsdbClientService {
95
96 private final Logger log = LoggerFactory
97 .getLogger(DefaultOvsdbClient.class);
98
99 private Channel channel;
100
101 private OvsdbAgent agent;
102 private boolean connected;
103 private OvsdbNodeId nodeId;
104 private Callback monitorCallBack;
105
106 private OvsdbStore ovsdbStore = new OvsdbStore();
107
108 private final Map<String, String> requestMethod = Maps.newHashMap();
109 private final Map<String, SettableFuture<? extends Object>> requestResult = Maps
110 .newHashMap();
111
112 private final Map<String, DatabaseSchema> schema = Maps.newHashMap();
113 private final Set<OvsdbTunnel> ovsdbTunnels = new HashSet<OvsdbTunnel>();
114
115 /**
116 * Creates an OvsdbClient.
117 *
118 * @param nodeId ovsdb node id
119 */
120 public DefaultOvsdbClient(OvsdbNodeId nodeId) {
121 this.nodeId = nodeId;
122 }
123
124 @Override
125 public OvsdbNodeId nodeId() {
126 return nodeId;
127 }
128
129 @Override
130 public void setAgent(OvsdbAgent agent) {
131 if (this.agent == null) {
132 this.agent = agent;
133 }
134 }
135
136 @Override
137 public void setChannel(Channel channel) {
138 this.channel = channel;
139 }
140
141 @Override
142 public void setConnection(boolean connected) {
143 this.connected = connected;
144 }
145
146 @Override
147 public boolean isConnected() {
148 return this.connected;
149 }
150
151 @Override
152 public void nodeAdded() {
153 this.agent.addConnectedNode(nodeId, this);
154 }
155
156 @Override
157 public void nodeRemoved() {
158 this.agent.removeConnectedNode(nodeId);
159 channel.disconnect();
160 }
161
162 /**
163 * Gets the ovsdb table store.
164 *
165 * @param dbName the ovsdb database name
166 * @return ovsTableStore, empty if table store is find
167 */
168 private OvsdbTableStore getTableStore(String dbName) {
169 if (ovsdbStore == null) {
170 return null;
171 }
172 return ovsdbStore.getOvsdbTableStore(dbName);
173 }
174
175 /**
176 * Gets the ovsdb row store.
177 *
andreaed976a42015-10-05 14:38:25 -0700178 * @param dbName the ovsdb database name
Sho SHIMIZUe4efe452015-08-26 15:06:55 -0700179 * @param tableName the ovsdb table name
Hyunsun Moon6125c612015-10-15 10:54:44 -0700180 * @return ovsRowStore, empty store if no rows exist in the table
Sho SHIMIZUe4efe452015-08-26 15:06:55 -0700181 */
182 private OvsdbRowStore getRowStore(String dbName, String tableName) {
183 OvsdbTableStore tableStore = getTableStore(dbName);
184 if (tableStore == null) {
185 return null;
186 }
Hyunsun Moon6125c612015-10-15 10:54:44 -0700187
188 OvsdbRowStore rowStore = tableStore.getRows(tableName);
189 if (rowStore == null) {
190 rowStore = new OvsdbRowStore();
191 }
192 return rowStore;
Sho SHIMIZUe4efe452015-08-26 15:06:55 -0700193 }
194
195 /**
196 * Gets the ovsdb row.
197 *
andreaed976a42015-10-05 14:38:25 -0700198 * @param dbName the ovsdb database name
Sho SHIMIZUe4efe452015-08-26 15:06:55 -0700199 * @param tableName the ovsdb table name
andreaed976a42015-10-05 14:38:25 -0700200 * @param uuid the key of the row
Sho SHIMIZUe4efe452015-08-26 15:06:55 -0700201 * @return row, empty if row is find
202 */
203 @Override
204 public Row getRow(String dbName, String tableName, String uuid) {
205 OvsdbTableStore tableStore = getTableStore(dbName);
206 if (tableStore == null) {
207 return null;
208 }
209 OvsdbRowStore rowStore = tableStore.getRows(tableName);
210 if (rowStore == null) {
211 return null;
212 }
213 return rowStore.getRow(uuid);
214 }
215
216 @Override
217 public void removeRow(String dbName, String tableName, String uuid) {
218 OvsdbTableStore tableStore = getTableStore(dbName);
219 if (tableStore == null) {
220 return;
221 }
222 OvsdbRowStore rowStore = tableStore.getRows(tableName);
223 if (rowStore == null) {
224 return;
225 }
226 rowStore.deleteRow(uuid);
227 }
228
229 @Override
230 public void updateOvsdbStore(String dbName, String tableName, String uuid,
231 Row row) {
232 OvsdbTableStore tableStore = ovsdbStore.getOvsdbTableStore(dbName);
233 if (tableStore == null) {
234 tableStore = new OvsdbTableStore();
235 }
236 OvsdbRowStore rowStore = tableStore.getRows(tableName);
237 if (rowStore == null) {
238 rowStore = new OvsdbRowStore();
239 }
240 rowStore.insertRow(uuid, row);
241 tableStore.createOrUpdateTable(tableName, rowStore);
242 ovsdbStore.createOrUpdateOvsdbStore(dbName, tableStore);
243 }
244
245 @Override
246 public String getPortUuid(String portName, String bridgeUuid) {
247 DatabaseSchema dbSchema = schema.get(OvsdbConstant.DATABASENAME);
248
249 Row bridgeRow = getRow(OvsdbConstant.DATABASENAME,
250 OvsdbConstant.BRIDGE, bridgeUuid);
251
252 Bridge bridge = (Bridge) TableGenerator.getTable(dbSchema, bridgeRow,
253 OvsdbTable.BRIDGE);
254 if (bridge != null) {
255 OvsdbSet setPorts = (OvsdbSet) bridge.getPortsColumn().data();
256 @SuppressWarnings("unchecked")
257 Set<UUID> ports = setPorts.set();
258 if (ports == null || ports.size() == 0) {
259 log.warn("The port uuid is null");
260 return null;
261 }
262
263 for (UUID uuid : ports) {
264 Row portRow = getRow(OvsdbConstant.DATABASENAME,
265 OvsdbConstant.PORT, uuid.value());
266 Port port = (Port) TableGenerator.getTable(dbSchema, portRow,
267 OvsdbTable.PORT);
268 if (port != null && portName.equalsIgnoreCase(port.getName())) {
269 return uuid.value();
270 }
271 }
272
273 }
274 return null;
275 }
276
277 @Override
278 public String getInterfaceUuid(String portUuid, String portName) {
279 DatabaseSchema dbSchema = schema.get(OvsdbConstant.DATABASENAME);
280
281 Row portRow = getRow(OvsdbConstant.DATABASENAME, OvsdbConstant.PORT,
282 portUuid);
283 Port port = (Port) TableGenerator.getTable(dbSchema, portRow,
284 OvsdbTable.PORT);
285
286 if (port != null) {
287 OvsdbSet setInterfaces = (OvsdbSet) port.getInterfacesColumn().data();
288 @SuppressWarnings("unchecked")
289 Set<UUID> interfaces = setInterfaces.set();
290
291 if (interfaces == null || interfaces.size() == 0) {
292 log.warn("The interface uuid is null");
293 return null;
294 }
295
296 for (UUID uuid : interfaces) {
297 Row intfRow = getRow(OvsdbConstant.DATABASENAME,
298 OvsdbConstant.INTERFACE, uuid.value());
299 Interface intf = (Interface) TableGenerator
300 .getTable(dbSchema, intfRow, OvsdbTable.INTERFACE);
301 if (intf != null && portName.equalsIgnoreCase(intf.getName())) {
302 return uuid.value();
303 }
304 }
305
306 }
307
308 return null;
309 }
310
311 @Override
312 public String getBridgeUuid(String bridgeName) {
313 DatabaseSchema dbSchema = schema.get(OvsdbConstant.DATABASENAME);
314
315 OvsdbRowStore rowStore = getRowStore(OvsdbConstant.DATABASENAME,
316 OvsdbConstant.BRIDGE);
317 if (rowStore == null) {
318 log.debug("The bridge uuid is null");
319 return null;
320 }
321
322 ConcurrentMap<String, Row> bridgeTableRows = rowStore.getRowStore();
323 if (bridgeTableRows == null) {
324 log.debug("The bridge uuid is null");
325 return null;
326 }
327
328 for (String uuid : bridgeTableRows.keySet()) {
329 Bridge bridge = (Bridge) TableGenerator
330 .getTable(dbSchema, bridgeTableRows.get(uuid),
331 OvsdbTable.BRIDGE);
332
333 if (bridge.getName().equals(bridgeName)) {
334 return uuid;
335 }
336
337 }
338 return null;
339 }
340
341 @Override
342 public String getControllerUuid(String controllerName,
343 String controllerTarget) {
344 DatabaseSchema dbSchema = schema.get(OvsdbConstant.DATABASENAME);
345 OvsdbRowStore rowStore = getRowStore(OvsdbConstant.DATABASENAME,
346 OvsdbConstant.CONTROLLER);
347 if (rowStore == null) {
348 log.debug("The controller uuid is null");
349 return null;
350 }
351
352 ConcurrentMap<String, Row> controllerTableRows = rowStore.getRowStore();
353 if (controllerTableRows != null) {
354 for (String uuid : controllerTableRows.keySet()) {
355
356 Controller controller = (Controller) TableGenerator
357 .getTable(dbSchema, controllerTableRows.get(uuid),
358 OvsdbTable.CONTROLLER);
359 String target = (String) controller.getTargetColumn().data();
360 if (target.equalsIgnoreCase(controllerTarget)) {
361 return uuid;
362 }
363
364 }
365 }
366 return null;
367 }
368
369 @Override
370 public String getOvsUuid(String dbName) {
371 OvsdbRowStore rowStore = getRowStore(OvsdbConstant.DATABASENAME,
372 OvsdbConstant.DATABASENAME);
373 if (rowStore == null) {
374 log.debug("The bridge uuid is null");
375 return null;
376 }
377 ConcurrentMap<String, Row> ovsTableRows = rowStore.getRowStore();
378 if (ovsTableRows != null) {
379 for (String uuid : ovsTableRows.keySet()) {
380 Row row = ovsTableRows.get(uuid);
381 String tableName = row.tableName();
382 if (tableName.equals(dbName)) {
383 return uuid;
384 }
385 }
386 }
387 return null;
388 }
389
390 @Override
391 public void createPort(String bridgeName, String portName) {
392 String bridgeUuid = getBridgeUuid(bridgeName);
393 if (bridgeUuid == null) {
394 log.error("Can't find bridge {} in {}", bridgeName,
395 nodeId.getIpAddress());
396 return;
397 }
398
399 DatabaseSchema dbSchema = schema.get(OvsdbConstant.DATABASENAME);
400 String portUuid = getPortUuid(portName, bridgeUuid);
401
402 Port port = (Port) TableGenerator
403 .createTable(dbSchema, OvsdbTable.PORT);
404
405 port.setName(portName);
406 if (portUuid == null) {
407 insertConfig(OvsdbConstant.PORT, "_uuid", OvsdbConstant.BRIDGE,
andreaed976a42015-10-05 14:38:25 -0700408 "ports", bridgeUuid, port.getRow());
Sho SHIMIZUe4efe452015-08-26 15:06:55 -0700409 } else {
410 updateConfig(OvsdbConstant.PORT, "_uuid", portUuid, port.getRow());
411 }
412
413 return;
414 }
415
416 @Override
417 public void dropPort(String bridgeName, String portName) {
418 String bridgeUuid = getBridgeUuid(bridgeName);
419 if (bridgeUuid == null) {
420 log.error("Could not find Bridge {} in {}", bridgeName, nodeId);
421 return;
422 }
423
424 String portUuid = getPortUuid(portName, bridgeUuid);
425 if (portUuid != null) {
426 log.info("Port {} delete", portName);
427 deleteConfig(OvsdbConstant.PORT, "_uuid", portUuid,
andreaed976a42015-10-05 14:38:25 -0700428 OvsdbConstant.BRIDGE, "ports");
Sho SHIMIZUe4efe452015-08-26 15:06:55 -0700429 }
430 }
431
432 @Override
433 public void createBridge(String bridgeName) {
434 log.debug("create bridge {}", bridgeName);
435
436 DatabaseSchema dbSchema = schema.get(OvsdbConstant.DATABASENAME);
437 if (dbSchema == null) {
438 log.warn("The schema is null");
439 return;
440 }
441
442 Bridge bridge = (Bridge) TableGenerator.createTable(dbSchema,
443 OvsdbTable.BRIDGE);
444 if (bridge == null) {
445 log.debug("Can not create bridge");
446 return;
447 }
448
449 Set<String> failModes = new HashSet<>();
450 failModes.add("secure");
451 bridge.setFailMode(failModes);
452
453 Set<String> protocols = new HashSet<>();
454 protocols.add(OvsdbConstant.OPENFLOW13);
455 bridge.setProtocols(protocols);
456
457 String ovsUuid = getOvsUuid(OvsdbConstant.DATABASENAME);
458 if (ovsUuid == null) {
459 log.warn("The Open_vSwitch is null");
460 return;
461 }
462
463 String bridgeUuid = getBridgeUuid(bridgeName);
464 if (bridgeUuid == null) {
465 log.debug("Create a new bridge");
466
467 bridge.setName(bridgeName);
468 bridgeUuid = insertConfig(OvsdbConstant.BRIDGE, "_uuid",
andreaed976a42015-10-05 14:38:25 -0700469 OvsdbConstant.DATABASENAME, "bridges",
470 ovsUuid, bridge.getRow());
Sho SHIMIZUe4efe452015-08-26 15:06:55 -0700471
472 if (bridgeUuid != null) {
473 Port port = (Port) TableGenerator.createTable(dbSchema,
474 OvsdbTable.PORT);
475 if (port != null) {
476 log.debug("the port is not null");
477 port.setName(bridgeName);
478
479 insertConfig(OvsdbConstant.PORT, "_uuid", "Bridge", "ports", bridgeUuid,
andreaed976a42015-10-05 14:38:25 -0700480 port.getRow());
Sho SHIMIZUe4efe452015-08-26 15:06:55 -0700481 }
482 }
483
484 } else {
485 log.info("Update a bridge");
486 updateConfig(OvsdbConstant.BRIDGE, "_uuid", bridgeUuid, bridge.getRow());
487 }
488
andreaed976a42015-10-05 14:38:25 -0700489 setControllerAuto(bridgeUuid);
Sho SHIMIZUe4efe452015-08-26 15:06:55 -0700490 log.info("Create bridge success");
491 }
492
Hyunsun Moon646d8c42015-10-08 20:32:44 -0700493 @Override
lishuai6c56f5e2015-11-17 16:38:19 +0800494 public void createBridge(String bridgeName, String dpid, String exPortName) {
495 log.debug("create bridge {}", bridgeName);
496
497 DatabaseSchema dbSchema = schema.get(OvsdbConstant.DATABASENAME);
498 if (dbSchema == null) {
499 log.warn("The schema is null");
500 return;
501 }
502
503 Bridge bridge = (Bridge) TableGenerator.createTable(dbSchema,
504 OvsdbTable.BRIDGE);
505 if (bridge == null) {
506 log.debug("Can not create bridge");
507 return;
508 }
509
510 Set<String> failModes = new HashSet<>();
511 failModes.add("secure");
512 bridge.setFailMode(failModes);
513
514 Set<String> protocols = new HashSet<>();
515 protocols.add(OvsdbConstant.OPENFLOW13);
516 bridge.setProtocols(protocols);
517
518 String ovsUuid = getOvsUuid(OvsdbConstant.DATABASENAME);
519 if (ovsUuid == null) {
520 log.warn("The Open_vSwitch is null");
521 return;
522 }
523
524 String bridgeUuid = getBridgeUuid(bridgeName);
525 if (bridgeUuid == null) {
526 log.debug("Create a new bridge");
527
528 bridge.setName(bridgeName);
529 if (dpid != null) {
530 Map<String, String> options = new HashMap<>();
531 options.put("datapath-id", dpid);
532 bridge.setOtherConfig(options);
533 }
534 bridgeUuid = insertConfig(OvsdbConstant.BRIDGE, "_uuid",
535 OvsdbConstant.DATABASENAME, "bridges",
536 ovsUuid, bridge.getRow());
537
538 if (bridgeUuid != null) {
539 Port port = (Port) TableGenerator.createTable(dbSchema,
540 OvsdbTable.PORT);
541 if (port != null) {
542 log.debug("the port is not null");
543 port.setName(bridgeName);
544
545 insertConfig(OvsdbConstant.PORT, "_uuid", "Bridge", "ports", bridgeUuid,
546 port.getRow());
547 }
548 }
549
550 } else {
551 log.info("Update a bridge");
552 updateConfig(OvsdbConstant.BRIDGE, "_uuid", bridgeUuid, bridge.getRow());
553 }
554 // Create external port
555 if (exPortName != null) {
556 createPort(bridgeName, exPortName);
557 }
558
559 setControllerAuto(bridgeUuid);
560 log.info("Create bridge success");
561 }
562
563 @Override
Hyunsun Moon646d8c42015-10-08 20:32:44 -0700564 public boolean createBridge(String bridgeName, String dpid, List<ControllerInfo> controllers) {
565
566 DatabaseSchema dbSchema = schema.get(OvsdbConstant.DATABASENAME);
567 String ovsUuid = getOvsUuid(OvsdbConstant.DATABASENAME);
568
569 if (dbSchema == null || ovsUuid == null) {
570 log.warn("Couldn't find database Open_vSwitch");
571 return false;
572 }
573
574 String bridgeUuid = getBridgeUuid(bridgeName);
575 if (bridgeUuid != null) {
576 log.warn("Bridge {} is already exist", bridgeName);
577 // remove existing one and re-create?
578 return false;
579 }
580
581 Bridge bridge = (Bridge) TableGenerator.createTable(dbSchema, OvsdbTable.BRIDGE);
582 bridge.setName(bridgeName);
583
584 Set<String> failMode = new HashSet<>(Arrays.asList("secure"));
585 bridge.setFailMode(failMode);
586
587 Set<String> protocols = new HashSet<>(Arrays.asList(OvsdbConstant.OPENFLOW13));
588 bridge.setProtocols(protocols);
589
590 Map<String, String> options = new HashMap<>();
591 options.put("datapath-id", dpid);
592 bridge.setOtherConfig(options);
593
594 bridgeUuid = insertConfig(OvsdbConstant.BRIDGE, "_uuid",
595 OvsdbConstant.DATABASENAME, "bridges",
596 ovsUuid, bridge.getRow());
597
598 if (bridgeUuid != null) {
599 createPort(bridgeName, bridgeName);
600 } else {
601 log.warn("Failed to create bridge {} on {}", bridgeName, nodeId.toString());
602 return false;
603 }
604
605 setControllersWithUUID(UUID.uuid(bridgeUuid), controllers);
606 return true;
607 }
608
Sho SHIMIZUe4efe452015-08-26 15:06:55 -0700609 /**
Brian O'Connor6ee8aa32015-10-09 16:07:42 -0700610 * Sets the bridge's controller automatically.
611 * <p/>
612 * The connection is a TCP connection to the local ONOS instance's IP
613 * and the default OpenFlow port.
Sho SHIMIZUe4efe452015-08-26 15:06:55 -0700614 *
615 * @param bridgeUuid bridge uuid
616 */
andreaed976a42015-10-05 14:38:25 -0700617 private void setControllerAuto(String bridgeUuid) {
Brian O'Connor6ee8aa32015-10-09 16:07:42 -0700618 IpAddress ipAddress = IpAddress.valueOf(((InetSocketAddress) channel.localAddress()).getAddress());
619 ControllerInfo controllerInfo = new ControllerInfo(ipAddress, OvsdbConstant.OFPORT, "tcp");
620 log.debug("Automatically setting controller for bridge {} to {}",
621 bridgeUuid, controllerInfo.target());
622 setControllersWithUUID(UUID.uuid(bridgeUuid), ImmutableList.of(controllerInfo));
andreaed976a42015-10-05 14:38:25 -0700623 }
624
andreaed976a42015-10-05 14:38:25 -0700625 @Override
626 public void setControllersWithUUID(UUID bridgeUuid, List<ControllerInfo> controllers) {
627
Sho SHIMIZUe4efe452015-08-26 15:06:55 -0700628 DatabaseSchema dbSchema = schema.get(OvsdbConstant.DATABASENAME);
andreaed976a42015-10-05 14:38:25 -0700629 if (dbSchema == null) {
630 log.debug("There is no schema");
631 return;
632 }
633 List<Controller> oldControllers = getControllers(bridgeUuid);
634 if (oldControllers == null) {
635 log.warn("There are no controllers");
636 return;
637 }
638
639 Set<UUID> newControllerUuids = new HashSet<>();
640
641 Set<ControllerInfo> newControllers = new HashSet<>(controllers);
642 List<Controller> removeControllers = new ArrayList<>();
643 oldControllers.forEach(controller -> {
644 ControllerInfo controllerInfo = new ControllerInfo((String) controller.getTargetColumn().data());
645 if (newControllers.contains(controllerInfo)) {
646 newControllers.remove(controllerInfo);
647 newControllerUuids.add(controller.getRow().uuid());
648 } else {
649 removeControllers.add(controller);
650 }
651 });
652 OvsdbRowStore controllerRowStore = getRowStore(OvsdbConstant.DATABASENAME,
653 OvsdbConstant.CONTROLLER);
654 if (controllerRowStore == null) {
655 log.debug("There is no controller table");
656 return;
657 }
658
andreaed976a42015-10-05 14:38:25 -0700659 removeControllers.forEach(c -> deleteConfig(OvsdbConstant.CONTROLLER, "_uuid", c.getRow().uuid().value(),
660 OvsdbConstant.BRIDGE, "controller"));
661
662 newControllers.stream().map(c -> {
663 Controller controller = (Controller) TableGenerator
664 .createTable(dbSchema, OvsdbTable.CONTROLLER);
665 controller.setTarget(c.target());
666 return controller;
667 }).forEach(c -> {
andreaed976a42015-10-05 14:38:25 -0700668 String uuid = insertConfig(OvsdbConstant.CONTROLLER, "_uuid",
669 OvsdbConstant.BRIDGE, "controller", bridgeUuid.value(),
670 c.getRow());
andreaed976a42015-10-05 14:38:25 -0700671 newControllerUuids.add(UUID.uuid(uuid));
672
673 });
674
675 OvsdbRowStore rowStore = getRowStore(OvsdbConstant.DATABASENAME,
676 OvsdbConstant.BRIDGE);
677 if (rowStore == null) {
678 log.debug("There is no bridge table");
679 return;
680 }
681
682 Row bridgeRow = rowStore.getRow(bridgeUuid.value());
683 Bridge bridge = (Bridge) TableGenerator.getTable(dbSchema, bridgeRow, OvsdbTable.BRIDGE);
684 bridge.setController(OvsdbSet.ovsdbSet(newControllerUuids));
685 updateConfig(OvsdbConstant.BRIDGE, "_uuid", bridgeUuid.value(), bridge.getRow());
andreaed976a42015-10-05 14:38:25 -0700686 }
687
andreaed976a42015-10-05 14:38:25 -0700688 @Override
689 public void setControllersWithDeviceId(DeviceId deviceId, List<ControllerInfo> controllers) {
690 setControllersWithUUID(getBridgeUUID(deviceId), controllers);
691 }
692
Sho SHIMIZUe4efe452015-08-26 15:06:55 -0700693 @Override
694 public void dropBridge(String bridgeName) {
695 String bridgeUUID = getBridgeUuid(bridgeName);
696 if (bridgeUUID == null) {
697 log.warn("Could not find bridge in node", nodeId.getIpAddress());
698 return;
699 }
700 deleteConfig(OvsdbConstant.BRIDGE, "_uuid", bridgeUUID,
andreaed976a42015-10-05 14:38:25 -0700701 OvsdbConstant.DATABASENAME, "bridges");
Sho SHIMIZUe4efe452015-08-26 15:06:55 -0700702 }
703
704 @Override
705 public void createTunnel(IpAddress srcIp, IpAddress dstIp) {
706 String bridgeUuid = getBridgeUuid(OvsdbConstant.INTEGRATION_BRIDGE);
707 if (bridgeUuid == null) {
708 log.warn("Could not find bridge {} and Could not create tunnel. ",
709 OvsdbConstant.INTEGRATION_BRIDGE);
710 return;
711 }
712
713 DatabaseSchema dbSchema = schema.get(OvsdbConstant.DATABASENAME);
714 String portName = getTunnelName(OvsdbConstant.TYPEVXLAN, dstIp);
715 String portUuid = getPortUuid(portName, bridgeUuid);
716
717 Port port = (Port) TableGenerator
718 .createTable(dbSchema, OvsdbTable.PORT);
719 if (port != null) {
720 port.setName(portName);
721 }
722
723 if (portUuid == null) {
724 portUuid = insertConfig(OvsdbConstant.PORT, "_uuid", OvsdbConstant.BRIDGE,
andreaed976a42015-10-05 14:38:25 -0700725 "ports", bridgeUuid, port.getRow());
Sho SHIMIZUe4efe452015-08-26 15:06:55 -0700726 } else {
727 updateConfig(OvsdbConstant.PORT, "_uuid", portUuid, port.getRow());
728 }
729
730 // When a tunnel is created, A row is inserted into port table and
731 // interface table of the ovsdb node.
732 // and the following step is to get the interface uuid from local store
733 // in controller node.
734 // but it need spend some time synchronising data between node and
735 // controller.
736 // so loop to judge if interfaceUUid is null is necessary.
737 String interfaceUuid = null;
738 for (int i = 0; i < 10; i++) {
739 interfaceUuid = getInterfaceUuid(portUuid, portName);
740 if (interfaceUuid == null) {
741 try {
742 Thread.sleep(500);
743 } catch (InterruptedException e) {
744 log.warn("Interrupted while waiting to get interfaceUuid");
745 Thread.currentThread().interrupt();
746 }
747 } else {
748 break;
749 }
750 }
751
752 if (interfaceUuid != null) {
753
754 Interface tunInterface = (Interface) TableGenerator
755 .createTable(dbSchema, OvsdbTable.INTERFACE);
756
757 if (tunInterface != null) {
758
759 tunInterface.setType(OvsdbConstant.TYPEVXLAN);
760 Map<String, String> options = Maps.newHashMap();
761 options.put("key", "flow");
762 options.put("local_ip", srcIp.toString());
763 options.put("remote_ip", dstIp.toString());
764 tunInterface.setOptions(options);
765 updateConfig(OvsdbConstant.INTERFACE, "_uuid", interfaceUuid,
andreaed976a42015-10-05 14:38:25 -0700766 tunInterface.getRow());
Sho SHIMIZUe4efe452015-08-26 15:06:55 -0700767 log.info("Tunnel added success", tunInterface);
768
769 }
770 }
771
772 return;
773 }
774
775 @Override
Hyunsun Moon646d8c42015-10-08 20:32:44 -0700776 public boolean createTunnel(String bridgeName, String portName, String tunnelType, Map<String, String> options) {
777
778 String bridgeUuid = getBridgeUuid(bridgeName);
779 if (bridgeUuid == null) {
780 log.warn("Couldn't find bridge {} in {}", bridgeName, nodeId.getIpAddress());
781 return false;
782 }
783
784 if (getPortUuid(portName, bridgeUuid) != null) {
785 log.warn("Port {} already exists", portName);
786 // remove existing one and re-create?
787 return false;
788 }
789
790 ArrayList<Operation> operations = Lists.newArrayList();
791 DatabaseSchema dbSchema = schema.get(OvsdbConstant.DATABASENAME);
792
793 // insert a new port to the port table
794 Port port = (Port) TableGenerator.createTable(dbSchema, OvsdbTable.PORT);
795 port.setName(portName);
796 Insert portInsert = new Insert(dbSchema.getTableSchema("Port"), "Port", port.getRow());
797 portInsert.getRow().put("interfaces", UUID.uuid("Interface"));
798 operations.add(portInsert);
799
800 // update the bridge table
801 Condition condition = ConditionUtil.equals("_uuid", UUID.uuid(bridgeUuid));
802 Mutation mutation = MutationUtil.insert("ports", UUID.uuid("Port"));
803 List<Condition> conditions = new ArrayList<>(Arrays.asList(condition));
804 List<Mutation> mutations = new ArrayList<>(Arrays.asList(mutation));
805 operations.add(new Mutate(dbSchema.getTableSchema("Bridge"), conditions, mutations));
806
807 // insert a tunnel interface
808 Interface intf = (Interface) TableGenerator.createTable(dbSchema, OvsdbTable.INTERFACE);
809 intf.setName(portName);
810 intf.setType(tunnelType);
811 intf.setOptions(options);
812 Insert intfInsert = new Insert(dbSchema.getTableSchema("Interface"), "Interface", intf.getRow());
813 operations.add(intfInsert);
814
815 transactConfig(OvsdbConstant.DATABASENAME, operations);
816 return true;
817 }
818
819 @Override
Sho SHIMIZUe4efe452015-08-26 15:06:55 -0700820 public void dropTunnel(IpAddress srcIp, IpAddress dstIp) {
821 String bridgeName = OvsdbConstant.INTEGRATION_BRIDGE;
822 String portName = getTunnelName(OvsdbConstant.TYPEVXLAN, dstIp);
823 String bridgeUuid = getBridgeUuid(OvsdbConstant.INTEGRATION_BRIDGE);
824 if (bridgeUuid == null) {
825 log.warn("Could not find bridge {} in {}", bridgeName,
826 nodeId.getIpAddress());
827 return;
828 }
829
830 String portUUID = getPortUuid(portName, bridgeUuid);
831 if (portUUID != null) {
832 log.info("Delete tunnel");
833 deleteConfig(OvsdbConstant.PORT, "_uuid", portUUID,
andreaed976a42015-10-05 14:38:25 -0700834 OvsdbConstant.BRIDGE, "ports");
Sho SHIMIZUe4efe452015-08-26 15:06:55 -0700835 }
836
837 return;
838 }
839
840 /**
841 * Delete transact config.
842 *
andreaed976a42015-10-05 14:38:25 -0700843 * @param childTableName child table name
844 * @param childColumnName child column name
845 * @param childUuid child row uuid
846 * @param parentTableName parent table name
Sho SHIMIZUe4efe452015-08-26 15:06:55 -0700847 * @param parentColumnName parent column
Sho SHIMIZUe4efe452015-08-26 15:06:55 -0700848 */
849 private void deleteConfig(String childTableName, String childColumnName,
andreaed976a42015-10-05 14:38:25 -0700850 String childUuid, String parentTableName,
851 String parentColumnName) {
Sho SHIMIZUe4efe452015-08-26 15:06:55 -0700852 DatabaseSchema dbSchema = schema.get(OvsdbConstant.DATABASENAME);
853 TableSchema childTableSchema = dbSchema.getTableSchema(childTableName);
854
855 ArrayList<Operation> operations = Lists.newArrayList();
856 if (parentTableName != null && parentColumnName != null) {
857 TableSchema parentTableSchema = dbSchema
858 .getTableSchema(parentTableName);
859 ColumnSchema parentColumnSchema = parentTableSchema
860 .getColumnSchema(parentColumnName);
861 List<Mutation> mutations = Lists.newArrayList();
862 Mutation mutation = MutationUtil.delete(parentColumnSchema.name(),
863 UUID.uuid(childUuid));
864 mutations.add(mutation);
865 List<Condition> conditions = Lists.newArrayList();
866 Condition condition = ConditionUtil.includes(parentColumnName,
867 UUID.uuid(childUuid));
868 conditions.add(condition);
869 Mutate op = new Mutate(parentTableSchema, conditions, mutations);
870 operations.add(op);
871 }
872
873 List<Condition> conditions = Lists.newArrayList();
874 Condition condition = ConditionUtil.equals(childColumnName, UUID.uuid(childUuid));
875 conditions.add(condition);
876 Delete del = new Delete(childTableSchema, conditions);
877 operations.add(del);
878 transactConfig(OvsdbConstant.DATABASENAME, operations);
879
880 return;
881 }
882
883 /**
884 * Update transact config.
885 *
andreaed976a42015-10-05 14:38:25 -0700886 * @param tableName table name
Sho SHIMIZUe4efe452015-08-26 15:06:55 -0700887 * @param columnName column name
andreaed976a42015-10-05 14:38:25 -0700888 * @param uuid uuid
889 * @param row the config data
Sho SHIMIZUe4efe452015-08-26 15:06:55 -0700890 */
891 private void updateConfig(String tableName, String columnName, String uuid,
andreaed976a42015-10-05 14:38:25 -0700892 Row row) {
Sho SHIMIZUe4efe452015-08-26 15:06:55 -0700893 DatabaseSchema dbSchema = schema.get(OvsdbConstant.DATABASENAME);
894 TableSchema tableSchema = dbSchema.getTableSchema(tableName);
895
896 List<Condition> conditions = Lists.newArrayList();
897 Condition condition = ConditionUtil.equals(columnName, UUID.uuid(uuid));
898 conditions.add(condition);
899
900 Update update = new Update(tableSchema, row, conditions);
901
902 ArrayList<Operation> operations = Lists.newArrayList();
903 operations.add(update);
904
905 transactConfig(OvsdbConstant.DATABASENAME, operations);
906 }
907
908 /**
909 * Insert transact config.
910 *
andreaed976a42015-10-05 14:38:25 -0700911 * @param childTableName child table name
912 * @param childColumnName child column name
913 * @param parentTableName parent table name
Sho SHIMIZUe4efe452015-08-26 15:06:55 -0700914 * @param parentColumnName parent column
andreaed976a42015-10-05 14:38:25 -0700915 * @param parentUuid parent uuid
916 * @param row the config data
Sho SHIMIZUe4efe452015-08-26 15:06:55 -0700917 * @return uuid, empty if no uuid is find
918 */
919 private String insertConfig(String childTableName, String childColumnName,
andreaed976a42015-10-05 14:38:25 -0700920 String parentTableName, String parentColumnName,
921 String parentUuid, Row row) {
Sho SHIMIZUe4efe452015-08-26 15:06:55 -0700922 DatabaseSchema dbSchema = schema.get(OvsdbConstant.DATABASENAME);
923 TableSchema tableSchema = dbSchema.getTableSchema(childTableName);
924
925 String namedUuid = childTableName;
926 Insert insert = new Insert(tableSchema, namedUuid, row);
927
928 ArrayList<Operation> operations = Lists.newArrayList();
929 operations.add(insert);
930
931 if (parentTableName != null && parentColumnName != null) {
932 TableSchema parentTableSchema = dbSchema
933 .getTableSchema(parentTableName);
934 ColumnSchema parentColumnSchema = parentTableSchema
935 .getColumnSchema(parentColumnName);
936
937 List<Mutation> mutations = Lists.newArrayList();
938 Mutation mutation = MutationUtil.insert(parentColumnSchema.name(),
939 UUID.uuid(namedUuid));
940 mutations.add(mutation);
941
942 List<Condition> conditions = Lists.newArrayList();
943 Condition condition = ConditionUtil.equals("_uuid",
944 UUID.uuid(parentUuid));
945 conditions.add(condition);
946
947 Mutate op = new Mutate(parentTableSchema, conditions, mutations);
948 operations.add(op);
949 }
950 if (childTableName.equalsIgnoreCase(OvsdbConstant.PORT)) {
951 log.info("Handle port insert");
952 Insert intfInsert = handlePortInsertTable(OvsdbConstant.INTERFACE,
andreaed976a42015-10-05 14:38:25 -0700953 row);
Sho SHIMIZUe4efe452015-08-26 15:06:55 -0700954
955 if (intfInsert != null) {
956 operations.add(intfInsert);
957 }
958
959 Insert ins = (Insert) operations.get(0);
960 ins.getRow().put("interfaces",
961 UUID.uuid(OvsdbConstant.INTERFACE));
962 }
963
964 List<OperationResult> results;
965 try {
966 results = transactConfig(OvsdbConstant.DATABASENAME, operations)
967 .get();
968
969 return results.get(0).getUuid().value();
970 } catch (InterruptedException e) {
971 log.warn("Interrupted while waiting to get result");
972 Thread.currentThread().interrupt();
973 } catch (ExecutionException e) {
974 log.error("Exception thrown while to get result");
975 }
976
977 return null;
978 }
979
980 /**
981 * Handles port insert.
982 *
983 * @param tableName ovsdb table interface
andreaed976a42015-10-05 14:38:25 -0700984 * @param portRow row of port
Sho SHIMIZUe4efe452015-08-26 15:06:55 -0700985 * @return insert, empty if null
986 */
987 private Insert handlePortInsertTable(String tableName, Row portRow) {
988 DatabaseSchema dbSchema = schema.get(OvsdbConstant.DATABASENAME);
989
990 TableSchema portTableSchema = dbSchema
991 .getTableSchema(OvsdbConstant.PORT);
992 ColumnSchema portColumnSchema = portTableSchema.getColumnSchema("name");
993
994 String portName = (String) portRow.getColumn(portColumnSchema.name()).data();
995
996 Interface inf = (Interface) TableGenerator
997 .createTable(dbSchema, OvsdbTable.INTERFACE);
998
999 inf.setName(portName);
1000
1001 TableSchema intfTableSchema = dbSchema
1002 .getTableSchema(OvsdbConstant.INTERFACE);
1003 Insert insert = new Insert(intfTableSchema, OvsdbConstant.INTERFACE,
1004 inf.getRow());
1005 return insert;
1006 }
1007
1008 /**
1009 * Gets tunnel name.
1010 *
1011 * @param tunnelType
andreaed976a42015-10-05 14:38:25 -07001012 * @param dstIp the remote ip address
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001013 * @return tunnel name
1014 */
1015 private String getTunnelName(String tunnelType, IpAddress dstIp) {
1016 return tunnelType + "-" + dstIp.toString();
1017 }
1018
1019 @Override
1020 public ListenableFuture<DatabaseSchema> getOvsdbSchema(String dbName) {
1021 if (dbName == null) {
1022 return null;
1023 }
1024 DatabaseSchema databaseSchema = schema.get(dbName);
1025 if (databaseSchema == null) {
1026 List<String> dbNames = new ArrayList<String>();
1027 dbNames.add(dbName);
1028 Function<JsonNode, DatabaseSchema> rowFunction = new Function<JsonNode, DatabaseSchema>() {
1029 @Override
1030 public DatabaseSchema apply(JsonNode input) {
Hyunsun Moon5fb20a52015-09-25 17:02:33 -07001031 log.info("Get ovsdb database schema {}", dbName);
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001032 DatabaseSchema dbSchema = FromJsonUtil
1033 .jsonNodeToDbSchema(dbName, input);
1034 if (dbSchema == null) {
1035 log.debug("Get ovsdb database schema error");
1036 return null;
1037 }
1038 schema.put(dbName, dbSchema);
1039
1040 return dbSchema;
1041 }
1042 };
1043
1044 ListenableFuture<JsonNode> input = getSchema(dbNames);
1045 if (input != null) {
1046 return Futures.transform(input, rowFunction);
1047 }
1048 return null;
1049 } else {
1050 return Futures.immediateFuture(databaseSchema);
1051 }
1052 }
1053
1054 @Override
1055 public ListenableFuture<TableUpdates> monitorTables(String dbName, String id) {
1056 if (dbName == null) {
1057 return null;
1058 }
1059 DatabaseSchema dbSchema = schema.get(dbName);
1060 if (dbSchema != null) {
1061 Function<JsonNode, TableUpdates> rowFunction = new Function<JsonNode, TableUpdates>() {
1062 @Override
1063 public TableUpdates apply(JsonNode input) {
1064 log.info("Get table updates");
1065 TableUpdates updates = FromJsonUtil
1066 .jsonNodeToTableUpdates(input, dbSchema);
1067 if (updates == null) {
1068 log.debug("Get table updates error");
1069 return null;
1070 }
1071 return updates;
1072 }
1073 };
1074 return Futures.transform(monitor(dbSchema, id), rowFunction);
1075 }
1076 return null;
1077 }
1078
1079 @Override
1080 public ListenableFuture<List<OperationResult>> transactConfig(String dbName,
1081 List<Operation> operations) {
1082 if (dbName == null) {
1083 return null;
1084 }
1085 DatabaseSchema dbSchema = schema.get(dbName);
1086 if (dbSchema != null) {
andreaed976a42015-10-05 14:38:25 -07001087 Function<List<JsonNode>, List<OperationResult>> rowFunction = (input -> {
1088 log.info("Get ovsdb operation result");
1089 List<OperationResult> result = FromJsonUtil
1090 .jsonNodeToOperationResult(input, operations);
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001091
andreaed976a42015-10-05 14:38:25 -07001092 if (result == null) {
1093 log.debug("The operation result is null");
1094 return null;
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001095 }
andreaed976a42015-10-05 14:38:25 -07001096 return result;
1097 });
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001098 return Futures.transform(transact(dbSchema, operations),
1099 rowFunction);
1100 }
1101 return null;
1102 }
1103
1104 @Override
1105 public ListenableFuture<JsonNode> getSchema(List<String> dbnames) {
1106 String id = java.util.UUID.randomUUID().toString();
1107 String getSchemaString = JsonRpcWriterUtil.getSchemaStr(id, dbnames);
1108
1109 SettableFuture<JsonNode> sf = SettableFuture.create();
1110 requestResult.put(id, sf);
1111 requestMethod.put(id, "getSchema");
1112
1113 channel.writeAndFlush(getSchemaString);
1114 return sf;
1115
1116 }
1117
1118 @Override
1119 public ListenableFuture<List<String>> echo() {
1120 String id = java.util.UUID.randomUUID().toString();
1121 String echoString = JsonRpcWriterUtil.echoStr(id);
1122
1123 SettableFuture<List<String>> sf = SettableFuture.create();
1124 requestResult.put(id, sf);
1125 requestMethod.put(id, "echo");
1126
1127 channel.writeAndFlush(echoString);
1128 return sf;
1129
1130 }
1131
1132 @Override
1133 public ListenableFuture<JsonNode> monitor(DatabaseSchema dbSchema,
1134 String monitorId) {
1135 String id = java.util.UUID.randomUUID().toString();
1136 String monitorString = JsonRpcWriterUtil.monitorStr(id, monitorId,
1137 dbSchema);
1138
1139 SettableFuture<JsonNode> sf = SettableFuture.create();
1140 requestResult.put(id, sf);
1141 requestMethod.put(id, "monitor");
1142
1143 channel.writeAndFlush(monitorString);
1144 return sf;
1145
1146 }
1147
1148 @Override
1149 public ListenableFuture<List<String>> listDbs() {
1150 String id = java.util.UUID.randomUUID().toString();
1151 String listDbsString = JsonRpcWriterUtil.listDbsStr(id);
1152
1153 SettableFuture<List<String>> sf = SettableFuture.create();
1154 requestResult.put(id, sf);
1155 requestMethod.put(id, "listDbs");
1156
1157 channel.writeAndFlush(listDbsString);
1158 return sf;
1159
1160 }
1161
1162 @Override
1163 public ListenableFuture<List<JsonNode>> transact(DatabaseSchema dbSchema,
1164 List<Operation> operations) {
1165 String id = java.util.UUID.randomUUID().toString();
1166 String transactString = JsonRpcWriterUtil.transactStr(id, dbSchema,
1167 operations);
1168
1169 SettableFuture<List<JsonNode>> sf = SettableFuture.create();
1170 requestResult.put(id, sf);
1171 requestMethod.put(id, "transact");
1172
1173 channel.writeAndFlush(transactString);
1174 return sf;
1175
1176 }
1177
andreaed976a42015-10-05 14:38:25 -07001178 @SuppressWarnings({"rawtypes", "unchecked"})
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001179 @Override
1180 public void processResult(JsonNode response) {
1181 log.debug("Handle result");
1182 String requestId = response.get("id").asText();
1183 SettableFuture sf = requestResult.get(requestId);
1184 if (sf == null) {
1185 log.debug("No such future to process");
1186 return;
1187 }
1188 String methodName = requestMethod.get(requestId);
1189
1190 Object result;
1191 result = FromJsonUtil.jsonResultParser(response, methodName);
1192
1193 sf.set(result);
1194 return;
1195 }
1196
1197 @Override
1198 public void processRequest(JsonNode requestJson) {
1199 log.debug("Handle request");
1200 if (requestJson.get("method").asText().equalsIgnoreCase("echo")) {
1201 log.debug("handle echo request");
1202
1203 String replyString = FromJsonUtil.getEchoRequestStr(requestJson);
1204 channel.writeAndFlush(replyString);
1205
1206 return;
1207 } else {
1208 FromJsonUtil
1209 .jsonCallbackRequestParser(requestJson, monitorCallBack);
1210 return;
1211 }
1212 }
1213
1214 @Override
1215 public void setCallback(Callback monitorCallback) {
1216 this.monitorCallBack = monitorCallback;
1217 }
1218
1219 @Override
1220 public Set<OvsdbTunnel> getTunnels() {
1221 return ovsdbTunnels;
1222 }
1223
1224 @Override
1225 public Set<OvsdbBridge> getBridges() {
1226 Set<OvsdbBridge> ovsdbBridges = new HashSet<OvsdbBridge>();
1227 OvsdbTableStore tableStore = getTableStore(OvsdbConstant.DATABASENAME);
1228 if (tableStore == null) {
1229 return null;
1230 }
1231 OvsdbRowStore rowStore = tableStore.getRows(OvsdbConstant.BRIDGE);
1232 if (rowStore == null) {
1233 return null;
1234 }
1235 ConcurrentMap<String, Row> rows = rowStore.getRowStore();
1236 for (String uuid : rows.keySet()) {
1237 Row row = getRow(OvsdbConstant.DATABASENAME, OvsdbConstant.BRIDGE,
1238 uuid);
1239 OvsdbBridge ovsdbBridge = getOvsdbBridge(row);
1240 if (ovsdbBridge != null) {
1241 ovsdbBridges.add(ovsdbBridge);
1242 }
1243 }
1244 return ovsdbBridges;
1245 }
1246
1247 @Override
andreaed976a42015-10-05 14:38:25 -07001248 public Set<ControllerInfo> getControllers(DeviceId openflowDeviceId) {
1249 UUID bridgeUuid = getBridgeUUID(openflowDeviceId);
1250 if (bridgeUuid == null) {
1251 log.warn("bad bridge Uuid");
1252 return null;
1253 }
1254 List<Controller> controllers = getControllers(bridgeUuid);
1255 if (controllers == null) {
1256 log.warn("bad list of controllers");
1257 return null;
1258 }
1259 return controllers.stream().
1260 map(controller -> new ControllerInfo(
1261 (String) controller.getTargetColumn()
1262 .data())).collect(Collectors.toSet());
1263 }
1264
1265 private List<Controller> getControllers(UUID bridgeUuid) {
1266 DatabaseSchema dbSchema = schema.get(OvsdbConstant.DATABASENAME);
1267 if (dbSchema == null) {
1268 return null;
1269 }
1270 OvsdbRowStore rowStore = getRowStore(OvsdbConstant.DATABASENAME,
1271 OvsdbConstant.BRIDGE);
1272 if (rowStore == null) {
1273 log.debug("There is no bridge table");
1274 return null;
1275 }
1276
1277 Row bridgeRow = rowStore.getRow(bridgeUuid.value());
1278 Bridge bridge = (Bridge) TableGenerator.
1279 getTable(dbSchema, bridgeRow, OvsdbTable.BRIDGE);
1280
1281 //FIXME remove log
1282 log.warn("type of controller column", bridge.getControllerColumn()
1283 .data().getClass());
1284 Set<UUID> controllerUuids = (Set<UUID>) ((OvsdbSet) bridge
1285 .getControllerColumn().data()).set();
1286// Set<String> controllerUuidStrings = (Set<String>) bridge.getControllerColumn().data();
1287
1288 OvsdbRowStore controllerRowStore = getRowStore(OvsdbConstant.DATABASENAME,
1289 OvsdbConstant.CONTROLLER);
1290 if (controllerRowStore == null) {
1291 log.debug("There is no controller table");
1292 return null;
1293 }
1294
1295 List<Controller> ovsdbControllers = new ArrayList<>();
1296 ConcurrentMap<String, Row> controllerTableRows = controllerRowStore.getRowStore();
1297 controllerTableRows.forEach((key, row) -> {
1298 if (!controllerUuids.contains(UUID.uuid(key))) {
1299 return;
1300 }
1301 Controller controller = (Controller) TableGenerator
1302 .getTable(dbSchema, row, OvsdbTable.CONTROLLER);
1303 ovsdbControllers.add(controller);
1304 });
1305 return ovsdbControllers;
1306 }
1307
1308
1309 private UUID getBridgeUUID(DeviceId openflowDeviceId) {
1310 DatabaseSchema dbSchema = schema.get(OvsdbConstant.DATABASENAME);
1311 if (dbSchema == null) {
1312 return null;
1313 }
1314 OvsdbRowStore rowStore = getRowStore(OvsdbConstant.DATABASENAME,
1315 OvsdbConstant.BRIDGE);
1316 if (rowStore == null) {
1317 log.debug("There is no bridge table");
1318 return null;
1319 }
1320
1321 ConcurrentMap<String, Row> bridgeTableRows = rowStore.getRowStore();
1322 final AtomicReference<UUID> uuid = new AtomicReference<>();
1323 for (Map.Entry<String, Row> entry : bridgeTableRows.entrySet()) {
1324 Bridge b = (Bridge) TableGenerator.getTable(dbSchema,
1325 entry.getValue(),
1326 OvsdbTable.BRIDGE);
1327 if (matchesDpid(b, openflowDeviceId)) {
1328 uuid.set(UUID.uuid(entry.getKey()));
1329 break;
1330 }
1331 }
1332 if (uuid.get() == null) {
1333 log.debug("There is no bridge for {}", openflowDeviceId);
1334 }
1335 return uuid.get();
1336
1337 }
1338
1339 private static boolean matchesDpid(Bridge b, DeviceId deviceId) {
1340 String ofDpid = deviceId.toString().replace("of:", "");
1341 Set ofDeviceIds = ((OvsdbSet) b.getDatapathIdColumn().data()).set();
1342 //TODO Set<String>
1343 return ofDeviceIds.contains(ofDpid);
1344 }
1345
1346 @Override
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001347 public Set<OvsdbPort> getPorts() {
1348 Set<OvsdbPort> ovsdbPorts = new HashSet<OvsdbPort>();
1349 OvsdbTableStore tableStore = getTableStore(OvsdbConstant.DATABASENAME);
1350 if (tableStore == null) {
1351 return null;
1352 }
1353 OvsdbRowStore rowStore = tableStore.getRows(OvsdbConstant.INTERFACE);
1354 if (rowStore == null) {
1355 return null;
1356 }
1357 ConcurrentMap<String, Row> rows = rowStore.getRowStore();
1358 for (String uuid : rows.keySet()) {
1359 Row row = getRow(OvsdbConstant.DATABASENAME,
1360 OvsdbConstant.INTERFACE, uuid);
1361 OvsdbPort ovsdbPort = getOvsdbPort(row);
1362 if (ovsdbPort != null) {
1363 ovsdbPorts.add(ovsdbPort);
1364 }
1365 }
1366 return ovsdbPorts;
1367 }
1368
1369 @Override
1370 public DatabaseSchema getDatabaseSchema(String dbName) {
1371 return schema.get(dbName);
1372 }
1373
1374 //Gets ovsdb port.
1375 private OvsdbPort getOvsdbPort(Row row) {
1376 DatabaseSchema dbSchema = getDatabaseSchema(OvsdbConstant.DATABASENAME);
1377 Interface intf = (Interface) TableGenerator
1378 .getTable(dbSchema, row, OvsdbTable.INTERFACE);
1379 if (intf == null) {
1380 return null;
1381 }
1382 long ofPort = getOfPort(intf);
1383 String portName = intf.getName();
1384 if ((ofPort < 0) || (portName == null)) {
1385 return null;
1386 }
1387
1388 OvsdbPort ovsdbPort = new OvsdbPort(new OvsdbPortNumber(ofPort),
1389 new OvsdbPortName(portName));
1390 return ovsdbPort;
1391 }
1392
1393 ////Gets ovsdb bridge.
1394 private OvsdbBridge getOvsdbBridge(Row row) {
1395 DatabaseSchema dbSchema = getDatabaseSchema(OvsdbConstant.DATABASENAME);
1396 Bridge bridge = (Bridge) TableGenerator.getTable(dbSchema, row,
1397 OvsdbTable.BRIDGE);
1398 if (bridge == null) {
1399 return null;
1400 }
1401
1402 OvsdbSet datapathIdSet = (OvsdbSet) bridge.getDatapathIdColumn().data();
1403 @SuppressWarnings("unchecked")
1404 Set<String> datapathIds = datapathIdSet.set();
1405 if (datapathIds == null || datapathIds.size() == 0) {
1406 return null;
1407 }
1408 String datapathId = (String) datapathIds.toArray()[0];
1409 String bridgeName = bridge.getName();
1410 if ((datapathId == null) || (bridgeName == null)) {
1411 return null;
1412 }
1413
1414 OvsdbBridge ovsdbBridge = new OvsdbBridge(new OvsdbBridgeName(bridgeName),
1415 new OvsdbDatapathId(datapathId));
1416 return ovsdbBridge;
1417 }
1418
1419 //Gets ofPort in the interface.
1420 private long getOfPort(Interface intf) {
1421 OvsdbSet ofPortSet = (OvsdbSet) intf.getOpenFlowPortColumn().data();
1422 @SuppressWarnings("unchecked")
1423 Set<Integer> ofPorts = ofPortSet.set();
1424 while (ofPorts == null || ofPorts.size() <= 0) {
1425 log.debug("The ofport is null in {}", intf.getName());
1426 return -1;
1427 }
1428 // return (long) ofPorts.toArray()[0];
1429 Iterator<Integer> it = ofPorts.iterator();
1430 return Long.parseLong(it.next().toString());
1431 }
CNluciusa66c3972015-09-06 20:31:29 +08001432
1433 @Override
1434 public Set<OvsdbPort> getLocalPorts(Iterable<String> ifaceids) {
1435 Set<OvsdbPort> ovsdbPorts = new HashSet<OvsdbPort>();
1436 OvsdbTableStore tableStore = getTableStore(OvsdbConstant.DATABASENAME);
1437 if (tableStore == null) {
1438 return null;
1439 }
1440 OvsdbRowStore rowStore = tableStore.getRows(OvsdbConstant.INTERFACE);
1441 if (rowStore == null) {
1442 return null;
1443 }
1444 ConcurrentMap<String, Row> rows = rowStore.getRowStore();
1445 for (String uuid : rows.keySet()) {
1446 Row row = getRow(OvsdbConstant.DATABASENAME,
1447 OvsdbConstant.INTERFACE, uuid);
1448 DatabaseSchema dbSchema = getDatabaseSchema(OvsdbConstant.DATABASENAME);
1449 Interface intf = (Interface) TableGenerator
1450 .getTable(dbSchema, row, OvsdbTable.INTERFACE);
1451 if (intf == null || getIfaceid(intf) == null) {
1452 continue;
1453 }
1454 String portName = intf.getName();
1455 Set<String> ifaceidSet = Sets.newHashSet(ifaceids);
1456 if (portName.startsWith("vxlan")
1457 || !ifaceidSet.contains(getIfaceid(intf))) {
1458 continue;
1459 }
1460 long ofPort = getOfPort(intf);
1461 if ((ofPort < 0) || (portName == null)) {
1462 continue;
1463 }
1464
1465 OvsdbPort ovsdbPort = new OvsdbPort(new OvsdbPortNumber(ofPort),
1466 new OvsdbPortName(portName));
1467 if (ovsdbPort != null) {
1468 ovsdbPorts.add(ovsdbPort);
1469 }
1470 }
1471 return ovsdbPorts;
1472 }
1473
1474 private String getIfaceid(Interface intf) {
1475 OvsdbMap ovsdbMap = (OvsdbMap) intf.getExternalIdsColumn().data();
1476 @SuppressWarnings("unchecked")
1477 Map<String, String> externalIds = ovsdbMap.map();
1478 if (externalIds.isEmpty()) {
1479 log.warn("The external_ids is null");
1480 return null;
1481 }
1482 String ifaceid = externalIds
1483 .get(OvsdbConstant.EXTERNAL_ID_INTERFACE_ID);
1484 if (ifaceid == null) {
1485 log.warn("The ifaceid is null");
1486 return null;
1487 }
1488 return ifaceid;
1489 }
Hyunsun Moon5fb20a52015-09-25 17:02:33 -07001490
1491 @Override
1492 public void disconnect() {
1493 channel.disconnect();
1494 this.agent.removeConnectedNode(nodeId);
1495 }
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001496}