blob: 3f0f6b4655385266dced924980be0cc0a6c01a4e [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
Sho SHIMIZUe4efe452015-08-26 15:06:55 -0700236 @Override
237 public Row getRow(String dbName, String tableName, String uuid) {
238 OvsdbTableStore tableStore = getTableStore(dbName);
239 if (tableStore == null) {
240 return null;
241 }
242 OvsdbRowStore rowStore = tableStore.getRows(tableName);
243 if (rowStore == null) {
244 return null;
245 }
246 return rowStore.getRow(uuid);
247 }
248
249 @Override
250 public void removeRow(String dbName, String tableName, String uuid) {
251 OvsdbTableStore tableStore = getTableStore(dbName);
252 if (tableStore == null) {
253 return;
254 }
255 OvsdbRowStore rowStore = tableStore.getRows(tableName);
256 if (rowStore == null) {
257 return;
258 }
259 rowStore.deleteRow(uuid);
260 }
261
262 @Override
263 public void updateOvsdbStore(String dbName, String tableName, String uuid,
264 Row row) {
265 OvsdbTableStore tableStore = ovsdbStore.getOvsdbTableStore(dbName);
266 if (tableStore == null) {
267 tableStore = new OvsdbTableStore();
268 }
269 OvsdbRowStore rowStore = tableStore.getRows(tableName);
270 if (rowStore == null) {
271 rowStore = new OvsdbRowStore();
272 }
273 rowStore.insertRow(uuid, row);
274 tableStore.createOrUpdateTable(tableName, rowStore);
275 ovsdbStore.createOrUpdateOvsdbStore(dbName, tableStore);
276 }
277
Pier Ventref5d72362016-07-17 12:02:14 +0200278 @Override
279 public String getMirrorUuid(String mirrorName) {
280 DatabaseSchema dbSchema = schema.get(DATABASENAME);
281 OvsdbRowStore rowStore = getRowStore(DATABASENAME, MIRROR);
282 if (rowStore == null) {
283 log.warn("The mirror uuid is null");
284 return null;
285 }
286
287 ConcurrentMap<String, Row> mirrorTableRows = rowStore.getRowStore();
288 if (mirrorTableRows == null) {
289 log.warn("The mirror uuid is null");
290 return null;
291 }
292
293 for (String uuid : mirrorTableRows.keySet()) {
294 Mirror mirror = (Mirror) TableGenerator
295 .getTable(dbSchema, mirrorTableRows.get(uuid), OvsdbTable.MIRROR);
296 String name = mirror.getName();
297 if (name.contains(mirrorName)) {
298 return uuid;
299 }
300 }
301 log.warn("Mirroring not found");
302 return null;
303 }
304
Pier Ventref5d72362016-07-17 12:02:14 +0200305 @Override
306 public Set<MirroringStatistics> getMirroringStatistics(DeviceId deviceId) {
307 Uuid bridgeUuid = getBridgeUuid(deviceId);
308 if (bridgeUuid == null) {
309 log.warn("Couldn't find bridge {} in {}", deviceId, nodeId.getIpAddress());
310 return null;
311 }
312
313 List<MirroringStatistics> mirrorings = getMirrorings(bridgeUuid);
314 if (mirrorings == null) {
315 log.warn("Couldn't find mirrors in {}", nodeId.getIpAddress());
316 return null;
317 }
318 return ImmutableSet.copyOf(mirrorings);
319 }
320
321 /**
322 * Helper method which retrieves mirrorings statistics using bridge uuid.
323 *
324 * @param bridgeUuid the uuid of the bridge
325 * @return the list of the mirrorings statistics.
326 */
327 private List<MirroringStatistics> getMirrorings(Uuid bridgeUuid) {
328 DatabaseSchema dbSchema = schema.get(DATABASENAME);
329 if (dbSchema == null) {
330 log.warn("Unable to retrieve dbSchema {}", DATABASENAME);
331 return null;
332 }
333 OvsdbRowStore rowStore = getRowStore(DATABASENAME, BRIDGE);
334 if (rowStore == null) {
335 log.warn("Unable to retrieve rowStore {} of {}", BRIDGE, DATABASENAME);
336 return null;
337 }
338
339 Row bridgeRow = rowStore.getRow(bridgeUuid.value());
340 Bridge bridge = (Bridge) TableGenerator.
341 getTable(dbSchema, bridgeRow, OvsdbTable.BRIDGE);
342
343 Set<Uuid> mirroringsUuids = (Set<Uuid>) ((OvsdbSet) bridge
344 .getMirrorsColumn().data()).set();
345
346 OvsdbRowStore mirrorRowStore = getRowStore(DATABASENAME, MIRROR);
347 if (mirrorRowStore == null) {
348 log.warn("Unable to retrieve rowStore {} of {}", MIRROR, DATABASENAME);
349 return null;
350 }
351
352 List<MirroringStatistics> mirroringStatistics = new ArrayList<>();
353 ConcurrentMap<String, Row> mirrorTableRows = mirrorRowStore.getRowStore();
354 mirrorTableRows.forEach((key, row) -> {
355 if (!mirroringsUuids.contains(Uuid.uuid(key))) {
356 return;
357 }
358 Mirror mirror = (Mirror) TableGenerator
359 .getTable(dbSchema, row, OvsdbTable.MIRROR);
360 mirroringStatistics.add(MirroringStatistics.mirroringStatistics(mirror.getName(),
361 (Map<String, Integer>) ((OvsdbMap) mirror
362 .getStatisticsColumn().data()).map()));
363 });
364 return ImmutableList.copyOf(mirroringStatistics);
365 }
366
Sho SHIMIZUe4efe452015-08-26 15:06:55 -0700367 @Override
368 public String getPortUuid(String portName, String bridgeUuid) {
Hyunsun Moon1251e192016-06-07 16:57:05 -0700369 DatabaseSchema dbSchema = schema.get(DATABASENAME);
Sho SHIMIZUe4efe452015-08-26 15:06:55 -0700370
Hyunsun Moon1251e192016-06-07 16:57:05 -0700371 Row bridgeRow = getRow(DATABASENAME, BRIDGE, bridgeUuid);
Sho SHIMIZUe4efe452015-08-26 15:06:55 -0700372 Bridge bridge = (Bridge) TableGenerator.getTable(dbSchema, bridgeRow,
373 OvsdbTable.BRIDGE);
374 if (bridge != null) {
375 OvsdbSet setPorts = (OvsdbSet) bridge.getPortsColumn().data();
376 @SuppressWarnings("unchecked")
Jonathan Hart51539b82015-10-29 09:53:04 -0700377 Set<Uuid> ports = setPorts.set();
Jon Hallcbd1b392017-01-18 20:15:44 -0800378 if (ports == null || ports.isEmpty()) {
Sho SHIMIZUe4efe452015-08-26 15:06:55 -0700379 log.warn("The port uuid is null");
380 return null;
381 }
382
Jonathan Hart51539b82015-10-29 09:53:04 -0700383 for (Uuid uuid : ports) {
Hyunsun Moon1251e192016-06-07 16:57:05 -0700384 Row portRow = getRow(DATABASENAME, PORT, uuid.value());
Sho SHIMIZUe4efe452015-08-26 15:06:55 -0700385 Port port = (Port) TableGenerator.getTable(dbSchema, portRow,
386 OvsdbTable.PORT);
387 if (port != null && portName.equalsIgnoreCase(port.getName())) {
388 return uuid.value();
389 }
390 }
Sho SHIMIZUe4efe452015-08-26 15:06:55 -0700391 }
392 return null;
393 }
394
395 @Override
Sho SHIMIZUe4efe452015-08-26 15:06:55 -0700396 public String getBridgeUuid(String bridgeName) {
Hyunsun Moon1251e192016-06-07 16:57:05 -0700397 DatabaseSchema dbSchema = schema.get(DATABASENAME);
Hyunsun Moon1251e192016-06-07 16:57:05 -0700398 OvsdbRowStore rowStore = getRowStore(DATABASENAME, BRIDGE);
Sho SHIMIZUe4efe452015-08-26 15:06:55 -0700399 if (rowStore == null) {
400 log.debug("The bridge uuid is null");
401 return null;
402 }
403
404 ConcurrentMap<String, Row> bridgeTableRows = rowStore.getRowStore();
405 if (bridgeTableRows == null) {
406 log.debug("The bridge uuid is null");
407 return null;
408 }
409
410 for (String uuid : bridgeTableRows.keySet()) {
411 Bridge bridge = (Bridge) TableGenerator
Hyunsun Moon1251e192016-06-07 16:57:05 -0700412 .getTable(dbSchema, bridgeTableRows.get(uuid), OvsdbTable.BRIDGE);
Sho SHIMIZUe4efe452015-08-26 15:06:55 -0700413 if (bridge.getName().equals(bridgeName)) {
414 return uuid;
415 }
Sho SHIMIZUe4efe452015-08-26 15:06:55 -0700416 }
417 return null;
418 }
419
Hyunsun Moondd14e8e2016-06-09 16:17:32 -0700420 private String getOvsUuid(String dbName) {
Hyunsun Moon1251e192016-06-07 16:57:05 -0700421 OvsdbRowStore rowStore = getRowStore(DATABASENAME, DATABASENAME);
Sho SHIMIZUe4efe452015-08-26 15:06:55 -0700422 if (rowStore == null) {
423 log.debug("The bridge uuid is null");
424 return null;
425 }
426 ConcurrentMap<String, Row> ovsTableRows = rowStore.getRowStore();
427 if (ovsTableRows != null) {
428 for (String uuid : ovsTableRows.keySet()) {
429 Row row = ovsTableRows.get(uuid);
430 String tableName = row.tableName();
431 if (tableName.equals(dbName)) {
432 return uuid;
433 }
434 }
435 }
436 return null;
437 }
438
439 @Override
440 public void createPort(String bridgeName, String portName) {
441 String bridgeUuid = getBridgeUuid(bridgeName);
442 if (bridgeUuid == null) {
Hyunsun Moon1251e192016-06-07 16:57:05 -0700443 log.error("Can't find bridge {} in {}", bridgeName, nodeId.getIpAddress());
Sho SHIMIZUe4efe452015-08-26 15:06:55 -0700444 return;
445 }
446
Hyunsun Moon1251e192016-06-07 16:57:05 -0700447 DatabaseSchema dbSchema = schema.get(DATABASENAME);
Sho SHIMIZUe4efe452015-08-26 15:06:55 -0700448 String portUuid = getPortUuid(portName, bridgeUuid);
Hyunsun Moon1251e192016-06-07 16:57:05 -0700449 Port port = (Port) TableGenerator.createTable(dbSchema, OvsdbTable.PORT);
Sho SHIMIZUe4efe452015-08-26 15:06:55 -0700450 port.setName(portName);
451 if (portUuid == null) {
Hyunsun Moon1251e192016-06-07 16:57:05 -0700452 insertConfig(PORT, UUID, BRIDGE, PORTS, bridgeUuid, port.getRow());
Sho SHIMIZUe4efe452015-08-26 15:06:55 -0700453 }
Sho SHIMIZUe4efe452015-08-26 15:06:55 -0700454 }
455
456 @Override
457 public void dropPort(String bridgeName, String portName) {
458 String bridgeUuid = getBridgeUuid(bridgeName);
459 if (bridgeUuid == null) {
460 log.error("Could not find Bridge {} in {}", bridgeName, nodeId);
461 return;
462 }
463
464 String portUuid = getPortUuid(portName, bridgeUuid);
465 if (portUuid != null) {
466 log.info("Port {} delete", portName);
Frank Wange11a98d2016-10-26 17:04:03 +0800467 deleteConfig(PORT, UUID, portUuid, BRIDGE, PORTS, Uuid.uuid(portUuid));
Sho SHIMIZUe4efe452015-08-26 15:06:55 -0700468 }
469 }
470
lishuai6c56f5e2015-11-17 16:38:19 +0800471 @Override
Hyunsun Moon1251e192016-06-07 16:57:05 -0700472 public boolean createBridge(OvsdbBridge ovsdbBridge) {
473 DatabaseSchema dbSchema = schema.get(DATABASENAME);
474 String ovsUuid = getOvsUuid(DATABASENAME);
Hyunsun Moon646d8c42015-10-08 20:32:44 -0700475
476 if (dbSchema == null || ovsUuid == null) {
Hyunsun Moon1251e192016-06-07 16:57:05 -0700477 log.error("Can't find database Open_vSwitch");
Hyunsun Moon646d8c42015-10-08 20:32:44 -0700478 return false;
479 }
480
Hyunsun Moon646d8c42015-10-08 20:32:44 -0700481 Bridge bridge = (Bridge) TableGenerator.createTable(dbSchema, OvsdbTable.BRIDGE);
Hyunsun Moon1251e192016-06-07 16:57:05 -0700482 bridge.setOtherConfig(ovsdbBridge.otherConfigs());
Hyunsun Moon646d8c42015-10-08 20:32:44 -0700483
Hyunsun Moon1251e192016-06-07 16:57:05 -0700484 if (ovsdbBridge.failMode().isPresent()) {
485 String failMode = ovsdbBridge.failMode().get().name().toLowerCase();
486 bridge.setFailMode(Sets.newHashSet(failMode));
Bob zhoue9795fd2016-05-12 20:18:45 +0800487 }
Hyunsun Moon646d8c42015-10-08 20:32:44 -0700488
jaegonkim80bee532017-05-15 15:16:38 +0900489 if (ovsdbBridge.datapathType().isPresent()) {
490 String datapathType = ovsdbBridge.datapathType().get();
491 bridge.setDatapathType(datapathType);
492 }
493
rohitsharana127ba82018-01-16 02:17:30 +0530494 if (ovsdbBridge.controlProtocols().isPresent()) {
495 bridge.setProtocols(ovsdbBridge.controlProtocols().get().stream()
496 .map(ControlProtocolVersion::toString)
497 .collect(Collectors.toCollection(HashSet::new)));
498 }
499
Jian Li0aed0e62020-12-12 03:54:54 +0900500 if (ovsdbBridge.mcastSnoopingEnable().isPresent()) {
501 boolean mcastSnoopingFlag = ovsdbBridge.mcastSnoopingEnable().get();
502 bridge.setMcastSnoopingEnable(mcastSnoopingFlag);
503 }
504
Hyunsun Moon1251e192016-06-07 16:57:05 -0700505 String bridgeUuid = getBridgeUuid(ovsdbBridge.name());
Hyunsun Moon98025542016-03-08 04:36:02 -0800506 if (bridgeUuid == null) {
Hyunsun Moon1251e192016-06-07 16:57:05 -0700507 bridge.setName(ovsdbBridge.name());
508 bridgeUuid = insertConfig(
509 BRIDGE, UUID, DATABASENAME, BRIDGES,
510 ovsUuid, bridge.getRow());
Hyunsun Moon98025542016-03-08 04:36:02 -0800511 } else {
Hyunsun Moon1251e192016-06-07 16:57:05 -0700512 // update the bridge if it's already existing
513 updateConfig(BRIDGE, UUID, bridgeUuid, bridge.getRow());
Hyunsun Moon98025542016-03-08 04:36:02 -0800514 }
Hyunsun Moon646d8c42015-10-08 20:32:44 -0700515
Hyunsun Moon1251e192016-06-07 16:57:05 -0700516 if (bridgeUuid == null) {
517 log.warn("Failed to create bridge {} on {}", ovsdbBridge.name(), nodeId);
Hyunsun Moon646d8c42015-10-08 20:32:44 -0700518 return false;
519 }
520
Hyunsun Moon1251e192016-06-07 16:57:05 -0700521 createPort(ovsdbBridge.name(), ovsdbBridge.name());
522 setControllersWithUuid(Uuid.uuid(bridgeUuid), ovsdbBridge.controllers());
523
524 log.info("Created bridge {}", ovsdbBridge.name());
Hyunsun Moon646d8c42015-10-08 20:32:44 -0700525 return true;
526 }
527
Hyunsun Moon1251e192016-06-07 16:57:05 -0700528 @Override
529 public ControllerInfo localController() {
530 IpAddress ipAddress = IpAddress.valueOf(((InetSocketAddress)
531 channel.localAddress()).getAddress());
532 return new ControllerInfo(ipAddress, OFPORT, "tcp");
andreaed976a42015-10-05 14:38:25 -0700533 }
534
Hyunsun Moondd14e8e2016-06-09 16:17:32 -0700535 private void setControllersWithUuid(Uuid bridgeUuid, List<ControllerInfo> controllers) {
Hyunsun Moon1251e192016-06-07 16:57:05 -0700536 DatabaseSchema dbSchema = schema.get(DATABASENAME);
andreaed976a42015-10-05 14:38:25 -0700537 if (dbSchema == null) {
538 log.debug("There is no schema");
539 return;
540 }
541 List<Controller> oldControllers = getControllers(bridgeUuid);
542 if (oldControllers == null) {
543 log.warn("There are no controllers");
544 return;
545 }
546
andreaed976a42015-10-05 14:38:25 -0700547 Set<ControllerInfo> newControllers = new HashSet<>(controllers);
548 List<Controller> removeControllers = new ArrayList<>();
549 oldControllers.forEach(controller -> {
550 ControllerInfo controllerInfo = new ControllerInfo((String) controller.getTargetColumn().data());
551 if (newControllers.contains(controllerInfo)) {
552 newControllers.remove(controllerInfo);
andreaed976a42015-10-05 14:38:25 -0700553 } else {
554 removeControllers.add(controller);
555 }
556 });
Hyunsun Moon1251e192016-06-07 16:57:05 -0700557 OvsdbRowStore controllerRowStore = getRowStore(DATABASENAME, CONTROLLER);
andreaed976a42015-10-05 14:38:25 -0700558 if (controllerRowStore == null) {
559 log.debug("There is no controller table");
560 return;
561 }
562
andreaed976a42015-10-05 14:38:25 -0700563 newControllers.stream().map(c -> {
564 Controller controller = (Controller) TableGenerator
565 .createTable(dbSchema, OvsdbTable.CONTROLLER);
566 controller.setTarget(c.target());
567 return controller;
tanbangcheng62cd4492017-11-24 21:57:05 +0800568 }).forEach(c -> insertConfig(CONTROLLER, UUID, BRIDGE, BRIDGE_CONTROLLER,
569 bridgeUuid.value(),
570 c.getRow()));
andreaed976a42015-10-05 14:38:25 -0700571
Jian Li46fcbe42019-06-13 13:45:26 +0900572 // Controller removal is extremely dangerous operation, because with
573 // empty controller list, all existing flow rules will be wiped out.
574 // To harden the setController operation, we need to double check whether
575 // the updated controller list size is bigger than the remove controller list size
576 List<Controller> updatedControllers = getControllers(bridgeUuid);
577 if (updatedControllers != null && updatedControllers.size() > removeControllers.size()) {
578 removeControllers.forEach(c ->
579 deleteConfig(CONTROLLER, UUID, c.getRow().uuid().value(),
580 BRIDGE, BRIDGE_CONTROLLER, c.getRow().uuid()));
581 } else {
582 log.warn("New controllers were not properly configured to OVS " +
583 "bridge {} or failed to retrieve controller list from OVS " +
584 "bridge {}", bridgeUuid, bridgeUuid);
585 }
andreaed976a42015-10-05 14:38:25 -0700586 }
587
andreaed976a42015-10-05 14:38:25 -0700588 @Override
589 public void setControllersWithDeviceId(DeviceId deviceId, List<ControllerInfo> controllers) {
Jonathan Hart51539b82015-10-29 09:53:04 -0700590 setControllersWithUuid(getBridgeUuid(deviceId), controllers);
andreaed976a42015-10-05 14:38:25 -0700591 }
592
Sho SHIMIZUe4efe452015-08-26 15:06:55 -0700593 @Override
594 public void dropBridge(String bridgeName) {
Jonathan Hart51539b82015-10-29 09:53:04 -0700595 String bridgeUuid = getBridgeUuid(bridgeName);
596 if (bridgeUuid == null) {
Sho SHIMIZUe4efe452015-08-26 15:06:55 -0700597 log.warn("Could not find bridge in node", nodeId.getIpAddress());
598 return;
599 }
Frank Wange11a98d2016-10-26 17:04:03 +0800600 deleteConfig(BRIDGE, UUID, bridgeUuid, DATABASENAME, BRIDGES, Uuid.uuid(bridgeUuid));
Hyunsun Moondd14e8e2016-06-09 16:17:32 -0700601 }
602
Frank Wange11a98d2016-10-26 17:04:03 +0800603 @Override
604 public void applyQos(PortNumber portNumber, String qosName) {
605 DatabaseSchema dbSchema = schema.get(DATABASENAME);
606 OvsdbRowStore portRowStore = getRowStore(DATABASENAME, PORT);
607 if (portRowStore == null) {
608 log.debug("The port uuid is null");
609 return;
610 }
611 OvsdbRowStore qosRowStore = getRowStore(DATABASENAME, QOS);
612 if (qosRowStore == null) {
613 log.debug("The qos uuid is null");
614 return;
615 }
616
617 // Due to Qos Table doesn't have a unique identifier except uuid, unlike
618 // Bridge or Port Table has a name column,in order to make the api more
619 // general, put qos name in external_ids column of Qos Table if this qos
620 // created by onos.
621 ConcurrentMap<String, Row> qosTableRows = qosRowStore.getRowStore();
622 ConcurrentMap<String, Row> portTableRows = portRowStore.getRowStore();
623 Row qosRow = qosTableRows.values().stream().filter(r -> {
624 OvsdbMap ovsdbMap = (OvsdbMap) (r.getColumn(EXTERNAL_ID).data());
625 return qosName.equals(ovsdbMap.map().get(QOS_EXTERNAL_ID_KEY));
626 }).findFirst().orElse(null);
627
628 Row portRow = portTableRows.values().stream()
629 .filter(r -> r.getColumn("name").data().equals(portNumber.name()))
630 .findFirst().orElse(null);
631 if (portRow != null && qosRow != null) {
632 String qosId = qosRow.uuid().value();
633 Uuid portUuid = portRow.uuid();
634 Map<String, Column> columns = new HashMap<>();
635 Row newPortRow = new Row(PORT, portUuid, columns);
636 Port newport = new Port(dbSchema, newPortRow);
637 columns.put(Port.PortColumn.QOS.columnName(), newport.getQosColumn());
638 newport.setQos(Uuid.uuid(qosId));
639 updateConfig(PORT, UUID, portUuid.value(), newport.getRow());
640 }
641 }
642
643 @Override
644 public void removeQos(PortNumber portNumber) {
645 DatabaseSchema dbSchema = schema.get(DATABASENAME);
646 OvsdbRowStore rowStore = getRowStore(DATABASENAME, PORT);
647 if (rowStore == null) {
648 log.debug("The qos uuid is null");
649 return;
650 }
651
652 ConcurrentMap<String, Row> ovsTableRows = rowStore.getRowStore();
653 Row portRow = ovsTableRows.values().stream()
654 .filter(r -> r.getColumn("name").data().equals(portNumber.name()))
655 .findFirst().orElse(null);
656 if (portRow == null) {
657 log.warn("Couldn't find port {} in ovsdb port table.", portNumber.name());
658 return;
659 }
660
661 OvsdbSet ovsdbSet = ((OvsdbSet) portRow.getColumn(PORT_QOS).data());
662 @SuppressWarnings("unchecked")
663 Set<Uuid> qosIdSet = ovsdbSet.set();
664 if (qosIdSet == null || qosIdSet.isEmpty()) {
665 return;
666 }
667 Uuid qosUuid = (Uuid) qosIdSet.toArray()[0];
668 Condition condition = ConditionUtil.isEqual(UUID, portRow.uuid());
669 List<Condition> conditions = Lists.newArrayList(condition);
670 Mutation mutation = MutationUtil.delete(PORT_QOS, qosUuid);
671 List<Mutation> mutations = Lists.newArrayList(mutation);
672
673 ArrayList<Operation> operations = Lists.newArrayList();
674 Mutate mutate = new Mutate(dbSchema.getTableSchema(PORT), conditions, mutations);
675 operations.add(mutate);
676 transactConfig(DATABASENAME, operations);
677 }
678
679 @Override
680 public boolean createQos(OvsdbQos ovsdbQos) {
681 DatabaseSchema dbSchema = schema.get(DATABASENAME);
682 Qos qos = (Qos) TableGenerator.createTable(dbSchema, OvsdbTable.QOS);
683 OvsdbRowStore rowStore = getRowStore(DATABASENAME, QOS);
684 if (rowStore == null) {
685 log.debug("The qos uuid is null");
686 return false;
687 }
688
689 ArrayList<Operation> operations = Lists.newArrayList();
690 Set<String> types = Sets.newHashSet();
691 Map<Long, Uuid> queues = Maps.newHashMap();
692
693 types.add(ovsdbQos.qosType());
694 qos.setOtherConfig(ovsdbQos.otherConfigs());
695 qos.setExternalIds(ovsdbQos.externalIds());
696 qos.setType(types);
697 if (ovsdbQos.qosQueues().isPresent()) {
698 for (Map.Entry<Long, String> entry : ovsdbQos.qosQueues().get().entrySet()) {
699 OvsdbRowStore queueRowStore = getRowStore(DATABASENAME, QUEUE);
700 if (queueRowStore != null) {
701 ConcurrentMap<String, Row> queueTableRows = queueRowStore.getRowStore();
702 Row queueRow = queueTableRows.values().stream().filter(r -> {
703 OvsdbMap ovsdbMap = (OvsdbMap) (r.getColumn(EXTERNAL_ID).data());
704 return entry.getValue().equals(ovsdbMap.map().get(QUEUE_EXTERNAL_ID_KEY));
705 }).findFirst().orElse(null);
706 if (queueRow != null) {
707 queues.put(entry.getKey(), queueRow.uuid());
708 }
709 }
710 }
711 qos.setQueues(queues);
712 }
713
714 Insert qosInsert = new Insert(dbSchema.getTableSchema(QOS), QOS, qos.getRow());
715 operations.add(qosInsert);
716 try {
717 transactConfig(DATABASENAME, operations).get();
718 } catch (InterruptedException | ExecutionException e) {
719 return false;
720 }
721 return true;
722 }
723
724 @Override
725 public void dropQos(QosId qosId) {
726 OvsdbRowStore rowStore = getRowStore(DATABASENAME, QOS);
727 if (rowStore != null) {
728 ConcurrentMap<String, Row> qosTableRows = rowStore.getRowStore();
729 Row qosRow = qosTableRows.values().stream().filter(r -> {
730 OvsdbMap ovsdbMap = (OvsdbMap) (r.getColumn(EXTERNAL_ID).data());
731 return qosId.name().equals(ovsdbMap.map().get(QOS_EXTERNAL_ID_KEY));
732 }).findFirst().orElse(null);
733 if (qosRow != null) {
734 deleteConfig(QOS, UUID, qosRow.uuid().value(), PORT, PORT_QOS, qosRow.uuid());
735 }
736 }
737 }
738 @Override
739 public OvsdbQos getQos(QosId qosId) {
740 Set<OvsdbQos> ovsdbQoses = getQoses();
741 return ovsdbQoses.stream().filter(r ->
742 qosId.name().equals(r.externalIds().get(QOS_EXTERNAL_ID_KEY))).
743 findFirst().orElse(null);
744 }
745
746 @Override
747 public Set<OvsdbQos> getQoses() {
748 Set<OvsdbQos> ovsdbQoses = new HashSet<>();
749 OvsdbRowStore rowStore = getRowStore(DATABASENAME, QOS);
750 if (rowStore == null) {
751 log.debug("The qos uuid is null");
752 return ovsdbQoses;
753 }
754 ConcurrentMap<String, Row> rows = rowStore.getRowStore();
kdarapufce5abb2018-05-10 19:37:53 +0530755 ovsdbQoses = rows.keySet().stream()
756 .map(uuid -> getRow(DATABASENAME, QOS, uuid))
757 .map(this::getOvsdbQos)
758 .filter(Objects::nonNull)
759 .collect(Collectors.toSet());
Frank Wange11a98d2016-10-26 17:04:03 +0800760 return ovsdbQoses;
761 }
762
763 @Override
tanbangchengc944c282017-11-12 20:42:59 +0800764 public void bindQueues(QosId qosId, Map<Long, QueueDescription> queues) {
765 DatabaseSchema dbSchema = schema.get(DATABASENAME);
766 OvsdbRowStore qosRowStore = getRowStore(DATABASENAME, QOS);
767 if (qosRowStore == null) {
768 log.debug("The qos uuid is null");
769 return;
770 }
771 OvsdbRowStore queueRowStore = getRowStore(DATABASENAME, QUEUE);
772 if (queueRowStore == null) {
773 log.debug("The queue uuid is null");
774 return;
775 }
776
777 ConcurrentMap<String, Row> qosTableRows = qosRowStore.getRowStore();
778 ConcurrentMap<String, Row> queueTableRows = queueRowStore.getRowStore();
779
780 Row qosRow = qosTableRows.values().stream().filter(r -> {
781 OvsdbMap ovsdbMap = (OvsdbMap) (r.getColumn(EXTERNAL_ID).data());
782 return qosId.name().equals(ovsdbMap.map().get(QOS_EXTERNAL_ID_KEY));
783 }).findFirst().orElse(null);
784
785 if (qosRow == null) {
786 log.warn("Can't find QoS {}", qosId);
787 return;
788 }
789
790 Uuid qosUuid = qosRow.uuid();
791
kdarapufce5abb2018-05-10 19:37:53 +0530792 Map<Long, Uuid> newQueues = new HashMap<>();
tanbangchengc944c282017-11-12 20:42:59 +0800793 for (Map.Entry<Long, QueueDescription> entry : queues.entrySet()) {
794 Row queueRow = queueTableRows.values().stream().filter(r -> {
795 OvsdbMap ovsdbMap = (OvsdbMap) (r.getColumn(EXTERNAL_ID).data());
796 return entry.getValue().queueId().name().equals(ovsdbMap.map().get(QUEUE_EXTERNAL_ID_KEY));
797 }).findFirst().orElse(null);
798 if (queueRow != null) {
799 newQueues.put(entry.getKey(), queueRow.uuid());
800 }
801 }
802
803 // update the qos table
804 ArrayList<Operation> operations = Lists.newArrayList();
805 Condition condition = ConditionUtil.isEqual(UUID, qosUuid);
806 Mutation mutation = MutationUtil.insert(QUEUES, newQueues);
807 List<Condition> conditions = Collections.singletonList(condition);
808 List<Mutation> mutations = Collections.singletonList(mutation);
809 operations.add(new Mutate(dbSchema.getTableSchema(QOS), conditions, mutations));
810
811 transactConfig(DATABASENAME, operations);
812 }
813
814
815 @SuppressWarnings("unchecked")
816 @Override
817 public void unbindQueues(QosId qosId, List<Long> queueKeys) {
818 DatabaseSchema dbSchema = schema.get(DATABASENAME);
819 OvsdbRowStore qosRowStore = getRowStore(DATABASENAME, QOS);
820 if (qosRowStore == null) {
821 return;
822 }
823
824 ConcurrentMap<String, Row> qosTableRows = qosRowStore.getRowStore();
825
826 Row qosRow = qosTableRows.values().stream().filter(r -> {
827 OvsdbMap ovsdbMap = (OvsdbMap) (r.getColumn(EXTERNAL_ID).data());
828 return qosId.name().equals(ovsdbMap.map().get(QOS_EXTERNAL_ID_KEY));
829 }).findFirst().orElse(null);
830
831 if (qosRow == null) {
832 log.warn("Can't find QoS {}", qosId);
833 return;
834 }
835
kdarapufce5abb2018-05-10 19:37:53 +0530836 Map<Long, Uuid> deleteQueuesMap;
tanbangchengc944c282017-11-12 20:42:59 +0800837 Map<Integer, Uuid> queuesMap = ((OvsdbMap) qosRow.getColumn(QUEUES).data()).map();
838
kdarapufce5abb2018-05-10 19:37:53 +0530839 deleteQueuesMap = queueKeys.stream()
840 .filter(key -> queuesMap.containsKey(key.intValue()))
841 .collect(Collectors.toMap(key -> key, key -> queuesMap.get(key.intValue()), (a, b) -> b));
tanbangchengc944c282017-11-12 20:42:59 +0800842
843 if (deleteQueuesMap.size() != 0) {
844 TableSchema parentTableSchema = dbSchema
845 .getTableSchema(QOS);
846 ColumnSchema parentColumnSchema = parentTableSchema
847 .getColumnSchema(QUEUES);
848
849 Mutation mutation = MutationUtil.delete(parentColumnSchema.name(), OvsdbMap.ovsdbMap(deleteQueuesMap));
850 List<Mutation> mutations = Collections.singletonList(mutation);
851
852 Condition condition = ConditionUtil.isEqual(UUID, qosRow.uuid());
853 List<Condition> conditionList = Collections.singletonList(condition);
854 List<Operation> operations = Collections.singletonList(
855 new Mutate(parentTableSchema, conditionList, mutations));
856
857 transactConfig(DATABASENAME, operations);
858 }
859 }
860
861
862 @Override
Frank Wange11a98d2016-10-26 17:04:03 +0800863 public boolean createQueue(OvsdbQueue ovsdbQueue) {
864 DatabaseSchema dbSchema = schema.get(DATABASENAME);
865 Queue queue = (Queue) TableGenerator.createTable(dbSchema, OvsdbTable.QUEUE);
866 ArrayList<Operation> operations = Lists.newArrayList();
867 OvsdbRowStore rowStore = getRowStore(DATABASENAME, QUEUE);
868 if (rowStore == null) {
869 log.debug("The queue uuid is null");
870 return false;
871 }
872
873 if (ovsdbQueue.dscp().isPresent()) {
874 queue.setDscp(ImmutableSet.of(ovsdbQueue.dscp().get()));
875 }
876 queue.setOtherConfig(ovsdbQueue.otherConfigs());
877 queue.setExternalIds(ovsdbQueue.externalIds());
878 Insert queueInsert = new Insert(dbSchema.getTableSchema(QUEUE), QUEUE, queue.getRow());
879 operations.add(queueInsert);
880
881 try {
882 transactConfig(DATABASENAME, operations).get();
883 } catch (InterruptedException | ExecutionException e) {
884 log.error("createQueue transactConfig get exception !");
885 }
886 return true;
887 }
888
889 @Override
890 public void dropQueue(QueueId queueId) {
891 OvsdbRowStore queueRowStore = getRowStore(DATABASENAME, QUEUE);
892 if (queueRowStore == null) {
893 return;
894 }
895
896 ConcurrentMap<String, Row> queueTableRows = queueRowStore.getRowStore();
897 Row queueRow = queueTableRows.values().stream().filter(r -> {
898 OvsdbMap ovsdbMap = (OvsdbMap) (r.getColumn(EXTERNAL_ID).data());
899 return queueId.name().equals(ovsdbMap.map().get(QUEUE_EXTERNAL_ID_KEY));
900 }).findFirst().orElse(null);
901 if (queueRow == null) {
902 return;
903 }
904
905 String queueUuid = queueRow.uuid().value();
906 OvsdbRowStore qosRowStore = getRowStore(DATABASENAME, QOS);
907 if (qosRowStore != null) {
908 Map<Long, Uuid> queueMap = new HashMap<>();
909 ConcurrentMap<String, Row> qosTableRows = qosRowStore.getRowStore();
910 qosTableRows.values().stream().filter(r -> {
911 Map<Integer, Uuid> ovsdbMap = ((OvsdbMap) r.getColumn(QUEUES).data()).map();
912 Set<Integer> keySet = ovsdbMap.keySet();
913 for (Integer keyId : keySet) {
914 if (ovsdbMap.get(keyId).equals(Uuid.uuid(queueUuid))) {
915 queueMap.put(keyId.longValue(), Uuid.uuid(queueUuid));
916 return true;
917 }
918 }
919 return false;
920 }).findFirst().orElse(null);
921 deleteConfig(QUEUE, UUID, queueUuid, QOS, QUEUES, OvsdbMap.ovsdbMap(queueMap));
922 } else {
923 deleteConfig(QUEUE, UUID, queueUuid, null, null, null);
924 }
925 }
926 @Override
927 public OvsdbQueue getQueue(QueueId queueId) {
928 Set<OvsdbQueue> ovsdbQueues = getQueues();
929 return ovsdbQueues.stream().filter(r ->
930 queueId.name().equals(r.externalIds().get(QUEUE_EXTERNAL_ID_KEY))).
931 findFirst().orElse(null);
932 }
933
934 @Override
935 public Set<OvsdbQueue> getQueues() {
936 Set<OvsdbQueue> ovsdbqueues = new HashSet<>();
937 OvsdbRowStore rowStore = getRowStore(DATABASENAME, QUEUE);
938 if (rowStore == null) {
939 log.debug("The queue uuid is null");
940 return ovsdbqueues;
941 }
942 ConcurrentMap<String, Row> rows = rowStore.getRowStore();
kdarapufce5abb2018-05-10 19:37:53 +0530943 ovsdbqueues = rows.keySet()
944 .stream()
945 .map(uuid -> getRow(DATABASENAME, QUEUE, uuid))
946 .map(this::getOvsdbQueue)
947 .filter(Objects::nonNull)
948 .collect(Collectors.toSet());
Frank Wange11a98d2016-10-26 17:04:03 +0800949 return ovsdbqueues;
950 }
Jian Li46fcbe42019-06-13 13:45:26 +0900951
Pier Ventref5d72362016-07-17 12:02:14 +0200952 @Override
953 public boolean createMirror(String bridgeName, OvsdbMirror mirror) {
954
955 /**
956 * Retrieves bridge's uuid. It is necessary to update
957 * Bridge table.
958 */
959 String bridgeUuid = getBridgeUuid(bridgeName);
960 if (bridgeUuid == null) {
961 log.warn("Couldn't find bridge {} in {}", bridgeName, nodeId.getIpAddress());
962 return false;
963 }
964
965 OvsdbMirror.Builder mirrorBuilder = OvsdbMirror.builder();
966
967 mirrorBuilder.mirroringName(mirror.mirroringName());
968 mirrorBuilder.selectAll(mirror.selectAll());
969
970 /**
971 * Retrieves the uuid of the monitored dst ports.
972 */
973 mirrorBuilder.monitorDstPorts(mirror.monitorDstPorts().parallelStream()
974 .map(dstPort -> {
975 String dstPortUuid = getPortUuid(dstPort.value(), bridgeUuid);
976 if (dstPortUuid != null) {
977 return Uuid.uuid(dstPortUuid);
978 }
979 log.warn("Couldn't find port {} in {}",
980 dstPort.value(), nodeId.getIpAddress());
981 return null;
982 })
983 .filter(Objects::nonNull)
984 .collect(Collectors.toSet())
985 );
986
987 /**
988 * Retrieves the uuid of the monitored src ports.
989 */
990 mirrorBuilder.monitorSrcPorts(mirror.monitorSrcPorts().parallelStream()
991 .map(srcPort -> {
992 String srcPortUuid = getPortUuid(srcPort.value(), bridgeUuid);
993 if (srcPortUuid != null) {
994 return Uuid.uuid(srcPortUuid);
995 }
996 log.warn("Couldn't find port {} in {}",
997 srcPort.value(), nodeId.getIpAddress());
998 return null;
999 }).filter(Objects::nonNull)
1000 .collect(Collectors.toSet())
1001 );
1002
1003 mirrorBuilder.monitorVlans(mirror.monitorVlans());
1004 mirrorBuilder.mirrorPort(mirror.mirrorPort());
1005 mirrorBuilder.mirrorVlan(mirror.mirrorVlan());
1006 mirrorBuilder.externalIds(mirror.externalIds());
1007 mirror = mirrorBuilder.build();
1008
Jon Hallcbd1b392017-01-18 20:15:44 -08001009 if (mirror.monitorDstPorts().isEmpty() &&
1010 mirror.monitorSrcPorts().isEmpty() &&
1011 mirror.monitorVlans().isEmpty()) {
Pier Ventref5d72362016-07-17 12:02:14 +02001012 log.warn("Invalid monitoring data");
1013 return false;
1014 }
1015
1016 DatabaseSchema dbSchema = schema.get(DATABASENAME);
1017
1018 Mirror mirrorEntry = (Mirror) TableGenerator.createTable(dbSchema, OvsdbTable.MIRROR);
1019 mirrorEntry.setName(mirror.mirroringName());
1020 mirrorEntry.setSelectDstPort(mirror.monitorDstPorts());
1021 mirrorEntry.setSelectSrcPort(mirror.monitorSrcPorts());
1022 mirrorEntry.setSelectVlan(mirror.monitorVlans());
1023 mirrorEntry.setExternalIds(mirror.externalIds());
1024
1025 /**
1026 * If mirror port, retrieves the uuid of the mirror port.
1027 */
1028 if (mirror.mirrorPort() != null) {
1029
1030 String outputPortUuid = getPortUuid(mirror.mirrorPort().value(), bridgeUuid);
1031 if (outputPortUuid == null) {
1032 log.warn("Couldn't find port {} in {}", mirror.mirrorPort().value(), nodeId.getIpAddress());
1033 return false;
1034 }
1035
1036 mirrorEntry.setOutputPort(Uuid.uuid(outputPortUuid));
1037
1038 } else if (mirror.mirrorVlan() != null) {
1039
1040 mirrorEntry.setOutputVlan(mirror.mirrorVlan());
1041
1042 } else {
1043 log.warn("Invalid mirror, no mirror port and no mirror vlan");
1044 return false;
1045 }
1046
1047 ArrayList<Operation> operations = Lists.newArrayList();
1048 Insert mirrorInsert = new Insert(dbSchema.getTableSchema("Mirror"), "Mirror", mirrorEntry.getRow());
1049 operations.add(mirrorInsert);
1050
1051 // update the bridge table
1052 Condition condition = ConditionUtil.isEqual(UUID, Uuid.uuid(bridgeUuid));
1053 Mutation mutation = MutationUtil.insert(MIRRORS, Uuid.uuid("Mirror"));
1054 List<Condition> conditions = Lists.newArrayList(condition);
1055 List<Mutation> mutations = Lists.newArrayList(mutation);
1056 operations.add(new Mutate(dbSchema.getTableSchema("Bridge"), conditions, mutations));
1057
1058 transactConfig(DATABASENAME, operations);
1059 log.info("Created mirror {}", mirror.mirroringName());
1060 return true;
1061 }
1062
Pier Ventref5d72362016-07-17 12:02:14 +02001063 @Override
1064 public void dropMirror(MirroringName mirroringName) {
1065 String mirrorUuid = getMirrorUuid(mirroringName.name());
1066 if (mirrorUuid != null) {
1067 log.info("Deleted mirror {}", mirroringName.name());
Frank Wange11a98d2016-10-26 17:04:03 +08001068 deleteConfig(MIRROR, UUID, mirrorUuid, BRIDGE, MIRRORS, Uuid.uuid(mirrorUuid));
Pier Ventref5d72362016-07-17 12:02:14 +02001069 }
1070 log.warn("Unable to delete {}", mirroringName.name());
1071 return;
1072 }
1073
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001074 @Override
Hyunsun Moondd14e8e2016-06-09 16:17:32 -07001075 public boolean createInterface(String bridgeName, OvsdbInterface ovsdbIface) {
Hyunsun Moon646d8c42015-10-08 20:32:44 -07001076 String bridgeUuid = getBridgeUuid(bridgeName);
1077 if (bridgeUuid == null) {
1078 log.warn("Couldn't find bridge {} in {}", bridgeName, nodeId.getIpAddress());
1079 return false;
1080 }
1081
Hyunsun Moondd14e8e2016-06-09 16:17:32 -07001082 if (getPortUuid(ovsdbIface.name(), bridgeUuid) != null) {
1083 log.warn("Interface {} already exists", ovsdbIface.name());
Hyunsun Moon646d8c42015-10-08 20:32:44 -07001084 return false;
1085 }
1086
1087 ArrayList<Operation> operations = Lists.newArrayList();
Hyunsun Moon1251e192016-06-07 16:57:05 -07001088 DatabaseSchema dbSchema = schema.get(DATABASENAME);
Hyunsun Moon646d8c42015-10-08 20:32:44 -07001089
Hyunsun Moon89478662016-06-09 17:52:34 -07001090 // insert a new port with the interface name
Hyunsun Moon646d8c42015-10-08 20:32:44 -07001091 Port port = (Port) TableGenerator.createTable(dbSchema, OvsdbTable.PORT);
Hyunsun Moondd14e8e2016-06-09 16:17:32 -07001092 port.setName(ovsdbIface.name());
1093 Insert portInsert = new Insert(dbSchema.getTableSchema(PORT), PORT, port.getRow());
1094 portInsert.getRow().put(INTERFACES, Uuid.uuid(INTERFACE));
Hyunsun Moon646d8c42015-10-08 20:32:44 -07001095 operations.add(portInsert);
1096
Hyunsun Moon89478662016-06-09 17:52:34 -07001097 // update the bridge table with the new port
Hyunsun Moon1251e192016-06-07 16:57:05 -07001098 Condition condition = ConditionUtil.isEqual(UUID, Uuid.uuid(bridgeUuid));
Hyunsun Moondd14e8e2016-06-09 16:17:32 -07001099 Mutation mutation = MutationUtil.insert(PORTS, Uuid.uuid(PORT));
1100 List<Condition> conditions = Lists.newArrayList(condition);
1101 List<Mutation> mutations = Lists.newArrayList(mutation);
1102 operations.add(new Mutate(dbSchema.getTableSchema(BRIDGE), conditions, mutations));
Hyunsun Moon646d8c42015-10-08 20:32:44 -07001103
Hyunsun Moon646d8c42015-10-08 20:32:44 -07001104 Interface intf = (Interface) TableGenerator.createTable(dbSchema, OvsdbTable.INTERFACE);
Hyunsun Moondd14e8e2016-06-09 16:17:32 -07001105 intf.setName(ovsdbIface.name());
jaegonkim256f2c12017-05-26 00:03:42 +09001106
Jian Lif5c92762019-05-17 19:50:28 +09001107 if (ovsdbIface.type() != null) {
1108 intf.setType(ovsdbIface.typeToString());
1109 }
jaegonkim256f2c12017-05-26 00:03:42 +09001110
1111 if (ovsdbIface.mtu().isPresent()) {
1112 Set<Long> mtuSet = Sets.newConcurrentHashSet();
1113 mtuSet.add(ovsdbIface.mtu().get());
1114 intf.setMtu(mtuSet);
1115 intf.setMtuRequest(mtuSet);
1116 }
1117
Hyunsun Moondd14e8e2016-06-09 16:17:32 -07001118 intf.setOptions(ovsdbIface.options());
Jian Lif5c92762019-05-17 19:50:28 +09001119
1120 ovsdbIface.data().forEach((k, v) -> {
1121 if (k == Interface.InterfaceColumn.EXTERNALIDS) {
1122 intf.setExternalIds(v);
1123 }
1124 });
1125
Hyunsun Moondd14e8e2016-06-09 16:17:32 -07001126 Insert intfInsert = new Insert(dbSchema.getTableSchema(INTERFACE), INTERFACE, intf.getRow());
Hyunsun Moon646d8c42015-10-08 20:32:44 -07001127 operations.add(intfInsert);
1128
Hyunsun Moon1251e192016-06-07 16:57:05 -07001129 transactConfig(DATABASENAME, operations);
Hyunsun Moon89478662016-06-09 17:52:34 -07001130 log.info("Created interface {}", ovsdbIface);
Hyunsun Moon646d8c42015-10-08 20:32:44 -07001131 return true;
1132 }
1133
1134 @Override
Hyunsun Moondd14e8e2016-06-09 16:17:32 -07001135 public boolean dropInterface(String ifaceName) {
1136 OvsdbRowStore rowStore = getRowStore(DATABASENAME, BRIDGE);
1137 if (rowStore == null) {
1138 log.warn("Failed to get BRIDGE table");
1139 return false;
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001140 }
1141
Hyunsun Moondd14e8e2016-06-09 16:17:32 -07001142 ConcurrentMap<String, Row> bridgeTableRows = rowStore.getRowStore();
1143 if (bridgeTableRows == null) {
1144 log.warn("Failed to get BRIDGE table rows");
1145 return false;
1146 }
1147
1148 // interface name is unique
1149 Optional<String> bridgeId = bridgeTableRows.keySet().stream()
1150 .filter(uuid -> getPortUuid(ifaceName, uuid) != null)
1151 .findFirst();
1152
1153 if (bridgeId.isPresent()) {
1154 String portId = getPortUuid(ifaceName, bridgeId.get());
Frank Wange11a98d2016-10-26 17:04:03 +08001155 deleteConfig(PORT, UUID, portId, BRIDGE, PORTS, Uuid.uuid(portId));
Hyunsun Moondd14e8e2016-06-09 16:17:32 -07001156 return true;
1157 } else {
1158 log.warn("Unable to find the interface with name {}", ifaceName);
1159 return false;
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001160 }
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001161 }
1162
1163 /**
1164 * Delete transact config.
1165 *
andreaed976a42015-10-05 14:38:25 -07001166 * @param childTableName child table name
1167 * @param childColumnName child column name
1168 * @param childUuid child row uuid
1169 * @param parentTableName parent table name
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001170 * @param parentColumnName parent column
Frank Wange11a98d2016-10-26 17:04:03 +08001171 * @param referencedValue referenced value
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001172 */
1173 private void deleteConfig(String childTableName, String childColumnName,
andreaed976a42015-10-05 14:38:25 -07001174 String childUuid, String parentTableName,
Frank Wange11a98d2016-10-26 17:04:03 +08001175 String parentColumnName, Object referencedValue) {
Hyunsun Moon1251e192016-06-07 16:57:05 -07001176 DatabaseSchema dbSchema = schema.get(DATABASENAME);
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001177 TableSchema childTableSchema = dbSchema.getTableSchema(childTableName);
1178
1179 ArrayList<Operation> operations = Lists.newArrayList();
Frank Wange11a98d2016-10-26 17:04:03 +08001180 if (parentTableName != null && parentColumnName != null && referencedValue != null) {
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001181 TableSchema parentTableSchema = dbSchema
1182 .getTableSchema(parentTableName);
1183 ColumnSchema parentColumnSchema = parentTableSchema
1184 .getColumnSchema(parentColumnName);
1185 List<Mutation> mutations = Lists.newArrayList();
Frank Wange11a98d2016-10-26 17:04:03 +08001186 Mutation mutation = MutationUtil.delete(parentColumnSchema.name(), referencedValue);
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001187 mutations.add(mutation);
1188 List<Condition> conditions = Lists.newArrayList();
Frank Wange11a98d2016-10-26 17:04:03 +08001189 Condition condition = ConditionUtil.includes(parentColumnName, referencedValue);
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001190 conditions.add(condition);
1191 Mutate op = new Mutate(parentTableSchema, conditions, mutations);
1192 operations.add(op);
1193 }
1194
1195 List<Condition> conditions = Lists.newArrayList();
Jonathan Hart51539b82015-10-29 09:53:04 -07001196 Condition condition = ConditionUtil.isEqual(childColumnName, Uuid.uuid(childUuid));
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001197 conditions.add(condition);
1198 Delete del = new Delete(childTableSchema, conditions);
1199 operations.add(del);
Hyunsun Moon1251e192016-06-07 16:57:05 -07001200 transactConfig(DATABASENAME, operations);
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001201 }
1202
1203 /**
1204 * Update transact config.
1205 *
andreaed976a42015-10-05 14:38:25 -07001206 * @param tableName table name
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001207 * @param columnName column name
andreaed976a42015-10-05 14:38:25 -07001208 * @param uuid uuid
1209 * @param row the config data
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001210 */
1211 private void updateConfig(String tableName, String columnName, String uuid,
andreaed976a42015-10-05 14:38:25 -07001212 Row row) {
Hyunsun Moon1251e192016-06-07 16:57:05 -07001213 DatabaseSchema dbSchema = schema.get(DATABASENAME);
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001214 TableSchema tableSchema = dbSchema.getTableSchema(tableName);
1215
1216 List<Condition> conditions = Lists.newArrayList();
Jonathan Hart51539b82015-10-29 09:53:04 -07001217 Condition condition = ConditionUtil.isEqual(columnName, Uuid.uuid(uuid));
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001218 conditions.add(condition);
1219
1220 Update update = new Update(tableSchema, row, conditions);
1221
1222 ArrayList<Operation> operations = Lists.newArrayList();
1223 operations.add(update);
1224
Hyunsun Moon1251e192016-06-07 16:57:05 -07001225 transactConfig(DATABASENAME, operations);
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001226 }
1227
1228 /**
1229 * Insert transact config.
1230 *
andreaed976a42015-10-05 14:38:25 -07001231 * @param childTableName child table name
1232 * @param childColumnName child column name
1233 * @param parentTableName parent table name
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001234 * @param parentColumnName parent column
andreaed976a42015-10-05 14:38:25 -07001235 * @param parentUuid parent uuid
1236 * @param row the config data
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001237 * @return uuid, empty if no uuid is find
1238 */
1239 private String insertConfig(String childTableName, String childColumnName,
andreaed976a42015-10-05 14:38:25 -07001240 String parentTableName, String parentColumnName,
1241 String parentUuid, Row row) {
Hyunsun Moon1251e192016-06-07 16:57:05 -07001242 DatabaseSchema dbSchema = schema.get(DATABASENAME);
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001243 TableSchema tableSchema = dbSchema.getTableSchema(childTableName);
1244
Sho SHIMIZUff18f8c2016-03-11 14:43:53 -08001245 Insert insert = new Insert(tableSchema, childTableName, row);
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001246
1247 ArrayList<Operation> operations = Lists.newArrayList();
1248 operations.add(insert);
1249
1250 if (parentTableName != null && parentColumnName != null) {
1251 TableSchema parentTableSchema = dbSchema
1252 .getTableSchema(parentTableName);
1253 ColumnSchema parentColumnSchema = parentTableSchema
1254 .getColumnSchema(parentColumnName);
1255
1256 List<Mutation> mutations = Lists.newArrayList();
1257 Mutation mutation = MutationUtil.insert(parentColumnSchema.name(),
Sho SHIMIZUff18f8c2016-03-11 14:43:53 -08001258 Uuid.uuid(childTableName));
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001259 mutations.add(mutation);
1260
1261 List<Condition> conditions = Lists.newArrayList();
Hyunsun Moon1251e192016-06-07 16:57:05 -07001262 Condition condition = ConditionUtil.isEqual(UUID, Uuid.uuid(parentUuid));
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001263 conditions.add(condition);
1264
1265 Mutate op = new Mutate(parentTableSchema, conditions, mutations);
1266 operations.add(op);
1267 }
Hyunsun Moon1251e192016-06-07 16:57:05 -07001268 if (childTableName.equalsIgnoreCase(PORT)) {
1269 log.debug("Handle port insert");
Hyunsun Moondd14e8e2016-06-09 16:17:32 -07001270 Insert intfInsert = handlePortInsertTable(row);
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001271
1272 if (intfInsert != null) {
1273 operations.add(intfInsert);
1274 }
1275
1276 Insert ins = (Insert) operations.get(0);
Hyunsun Moon1251e192016-06-07 16:57:05 -07001277 ins.getRow().put("interfaces", Uuid.uuid(INTERFACE));
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001278 }
1279
1280 List<OperationResult> results;
1281 try {
jaegonkim01d7c912017-01-22 22:03:38 +09001282 results = transactConfig(DATABASENAME, operations)
1283 .get(TRANSACTCONFIG_TIMEOUT, TimeUnit.SECONDS);
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001284 return results.get(0).getUuid().value();
jaegonkim01d7c912017-01-22 22:03:38 +09001285 } catch (TimeoutException e) {
1286 log.warn("TimeoutException thrown while to get result");
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001287 } catch (InterruptedException e) {
1288 log.warn("Interrupted while waiting to get result");
1289 Thread.currentThread().interrupt();
1290 } catch (ExecutionException e) {
1291 log.error("Exception thrown while to get result");
1292 }
1293
1294 return null;
1295 }
1296
jaegonkim01d7c912017-01-22 22:03:38 +09001297
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001298 /**
1299 * Handles port insert.
1300 *
andreaed976a42015-10-05 14:38:25 -07001301 * @param portRow row of port
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001302 * @return insert, empty if null
1303 */
Hyunsun Moondd14e8e2016-06-09 16:17:32 -07001304 private Insert handlePortInsertTable(Row portRow) {
Hyunsun Moon1251e192016-06-07 16:57:05 -07001305 DatabaseSchema dbSchema = schema.get(DATABASENAME);
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001306
Hyunsun Moon1251e192016-06-07 16:57:05 -07001307 TableSchema portTableSchema = dbSchema.getTableSchema(PORT);
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001308 ColumnSchema portColumnSchema = portTableSchema.getColumnSchema("name");
1309
1310 String portName = (String) portRow.getColumn(portColumnSchema.name()).data();
Hyunsun Moon1251e192016-06-07 16:57:05 -07001311 Interface inf = (Interface) TableGenerator.createTable(dbSchema, OvsdbTable.INTERFACE);
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001312 inf.setName(portName);
1313
Hyunsun Moon1251e192016-06-07 16:57:05 -07001314 TableSchema intfTableSchema = dbSchema.getTableSchema(INTERFACE);
1315 return new Insert(intfTableSchema, INTERFACE, inf.getRow());
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001316 }
1317
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001318 @Override
1319 public ListenableFuture<DatabaseSchema> getOvsdbSchema(String dbName) {
1320 if (dbName == null) {
1321 return null;
1322 }
1323 DatabaseSchema databaseSchema = schema.get(dbName);
1324 if (databaseSchema == null) {
kdarapufce5abb2018-05-10 19:37:53 +05301325 List<String> dbNames = new ArrayList<>();
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001326 dbNames.add(dbName);
Hyunsun Moon1251e192016-06-07 16:57:05 -07001327 Function<JsonNode, DatabaseSchema> rowFunction = input -> {
1328 log.debug("Get ovsdb database schema {}", dbName);
1329 DatabaseSchema dbSchema = FromJsonUtil.jsonNodeToDbSchema(dbName, input);
1330 if (dbSchema == null) {
1331 log.debug("Get ovsdb database schema error");
1332 return null;
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001333 }
Hyunsun Moon1251e192016-06-07 16:57:05 -07001334 schema.put(dbName, dbSchema);
1335 return dbSchema;
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001336 };
1337
1338 ListenableFuture<JsonNode> input = getSchema(dbNames);
1339 if (input != null) {
Carmelo Casconeef478a62019-01-29 18:45:22 -08001340 return futureTransform(input, rowFunction);
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001341 }
1342 return null;
1343 } else {
1344 return Futures.immediateFuture(databaseSchema);
1345 }
1346 }
1347
1348 @Override
1349 public ListenableFuture<TableUpdates> monitorTables(String dbName, String id) {
1350 if (dbName == null) {
1351 return null;
1352 }
1353 DatabaseSchema dbSchema = schema.get(dbName);
1354 if (dbSchema != null) {
Hyunsun Moon1251e192016-06-07 16:57:05 -07001355 Function<JsonNode, TableUpdates> rowFunction = input -> {
1356 log.debug("Get table updates");
1357 TableUpdates updates = FromJsonUtil.jsonNodeToTableUpdates(input, dbSchema);
1358 if (updates == null) {
1359 log.debug("Get table updates error");
1360 return null;
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001361 }
Hyunsun Moon1251e192016-06-07 16:57:05 -07001362 return updates;
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001363 };
Carmelo Casconeef478a62019-01-29 18:45:22 -08001364 return futureTransform(monitor(dbSchema, id), rowFunction);
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001365 }
1366 return null;
1367 }
1368
Hyunsun Moondd14e8e2016-06-09 16:17:32 -07001369 private ListenableFuture<List<OperationResult>> transactConfig(String dbName,
1370 List<Operation> operations) {
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001371 if (dbName == null) {
1372 return null;
1373 }
1374 DatabaseSchema dbSchema = schema.get(dbName);
1375 if (dbSchema != null) {
andreaed976a42015-10-05 14:38:25 -07001376 Function<List<JsonNode>, List<OperationResult>> rowFunction = (input -> {
Jonathan Hart6523e122017-11-14 09:23:49 -08001377 try {
1378 log.debug("Get ovsdb operation result");
1379 List<OperationResult> result = FromJsonUtil.jsonNodeToOperationResult(input, operations);
1380 if (result == null) {
1381 log.debug("The operation result is null");
1382 return null;
1383 }
1384 return result;
1385 } catch (Exception e) {
1386 log.error("Exception while parsing result", e);
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001387 }
Jonathan Hart6523e122017-11-14 09:23:49 -08001388 return null;
andreaed976a42015-10-05 14:38:25 -07001389 });
Carmelo Casconeef478a62019-01-29 18:45:22 -08001390 return futureTransform(transact(dbSchema, operations), rowFunction);
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001391 }
1392 return null;
1393 }
1394
1395 @Override
1396 public ListenableFuture<JsonNode> getSchema(List<String> dbnames) {
1397 String id = java.util.UUID.randomUUID().toString();
1398 String getSchemaString = JsonRpcWriterUtil.getSchemaStr(id, dbnames);
1399
1400 SettableFuture<JsonNode> sf = SettableFuture.create();
1401 requestResult.put(id, sf);
1402 requestMethod.put(id, "getSchema");
1403
1404 channel.writeAndFlush(getSchemaString);
1405 return sf;
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001406 }
1407
1408 @Override
1409 public ListenableFuture<List<String>> echo() {
1410 String id = java.util.UUID.randomUUID().toString();
1411 String echoString = JsonRpcWriterUtil.echoStr(id);
1412
1413 SettableFuture<List<String>> sf = SettableFuture.create();
1414 requestResult.put(id, sf);
1415 requestMethod.put(id, "echo");
1416
1417 channel.writeAndFlush(echoString);
1418 return sf;
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001419 }
1420
1421 @Override
1422 public ListenableFuture<JsonNode> monitor(DatabaseSchema dbSchema,
1423 String monitorId) {
1424 String id = java.util.UUID.randomUUID().toString();
1425 String monitorString = JsonRpcWriterUtil.monitorStr(id, monitorId,
1426 dbSchema);
1427
1428 SettableFuture<JsonNode> sf = SettableFuture.create();
1429 requestResult.put(id, sf);
1430 requestMethod.put(id, "monitor");
1431
1432 channel.writeAndFlush(monitorString);
1433 return sf;
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001434 }
1435
1436 @Override
1437 public ListenableFuture<List<String>> listDbs() {
1438 String id = java.util.UUID.randomUUID().toString();
1439 String listDbsString = JsonRpcWriterUtil.listDbsStr(id);
1440
1441 SettableFuture<List<String>> sf = SettableFuture.create();
1442 requestResult.put(id, sf);
1443 requestMethod.put(id, "listDbs");
1444
1445 channel.writeAndFlush(listDbsString);
1446 return sf;
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001447 }
1448
1449 @Override
1450 public ListenableFuture<List<JsonNode>> transact(DatabaseSchema dbSchema,
1451 List<Operation> operations) {
1452 String id = java.util.UUID.randomUUID().toString();
1453 String transactString = JsonRpcWriterUtil.transactStr(id, dbSchema,
1454 operations);
1455
1456 SettableFuture<List<JsonNode>> sf = SettableFuture.create();
1457 requestResult.put(id, sf);
1458 requestMethod.put(id, "transact");
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001459 channel.writeAndFlush(transactString);
1460 return sf;
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001461 }
1462
andreaed976a42015-10-05 14:38:25 -07001463 @SuppressWarnings({"rawtypes", "unchecked"})
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001464 @Override
1465 public void processResult(JsonNode response) {
1466 log.debug("Handle result");
1467 String requestId = response.get("id").asText();
1468 SettableFuture sf = requestResult.get(requestId);
1469 if (sf == null) {
1470 log.debug("No such future to process");
1471 return;
1472 }
1473 String methodName = requestMethod.get(requestId);
Hyunsun Moon1251e192016-06-07 16:57:05 -07001474 sf.set(FromJsonUtil.jsonResultParser(response, methodName));
tanbangcheng1afecce2017-11-12 11:41:28 +08001475
1476 requestResult.remove(requestId);
1477 requestMethod.remove(requestId);
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001478 }
1479
1480 @Override
1481 public void processRequest(JsonNode requestJson) {
1482 log.debug("Handle request");
1483 if (requestJson.get("method").asText().equalsIgnoreCase("echo")) {
1484 log.debug("handle echo request");
1485
1486 String replyString = FromJsonUtil.getEchoRequestStr(requestJson);
1487 channel.writeAndFlush(replyString);
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001488 } else {
Hyunsun Moon1251e192016-06-07 16:57:05 -07001489 FromJsonUtil.jsonCallbackRequestParser(requestJson, monitorCallBack);
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001490 }
1491 }
1492
1493 @Override
1494 public void setCallback(Callback monitorCallback) {
1495 this.monitorCallBack = monitorCallback;
1496 }
1497
1498 @Override
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001499 public Set<OvsdbBridge> getBridges() {
Hyunsun Moon1251e192016-06-07 16:57:05 -07001500 Set<OvsdbBridge> ovsdbBridges = new HashSet<>();
1501 OvsdbTableStore tableStore = getTableStore(DATABASENAME);
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001502 if (tableStore == null) {
MaoJianweidac220d2016-07-04 22:37:52 +08001503 return ovsdbBridges;
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001504 }
Hyunsun Moon1251e192016-06-07 16:57:05 -07001505 OvsdbRowStore rowStore = tableStore.getRows(BRIDGE);
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001506 if (rowStore == null) {
MaoJianweidac220d2016-07-04 22:37:52 +08001507 return ovsdbBridges;
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001508 }
1509 ConcurrentMap<String, Row> rows = rowStore.getRowStore();
1510 for (String uuid : rows.keySet()) {
jaegonkim7b77f712018-01-14 17:18:27 +09001511 Row bridgeRow = getRow(DATABASENAME, BRIDGE, uuid);
1512 OvsdbBridge ovsdbBridge = getOvsdbBridge(bridgeRow, Uuid.uuid(uuid));
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001513 if (ovsdbBridge != null) {
1514 ovsdbBridges.add(ovsdbBridge);
1515 }
1516 }
1517 return ovsdbBridges;
1518 }
1519
1520 @Override
andreaed976a42015-10-05 14:38:25 -07001521 public Set<ControllerInfo> getControllers(DeviceId openflowDeviceId) {
Jonathan Hart51539b82015-10-29 09:53:04 -07001522 Uuid bridgeUuid = getBridgeUuid(openflowDeviceId);
andreaed976a42015-10-05 14:38:25 -07001523 if (bridgeUuid == null) {
1524 log.warn("bad bridge Uuid");
1525 return null;
1526 }
1527 List<Controller> controllers = getControllers(bridgeUuid);
1528 if (controllers == null) {
1529 log.warn("bad list of controllers");
1530 return null;
1531 }
Hyunsun Moon1251e192016-06-07 16:57:05 -07001532 return controllers.stream().map(controller -> new ControllerInfo(
1533 (String) controller.getTargetColumn()
1534 .data())).collect(Collectors.toSet());
andreaed976a42015-10-05 14:38:25 -07001535 }
1536
Jonathan Hart51539b82015-10-29 09:53:04 -07001537 private List<Controller> getControllers(Uuid bridgeUuid) {
Hyunsun Moon1251e192016-06-07 16:57:05 -07001538 DatabaseSchema dbSchema = schema.get(DATABASENAME);
andreaed976a42015-10-05 14:38:25 -07001539 if (dbSchema == null) {
1540 return null;
1541 }
Hyunsun Moon1251e192016-06-07 16:57:05 -07001542 OvsdbRowStore rowStore = getRowStore(DATABASENAME, BRIDGE);
andreaed976a42015-10-05 14:38:25 -07001543 if (rowStore == null) {
1544 log.debug("There is no bridge table");
1545 return null;
1546 }
1547
1548 Row bridgeRow = rowStore.getRow(bridgeUuid.value());
1549 Bridge bridge = (Bridge) TableGenerator.
1550 getTable(dbSchema, bridgeRow, OvsdbTable.BRIDGE);
1551
1552 //FIXME remove log
1553 log.warn("type of controller column", bridge.getControllerColumn()
1554 .data().getClass());
Jonathan Hart51539b82015-10-29 09:53:04 -07001555 Set<Uuid> controllerUuids = (Set<Uuid>) ((OvsdbSet) bridge
andreaed976a42015-10-05 14:38:25 -07001556 .getControllerColumn().data()).set();
andreaed976a42015-10-05 14:38:25 -07001557
Hyunsun Moon1251e192016-06-07 16:57:05 -07001558 OvsdbRowStore controllerRowStore = getRowStore(DATABASENAME, CONTROLLER);
andreaed976a42015-10-05 14:38:25 -07001559 if (controllerRowStore == null) {
1560 log.debug("There is no controller table");
1561 return null;
1562 }
1563
1564 List<Controller> ovsdbControllers = new ArrayList<>();
1565 ConcurrentMap<String, Row> controllerTableRows = controllerRowStore.getRowStore();
1566 controllerTableRows.forEach((key, row) -> {
Jonathan Hart51539b82015-10-29 09:53:04 -07001567 if (!controllerUuids.contains(Uuid.uuid(key))) {
andreaed976a42015-10-05 14:38:25 -07001568 return;
1569 }
1570 Controller controller = (Controller) TableGenerator
1571 .getTable(dbSchema, row, OvsdbTable.CONTROLLER);
1572 ovsdbControllers.add(controller);
1573 });
1574 return ovsdbControllers;
1575 }
1576
1577
Jonathan Hart51539b82015-10-29 09:53:04 -07001578 private Uuid getBridgeUuid(DeviceId openflowDeviceId) {
Hyunsun Moon1251e192016-06-07 16:57:05 -07001579 DatabaseSchema dbSchema = schema.get(DATABASENAME);
andreaed976a42015-10-05 14:38:25 -07001580 if (dbSchema == null) {
1581 return null;
1582 }
Hyunsun Moon1251e192016-06-07 16:57:05 -07001583 OvsdbRowStore rowStore = getRowStore(DATABASENAME, BRIDGE);
andreaed976a42015-10-05 14:38:25 -07001584 if (rowStore == null) {
1585 log.debug("There is no bridge table");
1586 return null;
1587 }
1588
1589 ConcurrentMap<String, Row> bridgeTableRows = rowStore.getRowStore();
Jonathan Hart51539b82015-10-29 09:53:04 -07001590 final AtomicReference<Uuid> uuid = new AtomicReference<>();
andreaed976a42015-10-05 14:38:25 -07001591 for (Map.Entry<String, Row> entry : bridgeTableRows.entrySet()) {
Hyunsun Moon1251e192016-06-07 16:57:05 -07001592 Bridge bridge = (Bridge) TableGenerator.getTable(
1593 dbSchema,
1594 entry.getValue(),
1595 OvsdbTable.BRIDGE);
1596
1597 if (matchesDpid(bridge, openflowDeviceId)) {
Jonathan Hart51539b82015-10-29 09:53:04 -07001598 uuid.set(Uuid.uuid(entry.getKey()));
andreaed976a42015-10-05 14:38:25 -07001599 break;
1600 }
1601 }
1602 if (uuid.get() == null) {
1603 log.debug("There is no bridge for {}", openflowDeviceId);
1604 }
1605 return uuid.get();
andreaed976a42015-10-05 14:38:25 -07001606 }
1607
1608 private static boolean matchesDpid(Bridge b, DeviceId deviceId) {
1609 String ofDpid = deviceId.toString().replace("of:", "");
1610 Set ofDeviceIds = ((OvsdbSet) b.getDatapathIdColumn().data()).set();
1611 //TODO Set<String>
1612 return ofDeviceIds.contains(ofDpid);
1613 }
1614
1615 @Override
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001616 public Set<OvsdbPort> getPorts() {
Daniel Park14552682018-08-28 11:25:01 +09001617 return (Set<OvsdbPort>) getElements(this::getOvsdbPort);
1618 }
1619
1620 @Override
1621 public Set<Interface> getInterfaces() {
1622 return (Set<Interface>) getElements(this::getInterface);
1623 }
1624
1625 private Set<?> getElements(Function<Row, ?> method) {
Hyunsun Moon1251e192016-06-07 16:57:05 -07001626 OvsdbTableStore tableStore = getTableStore(DATABASENAME);
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001627 if (tableStore == null) {
1628 return null;
1629 }
Hyunsun Moon1251e192016-06-07 16:57:05 -07001630 OvsdbRowStore rowStore = tableStore.getRows(INTERFACE);
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001631 if (rowStore == null) {
1632 return null;
1633 }
1634 ConcurrentMap<String, Row> rows = rowStore.getRowStore();
Daniel Park14552682018-08-28 11:25:01 +09001635
1636 return rows.keySet()
kdarapufce5abb2018-05-10 19:37:53 +05301637 .stream()
1638 .map(uuid -> getRow(DATABASENAME, INTERFACE, uuid))
Daniel Park14552682018-08-28 11:25:01 +09001639 .map(method)
kdarapufce5abb2018-05-10 19:37:53 +05301640 .filter(Objects::nonNull)
1641 .collect(Collectors.toSet());
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001642 }
1643
1644 @Override
Daniel Park14552682018-08-28 11:25:01 +09001645 public Interface getInterface(String intf) {
1646 return getInterfaces().stream()
1647 .filter(ovsdbIntf -> ovsdbIntf.getName().equals(intf))
1648 .findAny().orElse(null);
1649 }
1650
1651 private Interface getInterface(Row row) {
1652 DatabaseSchema dbSchema = getDatabaseSchema(DATABASENAME);
1653 Interface intf = (Interface) TableGenerator
1654 .getTable(dbSchema, row, OvsdbTable.INTERFACE);
1655 if (intf == null) {
1656 return null;
1657 }
1658 return intf;
1659 }
1660 @Override
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001661 public DatabaseSchema getDatabaseSchema(String dbName) {
1662 return schema.get(dbName);
1663 }
1664
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001665 private OvsdbPort getOvsdbPort(Row row) {
Hyunsun Moon1251e192016-06-07 16:57:05 -07001666 DatabaseSchema dbSchema = getDatabaseSchema(DATABASENAME);
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001667 Interface intf = (Interface) TableGenerator
1668 .getTable(dbSchema, row, OvsdbTable.INTERFACE);
1669 if (intf == null) {
1670 return null;
1671 }
1672 long ofPort = getOfPort(intf);
1673 String portName = intf.getName();
1674 if ((ofPort < 0) || (portName == null)) {
1675 return null;
1676 }
Hyunsun Moon1251e192016-06-07 16:57:05 -07001677 return new OvsdbPort(new OvsdbPortNumber(ofPort), new OvsdbPortName(portName));
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001678 }
1679
jaegonkim7b77f712018-01-14 17:18:27 +09001680 private OvsdbBridge getOvsdbBridge(Row row, Uuid bridgeUuid) {
Hyunsun Moon1251e192016-06-07 16:57:05 -07001681 DatabaseSchema dbSchema = getDatabaseSchema(DATABASENAME);
1682 Bridge bridge = (Bridge) TableGenerator.getTable(dbSchema, row, OvsdbTable.BRIDGE);
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001683 if (bridge == null) {
1684 return null;
1685 }
1686
1687 OvsdbSet datapathIdSet = (OvsdbSet) bridge.getDatapathIdColumn().data();
1688 @SuppressWarnings("unchecked")
1689 Set<String> datapathIds = datapathIdSet.set();
Jon Hallcbd1b392017-01-18 20:15:44 -08001690 if (datapathIds == null || datapathIds.isEmpty()) {
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001691 return null;
1692 }
1693 String datapathId = (String) datapathIds.toArray()[0];
1694 String bridgeName = bridge.getName();
1695 if ((datapathId == null) || (bridgeName == null)) {
1696 return null;
1697 }
jaegonkim7b77f712018-01-14 17:18:27 +09001698
1699 List<Controller> controllers = getControllers(bridgeUuid);
1700
1701 if (controllers != null) {
1702 List<ControllerInfo> controllerInfos = controllers.stream().map(
1703 controller -> new ControllerInfo(
1704 (String) controller.getTargetColumn()
1705 .data())).collect(Collectors.toList());
1706
1707 return OvsdbBridge.builder()
1708 .name(bridgeName)
1709 .datapathId(datapathId)
1710 .controllers(controllerInfos)
1711 .build();
1712 } else {
1713 return OvsdbBridge.builder()
1714 .name(bridgeName)
1715 .datapathId(datapathId)
1716 .build();
1717 }
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001718 }
1719
Frank Wange11a98d2016-10-26 17:04:03 +08001720 private OvsdbQos getOvsdbQos(Row row) {
1721 DatabaseSchema dbSchema = getDatabaseSchema(DATABASENAME);
1722 Qos qos = (Qos) TableGenerator.getTable(dbSchema, row, OvsdbTable.QOS);
1723 if (qos == null) {
1724 return null;
1725 }
1726
1727 String type = (String) qos.getTypeColumn().data();
1728 Map<String, String> otherConfigs;
1729 Map<String, String> externalIds;
1730 Map<Long, String> queues;
1731
1732 otherConfigs = ((OvsdbMap) qos.getOtherConfigColumn().data()).map();
1733 externalIds = ((OvsdbMap) qos.getExternalIdsColumn().data()).map();
1734 queues = ((OvsdbMap) qos.getQueuesColumn().data()).map();
1735 return OvsdbQos.builder().qosType(type).
1736 queues(queues).otherConfigs(otherConfigs).
1737 externalIds(externalIds).build();
1738 }
1739
1740 private OvsdbQueue getOvsdbQueue(Row row) {
1741 DatabaseSchema dbSchema = getDatabaseSchema(DATABASENAME);
1742 Queue queue = (Queue) TableGenerator.getTable(dbSchema, row, OvsdbTable.QUEUE);
1743 if (queue == null) {
1744 return null;
1745 }
1746
1747 OvsdbSet dscpOvsdbSet = ((OvsdbSet) queue.getDscpColumn().data());
Kamal Krishna Bhattdbef16f2018-06-04 13:25:58 +02001748 Set dscpSet = dscpOvsdbSet.set();
Frank Wange11a98d2016-10-26 17:04:03 +08001749 Long dscp = null;
1750 if (dscpSet != null && !dscpSet.isEmpty()) {
Kamal Krishna Bhattdbef16f2018-06-04 13:25:58 +02001751 dscp = Long.valueOf(dscpSet.toArray()[0].toString());
Frank Wange11a98d2016-10-26 17:04:03 +08001752 }
1753
1754 Map<String, String> otherConfigs;
1755 Map<String, String> externalIds;
1756
1757 otherConfigs = ((OvsdbMap) queue.getOtherConfigColumn().data()).map();
1758 externalIds = ((OvsdbMap) queue.getExternalIdsColumn().data()).map();
1759 return OvsdbQueue.builder().dscp(dscp).
1760 otherConfigs(otherConfigs).externalIds(externalIds).build();
1761 }
1762
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001763 private long getOfPort(Interface intf) {
1764 OvsdbSet ofPortSet = (OvsdbSet) intf.getOpenFlowPortColumn().data();
1765 @SuppressWarnings("unchecked")
1766 Set<Integer> ofPorts = ofPortSet.set();
Jon Hallcbd1b392017-01-18 20:15:44 -08001767 if (ofPorts == null || ofPorts.isEmpty()) {
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001768 log.debug("The ofport is null in {}", intf.getName());
1769 return -1;
1770 }
1771 // return (long) ofPorts.toArray()[0];
1772 Iterator<Integer> it = ofPorts.iterator();
1773 return Long.parseLong(it.next().toString());
1774 }
CNluciusa66c3972015-09-06 20:31:29 +08001775
1776 @Override
1777 public Set<OvsdbPort> getLocalPorts(Iterable<String> ifaceids) {
Hyunsun Moon1251e192016-06-07 16:57:05 -07001778 Set<OvsdbPort> ovsdbPorts = new HashSet<>();
1779 OvsdbTableStore tableStore = getTableStore(DATABASENAME);
CNluciusa66c3972015-09-06 20:31:29 +08001780 if (tableStore == null) {
1781 return null;
1782 }
Hyunsun Moon1251e192016-06-07 16:57:05 -07001783 OvsdbRowStore rowStore = tableStore.getRows(INTERFACE);
CNluciusa66c3972015-09-06 20:31:29 +08001784 if (rowStore == null) {
1785 return null;
1786 }
1787 ConcurrentMap<String, Row> rows = rowStore.getRowStore();
1788 for (String uuid : rows.keySet()) {
Hyunsun Moon1251e192016-06-07 16:57:05 -07001789 Row row = getRow(DATABASENAME, INTERFACE, uuid);
1790 DatabaseSchema dbSchema = getDatabaseSchema(DATABASENAME);
CNluciusa66c3972015-09-06 20:31:29 +08001791 Interface intf = (Interface) TableGenerator
1792 .getTable(dbSchema, row, OvsdbTable.INTERFACE);
1793 if (intf == null || getIfaceid(intf) == null) {
1794 continue;
1795 }
1796 String portName = intf.getName();
Hyunsun Moon1251e192016-06-07 16:57:05 -07001797 if (portName == null) {
1798 continue;
1799 }
CNluciusa66c3972015-09-06 20:31:29 +08001800 Set<String> ifaceidSet = Sets.newHashSet(ifaceids);
Hyunsun Moon1251e192016-06-07 16:57:05 -07001801 if (portName.startsWith(TYPEVXLAN) || !ifaceidSet.contains(getIfaceid(intf))) {
CNluciusa66c3972015-09-06 20:31:29 +08001802 continue;
1803 }
1804 long ofPort = getOfPort(intf);
Hyunsun Moon1251e192016-06-07 16:57:05 -07001805 if (ofPort < 0) {
CNluciusa66c3972015-09-06 20:31:29 +08001806 continue;
1807 }
Hyunsun Moon1251e192016-06-07 16:57:05 -07001808 ovsdbPorts.add(new OvsdbPort(new OvsdbPortNumber(ofPort),
1809 new OvsdbPortName(portName)));
CNluciusa66c3972015-09-06 20:31:29 +08001810 }
1811 return ovsdbPorts;
1812 }
1813
1814 private String getIfaceid(Interface intf) {
1815 OvsdbMap ovsdbMap = (OvsdbMap) intf.getExternalIdsColumn().data();
1816 @SuppressWarnings("unchecked")
1817 Map<String, String> externalIds = ovsdbMap.map();
1818 if (externalIds.isEmpty()) {
1819 log.warn("The external_ids is null");
1820 return null;
1821 }
Hyunsun Moon1251e192016-06-07 16:57:05 -07001822 String ifaceid = externalIds.get(EXTERNAL_ID_INTERFACE_ID);
CNluciusa66c3972015-09-06 20:31:29 +08001823 if (ifaceid == null) {
1824 log.warn("The ifaceid is null");
1825 return null;
1826 }
1827 return ifaceid;
1828 }
Hyunsun Moon5fb20a52015-09-25 17:02:33 -07001829
1830 @Override
1831 public void disconnect() {
1832 channel.disconnect();
Hyunsun Moon5fb20a52015-09-25 17:02:33 -07001833 }
Saritha1583a6f2017-06-16 14:42:58 +05301834
1835 @Override
1836 public List<OvsdbPortName> getPorts(List<String> portNames, DeviceId deviceId) {
1837 Uuid bridgeUuid = getBridgeUuid(deviceId);
1838 if (bridgeUuid == null) {
1839 log.error("Can't find the bridge for the deviceId {}", deviceId);
1840 return Collections.emptyList();
1841 }
1842 DatabaseSchema dbSchema = schema.get(DATABASENAME);
1843 Row bridgeRow = getRow(DATABASENAME, BRIDGE, bridgeUuid.value());
1844 Bridge bridge = (Bridge) TableGenerator.getTable(dbSchema, bridgeRow, OvsdbTable.BRIDGE);
1845 if (bridge == null) {
1846 return Collections.emptyList();
1847 }
1848 OvsdbSet setPorts = (OvsdbSet) bridge.getPortsColumn().data();
1849 Set<Uuid> portSet = setPorts.set();
1850 if (portSet.isEmpty()) {
1851 return Collections.emptyList();
1852 }
1853
1854 Map<Uuid, Port> portMap = portSet.stream().collect(Collectors.toMap(
1855 java.util.function.Function.identity(), port -> (Port) TableGenerator
1856 .getTable(dbSchema, getRow(DATABASENAME,
1857 PORT, port.value()), OvsdbTable.PORT)));
1858
1859 List<OvsdbPortName> portList = portMap.entrySet().stream().filter(port -> Objects.nonNull(port.getValue())
1860 && portNames.contains(port.getValue().getName())
1861 && Objects.nonNull(getInterfacebyPort(port.getKey().value(), port.getValue().getName())))
1862 .map(port -> new OvsdbPortName(port.getValue().getName())).collect(Collectors.toList());
1863
1864 return Collections.unmodifiableList(portList);
1865 }
1866
1867 @Override
1868 public boolean getPortError(List<OvsdbPortName> portNames, DeviceId bridgeId) {
1869 Uuid bridgeUuid = getBridgeUuid(bridgeId);
1870
1871 List<Interface> interfaceList = portNames.stream().collect(Collectors
1872 .toMap(java.util.function.Function.identity(),
1873 port -> (Interface) getInterfacebyPort(getPortUuid(port.value(),
1874 bridgeUuid.value()), port.value())))
1875 .entrySet().stream().filter(intf -> Objects.nonNull(intf.getValue())
1876 && ((OvsdbSet) intf.getValue().getOpenFlowPortColumn().data()).set()
1877 .stream().findAny().orElse(OFPORT_ERROR_COMPARISON).equals(OFPORT_ERROR))
kdarapufce5abb2018-05-10 19:37:53 +05301878 .map(Map.Entry::getValue).collect(Collectors.toList());
Saritha1583a6f2017-06-16 14:42:58 +05301879
kdarapufce5abb2018-05-10 19:37:53 +05301880 interfaceList.forEach(intf -> ((Consumer<Interface>) intf1 -> {
1881 try {
1882 Set<String> setErrors = ((OvsdbSet) intf1.getErrorColumn().data()).set();
1883 log.info("Port has errors. ofport value - {}, Interface - {} has error - {} ",
1884 intf1.getOpenFlowPortColumn().data(), intf1.getName(), setErrors.stream()
1885 .findFirst().get());
1886 } catch (ColumnSchemaNotFoundException | VersionMismatchException e) {
1887 log.debug("Port has errors. ofport value - {}, Interface - {} has error - {} ",
1888 intf1.getOpenFlowPortColumn().data(), intf1.getName(), e);
Saritha1583a6f2017-06-16 14:42:58 +05301889 }
kdarapufce5abb2018-05-10 19:37:53 +05301890 }).accept(intf));
Saritha1583a6f2017-06-16 14:42:58 +05301891
1892 return !interfaceList.isEmpty();
1893 }
1894
1895 private Interface getInterfacebyPort(String portUuid, String portName) {
1896 DatabaseSchema dbSchema = schema.get(DATABASENAME);
1897
1898 Row portRow = getRow(DATABASENAME, PORT, portUuid);
1899 Port port = (Port) TableGenerator.getTable(dbSchema, portRow,
1900 OvsdbTable.PORT);
1901 if (port == null) {
1902 return null;
1903 }
1904
1905 OvsdbSet setInterfaces = (OvsdbSet) port.getInterfacesColumn().data();
1906 Set<Uuid> interfaces = setInterfaces.set();
1907
1908 return interfaces.stream().map(intf -> (Interface) TableGenerator
1909 .getTable(dbSchema, getRow(DATABASENAME,
1910 INTERFACE, intf.value()), OvsdbTable.INTERFACE))
1911 .filter(intf -> Objects.nonNull(intf) && portName.equalsIgnoreCase(intf.getName()))
1912 .findFirst().orElse(null);
1913 }
nitinanandf14dccd2018-05-31 15:11:04 +05301914
nitinanandf14dccd2018-05-31 15:11:04 +05301915 @Override
1916 public Optional<Object> getFirstRow(String dbName, OvsdbTable tblName) {
1917
1918 DatabaseSchema dbSchema = getDatabaseSchema(dbName);
1919 if (Objects.isNull(dbSchema)) {
1920 return Optional.empty();
1921 }
1922
1923 OvsdbTableStore tableStore = ovsdbStore.getOvsdbTableStore(dbName);
1924 if (tableStore == null) {
1925 return Optional.empty();
1926 }
1927 OvsdbRowStore rowStore = tableStore.getRows(tblName.tableName());
1928 if (rowStore == null) {
1929 return Optional.empty();
1930 }
1931
1932 ConcurrentMap<String, Row> rows = rowStore.getRowStore();
1933 if (rows == null) {
1934 log.debug("The {} Table Rows is null", tblName);
1935 return Optional.empty();
1936 }
1937
1938 // There should be only 1 row in this table
1939 Optional<String> uuid = rows.keySet().stream().findFirst();
1940 if (uuid.isPresent() && rows.containsKey(uuid.get())) {
1941 return Optional.of(TableGenerator.getTable(dbSchema,
1942 rows.get(uuid.get()), tblName));
1943 } else {
1944 return Optional.empty();
1945 }
1946 }
1947
1948
nitinanandf14dccd2018-05-31 15:11:04 +05301949 @Override
1950 public Optional<DeviceMemoryStats> getDeviceMemoryUsage() {
1951 return Optional.empty();
1952 }
1953
1954
nitinanandf14dccd2018-05-31 15:11:04 +05301955 @Override
1956 public Optional<DeviceCpuStats> getDeviceCpuUsage() {
1957 return Optional.empty();
1958 }
Carmelo Casconeef478a62019-01-29 18:45:22 -08001959
1960 private <I, O> ListenableFuture<O> futureTransform(
1961 ListenableFuture<I> input, Function<? super I, ? extends O> function) {
1962 // Wrapper around deprecated Futures.transform() method. As per Guava
1963 // recommendation, passing MoreExecutors.directExecutor() for identical
1964 // behavior.
1965 return Futures.transform(input, function, MoreExecutors.directExecutor());
1966 }
Jian Lif5c92762019-05-17 19:50:28 +09001967}