blob: c32c34104ec5cb7b093224eae55cd5c5a083599e [file] [log] [blame]
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001/*
Brian O'Connora09fe5b2017-08-03 21:12:30 -07002 * Copyright 2015-present Open Networking Foundation
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
Jonathan Hart6523e122017-11-14 09:23:49 -080018import com.fasterxml.jackson.databind.JsonNode;
19import com.google.common.base.Function;
20import com.google.common.collect.ImmutableList;
21import com.google.common.collect.ImmutableSet;
22import com.google.common.collect.Lists;
23import com.google.common.collect.Maps;
24import com.google.common.collect.Sets;
25import com.google.common.util.concurrent.Futures;
26import com.google.common.util.concurrent.ListenableFuture;
Carmelo Casconeef478a62019-01-29 18:45:22 -080027import com.google.common.util.concurrent.MoreExecutors;
Jonathan Hart6523e122017-11-14 09:23:49 -080028import com.google.common.util.concurrent.SettableFuture;
Sho SHIMIZUe4efe452015-08-26 15:06:55 -070029import io.netty.channel.Channel;
Sho SHIMIZUe4efe452015-08-26 15:06:55 -070030import org.onlab.packet.IpAddress;
andreaed976a42015-10-05 14:38:25 -070031import org.onosproject.net.DeviceId;
Frank Wange11a98d2016-10-26 17:04:03 +080032import org.onosproject.net.PortNumber;
rohitsharana127ba82018-01-16 02:17:30 +053033import org.onosproject.net.behaviour.ControlProtocolVersion;
andreaed976a42015-10-05 14:38:25 -070034import org.onosproject.net.behaviour.ControllerInfo;
nitinanandf14dccd2018-05-31 15:11:04 +053035import org.onosproject.net.behaviour.DeviceCpuStats;
36import org.onosproject.net.behaviour.DeviceMemoryStats;
Pier Ventref5d72362016-07-17 12:02:14 +020037import org.onosproject.net.behaviour.MirroringName;
Ray Milkeyb1250322017-06-05 17:18:17 -070038import org.onosproject.net.behaviour.MirroringStatistics;
Frank Wange11a98d2016-10-26 17:04:03 +080039import org.onosproject.net.behaviour.QosId;
tanbangchengc944c282017-11-12 20:42:59 +080040import org.onosproject.net.behaviour.QueueDescription;
Frank Wange11a98d2016-10-26 17:04:03 +080041import org.onosproject.net.behaviour.QueueId;
Sho SHIMIZUe4efe452015-08-26 15:06:55 -070042import org.onosproject.ovsdb.controller.OvsdbBridge;
Sho SHIMIZUe4efe452015-08-26 15:06:55 -070043import org.onosproject.ovsdb.controller.OvsdbClientService;
Hyunsun Moondd14e8e2016-06-09 16:17:32 -070044import org.onosproject.ovsdb.controller.OvsdbInterface;
Pier Ventref5d72362016-07-17 12:02:14 +020045import org.onosproject.ovsdb.controller.OvsdbMirror;
Sho SHIMIZUe4efe452015-08-26 15:06:55 -070046import org.onosproject.ovsdb.controller.OvsdbNodeId;
47import org.onosproject.ovsdb.controller.OvsdbPort;
48import org.onosproject.ovsdb.controller.OvsdbPortName;
49import org.onosproject.ovsdb.controller.OvsdbPortNumber;
Frank Wange11a98d2016-10-26 17:04:03 +080050import org.onosproject.ovsdb.controller.OvsdbQos;
51import org.onosproject.ovsdb.controller.OvsdbQueue;
Sho SHIMIZUe4efe452015-08-26 15:06:55 -070052import org.onosproject.ovsdb.controller.OvsdbRowStore;
53import org.onosproject.ovsdb.controller.OvsdbStore;
54import org.onosproject.ovsdb.controller.OvsdbTableStore;
Saritha1583a6f2017-06-16 14:42:58 +053055import org.onosproject.ovsdb.rfc.exception.ColumnSchemaNotFoundException;
56import org.onosproject.ovsdb.rfc.exception.VersionMismatchException;
Sho SHIMIZUe4efe452015-08-26 15:06:55 -070057import org.onosproject.ovsdb.rfc.jsonrpc.Callback;
58import org.onosproject.ovsdb.rfc.message.OperationResult;
59import org.onosproject.ovsdb.rfc.message.TableUpdates;
Frank Wange11a98d2016-10-26 17:04:03 +080060import org.onosproject.ovsdb.rfc.notation.Column;
Sho SHIMIZUe4efe452015-08-26 15:06:55 -070061import org.onosproject.ovsdb.rfc.notation.Condition;
62import org.onosproject.ovsdb.rfc.notation.Mutation;
CNluciusa66c3972015-09-06 20:31:29 +080063import org.onosproject.ovsdb.rfc.notation.OvsdbMap;
Sho SHIMIZUe4efe452015-08-26 15:06:55 -070064import org.onosproject.ovsdb.rfc.notation.OvsdbSet;
65import org.onosproject.ovsdb.rfc.notation.Row;
Jonathan Hart51539b82015-10-29 09:53:04 -070066import org.onosproject.ovsdb.rfc.notation.Uuid;
Sho SHIMIZUe4efe452015-08-26 15:06:55 -070067import org.onosproject.ovsdb.rfc.operations.Delete;
68import org.onosproject.ovsdb.rfc.operations.Insert;
69import org.onosproject.ovsdb.rfc.operations.Mutate;
70import org.onosproject.ovsdb.rfc.operations.Operation;
71import org.onosproject.ovsdb.rfc.operations.Update;
72import org.onosproject.ovsdb.rfc.schema.ColumnSchema;
73import org.onosproject.ovsdb.rfc.schema.DatabaseSchema;
74import org.onosproject.ovsdb.rfc.schema.TableSchema;
75import org.onosproject.ovsdb.rfc.table.Bridge;
76import org.onosproject.ovsdb.rfc.table.Controller;
77import org.onosproject.ovsdb.rfc.table.Interface;
Pier Ventref5d72362016-07-17 12:02:14 +020078import org.onosproject.ovsdb.rfc.table.Mirror;
Sho SHIMIZUe4efe452015-08-26 15:06:55 -070079import org.onosproject.ovsdb.rfc.table.OvsdbTable;
80import org.onosproject.ovsdb.rfc.table.Port;
Frank Wange11a98d2016-10-26 17:04:03 +080081import org.onosproject.ovsdb.rfc.table.Qos;
82import org.onosproject.ovsdb.rfc.table.Queue;
Sho SHIMIZUe4efe452015-08-26 15:06:55 -070083import org.onosproject.ovsdb.rfc.table.TableGenerator;
84import org.onosproject.ovsdb.rfc.utils.ConditionUtil;
85import org.onosproject.ovsdb.rfc.utils.FromJsonUtil;
86import org.onosproject.ovsdb.rfc.utils.JsonRpcWriterUtil;
87import org.onosproject.ovsdb.rfc.utils.MutationUtil;
88import org.slf4j.Logger;
89import org.slf4j.LoggerFactory;
90
Jonathan Hart6523e122017-11-14 09:23:49 -080091import java.net.InetSocketAddress;
92import java.util.ArrayList;
93import java.util.Collections;
94import java.util.HashMap;
95import java.util.HashSet;
96import java.util.Iterator;
97import java.util.List;
98import java.util.Map;
99import java.util.Objects;
100import java.util.Optional;
101import java.util.Set;
102import java.util.concurrent.ConcurrentMap;
103import java.util.concurrent.ExecutionException;
104import java.util.concurrent.TimeUnit;
105import java.util.concurrent.TimeoutException;
106import java.util.concurrent.atomic.AtomicReference;
107import java.util.function.Consumer;
108import java.util.stream.Collectors;
Pier Ventref5d72362016-07-17 12:02:14 +0200109
Daniel Park14552682018-08-28 11:25:01 +0900110import static org.onosproject.ovsdb.controller.OvsdbConstant.BRIDGE;
111import static org.onosproject.ovsdb.controller.OvsdbConstant.BRIDGES;
112import static org.onosproject.ovsdb.controller.OvsdbConstant.BRIDGE_CONTROLLER;
113import static org.onosproject.ovsdb.controller.OvsdbConstant.CONTROLLER;
114import static org.onosproject.ovsdb.controller.OvsdbConstant.DATABASENAME;
115import static org.onosproject.ovsdb.controller.OvsdbConstant.EXTERNAL_ID;
116import static org.onosproject.ovsdb.controller.OvsdbConstant.EXTERNAL_ID_INTERFACE_ID;
117import static org.onosproject.ovsdb.controller.OvsdbConstant.INTERFACE;
118import static org.onosproject.ovsdb.controller.OvsdbConstant.INTERFACES;
119import static org.onosproject.ovsdb.controller.OvsdbConstant.MIRROR;
120import static org.onosproject.ovsdb.controller.OvsdbConstant.MIRRORS;
121import static org.onosproject.ovsdb.controller.OvsdbConstant.OFPORT;
122import static org.onosproject.ovsdb.controller.OvsdbConstant.OFPORT_ERROR;
123import static org.onosproject.ovsdb.controller.OvsdbConstant.PORT;
124import static org.onosproject.ovsdb.controller.OvsdbConstant.PORTS;
125import static org.onosproject.ovsdb.controller.OvsdbConstant.PORT_QOS;
126import static org.onosproject.ovsdb.controller.OvsdbConstant.QOS;
127import static org.onosproject.ovsdb.controller.OvsdbConstant.QOS_EXTERNAL_ID_KEY;
128import static org.onosproject.ovsdb.controller.OvsdbConstant.QUEUE;
129import static org.onosproject.ovsdb.controller.OvsdbConstant.QUEUES;
130import static org.onosproject.ovsdb.controller.OvsdbConstant.QUEUE_EXTERNAL_ID_KEY;
131import static org.onosproject.ovsdb.controller.OvsdbConstant.TYPEVXLAN;
132import static org.onosproject.ovsdb.controller.OvsdbConstant.UUID;
Hyunsun Moon1251e192016-06-07 16:57:05 -0700133
Sho SHIMIZUe4efe452015-08-26 15:06:55 -0700134/**
135 * An representation of an ovsdb client.
136 */
Hyunsun Moon1251e192016-06-07 16:57:05 -0700137public class DefaultOvsdbClient implements OvsdbProviderService, OvsdbClientService {
Sho SHIMIZUe4efe452015-08-26 15:06:55 -0700138
jaegonkim01d7c912017-01-22 22:03:38 +0900139 private static final int TRANSACTCONFIG_TIMEOUT = 3; //sec
Saritha1583a6f2017-06-16 14:42:58 +0530140 private static final int OFPORT_ERROR_COMPARISON = 0;
jaegonkim01d7c912017-01-22 22:03:38 +0900141
Hyunsun Moon1251e192016-06-07 16:57:05 -0700142 private final Logger log = LoggerFactory.getLogger(DefaultOvsdbClient.class);
Sho SHIMIZUe4efe452015-08-26 15:06:55 -0700143
144 private Channel channel;
Sho SHIMIZUe4efe452015-08-26 15:06:55 -0700145 private OvsdbAgent agent;
146 private boolean connected;
147 private OvsdbNodeId nodeId;
148 private Callback monitorCallBack;
Sho SHIMIZUe4efe452015-08-26 15:06:55 -0700149 private OvsdbStore ovsdbStore = new OvsdbStore();
150
151 private final Map<String, String> requestMethod = Maps.newHashMap();
Hyunsun Moon1251e192016-06-07 16:57:05 -0700152 private final Map<String, SettableFuture<? extends Object>> requestResult = Maps.newHashMap();
Sho SHIMIZUe4efe452015-08-26 15:06:55 -0700153 private final Map<String, DatabaseSchema> schema = Maps.newHashMap();
Sho SHIMIZUe4efe452015-08-26 15:06:55 -0700154
Pier Ventref5d72362016-07-17 12:02:14 +0200155
Sho SHIMIZUe4efe452015-08-26 15:06:55 -0700156 /**
157 * Creates an OvsdbClient.
158 *
159 * @param nodeId ovsdb node id
160 */
161 public DefaultOvsdbClient(OvsdbNodeId nodeId) {
162 this.nodeId = nodeId;
163 }
164
165 @Override
166 public OvsdbNodeId nodeId() {
167 return nodeId;
168 }
169
170 @Override
171 public void setAgent(OvsdbAgent agent) {
172 if (this.agent == null) {
173 this.agent = agent;
174 }
175 }
176
177 @Override
178 public void setChannel(Channel channel) {
179 this.channel = channel;
180 }
181
182 @Override
183 public void setConnection(boolean connected) {
184 this.connected = connected;
185 }
186
187 @Override
188 public boolean isConnected() {
189 return this.connected;
190 }
191
192 @Override
193 public void nodeAdded() {
194 this.agent.addConnectedNode(nodeId, this);
195 }
196
197 @Override
198 public void nodeRemoved() {
199 this.agent.removeConnectedNode(nodeId);
200 channel.disconnect();
201 }
202
203 /**
204 * Gets the ovsdb table store.
205 *
206 * @param dbName the ovsdb database name
207 * @return ovsTableStore, empty if table store is find
208 */
209 private OvsdbTableStore getTableStore(String dbName) {
210 if (ovsdbStore == null) {
211 return null;
212 }
213 return ovsdbStore.getOvsdbTableStore(dbName);
214 }
215
216 /**
217 * Gets the ovsdb row store.
218 *
andreaed976a42015-10-05 14:38:25 -0700219 * @param dbName the ovsdb database name
Sho SHIMIZUe4efe452015-08-26 15:06:55 -0700220 * @param tableName the ovsdb table name
Hyunsun Moon6125c612015-10-15 10:54:44 -0700221 * @return ovsRowStore, empty store if no rows exist in the table
Sho SHIMIZUe4efe452015-08-26 15:06:55 -0700222 */
223 private OvsdbRowStore getRowStore(String dbName, String tableName) {
224 OvsdbTableStore tableStore = getTableStore(dbName);
225 if (tableStore == null) {
226 return null;
227 }
Hyunsun Moon6125c612015-10-15 10:54:44 -0700228
229 OvsdbRowStore rowStore = tableStore.getRows(tableName);
230 if (rowStore == null) {
231 rowStore = new OvsdbRowStore();
232 }
233 return rowStore;
Sho SHIMIZUe4efe452015-08-26 15:06:55 -0700234 }
235
236 /**
237 * Gets the ovsdb row.
238 *
andreaed976a42015-10-05 14:38:25 -0700239 * @param dbName the ovsdb database name
Sho SHIMIZUe4efe452015-08-26 15:06:55 -0700240 * @param tableName the ovsdb table name
andreaed976a42015-10-05 14:38:25 -0700241 * @param uuid the key of the row
Sho SHIMIZUe4efe452015-08-26 15:06:55 -0700242 * @return row, empty if row is find
243 */
244 @Override
245 public Row getRow(String dbName, String tableName, String uuid) {
246 OvsdbTableStore tableStore = getTableStore(dbName);
247 if (tableStore == null) {
248 return null;
249 }
250 OvsdbRowStore rowStore = tableStore.getRows(tableName);
251 if (rowStore == null) {
252 return null;
253 }
254 return rowStore.getRow(uuid);
255 }
256
257 @Override
258 public void removeRow(String dbName, String tableName, String uuid) {
259 OvsdbTableStore tableStore = getTableStore(dbName);
260 if (tableStore == null) {
261 return;
262 }
263 OvsdbRowStore rowStore = tableStore.getRows(tableName);
264 if (rowStore == null) {
265 return;
266 }
267 rowStore.deleteRow(uuid);
268 }
269
270 @Override
271 public void updateOvsdbStore(String dbName, String tableName, String uuid,
272 Row row) {
273 OvsdbTableStore tableStore = ovsdbStore.getOvsdbTableStore(dbName);
274 if (tableStore == null) {
275 tableStore = new OvsdbTableStore();
276 }
277 OvsdbRowStore rowStore = tableStore.getRows(tableName);
278 if (rowStore == null) {
279 rowStore = new OvsdbRowStore();
280 }
281 rowStore.insertRow(uuid, row);
282 tableStore.createOrUpdateTable(tableName, rowStore);
283 ovsdbStore.createOrUpdateOvsdbStore(dbName, tableStore);
284 }
285
Pier Ventref5d72362016-07-17 12:02:14 +0200286 /**
287 * Gets the Mirror uuid.
288 *
289 * @param mirrorName mirror name
290 * @return mirror uuid, empty if no uuid is found
291 */
292 @Override
293 public String getMirrorUuid(String mirrorName) {
294 DatabaseSchema dbSchema = schema.get(DATABASENAME);
295 OvsdbRowStore rowStore = getRowStore(DATABASENAME, MIRROR);
296 if (rowStore == null) {
297 log.warn("The mirror uuid is null");
298 return null;
299 }
300
301 ConcurrentMap<String, Row> mirrorTableRows = rowStore.getRowStore();
302 if (mirrorTableRows == null) {
303 log.warn("The mirror uuid is null");
304 return null;
305 }
306
307 for (String uuid : mirrorTableRows.keySet()) {
308 Mirror mirror = (Mirror) TableGenerator
309 .getTable(dbSchema, mirrorTableRows.get(uuid), OvsdbTable.MIRROR);
310 String name = mirror.getName();
311 if (name.contains(mirrorName)) {
312 return uuid;
313 }
314 }
315 log.warn("Mirroring not found");
316 return null;
317 }
318
319 /**
320 * Gets mirrors of the device.
321 *
322 * @param deviceId target device id
323 * @return set of mirroring; empty if no mirror is found
324 */
325 @Override
326 public Set<MirroringStatistics> getMirroringStatistics(DeviceId deviceId) {
327 Uuid bridgeUuid = getBridgeUuid(deviceId);
328 if (bridgeUuid == null) {
329 log.warn("Couldn't find bridge {} in {}", deviceId, nodeId.getIpAddress());
330 return null;
331 }
332
333 List<MirroringStatistics> mirrorings = getMirrorings(bridgeUuid);
334 if (mirrorings == null) {
335 log.warn("Couldn't find mirrors in {}", nodeId.getIpAddress());
336 return null;
337 }
338 return ImmutableSet.copyOf(mirrorings);
339 }
340
341 /**
342 * Helper method which retrieves mirrorings statistics using bridge uuid.
343 *
344 * @param bridgeUuid the uuid of the bridge
345 * @return the list of the mirrorings statistics.
346 */
347 private List<MirroringStatistics> getMirrorings(Uuid bridgeUuid) {
348 DatabaseSchema dbSchema = schema.get(DATABASENAME);
349 if (dbSchema == null) {
350 log.warn("Unable to retrieve dbSchema {}", DATABASENAME);
351 return null;
352 }
353 OvsdbRowStore rowStore = getRowStore(DATABASENAME, BRIDGE);
354 if (rowStore == null) {
355 log.warn("Unable to retrieve rowStore {} of {}", BRIDGE, DATABASENAME);
356 return null;
357 }
358
359 Row bridgeRow = rowStore.getRow(bridgeUuid.value());
360 Bridge bridge = (Bridge) TableGenerator.
361 getTable(dbSchema, bridgeRow, OvsdbTable.BRIDGE);
362
363 Set<Uuid> mirroringsUuids = (Set<Uuid>) ((OvsdbSet) bridge
364 .getMirrorsColumn().data()).set();
365
366 OvsdbRowStore mirrorRowStore = getRowStore(DATABASENAME, MIRROR);
367 if (mirrorRowStore == null) {
368 log.warn("Unable to retrieve rowStore {} of {}", MIRROR, DATABASENAME);
369 return null;
370 }
371
372 List<MirroringStatistics> mirroringStatistics = new ArrayList<>();
373 ConcurrentMap<String, Row> mirrorTableRows = mirrorRowStore.getRowStore();
374 mirrorTableRows.forEach((key, row) -> {
375 if (!mirroringsUuids.contains(Uuid.uuid(key))) {
376 return;
377 }
378 Mirror mirror = (Mirror) TableGenerator
379 .getTable(dbSchema, row, OvsdbTable.MIRROR);
380 mirroringStatistics.add(MirroringStatistics.mirroringStatistics(mirror.getName(),
381 (Map<String, Integer>) ((OvsdbMap) mirror
382 .getStatisticsColumn().data()).map()));
383 });
384 return ImmutableList.copyOf(mirroringStatistics);
385 }
386
Sho SHIMIZUe4efe452015-08-26 15:06:55 -0700387 @Override
388 public String getPortUuid(String portName, String bridgeUuid) {
Hyunsun Moon1251e192016-06-07 16:57:05 -0700389 DatabaseSchema dbSchema = schema.get(DATABASENAME);
Sho SHIMIZUe4efe452015-08-26 15:06:55 -0700390
Hyunsun Moon1251e192016-06-07 16:57:05 -0700391 Row bridgeRow = getRow(DATABASENAME, BRIDGE, bridgeUuid);
Sho SHIMIZUe4efe452015-08-26 15:06:55 -0700392 Bridge bridge = (Bridge) TableGenerator.getTable(dbSchema, bridgeRow,
393 OvsdbTable.BRIDGE);
394 if (bridge != null) {
395 OvsdbSet setPorts = (OvsdbSet) bridge.getPortsColumn().data();
396 @SuppressWarnings("unchecked")
Jonathan Hart51539b82015-10-29 09:53:04 -0700397 Set<Uuid> ports = setPorts.set();
Jon Hallcbd1b392017-01-18 20:15:44 -0800398 if (ports == null || ports.isEmpty()) {
Sho SHIMIZUe4efe452015-08-26 15:06:55 -0700399 log.warn("The port uuid is null");
400 return null;
401 }
402
Jonathan Hart51539b82015-10-29 09:53:04 -0700403 for (Uuid uuid : ports) {
Hyunsun Moon1251e192016-06-07 16:57:05 -0700404 Row portRow = getRow(DATABASENAME, PORT, uuid.value());
Sho SHIMIZUe4efe452015-08-26 15:06:55 -0700405 Port port = (Port) TableGenerator.getTable(dbSchema, portRow,
406 OvsdbTable.PORT);
407 if (port != null && portName.equalsIgnoreCase(port.getName())) {
408 return uuid.value();
409 }
410 }
Sho SHIMIZUe4efe452015-08-26 15:06:55 -0700411 }
412 return null;
413 }
414
415 @Override
Sho SHIMIZUe4efe452015-08-26 15:06:55 -0700416 public String getBridgeUuid(String bridgeName) {
Hyunsun Moon1251e192016-06-07 16:57:05 -0700417 DatabaseSchema dbSchema = schema.get(DATABASENAME);
Hyunsun Moon1251e192016-06-07 16:57:05 -0700418 OvsdbRowStore rowStore = getRowStore(DATABASENAME, BRIDGE);
Sho SHIMIZUe4efe452015-08-26 15:06:55 -0700419 if (rowStore == null) {
420 log.debug("The bridge uuid is null");
421 return null;
422 }
423
424 ConcurrentMap<String, Row> bridgeTableRows = rowStore.getRowStore();
425 if (bridgeTableRows == null) {
426 log.debug("The bridge uuid is null");
427 return null;
428 }
429
430 for (String uuid : bridgeTableRows.keySet()) {
431 Bridge bridge = (Bridge) TableGenerator
Hyunsun Moon1251e192016-06-07 16:57:05 -0700432 .getTable(dbSchema, bridgeTableRows.get(uuid), OvsdbTable.BRIDGE);
Sho SHIMIZUe4efe452015-08-26 15:06:55 -0700433 if (bridge.getName().equals(bridgeName)) {
434 return uuid;
435 }
Sho SHIMIZUe4efe452015-08-26 15:06:55 -0700436 }
437 return null;
438 }
439
Hyunsun Moondd14e8e2016-06-09 16:17:32 -0700440 private String getOvsUuid(String dbName) {
Hyunsun Moon1251e192016-06-07 16:57:05 -0700441 OvsdbRowStore rowStore = getRowStore(DATABASENAME, DATABASENAME);
Sho SHIMIZUe4efe452015-08-26 15:06:55 -0700442 if (rowStore == null) {
443 log.debug("The bridge uuid is null");
444 return null;
445 }
446 ConcurrentMap<String, Row> ovsTableRows = rowStore.getRowStore();
447 if (ovsTableRows != null) {
448 for (String uuid : ovsTableRows.keySet()) {
449 Row row = ovsTableRows.get(uuid);
450 String tableName = row.tableName();
451 if (tableName.equals(dbName)) {
452 return uuid;
453 }
454 }
455 }
456 return null;
457 }
458
459 @Override
460 public void createPort(String bridgeName, String portName) {
461 String bridgeUuid = getBridgeUuid(bridgeName);
462 if (bridgeUuid == null) {
Hyunsun Moon1251e192016-06-07 16:57:05 -0700463 log.error("Can't find bridge {} in {}", bridgeName, nodeId.getIpAddress());
Sho SHIMIZUe4efe452015-08-26 15:06:55 -0700464 return;
465 }
466
Hyunsun Moon1251e192016-06-07 16:57:05 -0700467 DatabaseSchema dbSchema = schema.get(DATABASENAME);
Sho SHIMIZUe4efe452015-08-26 15:06:55 -0700468 String portUuid = getPortUuid(portName, bridgeUuid);
Hyunsun Moon1251e192016-06-07 16:57:05 -0700469 Port port = (Port) TableGenerator.createTable(dbSchema, OvsdbTable.PORT);
Sho SHIMIZUe4efe452015-08-26 15:06:55 -0700470 port.setName(portName);
471 if (portUuid == null) {
Hyunsun Moon1251e192016-06-07 16:57:05 -0700472 insertConfig(PORT, UUID, BRIDGE, PORTS, bridgeUuid, port.getRow());
Sho SHIMIZUe4efe452015-08-26 15:06:55 -0700473 }
Sho SHIMIZUe4efe452015-08-26 15:06:55 -0700474 }
475
476 @Override
477 public void dropPort(String bridgeName, String portName) {
478 String bridgeUuid = getBridgeUuid(bridgeName);
479 if (bridgeUuid == null) {
480 log.error("Could not find Bridge {} in {}", bridgeName, nodeId);
481 return;
482 }
483
484 String portUuid = getPortUuid(portName, bridgeUuid);
485 if (portUuid != null) {
486 log.info("Port {} delete", portName);
Frank Wange11a98d2016-10-26 17:04:03 +0800487 deleteConfig(PORT, UUID, portUuid, BRIDGE, PORTS, Uuid.uuid(portUuid));
Sho SHIMIZUe4efe452015-08-26 15:06:55 -0700488 }
489 }
490
lishuai6c56f5e2015-11-17 16:38:19 +0800491 @Override
Hyunsun Moon1251e192016-06-07 16:57:05 -0700492 public boolean createBridge(OvsdbBridge ovsdbBridge) {
493 DatabaseSchema dbSchema = schema.get(DATABASENAME);
494 String ovsUuid = getOvsUuid(DATABASENAME);
Hyunsun Moon646d8c42015-10-08 20:32:44 -0700495
496 if (dbSchema == null || ovsUuid == null) {
Hyunsun Moon1251e192016-06-07 16:57:05 -0700497 log.error("Can't find database Open_vSwitch");
Hyunsun Moon646d8c42015-10-08 20:32:44 -0700498 return false;
499 }
500
Hyunsun Moon646d8c42015-10-08 20:32:44 -0700501 Bridge bridge = (Bridge) TableGenerator.createTable(dbSchema, OvsdbTable.BRIDGE);
Hyunsun Moon1251e192016-06-07 16:57:05 -0700502 bridge.setOtherConfig(ovsdbBridge.otherConfigs());
Hyunsun Moon646d8c42015-10-08 20:32:44 -0700503
Hyunsun Moon1251e192016-06-07 16:57:05 -0700504 if (ovsdbBridge.failMode().isPresent()) {
505 String failMode = ovsdbBridge.failMode().get().name().toLowerCase();
506 bridge.setFailMode(Sets.newHashSet(failMode));
Bob zhoue9795fd2016-05-12 20:18:45 +0800507 }
Hyunsun Moon646d8c42015-10-08 20:32:44 -0700508
jaegonkim80bee532017-05-15 15:16:38 +0900509 if (ovsdbBridge.datapathType().isPresent()) {
510 String datapathType = ovsdbBridge.datapathType().get();
511 bridge.setDatapathType(datapathType);
512 }
513
rohitsharana127ba82018-01-16 02:17:30 +0530514 if (ovsdbBridge.controlProtocols().isPresent()) {
515 bridge.setProtocols(ovsdbBridge.controlProtocols().get().stream()
516 .map(ControlProtocolVersion::toString)
517 .collect(Collectors.toCollection(HashSet::new)));
518 }
519
Hyunsun Moon1251e192016-06-07 16:57:05 -0700520 String bridgeUuid = getBridgeUuid(ovsdbBridge.name());
Hyunsun Moon98025542016-03-08 04:36:02 -0800521 if (bridgeUuid == null) {
Hyunsun Moon1251e192016-06-07 16:57:05 -0700522 bridge.setName(ovsdbBridge.name());
523 bridgeUuid = insertConfig(
524 BRIDGE, UUID, DATABASENAME, BRIDGES,
525 ovsUuid, bridge.getRow());
Hyunsun Moon98025542016-03-08 04:36:02 -0800526 } else {
Hyunsun Moon1251e192016-06-07 16:57:05 -0700527 // update the bridge if it's already existing
528 updateConfig(BRIDGE, UUID, bridgeUuid, bridge.getRow());
Hyunsun Moon98025542016-03-08 04:36:02 -0800529 }
Hyunsun Moon646d8c42015-10-08 20:32:44 -0700530
Hyunsun Moon1251e192016-06-07 16:57:05 -0700531 if (bridgeUuid == null) {
532 log.warn("Failed to create bridge {} on {}", ovsdbBridge.name(), nodeId);
Hyunsun Moon646d8c42015-10-08 20:32:44 -0700533 return false;
534 }
535
Hyunsun Moon1251e192016-06-07 16:57:05 -0700536 createPort(ovsdbBridge.name(), ovsdbBridge.name());
537 setControllersWithUuid(Uuid.uuid(bridgeUuid), ovsdbBridge.controllers());
538
539 log.info("Created bridge {}", ovsdbBridge.name());
Hyunsun Moon646d8c42015-10-08 20:32:44 -0700540 return true;
541 }
542
Hyunsun Moon1251e192016-06-07 16:57:05 -0700543 @Override
544 public ControllerInfo localController() {
545 IpAddress ipAddress = IpAddress.valueOf(((InetSocketAddress)
546 channel.localAddress()).getAddress());
547 return new ControllerInfo(ipAddress, OFPORT, "tcp");
andreaed976a42015-10-05 14:38:25 -0700548 }
549
Hyunsun Moondd14e8e2016-06-09 16:17:32 -0700550 private void setControllersWithUuid(Uuid bridgeUuid, List<ControllerInfo> controllers) {
Hyunsun Moon1251e192016-06-07 16:57:05 -0700551 DatabaseSchema dbSchema = schema.get(DATABASENAME);
andreaed976a42015-10-05 14:38:25 -0700552 if (dbSchema == null) {
553 log.debug("There is no schema");
554 return;
555 }
556 List<Controller> oldControllers = getControllers(bridgeUuid);
557 if (oldControllers == null) {
558 log.warn("There are no controllers");
559 return;
560 }
561
andreaed976a42015-10-05 14:38:25 -0700562 Set<ControllerInfo> newControllers = new HashSet<>(controllers);
563 List<Controller> removeControllers = new ArrayList<>();
564 oldControllers.forEach(controller -> {
565 ControllerInfo controllerInfo = new ControllerInfo((String) controller.getTargetColumn().data());
566 if (newControllers.contains(controllerInfo)) {
567 newControllers.remove(controllerInfo);
andreaed976a42015-10-05 14:38:25 -0700568 } else {
569 removeControllers.add(controller);
570 }
571 });
Hyunsun Moon1251e192016-06-07 16:57:05 -0700572 OvsdbRowStore controllerRowStore = getRowStore(DATABASENAME, CONTROLLER);
andreaed976a42015-10-05 14:38:25 -0700573 if (controllerRowStore == null) {
574 log.debug("There is no controller table");
575 return;
576 }
577
andreaed976a42015-10-05 14:38:25 -0700578 newControllers.stream().map(c -> {
579 Controller controller = (Controller) TableGenerator
580 .createTable(dbSchema, OvsdbTable.CONTROLLER);
581 controller.setTarget(c.target());
582 return controller;
tanbangcheng62cd4492017-11-24 21:57:05 +0800583 }).forEach(c -> insertConfig(CONTROLLER, UUID, BRIDGE, BRIDGE_CONTROLLER,
584 bridgeUuid.value(),
585 c.getRow()));
andreaed976a42015-10-05 14:38:25 -0700586
Jian Lid575a3c2019-06-12 13:11:51 +0900587 removeControllers.forEach(c -> deleteConfig(CONTROLLER, UUID, c.getRow().uuid().value(),
588 BRIDGE, BRIDGE_CONTROLLER, c.getRow().uuid()));
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();
kdarapufce5abb2018-05-10 19:37:53 +0530758 ovsdbQoses = rows.keySet().stream()
759 .map(uuid -> getRow(DATABASENAME, QOS, uuid))
760 .map(this::getOvsdbQos)
761 .filter(Objects::nonNull)
762 .collect(Collectors.toSet());
Frank Wange11a98d2016-10-26 17:04:03 +0800763 return ovsdbQoses;
764 }
765
766 @Override
tanbangchengc944c282017-11-12 20:42:59 +0800767 public void bindQueues(QosId qosId, Map<Long, QueueDescription> queues) {
768 DatabaseSchema dbSchema = schema.get(DATABASENAME);
769 OvsdbRowStore qosRowStore = getRowStore(DATABASENAME, QOS);
770 if (qosRowStore == null) {
771 log.debug("The qos uuid is null");
772 return;
773 }
774 OvsdbRowStore queueRowStore = getRowStore(DATABASENAME, QUEUE);
775 if (queueRowStore == null) {
776 log.debug("The queue uuid is null");
777 return;
778 }
779
780 ConcurrentMap<String, Row> qosTableRows = qosRowStore.getRowStore();
781 ConcurrentMap<String, Row> queueTableRows = queueRowStore.getRowStore();
782
783 Row qosRow = qosTableRows.values().stream().filter(r -> {
784 OvsdbMap ovsdbMap = (OvsdbMap) (r.getColumn(EXTERNAL_ID).data());
785 return qosId.name().equals(ovsdbMap.map().get(QOS_EXTERNAL_ID_KEY));
786 }).findFirst().orElse(null);
787
788 if (qosRow == null) {
789 log.warn("Can't find QoS {}", qosId);
790 return;
791 }
792
793 Uuid qosUuid = qosRow.uuid();
794
kdarapufce5abb2018-05-10 19:37:53 +0530795 Map<Long, Uuid> newQueues = new HashMap<>();
tanbangchengc944c282017-11-12 20:42:59 +0800796 for (Map.Entry<Long, QueueDescription> entry : queues.entrySet()) {
797 Row queueRow = queueTableRows.values().stream().filter(r -> {
798 OvsdbMap ovsdbMap = (OvsdbMap) (r.getColumn(EXTERNAL_ID).data());
799 return entry.getValue().queueId().name().equals(ovsdbMap.map().get(QUEUE_EXTERNAL_ID_KEY));
800 }).findFirst().orElse(null);
801 if (queueRow != null) {
802 newQueues.put(entry.getKey(), queueRow.uuid());
803 }
804 }
805
806 // update the qos table
807 ArrayList<Operation> operations = Lists.newArrayList();
808 Condition condition = ConditionUtil.isEqual(UUID, qosUuid);
809 Mutation mutation = MutationUtil.insert(QUEUES, newQueues);
810 List<Condition> conditions = Collections.singletonList(condition);
811 List<Mutation> mutations = Collections.singletonList(mutation);
812 operations.add(new Mutate(dbSchema.getTableSchema(QOS), conditions, mutations));
813
814 transactConfig(DATABASENAME, operations);
815 }
816
817
818 @SuppressWarnings("unchecked")
819 @Override
820 public void unbindQueues(QosId qosId, List<Long> queueKeys) {
821 DatabaseSchema dbSchema = schema.get(DATABASENAME);
822 OvsdbRowStore qosRowStore = getRowStore(DATABASENAME, QOS);
823 if (qosRowStore == null) {
824 return;
825 }
826
827 ConcurrentMap<String, Row> qosTableRows = qosRowStore.getRowStore();
828
829 Row qosRow = qosTableRows.values().stream().filter(r -> {
830 OvsdbMap ovsdbMap = (OvsdbMap) (r.getColumn(EXTERNAL_ID).data());
831 return qosId.name().equals(ovsdbMap.map().get(QOS_EXTERNAL_ID_KEY));
832 }).findFirst().orElse(null);
833
834 if (qosRow == null) {
835 log.warn("Can't find QoS {}", qosId);
836 return;
837 }
838
kdarapufce5abb2018-05-10 19:37:53 +0530839 Map<Long, Uuid> deleteQueuesMap;
tanbangchengc944c282017-11-12 20:42:59 +0800840 Map<Integer, Uuid> queuesMap = ((OvsdbMap) qosRow.getColumn(QUEUES).data()).map();
841
kdarapufce5abb2018-05-10 19:37:53 +0530842 deleteQueuesMap = queueKeys.stream()
843 .filter(key -> queuesMap.containsKey(key.intValue()))
844 .collect(Collectors.toMap(key -> key, key -> queuesMap.get(key.intValue()), (a, b) -> b));
tanbangchengc944c282017-11-12 20:42:59 +0800845
846 if (deleteQueuesMap.size() != 0) {
847 TableSchema parentTableSchema = dbSchema
848 .getTableSchema(QOS);
849 ColumnSchema parentColumnSchema = parentTableSchema
850 .getColumnSchema(QUEUES);
851
852 Mutation mutation = MutationUtil.delete(parentColumnSchema.name(), OvsdbMap.ovsdbMap(deleteQueuesMap));
853 List<Mutation> mutations = Collections.singletonList(mutation);
854
855 Condition condition = ConditionUtil.isEqual(UUID, qosRow.uuid());
856 List<Condition> conditionList = Collections.singletonList(condition);
857 List<Operation> operations = Collections.singletonList(
858 new Mutate(parentTableSchema, conditionList, mutations));
859
860 transactConfig(DATABASENAME, operations);
861 }
862 }
863
864
865 @Override
Frank Wange11a98d2016-10-26 17:04:03 +0800866 public boolean createQueue(OvsdbQueue ovsdbQueue) {
867 DatabaseSchema dbSchema = schema.get(DATABASENAME);
868 Queue queue = (Queue) TableGenerator.createTable(dbSchema, OvsdbTable.QUEUE);
869 ArrayList<Operation> operations = Lists.newArrayList();
870 OvsdbRowStore rowStore = getRowStore(DATABASENAME, QUEUE);
871 if (rowStore == null) {
872 log.debug("The queue uuid is null");
873 return false;
874 }
875
876 if (ovsdbQueue.dscp().isPresent()) {
877 queue.setDscp(ImmutableSet.of(ovsdbQueue.dscp().get()));
878 }
879 queue.setOtherConfig(ovsdbQueue.otherConfigs());
880 queue.setExternalIds(ovsdbQueue.externalIds());
881 Insert queueInsert = new Insert(dbSchema.getTableSchema(QUEUE), QUEUE, queue.getRow());
882 operations.add(queueInsert);
883
884 try {
885 transactConfig(DATABASENAME, operations).get();
886 } catch (InterruptedException | ExecutionException e) {
887 log.error("createQueue transactConfig get exception !");
888 }
889 return true;
890 }
891
892 @Override
893 public void dropQueue(QueueId queueId) {
894 OvsdbRowStore queueRowStore = getRowStore(DATABASENAME, QUEUE);
895 if (queueRowStore == null) {
896 return;
897 }
898
899 ConcurrentMap<String, Row> queueTableRows = queueRowStore.getRowStore();
900 Row queueRow = queueTableRows.values().stream().filter(r -> {
901 OvsdbMap ovsdbMap = (OvsdbMap) (r.getColumn(EXTERNAL_ID).data());
902 return queueId.name().equals(ovsdbMap.map().get(QUEUE_EXTERNAL_ID_KEY));
903 }).findFirst().orElse(null);
904 if (queueRow == null) {
905 return;
906 }
907
908 String queueUuid = queueRow.uuid().value();
909 OvsdbRowStore qosRowStore = getRowStore(DATABASENAME, QOS);
910 if (qosRowStore != null) {
911 Map<Long, Uuid> queueMap = new HashMap<>();
912 ConcurrentMap<String, Row> qosTableRows = qosRowStore.getRowStore();
913 qosTableRows.values().stream().filter(r -> {
914 Map<Integer, Uuid> ovsdbMap = ((OvsdbMap) r.getColumn(QUEUES).data()).map();
915 Set<Integer> keySet = ovsdbMap.keySet();
916 for (Integer keyId : keySet) {
917 if (ovsdbMap.get(keyId).equals(Uuid.uuid(queueUuid))) {
918 queueMap.put(keyId.longValue(), Uuid.uuid(queueUuid));
919 return true;
920 }
921 }
922 return false;
923 }).findFirst().orElse(null);
924 deleteConfig(QUEUE, UUID, queueUuid, QOS, QUEUES, OvsdbMap.ovsdbMap(queueMap));
925 } else {
926 deleteConfig(QUEUE, UUID, queueUuid, null, null, null);
927 }
928 }
929 @Override
930 public OvsdbQueue getQueue(QueueId queueId) {
931 Set<OvsdbQueue> ovsdbQueues = getQueues();
932 return ovsdbQueues.stream().filter(r ->
933 queueId.name().equals(r.externalIds().get(QUEUE_EXTERNAL_ID_KEY))).
934 findFirst().orElse(null);
935 }
936
937 @Override
938 public Set<OvsdbQueue> getQueues() {
939 Set<OvsdbQueue> ovsdbqueues = new HashSet<>();
940 OvsdbRowStore rowStore = getRowStore(DATABASENAME, QUEUE);
941 if (rowStore == null) {
942 log.debug("The queue uuid is null");
943 return ovsdbqueues;
944 }
945 ConcurrentMap<String, Row> rows = rowStore.getRowStore();
kdarapufce5abb2018-05-10 19:37:53 +0530946 ovsdbqueues = rows.keySet()
947 .stream()
948 .map(uuid -> getRow(DATABASENAME, QUEUE, uuid))
949 .map(this::getOvsdbQueue)
950 .filter(Objects::nonNull)
951 .collect(Collectors.toSet());
Frank Wange11a98d2016-10-26 17:04:03 +0800952 return ovsdbqueues;
953 }
Pier Ventref5d72362016-07-17 12:02:14 +0200954 /**
955 * Creates a mirror port. Mirrors the traffic
956 * that goes to selectDstPort or comes from
957 * selectSrcPort or packets containing selectVlan
958 * to mirrorPort or to all ports that trunk mirrorVlan.
959 *
960 * @param mirror the OVSDB mirror description
961 * @return true if mirror creation is successful, false otherwise
962 */
963 @Override
964 public boolean createMirror(String bridgeName, OvsdbMirror mirror) {
965
966 /**
967 * Retrieves bridge's uuid. It is necessary to update
968 * Bridge table.
969 */
970 String bridgeUuid = getBridgeUuid(bridgeName);
971 if (bridgeUuid == null) {
972 log.warn("Couldn't find bridge {} in {}", bridgeName, nodeId.getIpAddress());
973 return false;
974 }
975
976 OvsdbMirror.Builder mirrorBuilder = OvsdbMirror.builder();
977
978 mirrorBuilder.mirroringName(mirror.mirroringName());
979 mirrorBuilder.selectAll(mirror.selectAll());
980
981 /**
982 * Retrieves the uuid of the monitored dst ports.
983 */
984 mirrorBuilder.monitorDstPorts(mirror.monitorDstPorts().parallelStream()
985 .map(dstPort -> {
986 String dstPortUuid = getPortUuid(dstPort.value(), bridgeUuid);
987 if (dstPortUuid != null) {
988 return Uuid.uuid(dstPortUuid);
989 }
990 log.warn("Couldn't find port {} in {}",
991 dstPort.value(), nodeId.getIpAddress());
992 return null;
993 })
994 .filter(Objects::nonNull)
995 .collect(Collectors.toSet())
996 );
997
998 /**
999 * Retrieves the uuid of the monitored src ports.
1000 */
1001 mirrorBuilder.monitorSrcPorts(mirror.monitorSrcPorts().parallelStream()
1002 .map(srcPort -> {
1003 String srcPortUuid = getPortUuid(srcPort.value(), bridgeUuid);
1004 if (srcPortUuid != null) {
1005 return Uuid.uuid(srcPortUuid);
1006 }
1007 log.warn("Couldn't find port {} in {}",
1008 srcPort.value(), nodeId.getIpAddress());
1009 return null;
1010 }).filter(Objects::nonNull)
1011 .collect(Collectors.toSet())
1012 );
1013
1014 mirrorBuilder.monitorVlans(mirror.monitorVlans());
1015 mirrorBuilder.mirrorPort(mirror.mirrorPort());
1016 mirrorBuilder.mirrorVlan(mirror.mirrorVlan());
1017 mirrorBuilder.externalIds(mirror.externalIds());
1018 mirror = mirrorBuilder.build();
1019
Jon Hallcbd1b392017-01-18 20:15:44 -08001020 if (mirror.monitorDstPorts().isEmpty() &&
1021 mirror.monitorSrcPorts().isEmpty() &&
1022 mirror.monitorVlans().isEmpty()) {
Pier Ventref5d72362016-07-17 12:02:14 +02001023 log.warn("Invalid monitoring data");
1024 return false;
1025 }
1026
1027 DatabaseSchema dbSchema = schema.get(DATABASENAME);
1028
1029 Mirror mirrorEntry = (Mirror) TableGenerator.createTable(dbSchema, OvsdbTable.MIRROR);
1030 mirrorEntry.setName(mirror.mirroringName());
1031 mirrorEntry.setSelectDstPort(mirror.monitorDstPorts());
1032 mirrorEntry.setSelectSrcPort(mirror.monitorSrcPorts());
1033 mirrorEntry.setSelectVlan(mirror.monitorVlans());
1034 mirrorEntry.setExternalIds(mirror.externalIds());
1035
1036 /**
1037 * If mirror port, retrieves the uuid of the mirror port.
1038 */
1039 if (mirror.mirrorPort() != null) {
1040
1041 String outputPortUuid = getPortUuid(mirror.mirrorPort().value(), bridgeUuid);
1042 if (outputPortUuid == null) {
1043 log.warn("Couldn't find port {} in {}", mirror.mirrorPort().value(), nodeId.getIpAddress());
1044 return false;
1045 }
1046
1047 mirrorEntry.setOutputPort(Uuid.uuid(outputPortUuid));
1048
1049 } else if (mirror.mirrorVlan() != null) {
1050
1051 mirrorEntry.setOutputVlan(mirror.mirrorVlan());
1052
1053 } else {
1054 log.warn("Invalid mirror, no mirror port and no mirror vlan");
1055 return false;
1056 }
1057
1058 ArrayList<Operation> operations = Lists.newArrayList();
1059 Insert mirrorInsert = new Insert(dbSchema.getTableSchema("Mirror"), "Mirror", mirrorEntry.getRow());
1060 operations.add(mirrorInsert);
1061
1062 // update the bridge table
1063 Condition condition = ConditionUtil.isEqual(UUID, Uuid.uuid(bridgeUuid));
1064 Mutation mutation = MutationUtil.insert(MIRRORS, Uuid.uuid("Mirror"));
1065 List<Condition> conditions = Lists.newArrayList(condition);
1066 List<Mutation> mutations = Lists.newArrayList(mutation);
1067 operations.add(new Mutate(dbSchema.getTableSchema("Bridge"), conditions, mutations));
1068
1069 transactConfig(DATABASENAME, operations);
1070 log.info("Created mirror {}", mirror.mirroringName());
1071 return true;
1072 }
1073
1074 /**
1075 * Drops the configuration for mirror.
1076 *
Ray Milkeyef794342016-11-09 16:20:29 -08001077 * @param mirroringName name of mirror to drop
Pier Ventref5d72362016-07-17 12:02:14 +02001078 */
1079 @Override
1080 public void dropMirror(MirroringName mirroringName) {
1081 String mirrorUuid = getMirrorUuid(mirroringName.name());
1082 if (mirrorUuid != null) {
1083 log.info("Deleted mirror {}", mirroringName.name());
Frank Wange11a98d2016-10-26 17:04:03 +08001084 deleteConfig(MIRROR, UUID, mirrorUuid, BRIDGE, MIRRORS, Uuid.uuid(mirrorUuid));
Pier Ventref5d72362016-07-17 12:02:14 +02001085 }
1086 log.warn("Unable to delete {}", mirroringName.name());
1087 return;
1088 }
1089
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001090 @Override
Hyunsun Moondd14e8e2016-06-09 16:17:32 -07001091 public boolean createInterface(String bridgeName, OvsdbInterface ovsdbIface) {
Hyunsun Moon646d8c42015-10-08 20:32:44 -07001092 String bridgeUuid = getBridgeUuid(bridgeName);
1093 if (bridgeUuid == null) {
1094 log.warn("Couldn't find bridge {} in {}", bridgeName, nodeId.getIpAddress());
1095 return false;
1096 }
1097
Hyunsun Moondd14e8e2016-06-09 16:17:32 -07001098 if (getPortUuid(ovsdbIface.name(), bridgeUuid) != null) {
1099 log.warn("Interface {} already exists", ovsdbIface.name());
Hyunsun Moon646d8c42015-10-08 20:32:44 -07001100 return false;
1101 }
1102
1103 ArrayList<Operation> operations = Lists.newArrayList();
Hyunsun Moon1251e192016-06-07 16:57:05 -07001104 DatabaseSchema dbSchema = schema.get(DATABASENAME);
Hyunsun Moon646d8c42015-10-08 20:32:44 -07001105
Hyunsun Moon89478662016-06-09 17:52:34 -07001106 // insert a new port with the interface name
Hyunsun Moon646d8c42015-10-08 20:32:44 -07001107 Port port = (Port) TableGenerator.createTable(dbSchema, OvsdbTable.PORT);
Hyunsun Moondd14e8e2016-06-09 16:17:32 -07001108 port.setName(ovsdbIface.name());
1109 Insert portInsert = new Insert(dbSchema.getTableSchema(PORT), PORT, port.getRow());
1110 portInsert.getRow().put(INTERFACES, Uuid.uuid(INTERFACE));
Hyunsun Moon646d8c42015-10-08 20:32:44 -07001111 operations.add(portInsert);
1112
Hyunsun Moon89478662016-06-09 17:52:34 -07001113 // update the bridge table with the new port
Hyunsun Moon1251e192016-06-07 16:57:05 -07001114 Condition condition = ConditionUtil.isEqual(UUID, Uuid.uuid(bridgeUuid));
Hyunsun Moondd14e8e2016-06-09 16:17:32 -07001115 Mutation mutation = MutationUtil.insert(PORTS, Uuid.uuid(PORT));
1116 List<Condition> conditions = Lists.newArrayList(condition);
1117 List<Mutation> mutations = Lists.newArrayList(mutation);
1118 operations.add(new Mutate(dbSchema.getTableSchema(BRIDGE), conditions, mutations));
Hyunsun Moon646d8c42015-10-08 20:32:44 -07001119
Hyunsun Moon646d8c42015-10-08 20:32:44 -07001120 Interface intf = (Interface) TableGenerator.createTable(dbSchema, OvsdbTable.INTERFACE);
Hyunsun Moondd14e8e2016-06-09 16:17:32 -07001121 intf.setName(ovsdbIface.name());
jaegonkim256f2c12017-05-26 00:03:42 +09001122
Jian Lif5c92762019-05-17 19:50:28 +09001123 if (ovsdbIface.type() != null) {
1124 intf.setType(ovsdbIface.typeToString());
1125 }
jaegonkim256f2c12017-05-26 00:03:42 +09001126
1127 if (ovsdbIface.mtu().isPresent()) {
1128 Set<Long> mtuSet = Sets.newConcurrentHashSet();
1129 mtuSet.add(ovsdbIface.mtu().get());
1130 intf.setMtu(mtuSet);
1131 intf.setMtuRequest(mtuSet);
1132 }
1133
Hyunsun Moondd14e8e2016-06-09 16:17:32 -07001134 intf.setOptions(ovsdbIface.options());
Jian Lif5c92762019-05-17 19:50:28 +09001135
1136 ovsdbIface.data().forEach((k, v) -> {
1137 if (k == Interface.InterfaceColumn.EXTERNALIDS) {
1138 intf.setExternalIds(v);
1139 }
1140 });
1141
Hyunsun Moondd14e8e2016-06-09 16:17:32 -07001142 Insert intfInsert = new Insert(dbSchema.getTableSchema(INTERFACE), INTERFACE, intf.getRow());
Hyunsun Moon646d8c42015-10-08 20:32:44 -07001143 operations.add(intfInsert);
1144
Hyunsun Moon1251e192016-06-07 16:57:05 -07001145 transactConfig(DATABASENAME, operations);
Hyunsun Moon89478662016-06-09 17:52:34 -07001146 log.info("Created interface {}", ovsdbIface);
Hyunsun Moon646d8c42015-10-08 20:32:44 -07001147 return true;
1148 }
1149
1150 @Override
Hyunsun Moondd14e8e2016-06-09 16:17:32 -07001151 public boolean dropInterface(String ifaceName) {
1152 OvsdbRowStore rowStore = getRowStore(DATABASENAME, BRIDGE);
1153 if (rowStore == null) {
1154 log.warn("Failed to get BRIDGE table");
1155 return false;
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001156 }
1157
Hyunsun Moondd14e8e2016-06-09 16:17:32 -07001158 ConcurrentMap<String, Row> bridgeTableRows = rowStore.getRowStore();
1159 if (bridgeTableRows == null) {
1160 log.warn("Failed to get BRIDGE table rows");
1161 return false;
1162 }
1163
1164 // interface name is unique
1165 Optional<String> bridgeId = bridgeTableRows.keySet().stream()
1166 .filter(uuid -> getPortUuid(ifaceName, uuid) != null)
1167 .findFirst();
1168
1169 if (bridgeId.isPresent()) {
1170 String portId = getPortUuid(ifaceName, bridgeId.get());
Frank Wange11a98d2016-10-26 17:04:03 +08001171 deleteConfig(PORT, UUID, portId, BRIDGE, PORTS, Uuid.uuid(portId));
Hyunsun Moondd14e8e2016-06-09 16:17:32 -07001172 return true;
1173 } else {
1174 log.warn("Unable to find the interface with name {}", ifaceName);
1175 return false;
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001176 }
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001177 }
1178
1179 /**
1180 * Delete transact config.
1181 *
andreaed976a42015-10-05 14:38:25 -07001182 * @param childTableName child table name
1183 * @param childColumnName child column name
1184 * @param childUuid child row uuid
1185 * @param parentTableName parent table name
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001186 * @param parentColumnName parent column
Frank Wange11a98d2016-10-26 17:04:03 +08001187 * @param referencedValue referenced value
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001188 */
1189 private void deleteConfig(String childTableName, String childColumnName,
andreaed976a42015-10-05 14:38:25 -07001190 String childUuid, String parentTableName,
Frank Wange11a98d2016-10-26 17:04:03 +08001191 String parentColumnName, Object referencedValue) {
Hyunsun Moon1251e192016-06-07 16:57:05 -07001192 DatabaseSchema dbSchema = schema.get(DATABASENAME);
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001193 TableSchema childTableSchema = dbSchema.getTableSchema(childTableName);
1194
1195 ArrayList<Operation> operations = Lists.newArrayList();
Frank Wange11a98d2016-10-26 17:04:03 +08001196 if (parentTableName != null && parentColumnName != null && referencedValue != null) {
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001197 TableSchema parentTableSchema = dbSchema
1198 .getTableSchema(parentTableName);
1199 ColumnSchema parentColumnSchema = parentTableSchema
1200 .getColumnSchema(parentColumnName);
1201 List<Mutation> mutations = Lists.newArrayList();
Frank Wange11a98d2016-10-26 17:04:03 +08001202 Mutation mutation = MutationUtil.delete(parentColumnSchema.name(), referencedValue);
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001203 mutations.add(mutation);
1204 List<Condition> conditions = Lists.newArrayList();
Frank Wange11a98d2016-10-26 17:04:03 +08001205 Condition condition = ConditionUtil.includes(parentColumnName, referencedValue);
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001206 conditions.add(condition);
1207 Mutate op = new Mutate(parentTableSchema, conditions, mutations);
1208 operations.add(op);
1209 }
1210
1211 List<Condition> conditions = Lists.newArrayList();
Jonathan Hart51539b82015-10-29 09:53:04 -07001212 Condition condition = ConditionUtil.isEqual(childColumnName, Uuid.uuid(childUuid));
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001213 conditions.add(condition);
1214 Delete del = new Delete(childTableSchema, conditions);
1215 operations.add(del);
Hyunsun Moon1251e192016-06-07 16:57:05 -07001216 transactConfig(DATABASENAME, operations);
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001217 }
1218
1219 /**
1220 * Update transact config.
1221 *
andreaed976a42015-10-05 14:38:25 -07001222 * @param tableName table name
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001223 * @param columnName column name
andreaed976a42015-10-05 14:38:25 -07001224 * @param uuid uuid
1225 * @param row the config data
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001226 */
1227 private void updateConfig(String tableName, String columnName, String uuid,
andreaed976a42015-10-05 14:38:25 -07001228 Row row) {
Hyunsun Moon1251e192016-06-07 16:57:05 -07001229 DatabaseSchema dbSchema = schema.get(DATABASENAME);
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001230 TableSchema tableSchema = dbSchema.getTableSchema(tableName);
1231
1232 List<Condition> conditions = Lists.newArrayList();
Jonathan Hart51539b82015-10-29 09:53:04 -07001233 Condition condition = ConditionUtil.isEqual(columnName, Uuid.uuid(uuid));
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001234 conditions.add(condition);
1235
1236 Update update = new Update(tableSchema, row, conditions);
1237
1238 ArrayList<Operation> operations = Lists.newArrayList();
1239 operations.add(update);
1240
Hyunsun Moon1251e192016-06-07 16:57:05 -07001241 transactConfig(DATABASENAME, operations);
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001242 }
1243
1244 /**
1245 * Insert transact config.
1246 *
andreaed976a42015-10-05 14:38:25 -07001247 * @param childTableName child table name
1248 * @param childColumnName child column name
1249 * @param parentTableName parent table name
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001250 * @param parentColumnName parent column
andreaed976a42015-10-05 14:38:25 -07001251 * @param parentUuid parent uuid
1252 * @param row the config data
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001253 * @return uuid, empty if no uuid is find
1254 */
1255 private String insertConfig(String childTableName, String childColumnName,
andreaed976a42015-10-05 14:38:25 -07001256 String parentTableName, String parentColumnName,
1257 String parentUuid, Row row) {
Hyunsun Moon1251e192016-06-07 16:57:05 -07001258 DatabaseSchema dbSchema = schema.get(DATABASENAME);
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001259 TableSchema tableSchema = dbSchema.getTableSchema(childTableName);
1260
Sho SHIMIZUff18f8c2016-03-11 14:43:53 -08001261 Insert insert = new Insert(tableSchema, childTableName, row);
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001262
1263 ArrayList<Operation> operations = Lists.newArrayList();
1264 operations.add(insert);
1265
1266 if (parentTableName != null && parentColumnName != null) {
1267 TableSchema parentTableSchema = dbSchema
1268 .getTableSchema(parentTableName);
1269 ColumnSchema parentColumnSchema = parentTableSchema
1270 .getColumnSchema(parentColumnName);
1271
1272 List<Mutation> mutations = Lists.newArrayList();
1273 Mutation mutation = MutationUtil.insert(parentColumnSchema.name(),
Sho SHIMIZUff18f8c2016-03-11 14:43:53 -08001274 Uuid.uuid(childTableName));
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001275 mutations.add(mutation);
1276
1277 List<Condition> conditions = Lists.newArrayList();
Hyunsun Moon1251e192016-06-07 16:57:05 -07001278 Condition condition = ConditionUtil.isEqual(UUID, Uuid.uuid(parentUuid));
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001279 conditions.add(condition);
1280
1281 Mutate op = new Mutate(parentTableSchema, conditions, mutations);
1282 operations.add(op);
1283 }
Hyunsun Moon1251e192016-06-07 16:57:05 -07001284 if (childTableName.equalsIgnoreCase(PORT)) {
1285 log.debug("Handle port insert");
Hyunsun Moondd14e8e2016-06-09 16:17:32 -07001286 Insert intfInsert = handlePortInsertTable(row);
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001287
1288 if (intfInsert != null) {
1289 operations.add(intfInsert);
1290 }
1291
1292 Insert ins = (Insert) operations.get(0);
Hyunsun Moon1251e192016-06-07 16:57:05 -07001293 ins.getRow().put("interfaces", Uuid.uuid(INTERFACE));
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001294 }
1295
1296 List<OperationResult> results;
1297 try {
jaegonkim01d7c912017-01-22 22:03:38 +09001298 results = transactConfig(DATABASENAME, operations)
1299 .get(TRANSACTCONFIG_TIMEOUT, TimeUnit.SECONDS);
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001300 return results.get(0).getUuid().value();
jaegonkim01d7c912017-01-22 22:03:38 +09001301 } catch (TimeoutException e) {
1302 log.warn("TimeoutException thrown while to get result");
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001303 } catch (InterruptedException e) {
1304 log.warn("Interrupted while waiting to get result");
1305 Thread.currentThread().interrupt();
1306 } catch (ExecutionException e) {
1307 log.error("Exception thrown while to get result");
1308 }
1309
1310 return null;
1311 }
1312
jaegonkim01d7c912017-01-22 22:03:38 +09001313
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001314 /**
1315 * Handles port insert.
1316 *
andreaed976a42015-10-05 14:38:25 -07001317 * @param portRow row of port
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001318 * @return insert, empty if null
1319 */
Hyunsun Moondd14e8e2016-06-09 16:17:32 -07001320 private Insert handlePortInsertTable(Row portRow) {
Hyunsun Moon1251e192016-06-07 16:57:05 -07001321 DatabaseSchema dbSchema = schema.get(DATABASENAME);
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001322
Hyunsun Moon1251e192016-06-07 16:57:05 -07001323 TableSchema portTableSchema = dbSchema.getTableSchema(PORT);
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001324 ColumnSchema portColumnSchema = portTableSchema.getColumnSchema("name");
1325
1326 String portName = (String) portRow.getColumn(portColumnSchema.name()).data();
Hyunsun Moon1251e192016-06-07 16:57:05 -07001327 Interface inf = (Interface) TableGenerator.createTable(dbSchema, OvsdbTable.INTERFACE);
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001328 inf.setName(portName);
1329
Hyunsun Moon1251e192016-06-07 16:57:05 -07001330 TableSchema intfTableSchema = dbSchema.getTableSchema(INTERFACE);
1331 return new Insert(intfTableSchema, INTERFACE, inf.getRow());
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001332 }
1333
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001334 @Override
1335 public ListenableFuture<DatabaseSchema> getOvsdbSchema(String dbName) {
1336 if (dbName == null) {
1337 return null;
1338 }
1339 DatabaseSchema databaseSchema = schema.get(dbName);
1340 if (databaseSchema == null) {
kdarapufce5abb2018-05-10 19:37:53 +05301341 List<String> dbNames = new ArrayList<>();
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001342 dbNames.add(dbName);
Hyunsun Moon1251e192016-06-07 16:57:05 -07001343 Function<JsonNode, DatabaseSchema> rowFunction = input -> {
1344 log.debug("Get ovsdb database schema {}", dbName);
1345 DatabaseSchema dbSchema = FromJsonUtil.jsonNodeToDbSchema(dbName, input);
1346 if (dbSchema == null) {
1347 log.debug("Get ovsdb database schema error");
1348 return null;
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001349 }
Hyunsun Moon1251e192016-06-07 16:57:05 -07001350 schema.put(dbName, dbSchema);
1351 return dbSchema;
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001352 };
1353
1354 ListenableFuture<JsonNode> input = getSchema(dbNames);
1355 if (input != null) {
Carmelo Casconeef478a62019-01-29 18:45:22 -08001356 return futureTransform(input, rowFunction);
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001357 }
1358 return null;
1359 } else {
1360 return Futures.immediateFuture(databaseSchema);
1361 }
1362 }
1363
1364 @Override
1365 public ListenableFuture<TableUpdates> monitorTables(String dbName, String id) {
1366 if (dbName == null) {
1367 return null;
1368 }
1369 DatabaseSchema dbSchema = schema.get(dbName);
1370 if (dbSchema != null) {
Hyunsun Moon1251e192016-06-07 16:57:05 -07001371 Function<JsonNode, TableUpdates> rowFunction = input -> {
1372 log.debug("Get table updates");
1373 TableUpdates updates = FromJsonUtil.jsonNodeToTableUpdates(input, dbSchema);
1374 if (updates == null) {
1375 log.debug("Get table updates error");
1376 return null;
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001377 }
Hyunsun Moon1251e192016-06-07 16:57:05 -07001378 return updates;
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001379 };
Carmelo Casconeef478a62019-01-29 18:45:22 -08001380 return futureTransform(monitor(dbSchema, id), rowFunction);
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001381 }
1382 return null;
1383 }
1384
Hyunsun Moondd14e8e2016-06-09 16:17:32 -07001385 private ListenableFuture<List<OperationResult>> transactConfig(String dbName,
1386 List<Operation> operations) {
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001387 if (dbName == null) {
1388 return null;
1389 }
1390 DatabaseSchema dbSchema = schema.get(dbName);
1391 if (dbSchema != null) {
andreaed976a42015-10-05 14:38:25 -07001392 Function<List<JsonNode>, List<OperationResult>> rowFunction = (input -> {
Jonathan Hart6523e122017-11-14 09:23:49 -08001393 try {
1394 log.debug("Get ovsdb operation result");
1395 List<OperationResult> result = FromJsonUtil.jsonNodeToOperationResult(input, operations);
1396 if (result == null) {
1397 log.debug("The operation result is null");
1398 return null;
1399 }
1400 return result;
1401 } catch (Exception e) {
1402 log.error("Exception while parsing result", e);
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001403 }
Jonathan Hart6523e122017-11-14 09:23:49 -08001404 return null;
andreaed976a42015-10-05 14:38:25 -07001405 });
Carmelo Casconeef478a62019-01-29 18:45:22 -08001406 return futureTransform(transact(dbSchema, operations), rowFunction);
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001407 }
1408 return null;
1409 }
1410
1411 @Override
1412 public ListenableFuture<JsonNode> getSchema(List<String> dbnames) {
1413 String id = java.util.UUID.randomUUID().toString();
1414 String getSchemaString = JsonRpcWriterUtil.getSchemaStr(id, dbnames);
1415
1416 SettableFuture<JsonNode> sf = SettableFuture.create();
1417 requestResult.put(id, sf);
1418 requestMethod.put(id, "getSchema");
1419
1420 channel.writeAndFlush(getSchemaString);
1421 return sf;
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001422 }
1423
1424 @Override
1425 public ListenableFuture<List<String>> echo() {
1426 String id = java.util.UUID.randomUUID().toString();
1427 String echoString = JsonRpcWriterUtil.echoStr(id);
1428
1429 SettableFuture<List<String>> sf = SettableFuture.create();
1430 requestResult.put(id, sf);
1431 requestMethod.put(id, "echo");
1432
1433 channel.writeAndFlush(echoString);
1434 return sf;
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001435 }
1436
1437 @Override
1438 public ListenableFuture<JsonNode> monitor(DatabaseSchema dbSchema,
1439 String monitorId) {
1440 String id = java.util.UUID.randomUUID().toString();
1441 String monitorString = JsonRpcWriterUtil.monitorStr(id, monitorId,
1442 dbSchema);
1443
1444 SettableFuture<JsonNode> sf = SettableFuture.create();
1445 requestResult.put(id, sf);
1446 requestMethod.put(id, "monitor");
1447
1448 channel.writeAndFlush(monitorString);
1449 return sf;
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001450 }
1451
1452 @Override
1453 public ListenableFuture<List<String>> listDbs() {
1454 String id = java.util.UUID.randomUUID().toString();
1455 String listDbsString = JsonRpcWriterUtil.listDbsStr(id);
1456
1457 SettableFuture<List<String>> sf = SettableFuture.create();
1458 requestResult.put(id, sf);
1459 requestMethod.put(id, "listDbs");
1460
1461 channel.writeAndFlush(listDbsString);
1462 return sf;
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001463 }
1464
1465 @Override
1466 public ListenableFuture<List<JsonNode>> transact(DatabaseSchema dbSchema,
1467 List<Operation> operations) {
1468 String id = java.util.UUID.randomUUID().toString();
1469 String transactString = JsonRpcWriterUtil.transactStr(id, dbSchema,
1470 operations);
1471
1472 SettableFuture<List<JsonNode>> sf = SettableFuture.create();
1473 requestResult.put(id, sf);
1474 requestMethod.put(id, "transact");
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001475 channel.writeAndFlush(transactString);
1476 return sf;
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001477 }
1478
andreaed976a42015-10-05 14:38:25 -07001479 @SuppressWarnings({"rawtypes", "unchecked"})
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001480 @Override
1481 public void processResult(JsonNode response) {
1482 log.debug("Handle result");
1483 String requestId = response.get("id").asText();
1484 SettableFuture sf = requestResult.get(requestId);
1485 if (sf == null) {
1486 log.debug("No such future to process");
1487 return;
1488 }
1489 String methodName = requestMethod.get(requestId);
Hyunsun Moon1251e192016-06-07 16:57:05 -07001490 sf.set(FromJsonUtil.jsonResultParser(response, methodName));
tanbangcheng1afecce2017-11-12 11:41:28 +08001491
1492 requestResult.remove(requestId);
1493 requestMethod.remove(requestId);
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001494 }
1495
1496 @Override
1497 public void processRequest(JsonNode requestJson) {
1498 log.debug("Handle request");
1499 if (requestJson.get("method").asText().equalsIgnoreCase("echo")) {
1500 log.debug("handle echo request");
1501
1502 String replyString = FromJsonUtil.getEchoRequestStr(requestJson);
1503 channel.writeAndFlush(replyString);
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001504 } else {
Hyunsun Moon1251e192016-06-07 16:57:05 -07001505 FromJsonUtil.jsonCallbackRequestParser(requestJson, monitorCallBack);
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001506 }
1507 }
1508
1509 @Override
1510 public void setCallback(Callback monitorCallback) {
1511 this.monitorCallBack = monitorCallback;
1512 }
1513
1514 @Override
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001515 public Set<OvsdbBridge> getBridges() {
Hyunsun Moon1251e192016-06-07 16:57:05 -07001516 Set<OvsdbBridge> ovsdbBridges = new HashSet<>();
1517 OvsdbTableStore tableStore = getTableStore(DATABASENAME);
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001518 if (tableStore == null) {
MaoJianweidac220d2016-07-04 22:37:52 +08001519 return ovsdbBridges;
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001520 }
Hyunsun Moon1251e192016-06-07 16:57:05 -07001521 OvsdbRowStore rowStore = tableStore.getRows(BRIDGE);
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001522 if (rowStore == null) {
MaoJianweidac220d2016-07-04 22:37:52 +08001523 return ovsdbBridges;
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001524 }
1525 ConcurrentMap<String, Row> rows = rowStore.getRowStore();
1526 for (String uuid : rows.keySet()) {
jaegonkim7b77f712018-01-14 17:18:27 +09001527 Row bridgeRow = getRow(DATABASENAME, BRIDGE, uuid);
1528 OvsdbBridge ovsdbBridge = getOvsdbBridge(bridgeRow, Uuid.uuid(uuid));
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001529 if (ovsdbBridge != null) {
1530 ovsdbBridges.add(ovsdbBridge);
1531 }
1532 }
1533 return ovsdbBridges;
1534 }
1535
1536 @Override
andreaed976a42015-10-05 14:38:25 -07001537 public Set<ControllerInfo> getControllers(DeviceId openflowDeviceId) {
Jonathan Hart51539b82015-10-29 09:53:04 -07001538 Uuid bridgeUuid = getBridgeUuid(openflowDeviceId);
andreaed976a42015-10-05 14:38:25 -07001539 if (bridgeUuid == null) {
1540 log.warn("bad bridge Uuid");
1541 return null;
1542 }
1543 List<Controller> controllers = getControllers(bridgeUuid);
1544 if (controllers == null) {
1545 log.warn("bad list of controllers");
1546 return null;
1547 }
Hyunsun Moon1251e192016-06-07 16:57:05 -07001548 return controllers.stream().map(controller -> new ControllerInfo(
1549 (String) controller.getTargetColumn()
1550 .data())).collect(Collectors.toSet());
andreaed976a42015-10-05 14:38:25 -07001551 }
1552
Jonathan Hart51539b82015-10-29 09:53:04 -07001553 private List<Controller> getControllers(Uuid bridgeUuid) {
Hyunsun Moon1251e192016-06-07 16:57:05 -07001554 DatabaseSchema dbSchema = schema.get(DATABASENAME);
andreaed976a42015-10-05 14:38:25 -07001555 if (dbSchema == null) {
1556 return null;
1557 }
Hyunsun Moon1251e192016-06-07 16:57:05 -07001558 OvsdbRowStore rowStore = getRowStore(DATABASENAME, BRIDGE);
andreaed976a42015-10-05 14:38:25 -07001559 if (rowStore == null) {
1560 log.debug("There is no bridge table");
1561 return null;
1562 }
1563
1564 Row bridgeRow = rowStore.getRow(bridgeUuid.value());
1565 Bridge bridge = (Bridge) TableGenerator.
1566 getTable(dbSchema, bridgeRow, OvsdbTable.BRIDGE);
1567
1568 //FIXME remove log
1569 log.warn("type of controller column", bridge.getControllerColumn()
1570 .data().getClass());
Jonathan Hart51539b82015-10-29 09:53:04 -07001571 Set<Uuid> controllerUuids = (Set<Uuid>) ((OvsdbSet) bridge
andreaed976a42015-10-05 14:38:25 -07001572 .getControllerColumn().data()).set();
andreaed976a42015-10-05 14:38:25 -07001573
Hyunsun Moon1251e192016-06-07 16:57:05 -07001574 OvsdbRowStore controllerRowStore = getRowStore(DATABASENAME, CONTROLLER);
andreaed976a42015-10-05 14:38:25 -07001575 if (controllerRowStore == null) {
1576 log.debug("There is no controller table");
1577 return null;
1578 }
1579
1580 List<Controller> ovsdbControllers = new ArrayList<>();
1581 ConcurrentMap<String, Row> controllerTableRows = controllerRowStore.getRowStore();
1582 controllerTableRows.forEach((key, row) -> {
Jonathan Hart51539b82015-10-29 09:53:04 -07001583 if (!controllerUuids.contains(Uuid.uuid(key))) {
andreaed976a42015-10-05 14:38:25 -07001584 return;
1585 }
1586 Controller controller = (Controller) TableGenerator
1587 .getTable(dbSchema, row, OvsdbTable.CONTROLLER);
1588 ovsdbControllers.add(controller);
1589 });
1590 return ovsdbControllers;
1591 }
1592
1593
Jonathan Hart51539b82015-10-29 09:53:04 -07001594 private Uuid getBridgeUuid(DeviceId openflowDeviceId) {
Hyunsun Moon1251e192016-06-07 16:57:05 -07001595 DatabaseSchema dbSchema = schema.get(DATABASENAME);
andreaed976a42015-10-05 14:38:25 -07001596 if (dbSchema == null) {
1597 return null;
1598 }
Hyunsun Moon1251e192016-06-07 16:57:05 -07001599 OvsdbRowStore rowStore = getRowStore(DATABASENAME, BRIDGE);
andreaed976a42015-10-05 14:38:25 -07001600 if (rowStore == null) {
1601 log.debug("There is no bridge table");
1602 return null;
1603 }
1604
1605 ConcurrentMap<String, Row> bridgeTableRows = rowStore.getRowStore();
Jonathan Hart51539b82015-10-29 09:53:04 -07001606 final AtomicReference<Uuid> uuid = new AtomicReference<>();
andreaed976a42015-10-05 14:38:25 -07001607 for (Map.Entry<String, Row> entry : bridgeTableRows.entrySet()) {
Hyunsun Moon1251e192016-06-07 16:57:05 -07001608 Bridge bridge = (Bridge) TableGenerator.getTable(
1609 dbSchema,
1610 entry.getValue(),
1611 OvsdbTable.BRIDGE);
1612
1613 if (matchesDpid(bridge, openflowDeviceId)) {
Jonathan Hart51539b82015-10-29 09:53:04 -07001614 uuid.set(Uuid.uuid(entry.getKey()));
andreaed976a42015-10-05 14:38:25 -07001615 break;
1616 }
1617 }
1618 if (uuid.get() == null) {
1619 log.debug("There is no bridge for {}", openflowDeviceId);
1620 }
1621 return uuid.get();
andreaed976a42015-10-05 14:38:25 -07001622 }
1623
1624 private static boolean matchesDpid(Bridge b, DeviceId deviceId) {
1625 String ofDpid = deviceId.toString().replace("of:", "");
1626 Set ofDeviceIds = ((OvsdbSet) b.getDatapathIdColumn().data()).set();
1627 //TODO Set<String>
1628 return ofDeviceIds.contains(ofDpid);
1629 }
1630
1631 @Override
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001632 public Set<OvsdbPort> getPorts() {
Daniel Park14552682018-08-28 11:25:01 +09001633 return (Set<OvsdbPort>) getElements(this::getOvsdbPort);
1634 }
1635
1636 @Override
1637 public Set<Interface> getInterfaces() {
1638 return (Set<Interface>) getElements(this::getInterface);
1639 }
1640
1641 private Set<?> getElements(Function<Row, ?> method) {
Hyunsun Moon1251e192016-06-07 16:57:05 -07001642 OvsdbTableStore tableStore = getTableStore(DATABASENAME);
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001643 if (tableStore == null) {
1644 return null;
1645 }
Hyunsun Moon1251e192016-06-07 16:57:05 -07001646 OvsdbRowStore rowStore = tableStore.getRows(INTERFACE);
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001647 if (rowStore == null) {
1648 return null;
1649 }
1650 ConcurrentMap<String, Row> rows = rowStore.getRowStore();
Daniel Park14552682018-08-28 11:25:01 +09001651
1652 return rows.keySet()
kdarapufce5abb2018-05-10 19:37:53 +05301653 .stream()
1654 .map(uuid -> getRow(DATABASENAME, INTERFACE, uuid))
Daniel Park14552682018-08-28 11:25:01 +09001655 .map(method)
kdarapufce5abb2018-05-10 19:37:53 +05301656 .filter(Objects::nonNull)
1657 .collect(Collectors.toSet());
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001658 }
1659
1660 @Override
Daniel Park14552682018-08-28 11:25:01 +09001661 public Interface getInterface(String intf) {
1662 return getInterfaces().stream()
1663 .filter(ovsdbIntf -> ovsdbIntf.getName().equals(intf))
1664 .findAny().orElse(null);
1665 }
1666
1667 private Interface getInterface(Row row) {
1668 DatabaseSchema dbSchema = getDatabaseSchema(DATABASENAME);
1669 Interface intf = (Interface) TableGenerator
1670 .getTable(dbSchema, row, OvsdbTable.INTERFACE);
1671 if (intf == null) {
1672 return null;
1673 }
1674 return intf;
1675 }
1676 @Override
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001677 public DatabaseSchema getDatabaseSchema(String dbName) {
1678 return schema.get(dbName);
1679 }
1680
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001681 private OvsdbPort getOvsdbPort(Row row) {
Hyunsun Moon1251e192016-06-07 16:57:05 -07001682 DatabaseSchema dbSchema = getDatabaseSchema(DATABASENAME);
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001683 Interface intf = (Interface) TableGenerator
1684 .getTable(dbSchema, row, OvsdbTable.INTERFACE);
1685 if (intf == null) {
1686 return null;
1687 }
1688 long ofPort = getOfPort(intf);
1689 String portName = intf.getName();
1690 if ((ofPort < 0) || (portName == null)) {
1691 return null;
1692 }
Hyunsun Moon1251e192016-06-07 16:57:05 -07001693 return new OvsdbPort(new OvsdbPortNumber(ofPort), new OvsdbPortName(portName));
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001694 }
1695
jaegonkim7b77f712018-01-14 17:18:27 +09001696 private OvsdbBridge getOvsdbBridge(Row row, Uuid bridgeUuid) {
Hyunsun Moon1251e192016-06-07 16:57:05 -07001697 DatabaseSchema dbSchema = getDatabaseSchema(DATABASENAME);
1698 Bridge bridge = (Bridge) TableGenerator.getTable(dbSchema, row, OvsdbTable.BRIDGE);
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001699 if (bridge == null) {
1700 return null;
1701 }
1702
1703 OvsdbSet datapathIdSet = (OvsdbSet) bridge.getDatapathIdColumn().data();
1704 @SuppressWarnings("unchecked")
1705 Set<String> datapathIds = datapathIdSet.set();
Jon Hallcbd1b392017-01-18 20:15:44 -08001706 if (datapathIds == null || datapathIds.isEmpty()) {
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001707 return null;
1708 }
1709 String datapathId = (String) datapathIds.toArray()[0];
1710 String bridgeName = bridge.getName();
1711 if ((datapathId == null) || (bridgeName == null)) {
1712 return null;
1713 }
jaegonkim7b77f712018-01-14 17:18:27 +09001714
1715 List<Controller> controllers = getControllers(bridgeUuid);
1716
1717 if (controllers != null) {
1718 List<ControllerInfo> controllerInfos = controllers.stream().map(
1719 controller -> new ControllerInfo(
1720 (String) controller.getTargetColumn()
1721 .data())).collect(Collectors.toList());
1722
1723 return OvsdbBridge.builder()
1724 .name(bridgeName)
1725 .datapathId(datapathId)
1726 .controllers(controllerInfos)
1727 .build();
1728 } else {
1729 return OvsdbBridge.builder()
1730 .name(bridgeName)
1731 .datapathId(datapathId)
1732 .build();
1733 }
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001734 }
1735
Frank Wange11a98d2016-10-26 17:04:03 +08001736 private OvsdbQos getOvsdbQos(Row row) {
1737 DatabaseSchema dbSchema = getDatabaseSchema(DATABASENAME);
1738 Qos qos = (Qos) TableGenerator.getTable(dbSchema, row, OvsdbTable.QOS);
1739 if (qos == null) {
1740 return null;
1741 }
1742
1743 String type = (String) qos.getTypeColumn().data();
1744 Map<String, String> otherConfigs;
1745 Map<String, String> externalIds;
1746 Map<Long, String> queues;
1747
1748 otherConfigs = ((OvsdbMap) qos.getOtherConfigColumn().data()).map();
1749 externalIds = ((OvsdbMap) qos.getExternalIdsColumn().data()).map();
1750 queues = ((OvsdbMap) qos.getQueuesColumn().data()).map();
1751 return OvsdbQos.builder().qosType(type).
1752 queues(queues).otherConfigs(otherConfigs).
1753 externalIds(externalIds).build();
1754 }
1755
1756 private OvsdbQueue getOvsdbQueue(Row row) {
1757 DatabaseSchema dbSchema = getDatabaseSchema(DATABASENAME);
1758 Queue queue = (Queue) TableGenerator.getTable(dbSchema, row, OvsdbTable.QUEUE);
1759 if (queue == null) {
1760 return null;
1761 }
1762
1763 OvsdbSet dscpOvsdbSet = ((OvsdbSet) queue.getDscpColumn().data());
Kamal Krishna Bhattdbef16f2018-06-04 13:25:58 +02001764 Set dscpSet = dscpOvsdbSet.set();
Frank Wange11a98d2016-10-26 17:04:03 +08001765 Long dscp = null;
1766 if (dscpSet != null && !dscpSet.isEmpty()) {
Kamal Krishna Bhattdbef16f2018-06-04 13:25:58 +02001767 dscp = Long.valueOf(dscpSet.toArray()[0].toString());
Frank Wange11a98d2016-10-26 17:04:03 +08001768 }
1769
1770 Map<String, String> otherConfigs;
1771 Map<String, String> externalIds;
1772
1773 otherConfigs = ((OvsdbMap) queue.getOtherConfigColumn().data()).map();
1774 externalIds = ((OvsdbMap) queue.getExternalIdsColumn().data()).map();
1775 return OvsdbQueue.builder().dscp(dscp).
1776 otherConfigs(otherConfigs).externalIds(externalIds).build();
1777 }
1778
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001779 private long getOfPort(Interface intf) {
1780 OvsdbSet ofPortSet = (OvsdbSet) intf.getOpenFlowPortColumn().data();
1781 @SuppressWarnings("unchecked")
1782 Set<Integer> ofPorts = ofPortSet.set();
Jon Hallcbd1b392017-01-18 20:15:44 -08001783 if (ofPorts == null || ofPorts.isEmpty()) {
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001784 log.debug("The ofport is null in {}", intf.getName());
1785 return -1;
1786 }
1787 // return (long) ofPorts.toArray()[0];
1788 Iterator<Integer> it = ofPorts.iterator();
1789 return Long.parseLong(it.next().toString());
1790 }
CNluciusa66c3972015-09-06 20:31:29 +08001791
1792 @Override
1793 public Set<OvsdbPort> getLocalPorts(Iterable<String> ifaceids) {
Hyunsun Moon1251e192016-06-07 16:57:05 -07001794 Set<OvsdbPort> ovsdbPorts = new HashSet<>();
1795 OvsdbTableStore tableStore = getTableStore(DATABASENAME);
CNluciusa66c3972015-09-06 20:31:29 +08001796 if (tableStore == null) {
1797 return null;
1798 }
Hyunsun Moon1251e192016-06-07 16:57:05 -07001799 OvsdbRowStore rowStore = tableStore.getRows(INTERFACE);
CNluciusa66c3972015-09-06 20:31:29 +08001800 if (rowStore == null) {
1801 return null;
1802 }
1803 ConcurrentMap<String, Row> rows = rowStore.getRowStore();
1804 for (String uuid : rows.keySet()) {
Hyunsun Moon1251e192016-06-07 16:57:05 -07001805 Row row = getRow(DATABASENAME, INTERFACE, uuid);
1806 DatabaseSchema dbSchema = getDatabaseSchema(DATABASENAME);
CNluciusa66c3972015-09-06 20:31:29 +08001807 Interface intf = (Interface) TableGenerator
1808 .getTable(dbSchema, row, OvsdbTable.INTERFACE);
1809 if (intf == null || getIfaceid(intf) == null) {
1810 continue;
1811 }
1812 String portName = intf.getName();
Hyunsun Moon1251e192016-06-07 16:57:05 -07001813 if (portName == null) {
1814 continue;
1815 }
CNluciusa66c3972015-09-06 20:31:29 +08001816 Set<String> ifaceidSet = Sets.newHashSet(ifaceids);
Hyunsun Moon1251e192016-06-07 16:57:05 -07001817 if (portName.startsWith(TYPEVXLAN) || !ifaceidSet.contains(getIfaceid(intf))) {
CNluciusa66c3972015-09-06 20:31:29 +08001818 continue;
1819 }
1820 long ofPort = getOfPort(intf);
Hyunsun Moon1251e192016-06-07 16:57:05 -07001821 if (ofPort < 0) {
CNluciusa66c3972015-09-06 20:31:29 +08001822 continue;
1823 }
Hyunsun Moon1251e192016-06-07 16:57:05 -07001824 ovsdbPorts.add(new OvsdbPort(new OvsdbPortNumber(ofPort),
1825 new OvsdbPortName(portName)));
CNluciusa66c3972015-09-06 20:31:29 +08001826 }
1827 return ovsdbPorts;
1828 }
1829
1830 private String getIfaceid(Interface intf) {
1831 OvsdbMap ovsdbMap = (OvsdbMap) intf.getExternalIdsColumn().data();
1832 @SuppressWarnings("unchecked")
1833 Map<String, String> externalIds = ovsdbMap.map();
1834 if (externalIds.isEmpty()) {
1835 log.warn("The external_ids is null");
1836 return null;
1837 }
Hyunsun Moon1251e192016-06-07 16:57:05 -07001838 String ifaceid = externalIds.get(EXTERNAL_ID_INTERFACE_ID);
CNluciusa66c3972015-09-06 20:31:29 +08001839 if (ifaceid == null) {
1840 log.warn("The ifaceid is null");
1841 return null;
1842 }
1843 return ifaceid;
1844 }
Hyunsun Moon5fb20a52015-09-25 17:02:33 -07001845
1846 @Override
1847 public void disconnect() {
1848 channel.disconnect();
Hyunsun Moon5fb20a52015-09-25 17:02:33 -07001849 }
Saritha1583a6f2017-06-16 14:42:58 +05301850
1851 @Override
1852 public List<OvsdbPortName> getPorts(List<String> portNames, DeviceId deviceId) {
1853 Uuid bridgeUuid = getBridgeUuid(deviceId);
1854 if (bridgeUuid == null) {
1855 log.error("Can't find the bridge for the deviceId {}", deviceId);
1856 return Collections.emptyList();
1857 }
1858 DatabaseSchema dbSchema = schema.get(DATABASENAME);
1859 Row bridgeRow = getRow(DATABASENAME, BRIDGE, bridgeUuid.value());
1860 Bridge bridge = (Bridge) TableGenerator.getTable(dbSchema, bridgeRow, OvsdbTable.BRIDGE);
1861 if (bridge == null) {
1862 return Collections.emptyList();
1863 }
1864 OvsdbSet setPorts = (OvsdbSet) bridge.getPortsColumn().data();
1865 Set<Uuid> portSet = setPorts.set();
1866 if (portSet.isEmpty()) {
1867 return Collections.emptyList();
1868 }
1869
1870 Map<Uuid, Port> portMap = portSet.stream().collect(Collectors.toMap(
1871 java.util.function.Function.identity(), port -> (Port) TableGenerator
1872 .getTable(dbSchema, getRow(DATABASENAME,
1873 PORT, port.value()), OvsdbTable.PORT)));
1874
1875 List<OvsdbPortName> portList = portMap.entrySet().stream().filter(port -> Objects.nonNull(port.getValue())
1876 && portNames.contains(port.getValue().getName())
1877 && Objects.nonNull(getInterfacebyPort(port.getKey().value(), port.getValue().getName())))
1878 .map(port -> new OvsdbPortName(port.getValue().getName())).collect(Collectors.toList());
1879
1880 return Collections.unmodifiableList(portList);
1881 }
1882
1883 @Override
1884 public boolean getPortError(List<OvsdbPortName> portNames, DeviceId bridgeId) {
1885 Uuid bridgeUuid = getBridgeUuid(bridgeId);
1886
1887 List<Interface> interfaceList = portNames.stream().collect(Collectors
1888 .toMap(java.util.function.Function.identity(),
1889 port -> (Interface) getInterfacebyPort(getPortUuid(port.value(),
1890 bridgeUuid.value()), port.value())))
1891 .entrySet().stream().filter(intf -> Objects.nonNull(intf.getValue())
1892 && ((OvsdbSet) intf.getValue().getOpenFlowPortColumn().data()).set()
1893 .stream().findAny().orElse(OFPORT_ERROR_COMPARISON).equals(OFPORT_ERROR))
kdarapufce5abb2018-05-10 19:37:53 +05301894 .map(Map.Entry::getValue).collect(Collectors.toList());
Saritha1583a6f2017-06-16 14:42:58 +05301895
kdarapufce5abb2018-05-10 19:37:53 +05301896 interfaceList.forEach(intf -> ((Consumer<Interface>) intf1 -> {
1897 try {
1898 Set<String> setErrors = ((OvsdbSet) intf1.getErrorColumn().data()).set();
1899 log.info("Port has errors. ofport value - {}, Interface - {} has error - {} ",
1900 intf1.getOpenFlowPortColumn().data(), intf1.getName(), setErrors.stream()
1901 .findFirst().get());
1902 } catch (ColumnSchemaNotFoundException | VersionMismatchException e) {
1903 log.debug("Port has errors. ofport value - {}, Interface - {} has error - {} ",
1904 intf1.getOpenFlowPortColumn().data(), intf1.getName(), e);
Saritha1583a6f2017-06-16 14:42:58 +05301905 }
kdarapufce5abb2018-05-10 19:37:53 +05301906 }).accept(intf));
Saritha1583a6f2017-06-16 14:42:58 +05301907
1908 return !interfaceList.isEmpty();
1909 }
1910
1911 private Interface getInterfacebyPort(String portUuid, String portName) {
1912 DatabaseSchema dbSchema = schema.get(DATABASENAME);
1913
1914 Row portRow = getRow(DATABASENAME, PORT, portUuid);
1915 Port port = (Port) TableGenerator.getTable(dbSchema, portRow,
1916 OvsdbTable.PORT);
1917 if (port == null) {
1918 return null;
1919 }
1920
1921 OvsdbSet setInterfaces = (OvsdbSet) port.getInterfacesColumn().data();
1922 Set<Uuid> interfaces = setInterfaces.set();
1923
1924 return interfaces.stream().map(intf -> (Interface) TableGenerator
1925 .getTable(dbSchema, getRow(DATABASENAME,
1926 INTERFACE, intf.value()), OvsdbTable.INTERFACE))
1927 .filter(intf -> Objects.nonNull(intf) && portName.equalsIgnoreCase(intf.getName()))
1928 .findFirst().orElse(null);
1929 }
nitinanandf14dccd2018-05-31 15:11:04 +05301930
1931 /**
1932 * Get first row of given table from given db.
1933 *
1934 * @param dbName db name
1935 * @param tblName table name
1936 * @return firstRow, first row of the given table from given db if present
1937 */
1938 @Override
1939 public Optional<Object> getFirstRow(String dbName, OvsdbTable tblName) {
1940
1941 DatabaseSchema dbSchema = getDatabaseSchema(dbName);
1942 if (Objects.isNull(dbSchema)) {
1943 return Optional.empty();
1944 }
1945
1946 OvsdbTableStore tableStore = ovsdbStore.getOvsdbTableStore(dbName);
1947 if (tableStore == null) {
1948 return Optional.empty();
1949 }
1950 OvsdbRowStore rowStore = tableStore.getRows(tblName.tableName());
1951 if (rowStore == null) {
1952 return Optional.empty();
1953 }
1954
1955 ConcurrentMap<String, Row> rows = rowStore.getRowStore();
1956 if (rows == null) {
1957 log.debug("The {} Table Rows is null", tblName);
1958 return Optional.empty();
1959 }
1960
1961 // There should be only 1 row in this table
1962 Optional<String> uuid = rows.keySet().stream().findFirst();
1963 if (uuid.isPresent() && rows.containsKey(uuid.get())) {
1964 return Optional.of(TableGenerator.getTable(dbSchema,
1965 rows.get(uuid.get()), tblName));
1966 } else {
1967 return Optional.empty();
1968 }
1969 }
1970
1971
1972 /**
1973 * Get memory usage of device.
1974 *
1975 * @return memoryStats, empty data as there is no generic way to fetch such stats
1976 */
1977 @Override
1978 public Optional<DeviceMemoryStats> getDeviceMemoryUsage() {
1979 return Optional.empty();
1980 }
1981
1982
1983 /**
1984 * Get cpu usage of device.
1985 *
1986 * @return cpuStats, empty data as there is no generic way to fetch such stats
1987 */
1988 @Override
1989 public Optional<DeviceCpuStats> getDeviceCpuUsage() {
1990 return Optional.empty();
1991 }
Carmelo Casconeef478a62019-01-29 18:45:22 -08001992
1993 private <I, O> ListenableFuture<O> futureTransform(
1994 ListenableFuture<I> input, Function<? super I, ? extends O> function) {
1995 // Wrapper around deprecated Futures.transform() method. As per Guava
1996 // recommendation, passing MoreExecutors.directExecutor() for identical
1997 // behavior.
1998 return Futures.transform(input, function, MoreExecutors.directExecutor());
1999 }
Jian Lif5c92762019-05-17 19:50:28 +09002000}