blob: 2ed28f7b839431cdbe5223b5ab91bdbc632df39a [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
18import io.netty.channel.Channel;
lishuai6c56f5e2015-11-17 16:38:19 +080019
Ray Milkeyb1250322017-06-05 17:18:17 -070020import java.net.InetSocketAddress;
21import java.util.ArrayList;
22import java.util.HashMap;
23import java.util.HashSet;
24import java.util.Iterator;
25import java.util.List;
26import java.util.Map;
27import java.util.Objects;
28import java.util.Optional;
29import java.util.Set;
30import java.util.concurrent.ConcurrentMap;
31import java.util.concurrent.ExecutionException;
32import java.util.concurrent.TimeUnit;
33import java.util.concurrent.TimeoutException;
34import java.util.concurrent.atomic.AtomicReference;
35import java.util.stream.Collectors;
36
Sho SHIMIZUe4efe452015-08-26 15:06:55 -070037import org.onlab.packet.IpAddress;
andreaed976a42015-10-05 14:38:25 -070038import org.onosproject.net.DeviceId;
Frank Wange11a98d2016-10-26 17:04:03 +080039import org.onosproject.net.PortNumber;
andreaed976a42015-10-05 14:38:25 -070040import org.onosproject.net.behaviour.ControllerInfo;
Pier Ventref5d72362016-07-17 12:02:14 +020041import org.onosproject.net.behaviour.MirroringName;
Ray Milkeyb1250322017-06-05 17:18:17 -070042import org.onosproject.net.behaviour.MirroringStatistics;
Frank Wange11a98d2016-10-26 17:04:03 +080043import org.onosproject.net.behaviour.QosId;
44import org.onosproject.net.behaviour.QueueId;
Sho SHIMIZUe4efe452015-08-26 15:06:55 -070045import org.onosproject.ovsdb.controller.OvsdbBridge;
Sho SHIMIZUe4efe452015-08-26 15:06:55 -070046import org.onosproject.ovsdb.controller.OvsdbClientService;
Hyunsun Moondd14e8e2016-06-09 16:17:32 -070047import org.onosproject.ovsdb.controller.OvsdbInterface;
Pier Ventref5d72362016-07-17 12:02:14 +020048import org.onosproject.ovsdb.controller.OvsdbMirror;
Sho SHIMIZUe4efe452015-08-26 15:06:55 -070049import org.onosproject.ovsdb.controller.OvsdbNodeId;
50import org.onosproject.ovsdb.controller.OvsdbPort;
51import org.onosproject.ovsdb.controller.OvsdbPortName;
52import org.onosproject.ovsdb.controller.OvsdbPortNumber;
Frank Wange11a98d2016-10-26 17:04:03 +080053import org.onosproject.ovsdb.controller.OvsdbQos;
54import org.onosproject.ovsdb.controller.OvsdbQueue;
Sho SHIMIZUe4efe452015-08-26 15:06:55 -070055import org.onosproject.ovsdb.controller.OvsdbRowStore;
56import org.onosproject.ovsdb.controller.OvsdbStore;
57import org.onosproject.ovsdb.controller.OvsdbTableStore;
Sho SHIMIZUe4efe452015-08-26 15:06:55 -070058import org.onosproject.ovsdb.rfc.jsonrpc.Callback;
59import org.onosproject.ovsdb.rfc.message.OperationResult;
60import org.onosproject.ovsdb.rfc.message.TableUpdates;
Frank Wange11a98d2016-10-26 17:04:03 +080061import org.onosproject.ovsdb.rfc.notation.Column;
Sho SHIMIZUe4efe452015-08-26 15:06:55 -070062import org.onosproject.ovsdb.rfc.notation.Condition;
63import org.onosproject.ovsdb.rfc.notation.Mutation;
CNluciusa66c3972015-09-06 20:31:29 +080064import org.onosproject.ovsdb.rfc.notation.OvsdbMap;
Sho SHIMIZUe4efe452015-08-26 15:06:55 -070065import org.onosproject.ovsdb.rfc.notation.OvsdbSet;
66import org.onosproject.ovsdb.rfc.notation.Row;
Jonathan Hart51539b82015-10-29 09:53:04 -070067import org.onosproject.ovsdb.rfc.notation.Uuid;
Sho SHIMIZUe4efe452015-08-26 15:06:55 -070068import org.onosproject.ovsdb.rfc.operations.Delete;
69import org.onosproject.ovsdb.rfc.operations.Insert;
70import org.onosproject.ovsdb.rfc.operations.Mutate;
71import org.onosproject.ovsdb.rfc.operations.Operation;
72import org.onosproject.ovsdb.rfc.operations.Update;
73import org.onosproject.ovsdb.rfc.schema.ColumnSchema;
74import org.onosproject.ovsdb.rfc.schema.DatabaseSchema;
75import org.onosproject.ovsdb.rfc.schema.TableSchema;
76import org.onosproject.ovsdb.rfc.table.Bridge;
77import org.onosproject.ovsdb.rfc.table.Controller;
78import org.onosproject.ovsdb.rfc.table.Interface;
Pier Ventref5d72362016-07-17 12:02:14 +020079import org.onosproject.ovsdb.rfc.table.Mirror;
Sho SHIMIZUe4efe452015-08-26 15:06:55 -070080import org.onosproject.ovsdb.rfc.table.OvsdbTable;
81import org.onosproject.ovsdb.rfc.table.Port;
Frank Wange11a98d2016-10-26 17:04:03 +080082import org.onosproject.ovsdb.rfc.table.Qos;
83import org.onosproject.ovsdb.rfc.table.Queue;
Sho SHIMIZUe4efe452015-08-26 15:06:55 -070084import org.onosproject.ovsdb.rfc.table.TableGenerator;
85import org.onosproject.ovsdb.rfc.utils.ConditionUtil;
86import org.onosproject.ovsdb.rfc.utils.FromJsonUtil;
87import org.onosproject.ovsdb.rfc.utils.JsonRpcWriterUtil;
88import org.onosproject.ovsdb.rfc.utils.MutationUtil;
89import org.slf4j.Logger;
90import org.slf4j.LoggerFactory;
91
Ray Milkeyb1250322017-06-05 17:18:17 -070092import com.fasterxml.jackson.databind.JsonNode;
93import com.google.common.base.Function;
94import com.google.common.collect.ImmutableList;
95import com.google.common.collect.ImmutableSet;
96import com.google.common.collect.Lists;
97import com.google.common.collect.Maps;
98import com.google.common.collect.Sets;
99import com.google.common.util.concurrent.Futures;
100import com.google.common.util.concurrent.ListenableFuture;
101import com.google.common.util.concurrent.SettableFuture;
Pier Ventref5d72362016-07-17 12:02:14 +0200102
Ray Milkeyb1250322017-06-05 17:18:17 -0700103import static org.onosproject.ovsdb.controller.OvsdbConstant.BRIDGE;
104import static org.onosproject.ovsdb.controller.OvsdbConstant.BRIDGES;
105import static org.onosproject.ovsdb.controller.OvsdbConstant.CONTROLLER;
106import static org.onosproject.ovsdb.controller.OvsdbConstant.DATABASENAME;
107import static org.onosproject.ovsdb.controller.OvsdbConstant.EXTERNAL_ID;
108import static org.onosproject.ovsdb.controller.OvsdbConstant.EXTERNAL_ID_INTERFACE_ID;
109import static org.onosproject.ovsdb.controller.OvsdbConstant.INTERFACE;
110import static org.onosproject.ovsdb.controller.OvsdbConstant.INTERFACES;
111import static org.onosproject.ovsdb.controller.OvsdbConstant.MIRROR;
112import static org.onosproject.ovsdb.controller.OvsdbConstant.MIRRORS;
113import static org.onosproject.ovsdb.controller.OvsdbConstant.OFPORT;
114import static org.onosproject.ovsdb.controller.OvsdbConstant.PORT;
115import static org.onosproject.ovsdb.controller.OvsdbConstant.PORTS;
116import static org.onosproject.ovsdb.controller.OvsdbConstant.PORT_QOS;
117import static org.onosproject.ovsdb.controller.OvsdbConstant.QOS;
118import static org.onosproject.ovsdb.controller.OvsdbConstant.QOS_EXTERNAL_ID_KEY;
119import static org.onosproject.ovsdb.controller.OvsdbConstant.QUEUE;
120import static org.onosproject.ovsdb.controller.OvsdbConstant.QUEUES;
121import static org.onosproject.ovsdb.controller.OvsdbConstant.QUEUE_EXTERNAL_ID_KEY;
122import static org.onosproject.ovsdb.controller.OvsdbConstant.TYPEVXLAN;
123import static org.onosproject.ovsdb.controller.OvsdbConstant.UUID;
Hyunsun Moon1251e192016-06-07 16:57:05 -0700124
Sho SHIMIZUe4efe452015-08-26 15:06:55 -0700125/**
126 * An representation of an ovsdb client.
127 */
Hyunsun Moon1251e192016-06-07 16:57:05 -0700128public class DefaultOvsdbClient implements OvsdbProviderService, OvsdbClientService {
Sho SHIMIZUe4efe452015-08-26 15:06:55 -0700129
jaegonkim01d7c912017-01-22 22:03:38 +0900130 private static final int TRANSACTCONFIG_TIMEOUT = 3; //sec
131
Hyunsun Moon1251e192016-06-07 16:57:05 -0700132 private final Logger log = LoggerFactory.getLogger(DefaultOvsdbClient.class);
Sho SHIMIZUe4efe452015-08-26 15:06:55 -0700133
134 private Channel channel;
Sho SHIMIZUe4efe452015-08-26 15:06:55 -0700135 private OvsdbAgent agent;
136 private boolean connected;
137 private OvsdbNodeId nodeId;
138 private Callback monitorCallBack;
Sho SHIMIZUe4efe452015-08-26 15:06:55 -0700139 private OvsdbStore ovsdbStore = new OvsdbStore();
140
141 private final Map<String, String> requestMethod = Maps.newHashMap();
Hyunsun Moon1251e192016-06-07 16:57:05 -0700142 private final Map<String, SettableFuture<? extends Object>> requestResult = Maps.newHashMap();
Sho SHIMIZUe4efe452015-08-26 15:06:55 -0700143 private final Map<String, DatabaseSchema> schema = Maps.newHashMap();
Sho SHIMIZUe4efe452015-08-26 15:06:55 -0700144
Pier Ventref5d72362016-07-17 12:02:14 +0200145
Sho SHIMIZUe4efe452015-08-26 15:06:55 -0700146 /**
147 * Creates an OvsdbClient.
148 *
149 * @param nodeId ovsdb node id
150 */
151 public DefaultOvsdbClient(OvsdbNodeId nodeId) {
152 this.nodeId = nodeId;
153 }
154
155 @Override
156 public OvsdbNodeId nodeId() {
157 return nodeId;
158 }
159
160 @Override
161 public void setAgent(OvsdbAgent agent) {
162 if (this.agent == null) {
163 this.agent = agent;
164 }
165 }
166
167 @Override
168 public void setChannel(Channel channel) {
169 this.channel = channel;
170 }
171
172 @Override
173 public void setConnection(boolean connected) {
174 this.connected = connected;
175 }
176
177 @Override
178 public boolean isConnected() {
179 return this.connected;
180 }
181
182 @Override
183 public void nodeAdded() {
184 this.agent.addConnectedNode(nodeId, this);
185 }
186
187 @Override
188 public void nodeRemoved() {
189 this.agent.removeConnectedNode(nodeId);
190 channel.disconnect();
191 }
192
193 /**
194 * Gets the ovsdb table store.
195 *
196 * @param dbName the ovsdb database name
197 * @return ovsTableStore, empty if table store is find
198 */
199 private OvsdbTableStore getTableStore(String dbName) {
200 if (ovsdbStore == null) {
201 return null;
202 }
203 return ovsdbStore.getOvsdbTableStore(dbName);
204 }
205
206 /**
207 * Gets the ovsdb row store.
208 *
andreaed976a42015-10-05 14:38:25 -0700209 * @param dbName the ovsdb database name
Sho SHIMIZUe4efe452015-08-26 15:06:55 -0700210 * @param tableName the ovsdb table name
Hyunsun Moon6125c612015-10-15 10:54:44 -0700211 * @return ovsRowStore, empty store if no rows exist in the table
Sho SHIMIZUe4efe452015-08-26 15:06:55 -0700212 */
213 private OvsdbRowStore getRowStore(String dbName, String tableName) {
214 OvsdbTableStore tableStore = getTableStore(dbName);
215 if (tableStore == null) {
216 return null;
217 }
Hyunsun Moon6125c612015-10-15 10:54:44 -0700218
219 OvsdbRowStore rowStore = tableStore.getRows(tableName);
220 if (rowStore == null) {
221 rowStore = new OvsdbRowStore();
222 }
223 return rowStore;
Sho SHIMIZUe4efe452015-08-26 15:06:55 -0700224 }
225
226 /**
227 * Gets the ovsdb row.
228 *
andreaed976a42015-10-05 14:38:25 -0700229 * @param dbName the ovsdb database name
Sho SHIMIZUe4efe452015-08-26 15:06:55 -0700230 * @param tableName the ovsdb table name
andreaed976a42015-10-05 14:38:25 -0700231 * @param uuid the key of the row
Sho SHIMIZUe4efe452015-08-26 15:06:55 -0700232 * @return row, empty if row is find
233 */
234 @Override
235 public Row getRow(String dbName, String tableName, String uuid) {
236 OvsdbTableStore tableStore = getTableStore(dbName);
237 if (tableStore == null) {
238 return null;
239 }
240 OvsdbRowStore rowStore = tableStore.getRows(tableName);
241 if (rowStore == null) {
242 return null;
243 }
244 return rowStore.getRow(uuid);
245 }
246
247 @Override
248 public void removeRow(String dbName, String tableName, String uuid) {
249 OvsdbTableStore tableStore = getTableStore(dbName);
250 if (tableStore == null) {
251 return;
252 }
253 OvsdbRowStore rowStore = tableStore.getRows(tableName);
254 if (rowStore == null) {
255 return;
256 }
257 rowStore.deleteRow(uuid);
258 }
259
260 @Override
261 public void updateOvsdbStore(String dbName, String tableName, String uuid,
262 Row row) {
263 OvsdbTableStore tableStore = ovsdbStore.getOvsdbTableStore(dbName);
264 if (tableStore == null) {
265 tableStore = new OvsdbTableStore();
266 }
267 OvsdbRowStore rowStore = tableStore.getRows(tableName);
268 if (rowStore == null) {
269 rowStore = new OvsdbRowStore();
270 }
271 rowStore.insertRow(uuid, row);
272 tableStore.createOrUpdateTable(tableName, rowStore);
273 ovsdbStore.createOrUpdateOvsdbStore(dbName, tableStore);
274 }
275
Pier Ventref5d72362016-07-17 12:02:14 +0200276 /**
277 * Gets the Mirror uuid.
278 *
279 * @param mirrorName mirror name
280 * @return mirror uuid, empty if no uuid is found
281 */
282 @Override
283 public String getMirrorUuid(String mirrorName) {
284 DatabaseSchema dbSchema = schema.get(DATABASENAME);
285 OvsdbRowStore rowStore = getRowStore(DATABASENAME, MIRROR);
286 if (rowStore == null) {
287 log.warn("The mirror uuid is null");
288 return null;
289 }
290
291 ConcurrentMap<String, Row> mirrorTableRows = rowStore.getRowStore();
292 if (mirrorTableRows == null) {
293 log.warn("The mirror uuid is null");
294 return null;
295 }
296
297 for (String uuid : mirrorTableRows.keySet()) {
298 Mirror mirror = (Mirror) TableGenerator
299 .getTable(dbSchema, mirrorTableRows.get(uuid), OvsdbTable.MIRROR);
300 String name = mirror.getName();
301 if (name.contains(mirrorName)) {
302 return uuid;
303 }
304 }
305 log.warn("Mirroring not found");
306 return null;
307 }
308
309 /**
310 * Gets mirrors of the device.
311 *
312 * @param deviceId target device id
313 * @return set of mirroring; empty if no mirror is found
314 */
315 @Override
316 public Set<MirroringStatistics> getMirroringStatistics(DeviceId deviceId) {
317 Uuid bridgeUuid = getBridgeUuid(deviceId);
318 if (bridgeUuid == null) {
319 log.warn("Couldn't find bridge {} in {}", deviceId, nodeId.getIpAddress());
320 return null;
321 }
322
323 List<MirroringStatistics> mirrorings = getMirrorings(bridgeUuid);
324 if (mirrorings == null) {
325 log.warn("Couldn't find mirrors in {}", nodeId.getIpAddress());
326 return null;
327 }
328 return ImmutableSet.copyOf(mirrorings);
329 }
330
331 /**
332 * Helper method which retrieves mirrorings statistics using bridge uuid.
333 *
334 * @param bridgeUuid the uuid of the bridge
335 * @return the list of the mirrorings statistics.
336 */
337 private List<MirroringStatistics> getMirrorings(Uuid bridgeUuid) {
338 DatabaseSchema dbSchema = schema.get(DATABASENAME);
339 if (dbSchema == null) {
340 log.warn("Unable to retrieve dbSchema {}", DATABASENAME);
341 return null;
342 }
343 OvsdbRowStore rowStore = getRowStore(DATABASENAME, BRIDGE);
344 if (rowStore == null) {
345 log.warn("Unable to retrieve rowStore {} of {}", BRIDGE, DATABASENAME);
346 return null;
347 }
348
349 Row bridgeRow = rowStore.getRow(bridgeUuid.value());
350 Bridge bridge = (Bridge) TableGenerator.
351 getTable(dbSchema, bridgeRow, OvsdbTable.BRIDGE);
352
353 Set<Uuid> mirroringsUuids = (Set<Uuid>) ((OvsdbSet) bridge
354 .getMirrorsColumn().data()).set();
355
356 OvsdbRowStore mirrorRowStore = getRowStore(DATABASENAME, MIRROR);
357 if (mirrorRowStore == null) {
358 log.warn("Unable to retrieve rowStore {} of {}", MIRROR, DATABASENAME);
359 return null;
360 }
361
362 List<MirroringStatistics> mirroringStatistics = new ArrayList<>();
363 ConcurrentMap<String, Row> mirrorTableRows = mirrorRowStore.getRowStore();
364 mirrorTableRows.forEach((key, row) -> {
365 if (!mirroringsUuids.contains(Uuid.uuid(key))) {
366 return;
367 }
368 Mirror mirror = (Mirror) TableGenerator
369 .getTable(dbSchema, row, OvsdbTable.MIRROR);
370 mirroringStatistics.add(MirroringStatistics.mirroringStatistics(mirror.getName(),
371 (Map<String, Integer>) ((OvsdbMap) mirror
372 .getStatisticsColumn().data()).map()));
373 });
374 return ImmutableList.copyOf(mirroringStatistics);
375 }
376
Sho SHIMIZUe4efe452015-08-26 15:06:55 -0700377 @Override
378 public String getPortUuid(String portName, String bridgeUuid) {
Hyunsun Moon1251e192016-06-07 16:57:05 -0700379 DatabaseSchema dbSchema = schema.get(DATABASENAME);
Sho SHIMIZUe4efe452015-08-26 15:06:55 -0700380
Hyunsun Moon1251e192016-06-07 16:57:05 -0700381 Row bridgeRow = getRow(DATABASENAME, BRIDGE, bridgeUuid);
Sho SHIMIZUe4efe452015-08-26 15:06:55 -0700382 Bridge bridge = (Bridge) TableGenerator.getTable(dbSchema, bridgeRow,
383 OvsdbTable.BRIDGE);
384 if (bridge != null) {
385 OvsdbSet setPorts = (OvsdbSet) bridge.getPortsColumn().data();
386 @SuppressWarnings("unchecked")
Jonathan Hart51539b82015-10-29 09:53:04 -0700387 Set<Uuid> ports = setPorts.set();
Jon Hallcbd1b392017-01-18 20:15:44 -0800388 if (ports == null || ports.isEmpty()) {
Sho SHIMIZUe4efe452015-08-26 15:06:55 -0700389 log.warn("The port uuid is null");
390 return null;
391 }
392
Jonathan Hart51539b82015-10-29 09:53:04 -0700393 for (Uuid uuid : ports) {
Hyunsun Moon1251e192016-06-07 16:57:05 -0700394 Row portRow = getRow(DATABASENAME, PORT, uuid.value());
Sho SHIMIZUe4efe452015-08-26 15:06:55 -0700395 Port port = (Port) TableGenerator.getTable(dbSchema, portRow,
396 OvsdbTable.PORT);
397 if (port != null && portName.equalsIgnoreCase(port.getName())) {
398 return uuid.value();
399 }
400 }
Sho SHIMIZUe4efe452015-08-26 15:06:55 -0700401 }
402 return null;
403 }
404
405 @Override
Sho SHIMIZUe4efe452015-08-26 15:06:55 -0700406 public String getBridgeUuid(String bridgeName) {
Hyunsun Moon1251e192016-06-07 16:57:05 -0700407 DatabaseSchema dbSchema = schema.get(DATABASENAME);
Hyunsun Moon1251e192016-06-07 16:57:05 -0700408 OvsdbRowStore rowStore = getRowStore(DATABASENAME, BRIDGE);
Sho SHIMIZUe4efe452015-08-26 15:06:55 -0700409 if (rowStore == null) {
410 log.debug("The bridge uuid is null");
411 return null;
412 }
413
414 ConcurrentMap<String, Row> bridgeTableRows = rowStore.getRowStore();
415 if (bridgeTableRows == null) {
416 log.debug("The bridge uuid is null");
417 return null;
418 }
419
420 for (String uuid : bridgeTableRows.keySet()) {
421 Bridge bridge = (Bridge) TableGenerator
Hyunsun Moon1251e192016-06-07 16:57:05 -0700422 .getTable(dbSchema, bridgeTableRows.get(uuid), OvsdbTable.BRIDGE);
Sho SHIMIZUe4efe452015-08-26 15:06:55 -0700423 if (bridge.getName().equals(bridgeName)) {
424 return uuid;
425 }
Sho SHIMIZUe4efe452015-08-26 15:06:55 -0700426 }
427 return null;
428 }
429
Hyunsun Moondd14e8e2016-06-09 16:17:32 -0700430 private String getOvsUuid(String dbName) {
Hyunsun Moon1251e192016-06-07 16:57:05 -0700431 OvsdbRowStore rowStore = getRowStore(DATABASENAME, DATABASENAME);
Sho SHIMIZUe4efe452015-08-26 15:06:55 -0700432 if (rowStore == null) {
433 log.debug("The bridge uuid is null");
434 return null;
435 }
436 ConcurrentMap<String, Row> ovsTableRows = rowStore.getRowStore();
437 if (ovsTableRows != null) {
438 for (String uuid : ovsTableRows.keySet()) {
439 Row row = ovsTableRows.get(uuid);
440 String tableName = row.tableName();
441 if (tableName.equals(dbName)) {
442 return uuid;
443 }
444 }
445 }
446 return null;
447 }
448
449 @Override
450 public void createPort(String bridgeName, String portName) {
451 String bridgeUuid = getBridgeUuid(bridgeName);
452 if (bridgeUuid == null) {
Hyunsun Moon1251e192016-06-07 16:57:05 -0700453 log.error("Can't find bridge {} in {}", bridgeName, nodeId.getIpAddress());
Sho SHIMIZUe4efe452015-08-26 15:06:55 -0700454 return;
455 }
456
Hyunsun Moon1251e192016-06-07 16:57:05 -0700457 DatabaseSchema dbSchema = schema.get(DATABASENAME);
Sho SHIMIZUe4efe452015-08-26 15:06:55 -0700458 String portUuid = getPortUuid(portName, bridgeUuid);
Hyunsun Moon1251e192016-06-07 16:57:05 -0700459 Port port = (Port) TableGenerator.createTable(dbSchema, OvsdbTable.PORT);
Sho SHIMIZUe4efe452015-08-26 15:06:55 -0700460 port.setName(portName);
461 if (portUuid == null) {
Hyunsun Moon1251e192016-06-07 16:57:05 -0700462 insertConfig(PORT, UUID, BRIDGE, PORTS, bridgeUuid, port.getRow());
Sho SHIMIZUe4efe452015-08-26 15:06:55 -0700463 }
Sho SHIMIZUe4efe452015-08-26 15:06:55 -0700464 }
465
466 @Override
467 public void dropPort(String bridgeName, String portName) {
468 String bridgeUuid = getBridgeUuid(bridgeName);
469 if (bridgeUuid == null) {
470 log.error("Could not find Bridge {} in {}", bridgeName, nodeId);
471 return;
472 }
473
474 String portUuid = getPortUuid(portName, bridgeUuid);
475 if (portUuid != null) {
476 log.info("Port {} delete", portName);
Frank Wange11a98d2016-10-26 17:04:03 +0800477 deleteConfig(PORT, UUID, portUuid, BRIDGE, PORTS, Uuid.uuid(portUuid));
Sho SHIMIZUe4efe452015-08-26 15:06:55 -0700478 }
479 }
480
lishuai6c56f5e2015-11-17 16:38:19 +0800481 @Override
Hyunsun Moon1251e192016-06-07 16:57:05 -0700482 public boolean createBridge(OvsdbBridge ovsdbBridge) {
483 DatabaseSchema dbSchema = schema.get(DATABASENAME);
484 String ovsUuid = getOvsUuid(DATABASENAME);
Hyunsun Moon646d8c42015-10-08 20:32:44 -0700485
486 if (dbSchema == null || ovsUuid == null) {
Hyunsun Moon1251e192016-06-07 16:57:05 -0700487 log.error("Can't find database Open_vSwitch");
Hyunsun Moon646d8c42015-10-08 20:32:44 -0700488 return false;
489 }
490
Hyunsun Moon646d8c42015-10-08 20:32:44 -0700491 Bridge bridge = (Bridge) TableGenerator.createTable(dbSchema, OvsdbTable.BRIDGE);
Hyunsun Moon1251e192016-06-07 16:57:05 -0700492 bridge.setOtherConfig(ovsdbBridge.otherConfigs());
Hyunsun Moon646d8c42015-10-08 20:32:44 -0700493
Hyunsun Moon1251e192016-06-07 16:57:05 -0700494 if (ovsdbBridge.failMode().isPresent()) {
495 String failMode = ovsdbBridge.failMode().get().name().toLowerCase();
496 bridge.setFailMode(Sets.newHashSet(failMode));
Bob zhoue9795fd2016-05-12 20:18:45 +0800497 }
Hyunsun Moon646d8c42015-10-08 20:32:44 -0700498
jaegonkim80bee532017-05-15 15:16:38 +0900499 if (ovsdbBridge.datapathType().isPresent()) {
500 String datapathType = ovsdbBridge.datapathType().get();
501 bridge.setDatapathType(datapathType);
502 }
503
Hyunsun Moon1251e192016-06-07 16:57:05 -0700504 String bridgeUuid = getBridgeUuid(ovsdbBridge.name());
Hyunsun Moon98025542016-03-08 04:36:02 -0800505 if (bridgeUuid == null) {
Hyunsun Moon1251e192016-06-07 16:57:05 -0700506 bridge.setName(ovsdbBridge.name());
507 bridgeUuid = insertConfig(
508 BRIDGE, UUID, DATABASENAME, BRIDGES,
509 ovsUuid, bridge.getRow());
Hyunsun Moon98025542016-03-08 04:36:02 -0800510 } else {
Hyunsun Moon1251e192016-06-07 16:57:05 -0700511 // update the bridge if it's already existing
512 updateConfig(BRIDGE, UUID, bridgeUuid, bridge.getRow());
Hyunsun Moon98025542016-03-08 04:36:02 -0800513 }
Hyunsun Moon646d8c42015-10-08 20:32:44 -0700514
Hyunsun Moon1251e192016-06-07 16:57:05 -0700515 if (bridgeUuid == null) {
516 log.warn("Failed to create bridge {} on {}", ovsdbBridge.name(), nodeId);
Hyunsun Moon646d8c42015-10-08 20:32:44 -0700517 return false;
518 }
519
Hyunsun Moon1251e192016-06-07 16:57:05 -0700520 createPort(ovsdbBridge.name(), ovsdbBridge.name());
521 setControllersWithUuid(Uuid.uuid(bridgeUuid), ovsdbBridge.controllers());
522
523 log.info("Created bridge {}", ovsdbBridge.name());
Hyunsun Moon646d8c42015-10-08 20:32:44 -0700524 return true;
525 }
526
Hyunsun Moon1251e192016-06-07 16:57:05 -0700527 @Override
528 public ControllerInfo localController() {
529 IpAddress ipAddress = IpAddress.valueOf(((InetSocketAddress)
530 channel.localAddress()).getAddress());
531 return new ControllerInfo(ipAddress, OFPORT, "tcp");
andreaed976a42015-10-05 14:38:25 -0700532 }
533
Hyunsun Moondd14e8e2016-06-09 16:17:32 -0700534 private void setControllersWithUuid(Uuid bridgeUuid, List<ControllerInfo> controllers) {
Hyunsun Moon1251e192016-06-07 16:57:05 -0700535 DatabaseSchema dbSchema = schema.get(DATABASENAME);
andreaed976a42015-10-05 14:38:25 -0700536 if (dbSchema == null) {
537 log.debug("There is no schema");
538 return;
539 }
540 List<Controller> oldControllers = getControllers(bridgeUuid);
541 if (oldControllers == null) {
542 log.warn("There are no controllers");
543 return;
544 }
545
Jonathan Hart51539b82015-10-29 09:53:04 -0700546 Set<Uuid> newControllerUuids = new HashSet<>();
andreaed976a42015-10-05 14:38:25 -0700547
548 Set<ControllerInfo> newControllers = new HashSet<>(controllers);
549 List<Controller> removeControllers = new ArrayList<>();
550 oldControllers.forEach(controller -> {
551 ControllerInfo controllerInfo = new ControllerInfo((String) controller.getTargetColumn().data());
552 if (newControllers.contains(controllerInfo)) {
553 newControllers.remove(controllerInfo);
554 newControllerUuids.add(controller.getRow().uuid());
555 } else {
556 removeControllers.add(controller);
557 }
558 });
Hyunsun Moon1251e192016-06-07 16:57:05 -0700559 OvsdbRowStore controllerRowStore = getRowStore(DATABASENAME, CONTROLLER);
andreaed976a42015-10-05 14:38:25 -0700560 if (controllerRowStore == null) {
561 log.debug("There is no controller table");
562 return;
563 }
564
Hyunsun Moon1251e192016-06-07 16:57:05 -0700565 removeControllers.forEach(c -> deleteConfig(CONTROLLER, UUID, c.getRow().uuid().value(),
Frank Wange11a98d2016-10-26 17:04:03 +0800566 BRIDGE, "controller", c.getRow().uuid()));
andreaed976a42015-10-05 14:38:25 -0700567 newControllers.stream().map(c -> {
568 Controller controller = (Controller) TableGenerator
569 .createTable(dbSchema, OvsdbTable.CONTROLLER);
570 controller.setTarget(c.target());
571 return controller;
572 }).forEach(c -> {
Hyunsun Moon1251e192016-06-07 16:57:05 -0700573 String uuid = insertConfig(CONTROLLER, UUID, BRIDGE, "controller", bridgeUuid.value(),
andreaed976a42015-10-05 14:38:25 -0700574 c.getRow());
Jonathan Hart51539b82015-10-29 09:53:04 -0700575 newControllerUuids.add(Uuid.uuid(uuid));
andreaed976a42015-10-05 14:38:25 -0700576
577 });
578
Hyunsun Moon1251e192016-06-07 16:57:05 -0700579 OvsdbRowStore rowStore = getRowStore(DATABASENAME, BRIDGE);
andreaed976a42015-10-05 14:38:25 -0700580 if (rowStore == null) {
581 log.debug("There is no bridge table");
582 return;
583 }
584
585 Row bridgeRow = rowStore.getRow(bridgeUuid.value());
586 Bridge bridge = (Bridge) TableGenerator.getTable(dbSchema, bridgeRow, OvsdbTable.BRIDGE);
587 bridge.setController(OvsdbSet.ovsdbSet(newControllerUuids));
Hyunsun Moon1251e192016-06-07 16:57:05 -0700588 updateConfig(BRIDGE, UUID, bridgeUuid.value(), bridge.getRow());
andreaed976a42015-10-05 14:38:25 -0700589 }
590
andreaed976a42015-10-05 14:38:25 -0700591 @Override
592 public void setControllersWithDeviceId(DeviceId deviceId, List<ControllerInfo> controllers) {
Jonathan Hart51539b82015-10-29 09:53:04 -0700593 setControllersWithUuid(getBridgeUuid(deviceId), controllers);
andreaed976a42015-10-05 14:38:25 -0700594 }
595
Sho SHIMIZUe4efe452015-08-26 15:06:55 -0700596 @Override
597 public void dropBridge(String bridgeName) {
Jonathan Hart51539b82015-10-29 09:53:04 -0700598 String bridgeUuid = getBridgeUuid(bridgeName);
599 if (bridgeUuid == null) {
Sho SHIMIZUe4efe452015-08-26 15:06:55 -0700600 log.warn("Could not find bridge in node", nodeId.getIpAddress());
601 return;
602 }
Frank Wange11a98d2016-10-26 17:04:03 +0800603 deleteConfig(BRIDGE, UUID, bridgeUuid, DATABASENAME, BRIDGES, Uuid.uuid(bridgeUuid));
Hyunsun Moondd14e8e2016-06-09 16:17:32 -0700604 }
605
Frank Wange11a98d2016-10-26 17:04:03 +0800606 @Override
607 public void applyQos(PortNumber portNumber, String qosName) {
608 DatabaseSchema dbSchema = schema.get(DATABASENAME);
609 OvsdbRowStore portRowStore = getRowStore(DATABASENAME, PORT);
610 if (portRowStore == null) {
611 log.debug("The port uuid is null");
612 return;
613 }
614 OvsdbRowStore qosRowStore = getRowStore(DATABASENAME, QOS);
615 if (qosRowStore == null) {
616 log.debug("The qos uuid is null");
617 return;
618 }
619
620 // Due to Qos Table doesn't have a unique identifier except uuid, unlike
621 // Bridge or Port Table has a name column,in order to make the api more
622 // general, put qos name in external_ids column of Qos Table if this qos
623 // created by onos.
624 ConcurrentMap<String, Row> qosTableRows = qosRowStore.getRowStore();
625 ConcurrentMap<String, Row> portTableRows = portRowStore.getRowStore();
626 Row qosRow = qosTableRows.values().stream().filter(r -> {
627 OvsdbMap ovsdbMap = (OvsdbMap) (r.getColumn(EXTERNAL_ID).data());
628 return qosName.equals(ovsdbMap.map().get(QOS_EXTERNAL_ID_KEY));
629 }).findFirst().orElse(null);
630
631 Row portRow = portTableRows.values().stream()
632 .filter(r -> r.getColumn("name").data().equals(portNumber.name()))
633 .findFirst().orElse(null);
634 if (portRow != null && qosRow != null) {
635 String qosId = qosRow.uuid().value();
636 Uuid portUuid = portRow.uuid();
637 Map<String, Column> columns = new HashMap<>();
638 Row newPortRow = new Row(PORT, portUuid, columns);
639 Port newport = new Port(dbSchema, newPortRow);
640 columns.put(Port.PortColumn.QOS.columnName(), newport.getQosColumn());
641 newport.setQos(Uuid.uuid(qosId));
642 updateConfig(PORT, UUID, portUuid.value(), newport.getRow());
643 }
644 }
645
646 @Override
647 public void removeQos(PortNumber portNumber) {
648 DatabaseSchema dbSchema = schema.get(DATABASENAME);
649 OvsdbRowStore rowStore = getRowStore(DATABASENAME, PORT);
650 if (rowStore == null) {
651 log.debug("The qos uuid is null");
652 return;
653 }
654
655 ConcurrentMap<String, Row> ovsTableRows = rowStore.getRowStore();
656 Row portRow = ovsTableRows.values().stream()
657 .filter(r -> r.getColumn("name").data().equals(portNumber.name()))
658 .findFirst().orElse(null);
659 if (portRow == null) {
660 log.warn("Couldn't find port {} in ovsdb port table.", portNumber.name());
661 return;
662 }
663
664 OvsdbSet ovsdbSet = ((OvsdbSet) portRow.getColumn(PORT_QOS).data());
665 @SuppressWarnings("unchecked")
666 Set<Uuid> qosIdSet = ovsdbSet.set();
667 if (qosIdSet == null || qosIdSet.isEmpty()) {
668 return;
669 }
670 Uuid qosUuid = (Uuid) qosIdSet.toArray()[0];
671 Condition condition = ConditionUtil.isEqual(UUID, portRow.uuid());
672 List<Condition> conditions = Lists.newArrayList(condition);
673 Mutation mutation = MutationUtil.delete(PORT_QOS, qosUuid);
674 List<Mutation> mutations = Lists.newArrayList(mutation);
675
676 ArrayList<Operation> operations = Lists.newArrayList();
677 Mutate mutate = new Mutate(dbSchema.getTableSchema(PORT), conditions, mutations);
678 operations.add(mutate);
679 transactConfig(DATABASENAME, operations);
680 }
681
682 @Override
683 public boolean createQos(OvsdbQos ovsdbQos) {
684 DatabaseSchema dbSchema = schema.get(DATABASENAME);
685 Qos qos = (Qos) TableGenerator.createTable(dbSchema, OvsdbTable.QOS);
686 OvsdbRowStore rowStore = getRowStore(DATABASENAME, QOS);
687 if (rowStore == null) {
688 log.debug("The qos uuid is null");
689 return false;
690 }
691
692 ArrayList<Operation> operations = Lists.newArrayList();
693 Set<String> types = Sets.newHashSet();
694 Map<Long, Uuid> queues = Maps.newHashMap();
695
696 types.add(ovsdbQos.qosType());
697 qos.setOtherConfig(ovsdbQos.otherConfigs());
698 qos.setExternalIds(ovsdbQos.externalIds());
699 qos.setType(types);
700 if (ovsdbQos.qosQueues().isPresent()) {
701 for (Map.Entry<Long, String> entry : ovsdbQos.qosQueues().get().entrySet()) {
702 OvsdbRowStore queueRowStore = getRowStore(DATABASENAME, QUEUE);
703 if (queueRowStore != null) {
704 ConcurrentMap<String, Row> queueTableRows = queueRowStore.getRowStore();
705 Row queueRow = queueTableRows.values().stream().filter(r -> {
706 OvsdbMap ovsdbMap = (OvsdbMap) (r.getColumn(EXTERNAL_ID).data());
707 return entry.getValue().equals(ovsdbMap.map().get(QUEUE_EXTERNAL_ID_KEY));
708 }).findFirst().orElse(null);
709 if (queueRow != null) {
710 queues.put(entry.getKey(), queueRow.uuid());
711 }
712 }
713 }
714 qos.setQueues(queues);
715 }
716
717 Insert qosInsert = new Insert(dbSchema.getTableSchema(QOS), QOS, qos.getRow());
718 operations.add(qosInsert);
719 try {
720 transactConfig(DATABASENAME, operations).get();
721 } catch (InterruptedException | ExecutionException e) {
722 return false;
723 }
724 return true;
725 }
726
727 @Override
728 public void dropQos(QosId qosId) {
729 OvsdbRowStore rowStore = getRowStore(DATABASENAME, QOS);
730 if (rowStore != null) {
731 ConcurrentMap<String, Row> qosTableRows = rowStore.getRowStore();
732 Row qosRow = qosTableRows.values().stream().filter(r -> {
733 OvsdbMap ovsdbMap = (OvsdbMap) (r.getColumn(EXTERNAL_ID).data());
734 return qosId.name().equals(ovsdbMap.map().get(QOS_EXTERNAL_ID_KEY));
735 }).findFirst().orElse(null);
736 if (qosRow != null) {
737 deleteConfig(QOS, UUID, qosRow.uuid().value(), PORT, PORT_QOS, qosRow.uuid());
738 }
739 }
740 }
741 @Override
742 public OvsdbQos getQos(QosId qosId) {
743 Set<OvsdbQos> ovsdbQoses = getQoses();
744 return ovsdbQoses.stream().filter(r ->
745 qosId.name().equals(r.externalIds().get(QOS_EXTERNAL_ID_KEY))).
746 findFirst().orElse(null);
747 }
748
749 @Override
750 public Set<OvsdbQos> getQoses() {
751 Set<OvsdbQos> ovsdbQoses = new HashSet<>();
752 OvsdbRowStore rowStore = getRowStore(DATABASENAME, QOS);
753 if (rowStore == null) {
754 log.debug("The qos uuid is null");
755 return ovsdbQoses;
756 }
757 ConcurrentMap<String, Row> rows = rowStore.getRowStore();
758 for (String uuid : rows.keySet()) {
759 Row row = getRow(DATABASENAME, QOS, uuid);
760 OvsdbQos ovsdbQos = getOvsdbQos(row);
761 if (ovsdbQos != null) {
762 ovsdbQoses.add(ovsdbQos);
763 }
764 }
765 return ovsdbQoses;
766 }
767
768 @Override
769 public boolean createQueue(OvsdbQueue ovsdbQueue) {
770 DatabaseSchema dbSchema = schema.get(DATABASENAME);
771 Queue queue = (Queue) TableGenerator.createTable(dbSchema, OvsdbTable.QUEUE);
772 ArrayList<Operation> operations = Lists.newArrayList();
773 OvsdbRowStore rowStore = getRowStore(DATABASENAME, QUEUE);
774 if (rowStore == null) {
775 log.debug("The queue uuid is null");
776 return false;
777 }
778
779 if (ovsdbQueue.dscp().isPresent()) {
780 queue.setDscp(ImmutableSet.of(ovsdbQueue.dscp().get()));
781 }
782 queue.setOtherConfig(ovsdbQueue.otherConfigs());
783 queue.setExternalIds(ovsdbQueue.externalIds());
784 Insert queueInsert = new Insert(dbSchema.getTableSchema(QUEUE), QUEUE, queue.getRow());
785 operations.add(queueInsert);
786
787 try {
788 transactConfig(DATABASENAME, operations).get();
789 } catch (InterruptedException | ExecutionException e) {
790 log.error("createQueue transactConfig get exception !");
791 }
792 return true;
793 }
794
795 @Override
796 public void dropQueue(QueueId queueId) {
797 OvsdbRowStore queueRowStore = getRowStore(DATABASENAME, QUEUE);
798 if (queueRowStore == null) {
799 return;
800 }
801
802 ConcurrentMap<String, Row> queueTableRows = queueRowStore.getRowStore();
803 Row queueRow = queueTableRows.values().stream().filter(r -> {
804 OvsdbMap ovsdbMap = (OvsdbMap) (r.getColumn(EXTERNAL_ID).data());
805 return queueId.name().equals(ovsdbMap.map().get(QUEUE_EXTERNAL_ID_KEY));
806 }).findFirst().orElse(null);
807 if (queueRow == null) {
808 return;
809 }
810
811 String queueUuid = queueRow.uuid().value();
812 OvsdbRowStore qosRowStore = getRowStore(DATABASENAME, QOS);
813 if (qosRowStore != null) {
814 Map<Long, Uuid> queueMap = new HashMap<>();
815 ConcurrentMap<String, Row> qosTableRows = qosRowStore.getRowStore();
816 qosTableRows.values().stream().filter(r -> {
817 Map<Integer, Uuid> ovsdbMap = ((OvsdbMap) r.getColumn(QUEUES).data()).map();
818 Set<Integer> keySet = ovsdbMap.keySet();
819 for (Integer keyId : keySet) {
820 if (ovsdbMap.get(keyId).equals(Uuid.uuid(queueUuid))) {
821 queueMap.put(keyId.longValue(), Uuid.uuid(queueUuid));
822 return true;
823 }
824 }
825 return false;
826 }).findFirst().orElse(null);
827 deleteConfig(QUEUE, UUID, queueUuid, QOS, QUEUES, OvsdbMap.ovsdbMap(queueMap));
828 } else {
829 deleteConfig(QUEUE, UUID, queueUuid, null, null, null);
830 }
831 }
832 @Override
833 public OvsdbQueue getQueue(QueueId queueId) {
834 Set<OvsdbQueue> ovsdbQueues = getQueues();
835 return ovsdbQueues.stream().filter(r ->
836 queueId.name().equals(r.externalIds().get(QUEUE_EXTERNAL_ID_KEY))).
837 findFirst().orElse(null);
838 }
839
840 @Override
841 public Set<OvsdbQueue> getQueues() {
842 Set<OvsdbQueue> ovsdbqueues = new HashSet<>();
843 OvsdbRowStore rowStore = getRowStore(DATABASENAME, QUEUE);
844 if (rowStore == null) {
845 log.debug("The queue uuid is null");
846 return ovsdbqueues;
847 }
848 ConcurrentMap<String, Row> rows = rowStore.getRowStore();
849 for (String uuid : rows.keySet()) {
850 Row row = getRow(DATABASENAME, QUEUE, uuid);
851 OvsdbQueue ovsdbQueue = getOvsdbQueue(row);
852 if (ovsdbQueue != null) {
853 ovsdbqueues.add(ovsdbQueue);
854 }
855 }
856 return ovsdbqueues;
857 }
Pier Ventref5d72362016-07-17 12:02:14 +0200858 /**
859 * Creates a mirror port. Mirrors the traffic
860 * that goes to selectDstPort or comes from
861 * selectSrcPort or packets containing selectVlan
862 * to mirrorPort or to all ports that trunk mirrorVlan.
863 *
864 * @param mirror the OVSDB mirror description
865 * @return true if mirror creation is successful, false otherwise
866 */
867 @Override
868 public boolean createMirror(String bridgeName, OvsdbMirror mirror) {
869
870 /**
871 * Retrieves bridge's uuid. It is necessary to update
872 * Bridge table.
873 */
874 String bridgeUuid = getBridgeUuid(bridgeName);
875 if (bridgeUuid == null) {
876 log.warn("Couldn't find bridge {} in {}", bridgeName, nodeId.getIpAddress());
877 return false;
878 }
879
880 OvsdbMirror.Builder mirrorBuilder = OvsdbMirror.builder();
881
882 mirrorBuilder.mirroringName(mirror.mirroringName());
883 mirrorBuilder.selectAll(mirror.selectAll());
884
885 /**
886 * Retrieves the uuid of the monitored dst ports.
887 */
888 mirrorBuilder.monitorDstPorts(mirror.monitorDstPorts().parallelStream()
889 .map(dstPort -> {
890 String dstPortUuid = getPortUuid(dstPort.value(), bridgeUuid);
891 if (dstPortUuid != null) {
892 return Uuid.uuid(dstPortUuid);
893 }
894 log.warn("Couldn't find port {} in {}",
895 dstPort.value(), nodeId.getIpAddress());
896 return null;
897 })
898 .filter(Objects::nonNull)
899 .collect(Collectors.toSet())
900 );
901
902 /**
903 * Retrieves the uuid of the monitored src ports.
904 */
905 mirrorBuilder.monitorSrcPorts(mirror.monitorSrcPorts().parallelStream()
906 .map(srcPort -> {
907 String srcPortUuid = getPortUuid(srcPort.value(), bridgeUuid);
908 if (srcPortUuid != null) {
909 return Uuid.uuid(srcPortUuid);
910 }
911 log.warn("Couldn't find port {} in {}",
912 srcPort.value(), nodeId.getIpAddress());
913 return null;
914 }).filter(Objects::nonNull)
915 .collect(Collectors.toSet())
916 );
917
918 mirrorBuilder.monitorVlans(mirror.monitorVlans());
919 mirrorBuilder.mirrorPort(mirror.mirrorPort());
920 mirrorBuilder.mirrorVlan(mirror.mirrorVlan());
921 mirrorBuilder.externalIds(mirror.externalIds());
922 mirror = mirrorBuilder.build();
923
Jon Hallcbd1b392017-01-18 20:15:44 -0800924 if (mirror.monitorDstPorts().isEmpty() &&
925 mirror.monitorSrcPorts().isEmpty() &&
926 mirror.monitorVlans().isEmpty()) {
Pier Ventref5d72362016-07-17 12:02:14 +0200927 log.warn("Invalid monitoring data");
928 return false;
929 }
930
931 DatabaseSchema dbSchema = schema.get(DATABASENAME);
932
933 Mirror mirrorEntry = (Mirror) TableGenerator.createTable(dbSchema, OvsdbTable.MIRROR);
934 mirrorEntry.setName(mirror.mirroringName());
935 mirrorEntry.setSelectDstPort(mirror.monitorDstPorts());
936 mirrorEntry.setSelectSrcPort(mirror.monitorSrcPorts());
937 mirrorEntry.setSelectVlan(mirror.monitorVlans());
938 mirrorEntry.setExternalIds(mirror.externalIds());
939
940 /**
941 * If mirror port, retrieves the uuid of the mirror port.
942 */
943 if (mirror.mirrorPort() != null) {
944
945 String outputPortUuid = getPortUuid(mirror.mirrorPort().value(), bridgeUuid);
946 if (outputPortUuid == null) {
947 log.warn("Couldn't find port {} in {}", mirror.mirrorPort().value(), nodeId.getIpAddress());
948 return false;
949 }
950
951 mirrorEntry.setOutputPort(Uuid.uuid(outputPortUuid));
952
953 } else if (mirror.mirrorVlan() != null) {
954
955 mirrorEntry.setOutputVlan(mirror.mirrorVlan());
956
957 } else {
958 log.warn("Invalid mirror, no mirror port and no mirror vlan");
959 return false;
960 }
961
962 ArrayList<Operation> operations = Lists.newArrayList();
963 Insert mirrorInsert = new Insert(dbSchema.getTableSchema("Mirror"), "Mirror", mirrorEntry.getRow());
964 operations.add(mirrorInsert);
965
966 // update the bridge table
967 Condition condition = ConditionUtil.isEqual(UUID, Uuid.uuid(bridgeUuid));
968 Mutation mutation = MutationUtil.insert(MIRRORS, Uuid.uuid("Mirror"));
969 List<Condition> conditions = Lists.newArrayList(condition);
970 List<Mutation> mutations = Lists.newArrayList(mutation);
971 operations.add(new Mutate(dbSchema.getTableSchema("Bridge"), conditions, mutations));
972
973 transactConfig(DATABASENAME, operations);
974 log.info("Created mirror {}", mirror.mirroringName());
975 return true;
976 }
977
978 /**
979 * Drops the configuration for mirror.
980 *
Ray Milkeyef794342016-11-09 16:20:29 -0800981 * @param mirroringName name of mirror to drop
Pier Ventref5d72362016-07-17 12:02:14 +0200982 */
983 @Override
984 public void dropMirror(MirroringName mirroringName) {
985 String mirrorUuid = getMirrorUuid(mirroringName.name());
986 if (mirrorUuid != null) {
987 log.info("Deleted mirror {}", mirroringName.name());
Frank Wange11a98d2016-10-26 17:04:03 +0800988 deleteConfig(MIRROR, UUID, mirrorUuid, BRIDGE, MIRRORS, Uuid.uuid(mirrorUuid));
Pier Ventref5d72362016-07-17 12:02:14 +0200989 }
990 log.warn("Unable to delete {}", mirroringName.name());
991 return;
992 }
993
Sho SHIMIZUe4efe452015-08-26 15:06:55 -0700994 @Override
Hyunsun Moondd14e8e2016-06-09 16:17:32 -0700995 public boolean createInterface(String bridgeName, OvsdbInterface ovsdbIface) {
Hyunsun Moon646d8c42015-10-08 20:32:44 -0700996 String bridgeUuid = getBridgeUuid(bridgeName);
997 if (bridgeUuid == null) {
998 log.warn("Couldn't find bridge {} in {}", bridgeName, nodeId.getIpAddress());
999 return false;
1000 }
1001
Hyunsun Moondd14e8e2016-06-09 16:17:32 -07001002 if (getPortUuid(ovsdbIface.name(), bridgeUuid) != null) {
1003 log.warn("Interface {} already exists", ovsdbIface.name());
Hyunsun Moon646d8c42015-10-08 20:32:44 -07001004 // remove existing one and re-create?
1005 return false;
1006 }
1007
1008 ArrayList<Operation> operations = Lists.newArrayList();
Hyunsun Moon1251e192016-06-07 16:57:05 -07001009 DatabaseSchema dbSchema = schema.get(DATABASENAME);
Hyunsun Moon646d8c42015-10-08 20:32:44 -07001010
Hyunsun Moon89478662016-06-09 17:52:34 -07001011 // insert a new port with the interface name
Hyunsun Moon646d8c42015-10-08 20:32:44 -07001012 Port port = (Port) TableGenerator.createTable(dbSchema, OvsdbTable.PORT);
Hyunsun Moondd14e8e2016-06-09 16:17:32 -07001013 port.setName(ovsdbIface.name());
1014 Insert portInsert = new Insert(dbSchema.getTableSchema(PORT), PORT, port.getRow());
1015 portInsert.getRow().put(INTERFACES, Uuid.uuid(INTERFACE));
Hyunsun Moon646d8c42015-10-08 20:32:44 -07001016 operations.add(portInsert);
1017
Hyunsun Moon89478662016-06-09 17:52:34 -07001018 // update the bridge table with the new port
Hyunsun Moon1251e192016-06-07 16:57:05 -07001019 Condition condition = ConditionUtil.isEqual(UUID, Uuid.uuid(bridgeUuid));
Hyunsun Moondd14e8e2016-06-09 16:17:32 -07001020 Mutation mutation = MutationUtil.insert(PORTS, Uuid.uuid(PORT));
1021 List<Condition> conditions = Lists.newArrayList(condition);
1022 List<Mutation> mutations = Lists.newArrayList(mutation);
1023 operations.add(new Mutate(dbSchema.getTableSchema(BRIDGE), conditions, mutations));
Hyunsun Moon646d8c42015-10-08 20:32:44 -07001024
Hyunsun Moon89478662016-06-09 17:52:34 -07001025 // insert an interface
Hyunsun Moon646d8c42015-10-08 20:32:44 -07001026 Interface intf = (Interface) TableGenerator.createTable(dbSchema, OvsdbTable.INTERFACE);
Hyunsun Moondd14e8e2016-06-09 16:17:32 -07001027 intf.setName(ovsdbIface.name());
1028 intf.setType(ovsdbIface.typeToString());
1029 intf.setOptions(ovsdbIface.options());
1030 Insert intfInsert = new Insert(dbSchema.getTableSchema(INTERFACE), INTERFACE, intf.getRow());
Hyunsun Moon646d8c42015-10-08 20:32:44 -07001031 operations.add(intfInsert);
1032
Hyunsun Moon1251e192016-06-07 16:57:05 -07001033 transactConfig(DATABASENAME, operations);
Hyunsun Moon89478662016-06-09 17:52:34 -07001034 log.info("Created interface {}", ovsdbIface);
Hyunsun Moon646d8c42015-10-08 20:32:44 -07001035 return true;
1036 }
1037
1038 @Override
Hyunsun Moondd14e8e2016-06-09 16:17:32 -07001039 public boolean dropInterface(String ifaceName) {
1040 OvsdbRowStore rowStore = getRowStore(DATABASENAME, BRIDGE);
1041 if (rowStore == null) {
1042 log.warn("Failed to get BRIDGE table");
1043 return false;
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001044 }
1045
Hyunsun Moondd14e8e2016-06-09 16:17:32 -07001046 ConcurrentMap<String, Row> bridgeTableRows = rowStore.getRowStore();
1047 if (bridgeTableRows == null) {
1048 log.warn("Failed to get BRIDGE table rows");
1049 return false;
1050 }
1051
1052 // interface name is unique
1053 Optional<String> bridgeId = bridgeTableRows.keySet().stream()
1054 .filter(uuid -> getPortUuid(ifaceName, uuid) != null)
1055 .findFirst();
1056
1057 if (bridgeId.isPresent()) {
1058 String portId = getPortUuid(ifaceName, bridgeId.get());
Frank Wange11a98d2016-10-26 17:04:03 +08001059 deleteConfig(PORT, UUID, portId, BRIDGE, PORTS, Uuid.uuid(portId));
Hyunsun Moondd14e8e2016-06-09 16:17:32 -07001060 return true;
1061 } else {
1062 log.warn("Unable to find the interface with name {}", ifaceName);
1063 return false;
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001064 }
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001065 }
1066
1067 /**
1068 * Delete transact config.
1069 *
andreaed976a42015-10-05 14:38:25 -07001070 * @param childTableName child table name
1071 * @param childColumnName child column name
1072 * @param childUuid child row uuid
1073 * @param parentTableName parent table name
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001074 * @param parentColumnName parent column
Frank Wange11a98d2016-10-26 17:04:03 +08001075 * @param referencedValue referenced value
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001076 */
1077 private void deleteConfig(String childTableName, String childColumnName,
andreaed976a42015-10-05 14:38:25 -07001078 String childUuid, String parentTableName,
Frank Wange11a98d2016-10-26 17:04:03 +08001079 String parentColumnName, Object referencedValue) {
Hyunsun Moon1251e192016-06-07 16:57:05 -07001080 DatabaseSchema dbSchema = schema.get(DATABASENAME);
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001081 TableSchema childTableSchema = dbSchema.getTableSchema(childTableName);
1082
1083 ArrayList<Operation> operations = Lists.newArrayList();
Frank Wange11a98d2016-10-26 17:04:03 +08001084 if (parentTableName != null && parentColumnName != null && referencedValue != null) {
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001085 TableSchema parentTableSchema = dbSchema
1086 .getTableSchema(parentTableName);
1087 ColumnSchema parentColumnSchema = parentTableSchema
1088 .getColumnSchema(parentColumnName);
1089 List<Mutation> mutations = Lists.newArrayList();
Frank Wange11a98d2016-10-26 17:04:03 +08001090 Mutation mutation = MutationUtil.delete(parentColumnSchema.name(), referencedValue);
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001091 mutations.add(mutation);
1092 List<Condition> conditions = Lists.newArrayList();
Frank Wange11a98d2016-10-26 17:04:03 +08001093 Condition condition = ConditionUtil.includes(parentColumnName, referencedValue);
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001094 conditions.add(condition);
1095 Mutate op = new Mutate(parentTableSchema, conditions, mutations);
1096 operations.add(op);
1097 }
1098
1099 List<Condition> conditions = Lists.newArrayList();
Jonathan Hart51539b82015-10-29 09:53:04 -07001100 Condition condition = ConditionUtil.isEqual(childColumnName, Uuid.uuid(childUuid));
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001101 conditions.add(condition);
1102 Delete del = new Delete(childTableSchema, conditions);
1103 operations.add(del);
Hyunsun Moon1251e192016-06-07 16:57:05 -07001104 transactConfig(DATABASENAME, operations);
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001105 }
1106
1107 /**
1108 * Update transact config.
1109 *
andreaed976a42015-10-05 14:38:25 -07001110 * @param tableName table name
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001111 * @param columnName column name
andreaed976a42015-10-05 14:38:25 -07001112 * @param uuid uuid
1113 * @param row the config data
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001114 */
1115 private void updateConfig(String tableName, String columnName, String uuid,
andreaed976a42015-10-05 14:38:25 -07001116 Row row) {
Hyunsun Moon1251e192016-06-07 16:57:05 -07001117 DatabaseSchema dbSchema = schema.get(DATABASENAME);
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001118 TableSchema tableSchema = dbSchema.getTableSchema(tableName);
1119
1120 List<Condition> conditions = Lists.newArrayList();
Jonathan Hart51539b82015-10-29 09:53:04 -07001121 Condition condition = ConditionUtil.isEqual(columnName, Uuid.uuid(uuid));
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001122 conditions.add(condition);
1123
1124 Update update = new Update(tableSchema, row, conditions);
1125
1126 ArrayList<Operation> operations = Lists.newArrayList();
1127 operations.add(update);
1128
Hyunsun Moon1251e192016-06-07 16:57:05 -07001129 transactConfig(DATABASENAME, operations);
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001130 }
1131
1132 /**
1133 * Insert transact config.
1134 *
andreaed976a42015-10-05 14:38:25 -07001135 * @param childTableName child table name
1136 * @param childColumnName child column name
1137 * @param parentTableName parent table name
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001138 * @param parentColumnName parent column
andreaed976a42015-10-05 14:38:25 -07001139 * @param parentUuid parent uuid
1140 * @param row the config data
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001141 * @return uuid, empty if no uuid is find
1142 */
1143 private String insertConfig(String childTableName, String childColumnName,
andreaed976a42015-10-05 14:38:25 -07001144 String parentTableName, String parentColumnName,
1145 String parentUuid, Row row) {
Hyunsun Moon1251e192016-06-07 16:57:05 -07001146 DatabaseSchema dbSchema = schema.get(DATABASENAME);
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001147 TableSchema tableSchema = dbSchema.getTableSchema(childTableName);
1148
Sho SHIMIZUff18f8c2016-03-11 14:43:53 -08001149 Insert insert = new Insert(tableSchema, childTableName, row);
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001150
1151 ArrayList<Operation> operations = Lists.newArrayList();
1152 operations.add(insert);
1153
1154 if (parentTableName != null && parentColumnName != null) {
1155 TableSchema parentTableSchema = dbSchema
1156 .getTableSchema(parentTableName);
1157 ColumnSchema parentColumnSchema = parentTableSchema
1158 .getColumnSchema(parentColumnName);
1159
1160 List<Mutation> mutations = Lists.newArrayList();
1161 Mutation mutation = MutationUtil.insert(parentColumnSchema.name(),
Sho SHIMIZUff18f8c2016-03-11 14:43:53 -08001162 Uuid.uuid(childTableName));
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001163 mutations.add(mutation);
1164
1165 List<Condition> conditions = Lists.newArrayList();
Hyunsun Moon1251e192016-06-07 16:57:05 -07001166 Condition condition = ConditionUtil.isEqual(UUID, Uuid.uuid(parentUuid));
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001167 conditions.add(condition);
1168
1169 Mutate op = new Mutate(parentTableSchema, conditions, mutations);
1170 operations.add(op);
1171 }
Hyunsun Moon1251e192016-06-07 16:57:05 -07001172 if (childTableName.equalsIgnoreCase(PORT)) {
1173 log.debug("Handle port insert");
Hyunsun Moondd14e8e2016-06-09 16:17:32 -07001174 Insert intfInsert = handlePortInsertTable(row);
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001175
1176 if (intfInsert != null) {
1177 operations.add(intfInsert);
1178 }
1179
1180 Insert ins = (Insert) operations.get(0);
Hyunsun Moon1251e192016-06-07 16:57:05 -07001181 ins.getRow().put("interfaces", Uuid.uuid(INTERFACE));
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001182 }
1183
1184 List<OperationResult> results;
1185 try {
jaegonkim01d7c912017-01-22 22:03:38 +09001186 results = transactConfig(DATABASENAME, operations)
1187 .get(TRANSACTCONFIG_TIMEOUT, TimeUnit.SECONDS);
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001188 return results.get(0).getUuid().value();
jaegonkim01d7c912017-01-22 22:03:38 +09001189 } catch (TimeoutException e) {
1190 log.warn("TimeoutException thrown while to get result");
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001191 } catch (InterruptedException e) {
1192 log.warn("Interrupted while waiting to get result");
1193 Thread.currentThread().interrupt();
1194 } catch (ExecutionException e) {
1195 log.error("Exception thrown while to get result");
1196 }
1197
1198 return null;
1199 }
1200
jaegonkim01d7c912017-01-22 22:03:38 +09001201
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001202 /**
1203 * Handles port insert.
1204 *
andreaed976a42015-10-05 14:38:25 -07001205 * @param portRow row of port
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001206 * @return insert, empty if null
1207 */
Hyunsun Moondd14e8e2016-06-09 16:17:32 -07001208 private Insert handlePortInsertTable(Row portRow) {
Hyunsun Moon1251e192016-06-07 16:57:05 -07001209 DatabaseSchema dbSchema = schema.get(DATABASENAME);
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001210
Hyunsun Moon1251e192016-06-07 16:57:05 -07001211 TableSchema portTableSchema = dbSchema.getTableSchema(PORT);
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001212 ColumnSchema portColumnSchema = portTableSchema.getColumnSchema("name");
1213
1214 String portName = (String) portRow.getColumn(portColumnSchema.name()).data();
Hyunsun Moon1251e192016-06-07 16:57:05 -07001215 Interface inf = (Interface) TableGenerator.createTable(dbSchema, OvsdbTable.INTERFACE);
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001216 inf.setName(portName);
1217
Hyunsun Moon1251e192016-06-07 16:57:05 -07001218 TableSchema intfTableSchema = dbSchema.getTableSchema(INTERFACE);
1219 return new Insert(intfTableSchema, INTERFACE, inf.getRow());
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001220 }
1221
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001222 @Override
1223 public ListenableFuture<DatabaseSchema> getOvsdbSchema(String dbName) {
1224 if (dbName == null) {
1225 return null;
1226 }
1227 DatabaseSchema databaseSchema = schema.get(dbName);
1228 if (databaseSchema == null) {
1229 List<String> dbNames = new ArrayList<String>();
1230 dbNames.add(dbName);
Hyunsun Moon1251e192016-06-07 16:57:05 -07001231 Function<JsonNode, DatabaseSchema> rowFunction = input -> {
1232 log.debug("Get ovsdb database schema {}", dbName);
1233 DatabaseSchema dbSchema = FromJsonUtil.jsonNodeToDbSchema(dbName, input);
1234 if (dbSchema == null) {
1235 log.debug("Get ovsdb database schema error");
1236 return null;
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001237 }
Hyunsun Moon1251e192016-06-07 16:57:05 -07001238 schema.put(dbName, dbSchema);
1239 return dbSchema;
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001240 };
1241
1242 ListenableFuture<JsonNode> input = getSchema(dbNames);
1243 if (input != null) {
1244 return Futures.transform(input, rowFunction);
1245 }
1246 return null;
1247 } else {
1248 return Futures.immediateFuture(databaseSchema);
1249 }
1250 }
1251
1252 @Override
1253 public ListenableFuture<TableUpdates> monitorTables(String dbName, String id) {
1254 if (dbName == null) {
1255 return null;
1256 }
1257 DatabaseSchema dbSchema = schema.get(dbName);
1258 if (dbSchema != null) {
Hyunsun Moon1251e192016-06-07 16:57:05 -07001259 Function<JsonNode, TableUpdates> rowFunction = input -> {
1260 log.debug("Get table updates");
1261 TableUpdates updates = FromJsonUtil.jsonNodeToTableUpdates(input, dbSchema);
1262 if (updates == null) {
1263 log.debug("Get table updates error");
1264 return null;
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001265 }
Hyunsun Moon1251e192016-06-07 16:57:05 -07001266 return updates;
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001267 };
1268 return Futures.transform(monitor(dbSchema, id), rowFunction);
1269 }
1270 return null;
1271 }
1272
Hyunsun Moondd14e8e2016-06-09 16:17:32 -07001273 private ListenableFuture<List<OperationResult>> transactConfig(String dbName,
1274 List<Operation> operations) {
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001275 if (dbName == null) {
1276 return null;
1277 }
1278 DatabaseSchema dbSchema = schema.get(dbName);
1279 if (dbSchema != null) {
andreaed976a42015-10-05 14:38:25 -07001280 Function<List<JsonNode>, List<OperationResult>> rowFunction = (input -> {
Hyunsun Moon1251e192016-06-07 16:57:05 -07001281 log.debug("Get ovsdb operation result");
1282 List<OperationResult> result = FromJsonUtil.jsonNodeToOperationResult(input, operations);
andreaed976a42015-10-05 14:38:25 -07001283 if (result == null) {
1284 log.debug("The operation result is null");
1285 return null;
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001286 }
andreaed976a42015-10-05 14:38:25 -07001287 return result;
1288 });
Hyunsun Moon1251e192016-06-07 16:57:05 -07001289 return Futures.transform(transact(dbSchema, operations), rowFunction);
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001290 }
1291 return null;
1292 }
1293
1294 @Override
1295 public ListenableFuture<JsonNode> getSchema(List<String> dbnames) {
1296 String id = java.util.UUID.randomUUID().toString();
1297 String getSchemaString = JsonRpcWriterUtil.getSchemaStr(id, dbnames);
1298
1299 SettableFuture<JsonNode> sf = SettableFuture.create();
1300 requestResult.put(id, sf);
1301 requestMethod.put(id, "getSchema");
1302
1303 channel.writeAndFlush(getSchemaString);
1304 return sf;
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001305 }
1306
1307 @Override
1308 public ListenableFuture<List<String>> echo() {
1309 String id = java.util.UUID.randomUUID().toString();
1310 String echoString = JsonRpcWriterUtil.echoStr(id);
1311
1312 SettableFuture<List<String>> sf = SettableFuture.create();
1313 requestResult.put(id, sf);
1314 requestMethod.put(id, "echo");
1315
1316 channel.writeAndFlush(echoString);
1317 return sf;
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001318 }
1319
1320 @Override
1321 public ListenableFuture<JsonNode> monitor(DatabaseSchema dbSchema,
1322 String monitorId) {
1323 String id = java.util.UUID.randomUUID().toString();
1324 String monitorString = JsonRpcWriterUtil.monitorStr(id, monitorId,
1325 dbSchema);
1326
1327 SettableFuture<JsonNode> sf = SettableFuture.create();
1328 requestResult.put(id, sf);
1329 requestMethod.put(id, "monitor");
1330
1331 channel.writeAndFlush(monitorString);
1332 return sf;
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001333 }
1334
1335 @Override
1336 public ListenableFuture<List<String>> listDbs() {
1337 String id = java.util.UUID.randomUUID().toString();
1338 String listDbsString = JsonRpcWriterUtil.listDbsStr(id);
1339
1340 SettableFuture<List<String>> sf = SettableFuture.create();
1341 requestResult.put(id, sf);
1342 requestMethod.put(id, "listDbs");
1343
1344 channel.writeAndFlush(listDbsString);
1345 return sf;
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001346 }
1347
1348 @Override
1349 public ListenableFuture<List<JsonNode>> transact(DatabaseSchema dbSchema,
1350 List<Operation> operations) {
1351 String id = java.util.UUID.randomUUID().toString();
1352 String transactString = JsonRpcWriterUtil.transactStr(id, dbSchema,
1353 operations);
1354
1355 SettableFuture<List<JsonNode>> sf = SettableFuture.create();
1356 requestResult.put(id, sf);
1357 requestMethod.put(id, "transact");
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001358 channel.writeAndFlush(transactString);
1359 return sf;
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001360 }
1361
andreaed976a42015-10-05 14:38:25 -07001362 @SuppressWarnings({"rawtypes", "unchecked"})
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001363 @Override
1364 public void processResult(JsonNode response) {
1365 log.debug("Handle result");
1366 String requestId = response.get("id").asText();
1367 SettableFuture sf = requestResult.get(requestId);
1368 if (sf == null) {
1369 log.debug("No such future to process");
1370 return;
1371 }
1372 String methodName = requestMethod.get(requestId);
Hyunsun Moon1251e192016-06-07 16:57:05 -07001373 sf.set(FromJsonUtil.jsonResultParser(response, methodName));
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001374 }
1375
1376 @Override
1377 public void processRequest(JsonNode requestJson) {
1378 log.debug("Handle request");
1379 if (requestJson.get("method").asText().equalsIgnoreCase("echo")) {
1380 log.debug("handle echo request");
1381
1382 String replyString = FromJsonUtil.getEchoRequestStr(requestJson);
1383 channel.writeAndFlush(replyString);
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001384 } else {
Hyunsun Moon1251e192016-06-07 16:57:05 -07001385 FromJsonUtil.jsonCallbackRequestParser(requestJson, monitorCallBack);
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001386 }
1387 }
1388
1389 @Override
1390 public void setCallback(Callback monitorCallback) {
1391 this.monitorCallBack = monitorCallback;
1392 }
1393
1394 @Override
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001395 public Set<OvsdbBridge> getBridges() {
Hyunsun Moon1251e192016-06-07 16:57:05 -07001396 Set<OvsdbBridge> ovsdbBridges = new HashSet<>();
1397 OvsdbTableStore tableStore = getTableStore(DATABASENAME);
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001398 if (tableStore == null) {
MaoJianweidac220d2016-07-04 22:37:52 +08001399 return ovsdbBridges;
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001400 }
Hyunsun Moon1251e192016-06-07 16:57:05 -07001401 OvsdbRowStore rowStore = tableStore.getRows(BRIDGE);
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001402 if (rowStore == null) {
MaoJianweidac220d2016-07-04 22:37:52 +08001403 return ovsdbBridges;
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001404 }
1405 ConcurrentMap<String, Row> rows = rowStore.getRowStore();
1406 for (String uuid : rows.keySet()) {
Hyunsun Moon1251e192016-06-07 16:57:05 -07001407 Row row = getRow(DATABASENAME, BRIDGE, uuid);
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001408 OvsdbBridge ovsdbBridge = getOvsdbBridge(row);
1409 if (ovsdbBridge != null) {
1410 ovsdbBridges.add(ovsdbBridge);
1411 }
1412 }
1413 return ovsdbBridges;
1414 }
1415
1416 @Override
andreaed976a42015-10-05 14:38:25 -07001417 public Set<ControllerInfo> getControllers(DeviceId openflowDeviceId) {
Jonathan Hart51539b82015-10-29 09:53:04 -07001418 Uuid bridgeUuid = getBridgeUuid(openflowDeviceId);
andreaed976a42015-10-05 14:38:25 -07001419 if (bridgeUuid == null) {
1420 log.warn("bad bridge Uuid");
1421 return null;
1422 }
1423 List<Controller> controllers = getControllers(bridgeUuid);
1424 if (controllers == null) {
1425 log.warn("bad list of controllers");
1426 return null;
1427 }
Hyunsun Moon1251e192016-06-07 16:57:05 -07001428 return controllers.stream().map(controller -> new ControllerInfo(
1429 (String) controller.getTargetColumn()
1430 .data())).collect(Collectors.toSet());
andreaed976a42015-10-05 14:38:25 -07001431 }
1432
Jonathan Hart51539b82015-10-29 09:53:04 -07001433 private List<Controller> getControllers(Uuid bridgeUuid) {
Hyunsun Moon1251e192016-06-07 16:57:05 -07001434 DatabaseSchema dbSchema = schema.get(DATABASENAME);
andreaed976a42015-10-05 14:38:25 -07001435 if (dbSchema == null) {
1436 return null;
1437 }
Hyunsun Moon1251e192016-06-07 16:57:05 -07001438 OvsdbRowStore rowStore = getRowStore(DATABASENAME, BRIDGE);
andreaed976a42015-10-05 14:38:25 -07001439 if (rowStore == null) {
1440 log.debug("There is no bridge table");
1441 return null;
1442 }
1443
1444 Row bridgeRow = rowStore.getRow(bridgeUuid.value());
1445 Bridge bridge = (Bridge) TableGenerator.
1446 getTable(dbSchema, bridgeRow, OvsdbTable.BRIDGE);
1447
1448 //FIXME remove log
1449 log.warn("type of controller column", bridge.getControllerColumn()
1450 .data().getClass());
Jonathan Hart51539b82015-10-29 09:53:04 -07001451 Set<Uuid> controllerUuids = (Set<Uuid>) ((OvsdbSet) bridge
andreaed976a42015-10-05 14:38:25 -07001452 .getControllerColumn().data()).set();
andreaed976a42015-10-05 14:38:25 -07001453
Hyunsun Moon1251e192016-06-07 16:57:05 -07001454 OvsdbRowStore controllerRowStore = getRowStore(DATABASENAME, CONTROLLER);
andreaed976a42015-10-05 14:38:25 -07001455 if (controllerRowStore == null) {
1456 log.debug("There is no controller table");
1457 return null;
1458 }
1459
1460 List<Controller> ovsdbControllers = new ArrayList<>();
1461 ConcurrentMap<String, Row> controllerTableRows = controllerRowStore.getRowStore();
1462 controllerTableRows.forEach((key, row) -> {
Jonathan Hart51539b82015-10-29 09:53:04 -07001463 if (!controllerUuids.contains(Uuid.uuid(key))) {
andreaed976a42015-10-05 14:38:25 -07001464 return;
1465 }
1466 Controller controller = (Controller) TableGenerator
1467 .getTable(dbSchema, row, OvsdbTable.CONTROLLER);
1468 ovsdbControllers.add(controller);
1469 });
1470 return ovsdbControllers;
1471 }
1472
1473
Jonathan Hart51539b82015-10-29 09:53:04 -07001474 private Uuid getBridgeUuid(DeviceId openflowDeviceId) {
Hyunsun Moon1251e192016-06-07 16:57:05 -07001475 DatabaseSchema dbSchema = schema.get(DATABASENAME);
andreaed976a42015-10-05 14:38:25 -07001476 if (dbSchema == null) {
1477 return null;
1478 }
Hyunsun Moon1251e192016-06-07 16:57:05 -07001479 OvsdbRowStore rowStore = getRowStore(DATABASENAME, BRIDGE);
andreaed976a42015-10-05 14:38:25 -07001480 if (rowStore == null) {
1481 log.debug("There is no bridge table");
1482 return null;
1483 }
1484
1485 ConcurrentMap<String, Row> bridgeTableRows = rowStore.getRowStore();
Jonathan Hart51539b82015-10-29 09:53:04 -07001486 final AtomicReference<Uuid> uuid = new AtomicReference<>();
andreaed976a42015-10-05 14:38:25 -07001487 for (Map.Entry<String, Row> entry : bridgeTableRows.entrySet()) {
Hyunsun Moon1251e192016-06-07 16:57:05 -07001488 Bridge bridge = (Bridge) TableGenerator.getTable(
1489 dbSchema,
1490 entry.getValue(),
1491 OvsdbTable.BRIDGE);
1492
1493 if (matchesDpid(bridge, openflowDeviceId)) {
Jonathan Hart51539b82015-10-29 09:53:04 -07001494 uuid.set(Uuid.uuid(entry.getKey()));
andreaed976a42015-10-05 14:38:25 -07001495 break;
1496 }
1497 }
1498 if (uuid.get() == null) {
1499 log.debug("There is no bridge for {}", openflowDeviceId);
1500 }
1501 return uuid.get();
andreaed976a42015-10-05 14:38:25 -07001502 }
1503
1504 private static boolean matchesDpid(Bridge b, DeviceId deviceId) {
1505 String ofDpid = deviceId.toString().replace("of:", "");
1506 Set ofDeviceIds = ((OvsdbSet) b.getDatapathIdColumn().data()).set();
1507 //TODO Set<String>
1508 return ofDeviceIds.contains(ofDpid);
1509 }
1510
1511 @Override
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001512 public Set<OvsdbPort> getPorts() {
Hyunsun Moon1251e192016-06-07 16:57:05 -07001513 Set<OvsdbPort> ovsdbPorts = new HashSet<>();
1514 OvsdbTableStore tableStore = getTableStore(DATABASENAME);
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001515 if (tableStore == null) {
1516 return null;
1517 }
Hyunsun Moon1251e192016-06-07 16:57:05 -07001518 OvsdbRowStore rowStore = tableStore.getRows(INTERFACE);
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001519 if (rowStore == null) {
1520 return null;
1521 }
1522 ConcurrentMap<String, Row> rows = rowStore.getRowStore();
1523 for (String uuid : rows.keySet()) {
Hyunsun Moon1251e192016-06-07 16:57:05 -07001524 Row row = getRow(DATABASENAME, INTERFACE, uuid);
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001525 OvsdbPort ovsdbPort = getOvsdbPort(row);
1526 if (ovsdbPort != null) {
1527 ovsdbPorts.add(ovsdbPort);
1528 }
1529 }
1530 return ovsdbPorts;
1531 }
1532
1533 @Override
1534 public DatabaseSchema getDatabaseSchema(String dbName) {
1535 return schema.get(dbName);
1536 }
1537
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001538 private OvsdbPort getOvsdbPort(Row row) {
Hyunsun Moon1251e192016-06-07 16:57:05 -07001539 DatabaseSchema dbSchema = getDatabaseSchema(DATABASENAME);
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001540 Interface intf = (Interface) TableGenerator
1541 .getTable(dbSchema, row, OvsdbTable.INTERFACE);
1542 if (intf == null) {
1543 return null;
1544 }
1545 long ofPort = getOfPort(intf);
1546 String portName = intf.getName();
1547 if ((ofPort < 0) || (portName == null)) {
1548 return null;
1549 }
Hyunsun Moon1251e192016-06-07 16:57:05 -07001550 return new OvsdbPort(new OvsdbPortNumber(ofPort), new OvsdbPortName(portName));
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001551 }
1552
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001553 private OvsdbBridge getOvsdbBridge(Row row) {
Hyunsun Moon1251e192016-06-07 16:57:05 -07001554 DatabaseSchema dbSchema = getDatabaseSchema(DATABASENAME);
1555 Bridge bridge = (Bridge) TableGenerator.getTable(dbSchema, row, OvsdbTable.BRIDGE);
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001556 if (bridge == null) {
1557 return null;
1558 }
1559
1560 OvsdbSet datapathIdSet = (OvsdbSet) bridge.getDatapathIdColumn().data();
1561 @SuppressWarnings("unchecked")
1562 Set<String> datapathIds = datapathIdSet.set();
Jon Hallcbd1b392017-01-18 20:15:44 -08001563 if (datapathIds == null || datapathIds.isEmpty()) {
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001564 return null;
1565 }
1566 String datapathId = (String) datapathIds.toArray()[0];
1567 String bridgeName = bridge.getName();
1568 if ((datapathId == null) || (bridgeName == null)) {
1569 return null;
1570 }
Hyunsun Moon1251e192016-06-07 16:57:05 -07001571 return OvsdbBridge.builder().name(bridgeName).datapathId(datapathId).build();
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001572 }
1573
Frank Wange11a98d2016-10-26 17:04:03 +08001574 private OvsdbQos getOvsdbQos(Row row) {
1575 DatabaseSchema dbSchema = getDatabaseSchema(DATABASENAME);
1576 Qos qos = (Qos) TableGenerator.getTable(dbSchema, row, OvsdbTable.QOS);
1577 if (qos == null) {
1578 return null;
1579 }
1580
1581 String type = (String) qos.getTypeColumn().data();
1582 Map<String, String> otherConfigs;
1583 Map<String, String> externalIds;
1584 Map<Long, String> queues;
1585
1586 otherConfigs = ((OvsdbMap) qos.getOtherConfigColumn().data()).map();
1587 externalIds = ((OvsdbMap) qos.getExternalIdsColumn().data()).map();
1588 queues = ((OvsdbMap) qos.getQueuesColumn().data()).map();
1589 return OvsdbQos.builder().qosType(type).
1590 queues(queues).otherConfigs(otherConfigs).
1591 externalIds(externalIds).build();
1592 }
1593
1594 private OvsdbQueue getOvsdbQueue(Row row) {
1595 DatabaseSchema dbSchema = getDatabaseSchema(DATABASENAME);
1596 Queue queue = (Queue) TableGenerator.getTable(dbSchema, row, OvsdbTable.QUEUE);
1597 if (queue == null) {
1598 return null;
1599 }
1600
1601 OvsdbSet dscpOvsdbSet = ((OvsdbSet) queue.getDscpColumn().data());
1602 @SuppressWarnings("unchecked")
1603 Set<String> dscpSet = dscpOvsdbSet.set();
1604 Long dscp = null;
1605 if (dscpSet != null && !dscpSet.isEmpty()) {
1606 dscp = Long.valueOf((String) dscpSet.toArray()[0]);
1607 }
1608
1609 Map<String, String> otherConfigs;
1610 Map<String, String> externalIds;
1611
1612 otherConfigs = ((OvsdbMap) queue.getOtherConfigColumn().data()).map();
1613 externalIds = ((OvsdbMap) queue.getExternalIdsColumn().data()).map();
1614 return OvsdbQueue.builder().dscp(dscp).
1615 otherConfigs(otherConfigs).externalIds(externalIds).build();
1616 }
1617
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001618 private long getOfPort(Interface intf) {
1619 OvsdbSet ofPortSet = (OvsdbSet) intf.getOpenFlowPortColumn().data();
1620 @SuppressWarnings("unchecked")
1621 Set<Integer> ofPorts = ofPortSet.set();
Jon Hallcbd1b392017-01-18 20:15:44 -08001622 if (ofPorts == null || ofPorts.isEmpty()) {
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001623 log.debug("The ofport is null in {}", intf.getName());
1624 return -1;
1625 }
1626 // return (long) ofPorts.toArray()[0];
1627 Iterator<Integer> it = ofPorts.iterator();
1628 return Long.parseLong(it.next().toString());
1629 }
CNluciusa66c3972015-09-06 20:31:29 +08001630
1631 @Override
1632 public Set<OvsdbPort> getLocalPorts(Iterable<String> ifaceids) {
Hyunsun Moon1251e192016-06-07 16:57:05 -07001633 Set<OvsdbPort> ovsdbPorts = new HashSet<>();
1634 OvsdbTableStore tableStore = getTableStore(DATABASENAME);
CNluciusa66c3972015-09-06 20:31:29 +08001635 if (tableStore == null) {
1636 return null;
1637 }
Hyunsun Moon1251e192016-06-07 16:57:05 -07001638 OvsdbRowStore rowStore = tableStore.getRows(INTERFACE);
CNluciusa66c3972015-09-06 20:31:29 +08001639 if (rowStore == null) {
1640 return null;
1641 }
1642 ConcurrentMap<String, Row> rows = rowStore.getRowStore();
1643 for (String uuid : rows.keySet()) {
Hyunsun Moon1251e192016-06-07 16:57:05 -07001644 Row row = getRow(DATABASENAME, INTERFACE, uuid);
1645 DatabaseSchema dbSchema = getDatabaseSchema(DATABASENAME);
CNluciusa66c3972015-09-06 20:31:29 +08001646 Interface intf = (Interface) TableGenerator
1647 .getTable(dbSchema, row, OvsdbTable.INTERFACE);
1648 if (intf == null || getIfaceid(intf) == null) {
1649 continue;
1650 }
1651 String portName = intf.getName();
Hyunsun Moon1251e192016-06-07 16:57:05 -07001652 if (portName == null) {
1653 continue;
1654 }
CNluciusa66c3972015-09-06 20:31:29 +08001655 Set<String> ifaceidSet = Sets.newHashSet(ifaceids);
Hyunsun Moon1251e192016-06-07 16:57:05 -07001656 if (portName.startsWith(TYPEVXLAN) || !ifaceidSet.contains(getIfaceid(intf))) {
CNluciusa66c3972015-09-06 20:31:29 +08001657 continue;
1658 }
1659 long ofPort = getOfPort(intf);
Hyunsun Moon1251e192016-06-07 16:57:05 -07001660 if (ofPort < 0) {
CNluciusa66c3972015-09-06 20:31:29 +08001661 continue;
1662 }
Hyunsun Moon1251e192016-06-07 16:57:05 -07001663 ovsdbPorts.add(new OvsdbPort(new OvsdbPortNumber(ofPort),
1664 new OvsdbPortName(portName)));
CNluciusa66c3972015-09-06 20:31:29 +08001665 }
1666 return ovsdbPorts;
1667 }
1668
1669 private String getIfaceid(Interface intf) {
1670 OvsdbMap ovsdbMap = (OvsdbMap) intf.getExternalIdsColumn().data();
1671 @SuppressWarnings("unchecked")
1672 Map<String, String> externalIds = ovsdbMap.map();
1673 if (externalIds.isEmpty()) {
1674 log.warn("The external_ids is null");
1675 return null;
1676 }
Hyunsun Moon1251e192016-06-07 16:57:05 -07001677 String ifaceid = externalIds.get(EXTERNAL_ID_INTERFACE_ID);
CNluciusa66c3972015-09-06 20:31:29 +08001678 if (ifaceid == null) {
1679 log.warn("The ifaceid is null");
1680 return null;
1681 }
1682 return ifaceid;
1683 }
Hyunsun Moon5fb20a52015-09-25 17:02:33 -07001684
1685 @Override
1686 public void disconnect() {
1687 channel.disconnect();
1688 this.agent.removeConnectedNode(nodeId);
1689 }
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001690}