blob: ccb153de5ba1e367ea2a70a23e955ecff91a750d [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;
27import com.google.common.util.concurrent.SettableFuture;
Sho SHIMIZUe4efe452015-08-26 15:06:55 -070028import io.netty.channel.Channel;
Sho SHIMIZUe4efe452015-08-26 15:06:55 -070029import org.onlab.packet.IpAddress;
andreaed976a42015-10-05 14:38:25 -070030import org.onosproject.net.DeviceId;
Frank Wange11a98d2016-10-26 17:04:03 +080031import org.onosproject.net.PortNumber;
rohitsharana127ba82018-01-16 02:17:30 +053032import org.onosproject.net.behaviour.ControlProtocolVersion;
andreaed976a42015-10-05 14:38:25 -070033import org.onosproject.net.behaviour.ControllerInfo;
nitinanand9e8f8362018-05-31 15:11:04 +053034import org.onosproject.net.behaviour.DeviceCpuStats;
35import org.onosproject.net.behaviour.DeviceMemoryStats;
Pier Ventref5d72362016-07-17 12:02:14 +020036import org.onosproject.net.behaviour.MirroringName;
Ray Milkeyb1250322017-06-05 17:18:17 -070037import org.onosproject.net.behaviour.MirroringStatistics;
Frank Wange11a98d2016-10-26 17:04:03 +080038import org.onosproject.net.behaviour.QosId;
tanbangchengc944c282017-11-12 20:42:59 +080039import org.onosproject.net.behaviour.QueueDescription;
Frank Wange11a98d2016-10-26 17:04:03 +080040import org.onosproject.net.behaviour.QueueId;
Sho SHIMIZUe4efe452015-08-26 15:06:55 -070041import org.onosproject.ovsdb.controller.OvsdbBridge;
Sho SHIMIZUe4efe452015-08-26 15:06:55 -070042import org.onosproject.ovsdb.controller.OvsdbClientService;
Hyunsun Moondd14e8e2016-06-09 16:17:32 -070043import org.onosproject.ovsdb.controller.OvsdbInterface;
Pier Ventref5d72362016-07-17 12:02:14 +020044import org.onosproject.ovsdb.controller.OvsdbMirror;
Sho SHIMIZUe4efe452015-08-26 15:06:55 -070045import org.onosproject.ovsdb.controller.OvsdbNodeId;
46import org.onosproject.ovsdb.controller.OvsdbPort;
47import org.onosproject.ovsdb.controller.OvsdbPortName;
48import org.onosproject.ovsdb.controller.OvsdbPortNumber;
Frank Wange11a98d2016-10-26 17:04:03 +080049import org.onosproject.ovsdb.controller.OvsdbQos;
50import org.onosproject.ovsdb.controller.OvsdbQueue;
Sho SHIMIZUe4efe452015-08-26 15:06:55 -070051import org.onosproject.ovsdb.controller.OvsdbRowStore;
52import org.onosproject.ovsdb.controller.OvsdbStore;
53import org.onosproject.ovsdb.controller.OvsdbTableStore;
Saritha1583a6f2017-06-16 14:42:58 +053054import org.onosproject.ovsdb.rfc.exception.ColumnSchemaNotFoundException;
55import org.onosproject.ovsdb.rfc.exception.VersionMismatchException;
Sho SHIMIZUe4efe452015-08-26 15:06:55 -070056import org.onosproject.ovsdb.rfc.jsonrpc.Callback;
57import org.onosproject.ovsdb.rfc.message.OperationResult;
58import org.onosproject.ovsdb.rfc.message.TableUpdates;
Frank Wange11a98d2016-10-26 17:04:03 +080059import org.onosproject.ovsdb.rfc.notation.Column;
Sho SHIMIZUe4efe452015-08-26 15:06:55 -070060import org.onosproject.ovsdb.rfc.notation.Condition;
61import org.onosproject.ovsdb.rfc.notation.Mutation;
CNluciusa66c3972015-09-06 20:31:29 +080062import org.onosproject.ovsdb.rfc.notation.OvsdbMap;
Sho SHIMIZUe4efe452015-08-26 15:06:55 -070063import org.onosproject.ovsdb.rfc.notation.OvsdbSet;
64import org.onosproject.ovsdb.rfc.notation.Row;
Jonathan Hart51539b82015-10-29 09:53:04 -070065import org.onosproject.ovsdb.rfc.notation.Uuid;
Sho SHIMIZUe4efe452015-08-26 15:06:55 -070066import org.onosproject.ovsdb.rfc.operations.Delete;
67import org.onosproject.ovsdb.rfc.operations.Insert;
68import org.onosproject.ovsdb.rfc.operations.Mutate;
69import org.onosproject.ovsdb.rfc.operations.Operation;
70import org.onosproject.ovsdb.rfc.operations.Update;
71import org.onosproject.ovsdb.rfc.schema.ColumnSchema;
72import org.onosproject.ovsdb.rfc.schema.DatabaseSchema;
73import org.onosproject.ovsdb.rfc.schema.TableSchema;
74import org.onosproject.ovsdb.rfc.table.Bridge;
75import org.onosproject.ovsdb.rfc.table.Controller;
76import org.onosproject.ovsdb.rfc.table.Interface;
Pier Ventref5d72362016-07-17 12:02:14 +020077import org.onosproject.ovsdb.rfc.table.Mirror;
Sho SHIMIZUe4efe452015-08-26 15:06:55 -070078import org.onosproject.ovsdb.rfc.table.OvsdbTable;
79import org.onosproject.ovsdb.rfc.table.Port;
Frank Wange11a98d2016-10-26 17:04:03 +080080import org.onosproject.ovsdb.rfc.table.Qos;
81import org.onosproject.ovsdb.rfc.table.Queue;
Sho SHIMIZUe4efe452015-08-26 15:06:55 -070082import org.onosproject.ovsdb.rfc.table.TableGenerator;
83import org.onosproject.ovsdb.rfc.utils.ConditionUtil;
84import org.onosproject.ovsdb.rfc.utils.FromJsonUtil;
85import org.onosproject.ovsdb.rfc.utils.JsonRpcWriterUtil;
86import org.onosproject.ovsdb.rfc.utils.MutationUtil;
87import org.slf4j.Logger;
88import org.slf4j.LoggerFactory;
89
Jonathan Hart6523e122017-11-14 09:23:49 -080090import java.net.InetSocketAddress;
91import java.util.ArrayList;
92import java.util.Collections;
93import java.util.HashMap;
94import java.util.HashSet;
95import java.util.Iterator;
96import java.util.List;
97import java.util.Map;
98import java.util.Objects;
99import java.util.Optional;
100import java.util.Set;
101import java.util.concurrent.ConcurrentMap;
102import java.util.concurrent.ExecutionException;
103import java.util.concurrent.TimeUnit;
104import java.util.concurrent.TimeoutException;
105import java.util.concurrent.atomic.AtomicReference;
106import java.util.function.Consumer;
107import java.util.stream.Collectors;
Pier Ventref5d72362016-07-17 12:02:14 +0200108
Daniel Park24626382018-08-28 11:25:01 +0900109import static org.onosproject.ovsdb.controller.OvsdbConstant.BRIDGE;
110import static org.onosproject.ovsdb.controller.OvsdbConstant.BRIDGES;
111import static org.onosproject.ovsdb.controller.OvsdbConstant.BRIDGE_CONTROLLER;
112import static org.onosproject.ovsdb.controller.OvsdbConstant.CONTROLLER;
113import static org.onosproject.ovsdb.controller.OvsdbConstant.DATABASENAME;
114import static org.onosproject.ovsdb.controller.OvsdbConstant.EXTERNAL_ID;
115import static org.onosproject.ovsdb.controller.OvsdbConstant.EXTERNAL_ID_INTERFACE_ID;
116import static org.onosproject.ovsdb.controller.OvsdbConstant.INTERFACE;
117import static org.onosproject.ovsdb.controller.OvsdbConstant.INTERFACES;
118import static org.onosproject.ovsdb.controller.OvsdbConstant.MIRROR;
119import static org.onosproject.ovsdb.controller.OvsdbConstant.MIRRORS;
120import static org.onosproject.ovsdb.controller.OvsdbConstant.OFPORT;
121import static org.onosproject.ovsdb.controller.OvsdbConstant.OFPORT_ERROR;
122import static org.onosproject.ovsdb.controller.OvsdbConstant.PORT;
123import static org.onosproject.ovsdb.controller.OvsdbConstant.PORTS;
124import static org.onosproject.ovsdb.controller.OvsdbConstant.PORT_QOS;
125import static org.onosproject.ovsdb.controller.OvsdbConstant.QOS;
126import static org.onosproject.ovsdb.controller.OvsdbConstant.QOS_EXTERNAL_ID_KEY;
127import static org.onosproject.ovsdb.controller.OvsdbConstant.QUEUE;
128import static org.onosproject.ovsdb.controller.OvsdbConstant.QUEUES;
129import static org.onosproject.ovsdb.controller.OvsdbConstant.QUEUE_EXTERNAL_ID_KEY;
130import static org.onosproject.ovsdb.controller.OvsdbConstant.TYPEVXLAN;
131import static org.onosproject.ovsdb.controller.OvsdbConstant.UUID;
Hyunsun Moon1251e192016-06-07 16:57:05 -0700132
Sho SHIMIZUe4efe452015-08-26 15:06:55 -0700133/**
134 * An representation of an ovsdb client.
135 */
Hyunsun Moon1251e192016-06-07 16:57:05 -0700136public class DefaultOvsdbClient implements OvsdbProviderService, OvsdbClientService {
Sho SHIMIZUe4efe452015-08-26 15:06:55 -0700137
jaegonkim01d7c912017-01-22 22:03:38 +0900138 private static final int TRANSACTCONFIG_TIMEOUT = 3; //sec
Saritha1583a6f2017-06-16 14:42:58 +0530139 private static final int OFPORT_ERROR_COMPARISON = 0;
jaegonkim01d7c912017-01-22 22:03:38 +0900140
Hyunsun Moon1251e192016-06-07 16:57:05 -0700141 private final Logger log = LoggerFactory.getLogger(DefaultOvsdbClient.class);
Sho SHIMIZUe4efe452015-08-26 15:06:55 -0700142
143 private Channel channel;
Sho SHIMIZUe4efe452015-08-26 15:06:55 -0700144 private OvsdbAgent agent;
145 private boolean connected;
146 private OvsdbNodeId nodeId;
147 private Callback monitorCallBack;
Sho SHIMIZUe4efe452015-08-26 15:06:55 -0700148 private OvsdbStore ovsdbStore = new OvsdbStore();
149
150 private final Map<String, String> requestMethod = Maps.newHashMap();
Hyunsun Moon1251e192016-06-07 16:57:05 -0700151 private final Map<String, SettableFuture<? extends Object>> requestResult = Maps.newHashMap();
Sho SHIMIZUe4efe452015-08-26 15:06:55 -0700152 private final Map<String, DatabaseSchema> schema = Maps.newHashMap();
Sho SHIMIZUe4efe452015-08-26 15:06:55 -0700153
Pier Ventref5d72362016-07-17 12:02:14 +0200154
Sho SHIMIZUe4efe452015-08-26 15:06:55 -0700155 /**
156 * Creates an OvsdbClient.
157 *
158 * @param nodeId ovsdb node id
159 */
160 public DefaultOvsdbClient(OvsdbNodeId nodeId) {
161 this.nodeId = nodeId;
162 }
163
164 @Override
165 public OvsdbNodeId nodeId() {
166 return nodeId;
167 }
168
169 @Override
170 public void setAgent(OvsdbAgent agent) {
171 if (this.agent == null) {
172 this.agent = agent;
173 }
174 }
175
176 @Override
177 public void setChannel(Channel channel) {
178 this.channel = channel;
179 }
180
181 @Override
182 public void setConnection(boolean connected) {
183 this.connected = connected;
184 }
185
186 @Override
187 public boolean isConnected() {
188 return this.connected;
189 }
190
191 @Override
192 public void nodeAdded() {
193 this.agent.addConnectedNode(nodeId, this);
194 }
195
196 @Override
197 public void nodeRemoved() {
198 this.agent.removeConnectedNode(nodeId);
199 channel.disconnect();
200 }
201
202 /**
203 * Gets the ovsdb table store.
204 *
205 * @param dbName the ovsdb database name
206 * @return ovsTableStore, empty if table store is find
207 */
208 private OvsdbTableStore getTableStore(String dbName) {
209 if (ovsdbStore == null) {
210 return null;
211 }
212 return ovsdbStore.getOvsdbTableStore(dbName);
213 }
214
215 /**
216 * Gets the ovsdb row store.
217 *
andreaed976a42015-10-05 14:38:25 -0700218 * @param dbName the ovsdb database name
Sho SHIMIZUe4efe452015-08-26 15:06:55 -0700219 * @param tableName the ovsdb table name
Hyunsun Moon6125c612015-10-15 10:54:44 -0700220 * @return ovsRowStore, empty store if no rows exist in the table
Sho SHIMIZUe4efe452015-08-26 15:06:55 -0700221 */
222 private OvsdbRowStore getRowStore(String dbName, String tableName) {
223 OvsdbTableStore tableStore = getTableStore(dbName);
224 if (tableStore == null) {
225 return null;
226 }
Hyunsun Moon6125c612015-10-15 10:54:44 -0700227
228 OvsdbRowStore rowStore = tableStore.getRows(tableName);
229 if (rowStore == null) {
230 rowStore = new OvsdbRowStore();
231 }
232 return rowStore;
Sho SHIMIZUe4efe452015-08-26 15:06:55 -0700233 }
234
235 /**
236 * Gets the ovsdb row.
237 *
andreaed976a42015-10-05 14:38:25 -0700238 * @param dbName the ovsdb database name
Sho SHIMIZUe4efe452015-08-26 15:06:55 -0700239 * @param tableName the ovsdb table name
andreaed976a42015-10-05 14:38:25 -0700240 * @param uuid the key of the row
Sho SHIMIZUe4efe452015-08-26 15:06:55 -0700241 * @return row, empty if row is find
242 */
243 @Override
244 public Row getRow(String dbName, String tableName, String uuid) {
245 OvsdbTableStore tableStore = getTableStore(dbName);
246 if (tableStore == null) {
247 return null;
248 }
249 OvsdbRowStore rowStore = tableStore.getRows(tableName);
250 if (rowStore == null) {
251 return null;
252 }
253 return rowStore.getRow(uuid);
254 }
255
256 @Override
257 public void removeRow(String dbName, String tableName, String uuid) {
258 OvsdbTableStore tableStore = getTableStore(dbName);
259 if (tableStore == null) {
260 return;
261 }
262 OvsdbRowStore rowStore = tableStore.getRows(tableName);
263 if (rowStore == null) {
264 return;
265 }
266 rowStore.deleteRow(uuid);
267 }
268
269 @Override
270 public void updateOvsdbStore(String dbName, String tableName, String uuid,
271 Row row) {
272 OvsdbTableStore tableStore = ovsdbStore.getOvsdbTableStore(dbName);
273 if (tableStore == null) {
274 tableStore = new OvsdbTableStore();
275 }
276 OvsdbRowStore rowStore = tableStore.getRows(tableName);
277 if (rowStore == null) {
278 rowStore = new OvsdbRowStore();
279 }
280 rowStore.insertRow(uuid, row);
281 tableStore.createOrUpdateTable(tableName, rowStore);
282 ovsdbStore.createOrUpdateOvsdbStore(dbName, tableStore);
283 }
284
Pier Ventref5d72362016-07-17 12:02:14 +0200285 /**
286 * Gets the Mirror uuid.
287 *
288 * @param mirrorName mirror name
289 * @return mirror uuid, empty if no uuid is found
290 */
291 @Override
292 public String getMirrorUuid(String mirrorName) {
293 DatabaseSchema dbSchema = schema.get(DATABASENAME);
294 OvsdbRowStore rowStore = getRowStore(DATABASENAME, MIRROR);
295 if (rowStore == null) {
296 log.warn("The mirror uuid is null");
297 return null;
298 }
299
300 ConcurrentMap<String, Row> mirrorTableRows = rowStore.getRowStore();
301 if (mirrorTableRows == null) {
302 log.warn("The mirror uuid is null");
303 return null;
304 }
305
306 for (String uuid : mirrorTableRows.keySet()) {
307 Mirror mirror = (Mirror) TableGenerator
308 .getTable(dbSchema, mirrorTableRows.get(uuid), OvsdbTable.MIRROR);
309 String name = mirror.getName();
310 if (name.contains(mirrorName)) {
311 return uuid;
312 }
313 }
314 log.warn("Mirroring not found");
315 return null;
316 }
317
318 /**
319 * Gets mirrors of the device.
320 *
321 * @param deviceId target device id
322 * @return set of mirroring; empty if no mirror is found
323 */
324 @Override
325 public Set<MirroringStatistics> getMirroringStatistics(DeviceId deviceId) {
326 Uuid bridgeUuid = getBridgeUuid(deviceId);
327 if (bridgeUuid == null) {
328 log.warn("Couldn't find bridge {} in {}", deviceId, nodeId.getIpAddress());
329 return null;
330 }
331
332 List<MirroringStatistics> mirrorings = getMirrorings(bridgeUuid);
333 if (mirrorings == null) {
334 log.warn("Couldn't find mirrors in {}", nodeId.getIpAddress());
335 return null;
336 }
337 return ImmutableSet.copyOf(mirrorings);
338 }
339
340 /**
341 * Helper method which retrieves mirrorings statistics using bridge uuid.
342 *
343 * @param bridgeUuid the uuid of the bridge
344 * @return the list of the mirrorings statistics.
345 */
346 private List<MirroringStatistics> getMirrorings(Uuid bridgeUuid) {
347 DatabaseSchema dbSchema = schema.get(DATABASENAME);
348 if (dbSchema == null) {
349 log.warn("Unable to retrieve dbSchema {}", DATABASENAME);
350 return null;
351 }
352 OvsdbRowStore rowStore = getRowStore(DATABASENAME, BRIDGE);
353 if (rowStore == null) {
354 log.warn("Unable to retrieve rowStore {} of {}", BRIDGE, DATABASENAME);
355 return null;
356 }
357
358 Row bridgeRow = rowStore.getRow(bridgeUuid.value());
359 Bridge bridge = (Bridge) TableGenerator.
360 getTable(dbSchema, bridgeRow, OvsdbTable.BRIDGE);
361
362 Set<Uuid> mirroringsUuids = (Set<Uuid>) ((OvsdbSet) bridge
363 .getMirrorsColumn().data()).set();
364
365 OvsdbRowStore mirrorRowStore = getRowStore(DATABASENAME, MIRROR);
366 if (mirrorRowStore == null) {
367 log.warn("Unable to retrieve rowStore {} of {}", MIRROR, DATABASENAME);
368 return null;
369 }
370
371 List<MirroringStatistics> mirroringStatistics = new ArrayList<>();
372 ConcurrentMap<String, Row> mirrorTableRows = mirrorRowStore.getRowStore();
373 mirrorTableRows.forEach((key, row) -> {
374 if (!mirroringsUuids.contains(Uuid.uuid(key))) {
375 return;
376 }
377 Mirror mirror = (Mirror) TableGenerator
378 .getTable(dbSchema, row, OvsdbTable.MIRROR);
379 mirroringStatistics.add(MirroringStatistics.mirroringStatistics(mirror.getName(),
380 (Map<String, Integer>) ((OvsdbMap) mirror
381 .getStatisticsColumn().data()).map()));
382 });
383 return ImmutableList.copyOf(mirroringStatistics);
384 }
385
Sho SHIMIZUe4efe452015-08-26 15:06:55 -0700386 @Override
387 public String getPortUuid(String portName, String bridgeUuid) {
Hyunsun Moon1251e192016-06-07 16:57:05 -0700388 DatabaseSchema dbSchema = schema.get(DATABASENAME);
Sho SHIMIZUe4efe452015-08-26 15:06:55 -0700389
Hyunsun Moon1251e192016-06-07 16:57:05 -0700390 Row bridgeRow = getRow(DATABASENAME, BRIDGE, bridgeUuid);
Sho SHIMIZUe4efe452015-08-26 15:06:55 -0700391 Bridge bridge = (Bridge) TableGenerator.getTable(dbSchema, bridgeRow,
392 OvsdbTable.BRIDGE);
393 if (bridge != null) {
394 OvsdbSet setPorts = (OvsdbSet) bridge.getPortsColumn().data();
395 @SuppressWarnings("unchecked")
Jonathan Hart51539b82015-10-29 09:53:04 -0700396 Set<Uuid> ports = setPorts.set();
Jon Hallcbd1b392017-01-18 20:15:44 -0800397 if (ports == null || ports.isEmpty()) {
Sho SHIMIZUe4efe452015-08-26 15:06:55 -0700398 log.warn("The port uuid is null");
399 return null;
400 }
401
Jonathan Hart51539b82015-10-29 09:53:04 -0700402 for (Uuid uuid : ports) {
Hyunsun Moon1251e192016-06-07 16:57:05 -0700403 Row portRow = getRow(DATABASENAME, PORT, uuid.value());
Sho SHIMIZUe4efe452015-08-26 15:06:55 -0700404 Port port = (Port) TableGenerator.getTable(dbSchema, portRow,
405 OvsdbTable.PORT);
406 if (port != null && portName.equalsIgnoreCase(port.getName())) {
407 return uuid.value();
408 }
409 }
Sho SHIMIZUe4efe452015-08-26 15:06:55 -0700410 }
411 return null;
412 }
413
414 @Override
Sho SHIMIZUe4efe452015-08-26 15:06:55 -0700415 public String getBridgeUuid(String bridgeName) {
Hyunsun Moon1251e192016-06-07 16:57:05 -0700416 DatabaseSchema dbSchema = schema.get(DATABASENAME);
Hyunsun Moon1251e192016-06-07 16:57:05 -0700417 OvsdbRowStore rowStore = getRowStore(DATABASENAME, BRIDGE);
Sho SHIMIZUe4efe452015-08-26 15:06:55 -0700418 if (rowStore == null) {
419 log.debug("The bridge uuid is null");
420 return null;
421 }
422
423 ConcurrentMap<String, Row> bridgeTableRows = rowStore.getRowStore();
424 if (bridgeTableRows == null) {
425 log.debug("The bridge uuid is null");
426 return null;
427 }
428
429 for (String uuid : bridgeTableRows.keySet()) {
430 Bridge bridge = (Bridge) TableGenerator
Hyunsun Moon1251e192016-06-07 16:57:05 -0700431 .getTable(dbSchema, bridgeTableRows.get(uuid), OvsdbTable.BRIDGE);
Sho SHIMIZUe4efe452015-08-26 15:06:55 -0700432 if (bridge.getName().equals(bridgeName)) {
433 return uuid;
434 }
Sho SHIMIZUe4efe452015-08-26 15:06:55 -0700435 }
436 return null;
437 }
438
Hyunsun Moondd14e8e2016-06-09 16:17:32 -0700439 private String getOvsUuid(String dbName) {
Hyunsun Moon1251e192016-06-07 16:57:05 -0700440 OvsdbRowStore rowStore = getRowStore(DATABASENAME, DATABASENAME);
Sho SHIMIZUe4efe452015-08-26 15:06:55 -0700441 if (rowStore == null) {
442 log.debug("The bridge uuid is null");
443 return null;
444 }
445 ConcurrentMap<String, Row> ovsTableRows = rowStore.getRowStore();
446 if (ovsTableRows != null) {
447 for (String uuid : ovsTableRows.keySet()) {
448 Row row = ovsTableRows.get(uuid);
449 String tableName = row.tableName();
450 if (tableName.equals(dbName)) {
451 return uuid;
452 }
453 }
454 }
455 return null;
456 }
457
458 @Override
459 public void createPort(String bridgeName, String portName) {
460 String bridgeUuid = getBridgeUuid(bridgeName);
461 if (bridgeUuid == null) {
Hyunsun Moon1251e192016-06-07 16:57:05 -0700462 log.error("Can't find bridge {} in {}", bridgeName, nodeId.getIpAddress());
Sho SHIMIZUe4efe452015-08-26 15:06:55 -0700463 return;
464 }
465
Hyunsun Moon1251e192016-06-07 16:57:05 -0700466 DatabaseSchema dbSchema = schema.get(DATABASENAME);
Sho SHIMIZUe4efe452015-08-26 15:06:55 -0700467 String portUuid = getPortUuid(portName, bridgeUuid);
Hyunsun Moon1251e192016-06-07 16:57:05 -0700468 Port port = (Port) TableGenerator.createTable(dbSchema, OvsdbTable.PORT);
Sho SHIMIZUe4efe452015-08-26 15:06:55 -0700469 port.setName(portName);
470 if (portUuid == null) {
Hyunsun Moon1251e192016-06-07 16:57:05 -0700471 insertConfig(PORT, UUID, BRIDGE, PORTS, bridgeUuid, port.getRow());
Sho SHIMIZUe4efe452015-08-26 15:06:55 -0700472 }
Sho SHIMIZUe4efe452015-08-26 15:06:55 -0700473 }
474
475 @Override
476 public void dropPort(String bridgeName, String portName) {
477 String bridgeUuid = getBridgeUuid(bridgeName);
478 if (bridgeUuid == null) {
479 log.error("Could not find Bridge {} in {}", bridgeName, nodeId);
480 return;
481 }
482
483 String portUuid = getPortUuid(portName, bridgeUuid);
484 if (portUuid != null) {
485 log.info("Port {} delete", portName);
Frank Wange11a98d2016-10-26 17:04:03 +0800486 deleteConfig(PORT, UUID, portUuid, BRIDGE, PORTS, Uuid.uuid(portUuid));
Sho SHIMIZUe4efe452015-08-26 15:06:55 -0700487 }
488 }
489
lishuai6c56f5e2015-11-17 16:38:19 +0800490 @Override
Hyunsun Moon1251e192016-06-07 16:57:05 -0700491 public boolean createBridge(OvsdbBridge ovsdbBridge) {
492 DatabaseSchema dbSchema = schema.get(DATABASENAME);
493 String ovsUuid = getOvsUuid(DATABASENAME);
Hyunsun Moon646d8c42015-10-08 20:32:44 -0700494
495 if (dbSchema == null || ovsUuid == null) {
Hyunsun Moon1251e192016-06-07 16:57:05 -0700496 log.error("Can't find database Open_vSwitch");
Hyunsun Moon646d8c42015-10-08 20:32:44 -0700497 return false;
498 }
499
Hyunsun Moon646d8c42015-10-08 20:32:44 -0700500 Bridge bridge = (Bridge) TableGenerator.createTable(dbSchema, OvsdbTable.BRIDGE);
Hyunsun Moon1251e192016-06-07 16:57:05 -0700501 bridge.setOtherConfig(ovsdbBridge.otherConfigs());
Hyunsun Moon646d8c42015-10-08 20:32:44 -0700502
Hyunsun Moon1251e192016-06-07 16:57:05 -0700503 if (ovsdbBridge.failMode().isPresent()) {
504 String failMode = ovsdbBridge.failMode().get().name().toLowerCase();
505 bridge.setFailMode(Sets.newHashSet(failMode));
Bob zhoue9795fd2016-05-12 20:18:45 +0800506 }
Hyunsun Moon646d8c42015-10-08 20:32:44 -0700507
jaegonkim80bee532017-05-15 15:16:38 +0900508 if (ovsdbBridge.datapathType().isPresent()) {
509 String datapathType = ovsdbBridge.datapathType().get();
510 bridge.setDatapathType(datapathType);
511 }
512
rohitsharana127ba82018-01-16 02:17:30 +0530513 if (ovsdbBridge.controlProtocols().isPresent()) {
514 bridge.setProtocols(ovsdbBridge.controlProtocols().get().stream()
515 .map(ControlProtocolVersion::toString)
516 .collect(Collectors.toCollection(HashSet::new)));
517 }
518
Hyunsun Moon1251e192016-06-07 16:57:05 -0700519 String bridgeUuid = getBridgeUuid(ovsdbBridge.name());
Hyunsun Moon98025542016-03-08 04:36:02 -0800520 if (bridgeUuid == null) {
Hyunsun Moon1251e192016-06-07 16:57:05 -0700521 bridge.setName(ovsdbBridge.name());
522 bridgeUuid = insertConfig(
523 BRIDGE, UUID, DATABASENAME, BRIDGES,
524 ovsUuid, bridge.getRow());
Hyunsun Moon98025542016-03-08 04:36:02 -0800525 } else {
Hyunsun Moon1251e192016-06-07 16:57:05 -0700526 // update the bridge if it's already existing
527 updateConfig(BRIDGE, UUID, bridgeUuid, bridge.getRow());
Hyunsun Moon98025542016-03-08 04:36:02 -0800528 }
Hyunsun Moon646d8c42015-10-08 20:32:44 -0700529
Hyunsun Moon1251e192016-06-07 16:57:05 -0700530 if (bridgeUuid == null) {
531 log.warn("Failed to create bridge {} on {}", ovsdbBridge.name(), nodeId);
Hyunsun Moon646d8c42015-10-08 20:32:44 -0700532 return false;
533 }
534
Hyunsun Moon1251e192016-06-07 16:57:05 -0700535 createPort(ovsdbBridge.name(), ovsdbBridge.name());
536 setControllersWithUuid(Uuid.uuid(bridgeUuid), ovsdbBridge.controllers());
537
538 log.info("Created bridge {}", ovsdbBridge.name());
Hyunsun Moon646d8c42015-10-08 20:32:44 -0700539 return true;
540 }
541
Hyunsun Moon1251e192016-06-07 16:57:05 -0700542 @Override
543 public ControllerInfo localController() {
544 IpAddress ipAddress = IpAddress.valueOf(((InetSocketAddress)
545 channel.localAddress()).getAddress());
546 return new ControllerInfo(ipAddress, OFPORT, "tcp");
andreaed976a42015-10-05 14:38:25 -0700547 }
548
Hyunsun Moondd14e8e2016-06-09 16:17:32 -0700549 private void setControllersWithUuid(Uuid bridgeUuid, List<ControllerInfo> controllers) {
Hyunsun Moon1251e192016-06-07 16:57:05 -0700550 DatabaseSchema dbSchema = schema.get(DATABASENAME);
andreaed976a42015-10-05 14:38:25 -0700551 if (dbSchema == null) {
552 log.debug("There is no schema");
553 return;
554 }
555 List<Controller> oldControllers = getControllers(bridgeUuid);
556 if (oldControllers == null) {
557 log.warn("There are no controllers");
558 return;
559 }
560
andreaed976a42015-10-05 14:38:25 -0700561 Set<ControllerInfo> newControllers = new HashSet<>(controllers);
562 List<Controller> removeControllers = new ArrayList<>();
563 oldControllers.forEach(controller -> {
564 ControllerInfo controllerInfo = new ControllerInfo((String) controller.getTargetColumn().data());
565 if (newControllers.contains(controllerInfo)) {
566 newControllers.remove(controllerInfo);
andreaed976a42015-10-05 14:38:25 -0700567 } else {
568 removeControllers.add(controller);
569 }
570 });
Hyunsun Moon1251e192016-06-07 16:57:05 -0700571 OvsdbRowStore controllerRowStore = getRowStore(DATABASENAME, CONTROLLER);
andreaed976a42015-10-05 14:38:25 -0700572 if (controllerRowStore == null) {
573 log.debug("There is no controller table");
574 return;
575 }
576
Hyunsun Moon1251e192016-06-07 16:57:05 -0700577 removeControllers.forEach(c -> deleteConfig(CONTROLLER, UUID, c.getRow().uuid().value(),
Saritha8a0c36a2017-07-04 15:01:35 +0530578 BRIDGE, BRIDGE_CONTROLLER, c.getRow().uuid()));
andreaed976a42015-10-05 14:38:25 -0700579 newControllers.stream().map(c -> {
580 Controller controller = (Controller) TableGenerator
581 .createTable(dbSchema, OvsdbTable.CONTROLLER);
582 controller.setTarget(c.target());
583 return controller;
tanbangchengfe1e9012017-11-24 21:57:05 +0800584 }).forEach(c -> insertConfig(CONTROLLER, UUID, BRIDGE, BRIDGE_CONTROLLER,
585 bridgeUuid.value(),
586 c.getRow()));
andreaed976a42015-10-05 14:38:25 -0700587
andreaed976a42015-10-05 14:38:25 -0700588 }
589
andreaed976a42015-10-05 14:38:25 -0700590 @Override
591 public void setControllersWithDeviceId(DeviceId deviceId, List<ControllerInfo> controllers) {
Jonathan Hart51539b82015-10-29 09:53:04 -0700592 setControllersWithUuid(getBridgeUuid(deviceId), controllers);
andreaed976a42015-10-05 14:38:25 -0700593 }
594
Sho SHIMIZUe4efe452015-08-26 15:06:55 -0700595 @Override
596 public void dropBridge(String bridgeName) {
Jonathan Hart51539b82015-10-29 09:53:04 -0700597 String bridgeUuid = getBridgeUuid(bridgeName);
598 if (bridgeUuid == null) {
Sho SHIMIZUe4efe452015-08-26 15:06:55 -0700599 log.warn("Could not find bridge in node", nodeId.getIpAddress());
600 return;
601 }
Frank Wange11a98d2016-10-26 17:04:03 +0800602 deleteConfig(BRIDGE, UUID, bridgeUuid, DATABASENAME, BRIDGES, Uuid.uuid(bridgeUuid));
Hyunsun Moondd14e8e2016-06-09 16:17:32 -0700603 }
604
Frank Wange11a98d2016-10-26 17:04:03 +0800605 @Override
606 public void applyQos(PortNumber portNumber, String qosName) {
607 DatabaseSchema dbSchema = schema.get(DATABASENAME);
608 OvsdbRowStore portRowStore = getRowStore(DATABASENAME, PORT);
609 if (portRowStore == null) {
610 log.debug("The port uuid is null");
611 return;
612 }
613 OvsdbRowStore qosRowStore = getRowStore(DATABASENAME, QOS);
614 if (qosRowStore == null) {
615 log.debug("The qos uuid is null");
616 return;
617 }
618
619 // Due to Qos Table doesn't have a unique identifier except uuid, unlike
620 // Bridge or Port Table has a name column,in order to make the api more
621 // general, put qos name in external_ids column of Qos Table if this qos
622 // created by onos.
623 ConcurrentMap<String, Row> qosTableRows = qosRowStore.getRowStore();
624 ConcurrentMap<String, Row> portTableRows = portRowStore.getRowStore();
625 Row qosRow = qosTableRows.values().stream().filter(r -> {
626 OvsdbMap ovsdbMap = (OvsdbMap) (r.getColumn(EXTERNAL_ID).data());
627 return qosName.equals(ovsdbMap.map().get(QOS_EXTERNAL_ID_KEY));
628 }).findFirst().orElse(null);
629
630 Row portRow = portTableRows.values().stream()
631 .filter(r -> r.getColumn("name").data().equals(portNumber.name()))
632 .findFirst().orElse(null);
633 if (portRow != null && qosRow != null) {
634 String qosId = qosRow.uuid().value();
635 Uuid portUuid = portRow.uuid();
636 Map<String, Column> columns = new HashMap<>();
637 Row newPortRow = new Row(PORT, portUuid, columns);
638 Port newport = new Port(dbSchema, newPortRow);
639 columns.put(Port.PortColumn.QOS.columnName(), newport.getQosColumn());
640 newport.setQos(Uuid.uuid(qosId));
641 updateConfig(PORT, UUID, portUuid.value(), newport.getRow());
642 }
643 }
644
645 @Override
646 public void removeQos(PortNumber portNumber) {
647 DatabaseSchema dbSchema = schema.get(DATABASENAME);
648 OvsdbRowStore rowStore = getRowStore(DATABASENAME, PORT);
649 if (rowStore == null) {
650 log.debug("The qos uuid is null");
651 return;
652 }
653
654 ConcurrentMap<String, Row> ovsTableRows = rowStore.getRowStore();
655 Row portRow = ovsTableRows.values().stream()
656 .filter(r -> r.getColumn("name").data().equals(portNumber.name()))
657 .findFirst().orElse(null);
658 if (portRow == null) {
659 log.warn("Couldn't find port {} in ovsdb port table.", portNumber.name());
660 return;
661 }
662
663 OvsdbSet ovsdbSet = ((OvsdbSet) portRow.getColumn(PORT_QOS).data());
664 @SuppressWarnings("unchecked")
665 Set<Uuid> qosIdSet = ovsdbSet.set();
666 if (qosIdSet == null || qosIdSet.isEmpty()) {
667 return;
668 }
669 Uuid qosUuid = (Uuid) qosIdSet.toArray()[0];
670 Condition condition = ConditionUtil.isEqual(UUID, portRow.uuid());
671 List<Condition> conditions = Lists.newArrayList(condition);
672 Mutation mutation = MutationUtil.delete(PORT_QOS, qosUuid);
673 List<Mutation> mutations = Lists.newArrayList(mutation);
674
675 ArrayList<Operation> operations = Lists.newArrayList();
676 Mutate mutate = new Mutate(dbSchema.getTableSchema(PORT), conditions, mutations);
677 operations.add(mutate);
678 transactConfig(DATABASENAME, operations);
679 }
680
681 @Override
682 public boolean createQos(OvsdbQos ovsdbQos) {
683 DatabaseSchema dbSchema = schema.get(DATABASENAME);
684 Qos qos = (Qos) TableGenerator.createTable(dbSchema, OvsdbTable.QOS);
685 OvsdbRowStore rowStore = getRowStore(DATABASENAME, QOS);
686 if (rowStore == null) {
687 log.debug("The qos uuid is null");
688 return false;
689 }
690
691 ArrayList<Operation> operations = Lists.newArrayList();
692 Set<String> types = Sets.newHashSet();
693 Map<Long, Uuid> queues = Maps.newHashMap();
694
695 types.add(ovsdbQos.qosType());
696 qos.setOtherConfig(ovsdbQos.otherConfigs());
697 qos.setExternalIds(ovsdbQos.externalIds());
698 qos.setType(types);
699 if (ovsdbQos.qosQueues().isPresent()) {
700 for (Map.Entry<Long, String> entry : ovsdbQos.qosQueues().get().entrySet()) {
701 OvsdbRowStore queueRowStore = getRowStore(DATABASENAME, QUEUE);
702 if (queueRowStore != null) {
703 ConcurrentMap<String, Row> queueTableRows = queueRowStore.getRowStore();
704 Row queueRow = queueTableRows.values().stream().filter(r -> {
705 OvsdbMap ovsdbMap = (OvsdbMap) (r.getColumn(EXTERNAL_ID).data());
706 return entry.getValue().equals(ovsdbMap.map().get(QUEUE_EXTERNAL_ID_KEY));
707 }).findFirst().orElse(null);
708 if (queueRow != null) {
709 queues.put(entry.getKey(), queueRow.uuid());
710 }
711 }
712 }
713 qos.setQueues(queues);
714 }
715
716 Insert qosInsert = new Insert(dbSchema.getTableSchema(QOS), QOS, qos.getRow());
717 operations.add(qosInsert);
718 try {
719 transactConfig(DATABASENAME, operations).get();
720 } catch (InterruptedException | ExecutionException e) {
721 return false;
722 }
723 return true;
724 }
725
726 @Override
727 public void dropQos(QosId qosId) {
728 OvsdbRowStore rowStore = getRowStore(DATABASENAME, QOS);
729 if (rowStore != null) {
730 ConcurrentMap<String, Row> qosTableRows = rowStore.getRowStore();
731 Row qosRow = qosTableRows.values().stream().filter(r -> {
732 OvsdbMap ovsdbMap = (OvsdbMap) (r.getColumn(EXTERNAL_ID).data());
733 return qosId.name().equals(ovsdbMap.map().get(QOS_EXTERNAL_ID_KEY));
734 }).findFirst().orElse(null);
735 if (qosRow != null) {
736 deleteConfig(QOS, UUID, qosRow.uuid().value(), PORT, PORT_QOS, qosRow.uuid());
737 }
738 }
739 }
740 @Override
741 public OvsdbQos getQos(QosId qosId) {
742 Set<OvsdbQos> ovsdbQoses = getQoses();
743 return ovsdbQoses.stream().filter(r ->
744 qosId.name().equals(r.externalIds().get(QOS_EXTERNAL_ID_KEY))).
745 findFirst().orElse(null);
746 }
747
748 @Override
749 public Set<OvsdbQos> getQoses() {
750 Set<OvsdbQos> ovsdbQoses = new HashSet<>();
751 OvsdbRowStore rowStore = getRowStore(DATABASENAME, QOS);
752 if (rowStore == null) {
753 log.debug("The qos uuid is null");
754 return ovsdbQoses;
755 }
756 ConcurrentMap<String, Row> rows = rowStore.getRowStore();
kdarapu71f623c2018-05-10 19:37:53 +0530757 ovsdbQoses = rows.keySet().stream()
758 .map(uuid -> getRow(DATABASENAME, QOS, uuid))
759 .map(this::getOvsdbQos)
760 .filter(Objects::nonNull)
761 .collect(Collectors.toSet());
Frank Wange11a98d2016-10-26 17:04:03 +0800762 return ovsdbQoses;
763 }
764
765 @Override
tanbangchengc944c282017-11-12 20:42:59 +0800766 public void bindQueues(QosId qosId, Map<Long, QueueDescription> queues) {
767 DatabaseSchema dbSchema = schema.get(DATABASENAME);
768 OvsdbRowStore qosRowStore = getRowStore(DATABASENAME, QOS);
769 if (qosRowStore == null) {
770 log.debug("The qos uuid is null");
771 return;
772 }
773 OvsdbRowStore queueRowStore = getRowStore(DATABASENAME, QUEUE);
774 if (queueRowStore == null) {
775 log.debug("The queue uuid is null");
776 return;
777 }
778
779 ConcurrentMap<String, Row> qosTableRows = qosRowStore.getRowStore();
780 ConcurrentMap<String, Row> queueTableRows = queueRowStore.getRowStore();
781
782 Row qosRow = qosTableRows.values().stream().filter(r -> {
783 OvsdbMap ovsdbMap = (OvsdbMap) (r.getColumn(EXTERNAL_ID).data());
784 return qosId.name().equals(ovsdbMap.map().get(QOS_EXTERNAL_ID_KEY));
785 }).findFirst().orElse(null);
786
787 if (qosRow == null) {
788 log.warn("Can't find QoS {}", qosId);
789 return;
790 }
791
792 Uuid qosUuid = qosRow.uuid();
793
kdarapu71f623c2018-05-10 19:37:53 +0530794 Map<Long, Uuid> newQueues = new HashMap<>();
tanbangchengc944c282017-11-12 20:42:59 +0800795 for (Map.Entry<Long, QueueDescription> entry : queues.entrySet()) {
796 Row queueRow = queueTableRows.values().stream().filter(r -> {
797 OvsdbMap ovsdbMap = (OvsdbMap) (r.getColumn(EXTERNAL_ID).data());
798 return entry.getValue().queueId().name().equals(ovsdbMap.map().get(QUEUE_EXTERNAL_ID_KEY));
799 }).findFirst().orElse(null);
800 if (queueRow != null) {
801 newQueues.put(entry.getKey(), queueRow.uuid());
802 }
803 }
804
805 // update the qos table
806 ArrayList<Operation> operations = Lists.newArrayList();
807 Condition condition = ConditionUtil.isEqual(UUID, qosUuid);
808 Mutation mutation = MutationUtil.insert(QUEUES, newQueues);
809 List<Condition> conditions = Collections.singletonList(condition);
810 List<Mutation> mutations = Collections.singletonList(mutation);
811 operations.add(new Mutate(dbSchema.getTableSchema(QOS), conditions, mutations));
812
813 transactConfig(DATABASENAME, operations);
814 }
815
816
817 @SuppressWarnings("unchecked")
818 @Override
819 public void unbindQueues(QosId qosId, List<Long> queueKeys) {
820 DatabaseSchema dbSchema = schema.get(DATABASENAME);
821 OvsdbRowStore qosRowStore = getRowStore(DATABASENAME, QOS);
822 if (qosRowStore == null) {
823 return;
824 }
825
826 ConcurrentMap<String, Row> qosTableRows = qosRowStore.getRowStore();
827
828 Row qosRow = qosTableRows.values().stream().filter(r -> {
829 OvsdbMap ovsdbMap = (OvsdbMap) (r.getColumn(EXTERNAL_ID).data());
830 return qosId.name().equals(ovsdbMap.map().get(QOS_EXTERNAL_ID_KEY));
831 }).findFirst().orElse(null);
832
833 if (qosRow == null) {
834 log.warn("Can't find QoS {}", qosId);
835 return;
836 }
837
kdarapu71f623c2018-05-10 19:37:53 +0530838 Map<Long, Uuid> deleteQueuesMap;
tanbangchengc944c282017-11-12 20:42:59 +0800839 Map<Integer, Uuid> queuesMap = ((OvsdbMap) qosRow.getColumn(QUEUES).data()).map();
840
kdarapu71f623c2018-05-10 19:37:53 +0530841 deleteQueuesMap = queueKeys.stream()
842 .filter(key -> queuesMap.containsKey(key.intValue()))
843 .collect(Collectors.toMap(key -> key, key -> queuesMap.get(key.intValue()), (a, b) -> b));
tanbangchengc944c282017-11-12 20:42:59 +0800844
845 if (deleteQueuesMap.size() != 0) {
846 TableSchema parentTableSchema = dbSchema
847 .getTableSchema(QOS);
848 ColumnSchema parentColumnSchema = parentTableSchema
849 .getColumnSchema(QUEUES);
850
851 Mutation mutation = MutationUtil.delete(parentColumnSchema.name(), OvsdbMap.ovsdbMap(deleteQueuesMap));
852 List<Mutation> mutations = Collections.singletonList(mutation);
853
854 Condition condition = ConditionUtil.isEqual(UUID, qosRow.uuid());
855 List<Condition> conditionList = Collections.singletonList(condition);
856 List<Operation> operations = Collections.singletonList(
857 new Mutate(parentTableSchema, conditionList, mutations));
858
859 transactConfig(DATABASENAME, operations);
860 }
861 }
862
863
864 @Override
Frank Wange11a98d2016-10-26 17:04:03 +0800865 public boolean createQueue(OvsdbQueue ovsdbQueue) {
866 DatabaseSchema dbSchema = schema.get(DATABASENAME);
867 Queue queue = (Queue) TableGenerator.createTable(dbSchema, OvsdbTable.QUEUE);
868 ArrayList<Operation> operations = Lists.newArrayList();
869 OvsdbRowStore rowStore = getRowStore(DATABASENAME, QUEUE);
870 if (rowStore == null) {
871 log.debug("The queue uuid is null");
872 return false;
873 }
874
875 if (ovsdbQueue.dscp().isPresent()) {
876 queue.setDscp(ImmutableSet.of(ovsdbQueue.dscp().get()));
877 }
878 queue.setOtherConfig(ovsdbQueue.otherConfigs());
879 queue.setExternalIds(ovsdbQueue.externalIds());
880 Insert queueInsert = new Insert(dbSchema.getTableSchema(QUEUE), QUEUE, queue.getRow());
881 operations.add(queueInsert);
882
883 try {
884 transactConfig(DATABASENAME, operations).get();
885 } catch (InterruptedException | ExecutionException e) {
886 log.error("createQueue transactConfig get exception !");
887 }
888 return true;
889 }
890
891 @Override
892 public void dropQueue(QueueId queueId) {
893 OvsdbRowStore queueRowStore = getRowStore(DATABASENAME, QUEUE);
894 if (queueRowStore == null) {
895 return;
896 }
897
898 ConcurrentMap<String, Row> queueTableRows = queueRowStore.getRowStore();
899 Row queueRow = queueTableRows.values().stream().filter(r -> {
900 OvsdbMap ovsdbMap = (OvsdbMap) (r.getColumn(EXTERNAL_ID).data());
901 return queueId.name().equals(ovsdbMap.map().get(QUEUE_EXTERNAL_ID_KEY));
902 }).findFirst().orElse(null);
903 if (queueRow == null) {
904 return;
905 }
906
907 String queueUuid = queueRow.uuid().value();
908 OvsdbRowStore qosRowStore = getRowStore(DATABASENAME, QOS);
909 if (qosRowStore != null) {
910 Map<Long, Uuid> queueMap = new HashMap<>();
911 ConcurrentMap<String, Row> qosTableRows = qosRowStore.getRowStore();
912 qosTableRows.values().stream().filter(r -> {
913 Map<Integer, Uuid> ovsdbMap = ((OvsdbMap) r.getColumn(QUEUES).data()).map();
914 Set<Integer> keySet = ovsdbMap.keySet();
915 for (Integer keyId : keySet) {
916 if (ovsdbMap.get(keyId).equals(Uuid.uuid(queueUuid))) {
917 queueMap.put(keyId.longValue(), Uuid.uuid(queueUuid));
918 return true;
919 }
920 }
921 return false;
922 }).findFirst().orElse(null);
923 deleteConfig(QUEUE, UUID, queueUuid, QOS, QUEUES, OvsdbMap.ovsdbMap(queueMap));
924 } else {
925 deleteConfig(QUEUE, UUID, queueUuid, null, null, null);
926 }
927 }
928 @Override
929 public OvsdbQueue getQueue(QueueId queueId) {
930 Set<OvsdbQueue> ovsdbQueues = getQueues();
931 return ovsdbQueues.stream().filter(r ->
932 queueId.name().equals(r.externalIds().get(QUEUE_EXTERNAL_ID_KEY))).
933 findFirst().orElse(null);
934 }
935
936 @Override
937 public Set<OvsdbQueue> getQueues() {
938 Set<OvsdbQueue> ovsdbqueues = new HashSet<>();
939 OvsdbRowStore rowStore = getRowStore(DATABASENAME, QUEUE);
940 if (rowStore == null) {
941 log.debug("The queue uuid is null");
942 return ovsdbqueues;
943 }
944 ConcurrentMap<String, Row> rows = rowStore.getRowStore();
kdarapu71f623c2018-05-10 19:37:53 +0530945 ovsdbqueues = rows.keySet()
946 .stream()
947 .map(uuid -> getRow(DATABASENAME, QUEUE, uuid))
948 .map(this::getOvsdbQueue)
949 .filter(Objects::nonNull)
950 .collect(Collectors.toSet());
Frank Wange11a98d2016-10-26 17:04:03 +0800951 return ovsdbqueues;
952 }
Pier Ventref5d72362016-07-17 12:02:14 +0200953 /**
954 * Creates a mirror port. Mirrors the traffic
955 * that goes to selectDstPort or comes from
956 * selectSrcPort or packets containing selectVlan
957 * to mirrorPort or to all ports that trunk mirrorVlan.
958 *
959 * @param mirror the OVSDB mirror description
960 * @return true if mirror creation is successful, false otherwise
961 */
962 @Override
963 public boolean createMirror(String bridgeName, OvsdbMirror mirror) {
964
965 /**
966 * Retrieves bridge's uuid. It is necessary to update
967 * Bridge table.
968 */
969 String bridgeUuid = getBridgeUuid(bridgeName);
970 if (bridgeUuid == null) {
971 log.warn("Couldn't find bridge {} in {}", bridgeName, nodeId.getIpAddress());
972 return false;
973 }
974
975 OvsdbMirror.Builder mirrorBuilder = OvsdbMirror.builder();
976
977 mirrorBuilder.mirroringName(mirror.mirroringName());
978 mirrorBuilder.selectAll(mirror.selectAll());
979
980 /**
981 * Retrieves the uuid of the monitored dst ports.
982 */
983 mirrorBuilder.monitorDstPorts(mirror.monitorDstPorts().parallelStream()
984 .map(dstPort -> {
985 String dstPortUuid = getPortUuid(dstPort.value(), bridgeUuid);
986 if (dstPortUuid != null) {
987 return Uuid.uuid(dstPortUuid);
988 }
989 log.warn("Couldn't find port {} in {}",
990 dstPort.value(), nodeId.getIpAddress());
991 return null;
992 })
993 .filter(Objects::nonNull)
994 .collect(Collectors.toSet())
995 );
996
997 /**
998 * Retrieves the uuid of the monitored src ports.
999 */
1000 mirrorBuilder.monitorSrcPorts(mirror.monitorSrcPorts().parallelStream()
1001 .map(srcPort -> {
1002 String srcPortUuid = getPortUuid(srcPort.value(), bridgeUuid);
1003 if (srcPortUuid != null) {
1004 return Uuid.uuid(srcPortUuid);
1005 }
1006 log.warn("Couldn't find port {} in {}",
1007 srcPort.value(), nodeId.getIpAddress());
1008 return null;
1009 }).filter(Objects::nonNull)
1010 .collect(Collectors.toSet())
1011 );
1012
1013 mirrorBuilder.monitorVlans(mirror.monitorVlans());
1014 mirrorBuilder.mirrorPort(mirror.mirrorPort());
1015 mirrorBuilder.mirrorVlan(mirror.mirrorVlan());
1016 mirrorBuilder.externalIds(mirror.externalIds());
1017 mirror = mirrorBuilder.build();
1018
Jon Hallcbd1b392017-01-18 20:15:44 -08001019 if (mirror.monitorDstPorts().isEmpty() &&
1020 mirror.monitorSrcPorts().isEmpty() &&
1021 mirror.monitorVlans().isEmpty()) {
Pier Ventref5d72362016-07-17 12:02:14 +02001022 log.warn("Invalid monitoring data");
1023 return false;
1024 }
1025
1026 DatabaseSchema dbSchema = schema.get(DATABASENAME);
1027
1028 Mirror mirrorEntry = (Mirror) TableGenerator.createTable(dbSchema, OvsdbTable.MIRROR);
1029 mirrorEntry.setName(mirror.mirroringName());
1030 mirrorEntry.setSelectDstPort(mirror.monitorDstPorts());
1031 mirrorEntry.setSelectSrcPort(mirror.monitorSrcPorts());
1032 mirrorEntry.setSelectVlan(mirror.monitorVlans());
1033 mirrorEntry.setExternalIds(mirror.externalIds());
1034
1035 /**
1036 * If mirror port, retrieves the uuid of the mirror port.
1037 */
1038 if (mirror.mirrorPort() != null) {
1039
1040 String outputPortUuid = getPortUuid(mirror.mirrorPort().value(), bridgeUuid);
1041 if (outputPortUuid == null) {
1042 log.warn("Couldn't find port {} in {}", mirror.mirrorPort().value(), nodeId.getIpAddress());
1043 return false;
1044 }
1045
1046 mirrorEntry.setOutputPort(Uuid.uuid(outputPortUuid));
1047
1048 } else if (mirror.mirrorVlan() != null) {
1049
1050 mirrorEntry.setOutputVlan(mirror.mirrorVlan());
1051
1052 } else {
1053 log.warn("Invalid mirror, no mirror port and no mirror vlan");
1054 return false;
1055 }
1056
1057 ArrayList<Operation> operations = Lists.newArrayList();
1058 Insert mirrorInsert = new Insert(dbSchema.getTableSchema("Mirror"), "Mirror", mirrorEntry.getRow());
1059 operations.add(mirrorInsert);
1060
1061 // update the bridge table
1062 Condition condition = ConditionUtil.isEqual(UUID, Uuid.uuid(bridgeUuid));
1063 Mutation mutation = MutationUtil.insert(MIRRORS, Uuid.uuid("Mirror"));
1064 List<Condition> conditions = Lists.newArrayList(condition);
1065 List<Mutation> mutations = Lists.newArrayList(mutation);
1066 operations.add(new Mutate(dbSchema.getTableSchema("Bridge"), conditions, mutations));
1067
1068 transactConfig(DATABASENAME, operations);
1069 log.info("Created mirror {}", mirror.mirroringName());
1070 return true;
1071 }
1072
1073 /**
1074 * Drops the configuration for mirror.
1075 *
Ray Milkeyef794342016-11-09 16:20:29 -08001076 * @param mirroringName name of mirror to drop
Pier Ventref5d72362016-07-17 12:02:14 +02001077 */
1078 @Override
1079 public void dropMirror(MirroringName mirroringName) {
1080 String mirrorUuid = getMirrorUuid(mirroringName.name());
1081 if (mirrorUuid != null) {
1082 log.info("Deleted mirror {}", mirroringName.name());
Frank Wange11a98d2016-10-26 17:04:03 +08001083 deleteConfig(MIRROR, UUID, mirrorUuid, BRIDGE, MIRRORS, Uuid.uuid(mirrorUuid));
Pier Ventref5d72362016-07-17 12:02:14 +02001084 }
1085 log.warn("Unable to delete {}", mirroringName.name());
1086 return;
1087 }
1088
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001089 @Override
Hyunsun Moondd14e8e2016-06-09 16:17:32 -07001090 public boolean createInterface(String bridgeName, OvsdbInterface ovsdbIface) {
Hyunsun Moon646d8c42015-10-08 20:32:44 -07001091 String bridgeUuid = getBridgeUuid(bridgeName);
1092 if (bridgeUuid == null) {
1093 log.warn("Couldn't find bridge {} in {}", bridgeName, nodeId.getIpAddress());
1094 return false;
1095 }
1096
Hyunsun Moondd14e8e2016-06-09 16:17:32 -07001097 if (getPortUuid(ovsdbIface.name(), bridgeUuid) != null) {
1098 log.warn("Interface {} already exists", ovsdbIface.name());
Hyunsun Moon646d8c42015-10-08 20:32:44 -07001099 return false;
1100 }
1101
1102 ArrayList<Operation> operations = Lists.newArrayList();
Hyunsun Moon1251e192016-06-07 16:57:05 -07001103 DatabaseSchema dbSchema = schema.get(DATABASENAME);
Hyunsun Moon646d8c42015-10-08 20:32:44 -07001104
Hyunsun Moon89478662016-06-09 17:52:34 -07001105 // insert a new port with the interface name
Hyunsun Moon646d8c42015-10-08 20:32:44 -07001106 Port port = (Port) TableGenerator.createTable(dbSchema, OvsdbTable.PORT);
Hyunsun Moondd14e8e2016-06-09 16:17:32 -07001107 port.setName(ovsdbIface.name());
1108 Insert portInsert = new Insert(dbSchema.getTableSchema(PORT), PORT, port.getRow());
1109 portInsert.getRow().put(INTERFACES, Uuid.uuid(INTERFACE));
Hyunsun Moon646d8c42015-10-08 20:32:44 -07001110 operations.add(portInsert);
1111
Hyunsun Moon89478662016-06-09 17:52:34 -07001112 // update the bridge table with the new port
Hyunsun Moon1251e192016-06-07 16:57:05 -07001113 Condition condition = ConditionUtil.isEqual(UUID, Uuid.uuid(bridgeUuid));
Hyunsun Moondd14e8e2016-06-09 16:17:32 -07001114 Mutation mutation = MutationUtil.insert(PORTS, Uuid.uuid(PORT));
1115 List<Condition> conditions = Lists.newArrayList(condition);
1116 List<Mutation> mutations = Lists.newArrayList(mutation);
1117 operations.add(new Mutate(dbSchema.getTableSchema(BRIDGE), conditions, mutations));
Hyunsun Moon646d8c42015-10-08 20:32:44 -07001118
Hyunsun Moon646d8c42015-10-08 20:32:44 -07001119 Interface intf = (Interface) TableGenerator.createTable(dbSchema, OvsdbTable.INTERFACE);
Hyunsun Moondd14e8e2016-06-09 16:17:32 -07001120 intf.setName(ovsdbIface.name());
jaegonkim256f2c12017-05-26 00:03:42 +09001121
Jian Li83a5e8d2019-05-17 19:50:28 +09001122 if (ovsdbIface.type() != null) {
1123 intf.setType(ovsdbIface.typeToString());
1124 }
jaegonkim256f2c12017-05-26 00:03:42 +09001125
1126 if (ovsdbIface.mtu().isPresent()) {
1127 Set<Long> mtuSet = Sets.newConcurrentHashSet();
1128 mtuSet.add(ovsdbIface.mtu().get());
1129 intf.setMtu(mtuSet);
1130 intf.setMtuRequest(mtuSet);
1131 }
1132
Hyunsun Moondd14e8e2016-06-09 16:17:32 -07001133 intf.setOptions(ovsdbIface.options());
Jian Li83a5e8d2019-05-17 19:50:28 +09001134
1135 ovsdbIface.data().forEach((k, v) -> {
1136 if (k == Interface.InterfaceColumn.EXTERNALIDS) {
1137 intf.setExternalIds(v);
1138 }
1139 });
1140
Hyunsun Moondd14e8e2016-06-09 16:17:32 -07001141 Insert intfInsert = new Insert(dbSchema.getTableSchema(INTERFACE), INTERFACE, intf.getRow());
Hyunsun Moon646d8c42015-10-08 20:32:44 -07001142 operations.add(intfInsert);
1143
Hyunsun Moon1251e192016-06-07 16:57:05 -07001144 transactConfig(DATABASENAME, operations);
Hyunsun Moon89478662016-06-09 17:52:34 -07001145 log.info("Created interface {}", ovsdbIface);
Hyunsun Moon646d8c42015-10-08 20:32:44 -07001146 return true;
1147 }
1148
1149 @Override
Hyunsun Moondd14e8e2016-06-09 16:17:32 -07001150 public boolean dropInterface(String ifaceName) {
1151 OvsdbRowStore rowStore = getRowStore(DATABASENAME, BRIDGE);
1152 if (rowStore == null) {
1153 log.warn("Failed to get BRIDGE table");
1154 return false;
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001155 }
1156
Hyunsun Moondd14e8e2016-06-09 16:17:32 -07001157 ConcurrentMap<String, Row> bridgeTableRows = rowStore.getRowStore();
1158 if (bridgeTableRows == null) {
1159 log.warn("Failed to get BRIDGE table rows");
1160 return false;
1161 }
1162
1163 // interface name is unique
1164 Optional<String> bridgeId = bridgeTableRows.keySet().stream()
1165 .filter(uuid -> getPortUuid(ifaceName, uuid) != null)
1166 .findFirst();
1167
1168 if (bridgeId.isPresent()) {
1169 String portId = getPortUuid(ifaceName, bridgeId.get());
Frank Wange11a98d2016-10-26 17:04:03 +08001170 deleteConfig(PORT, UUID, portId, BRIDGE, PORTS, Uuid.uuid(portId));
Hyunsun Moondd14e8e2016-06-09 16:17:32 -07001171 return true;
1172 } else {
1173 log.warn("Unable to find the interface with name {}", ifaceName);
1174 return false;
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001175 }
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001176 }
1177
1178 /**
1179 * Delete transact config.
1180 *
andreaed976a42015-10-05 14:38:25 -07001181 * @param childTableName child table name
1182 * @param childColumnName child column name
1183 * @param childUuid child row uuid
1184 * @param parentTableName parent table name
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001185 * @param parentColumnName parent column
Frank Wange11a98d2016-10-26 17:04:03 +08001186 * @param referencedValue referenced value
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001187 */
1188 private void deleteConfig(String childTableName, String childColumnName,
andreaed976a42015-10-05 14:38:25 -07001189 String childUuid, String parentTableName,
Frank Wange11a98d2016-10-26 17:04:03 +08001190 String parentColumnName, Object referencedValue) {
Hyunsun Moon1251e192016-06-07 16:57:05 -07001191 DatabaseSchema dbSchema = schema.get(DATABASENAME);
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001192 TableSchema childTableSchema = dbSchema.getTableSchema(childTableName);
1193
1194 ArrayList<Operation> operations = Lists.newArrayList();
Frank Wange11a98d2016-10-26 17:04:03 +08001195 if (parentTableName != null && parentColumnName != null && referencedValue != null) {
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001196 TableSchema parentTableSchema = dbSchema
1197 .getTableSchema(parentTableName);
1198 ColumnSchema parentColumnSchema = parentTableSchema
1199 .getColumnSchema(parentColumnName);
1200 List<Mutation> mutations = Lists.newArrayList();
Frank Wange11a98d2016-10-26 17:04:03 +08001201 Mutation mutation = MutationUtil.delete(parentColumnSchema.name(), referencedValue);
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001202 mutations.add(mutation);
1203 List<Condition> conditions = Lists.newArrayList();
Frank Wange11a98d2016-10-26 17:04:03 +08001204 Condition condition = ConditionUtil.includes(parentColumnName, referencedValue);
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001205 conditions.add(condition);
1206 Mutate op = new Mutate(parentTableSchema, conditions, mutations);
1207 operations.add(op);
1208 }
1209
1210 List<Condition> conditions = Lists.newArrayList();
Jonathan Hart51539b82015-10-29 09:53:04 -07001211 Condition condition = ConditionUtil.isEqual(childColumnName, Uuid.uuid(childUuid));
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001212 conditions.add(condition);
1213 Delete del = new Delete(childTableSchema, conditions);
1214 operations.add(del);
Hyunsun Moon1251e192016-06-07 16:57:05 -07001215 transactConfig(DATABASENAME, operations);
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001216 }
1217
1218 /**
1219 * Update transact config.
1220 *
andreaed976a42015-10-05 14:38:25 -07001221 * @param tableName table name
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001222 * @param columnName column name
andreaed976a42015-10-05 14:38:25 -07001223 * @param uuid uuid
1224 * @param row the config data
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001225 */
1226 private void updateConfig(String tableName, String columnName, String uuid,
andreaed976a42015-10-05 14:38:25 -07001227 Row row) {
Hyunsun Moon1251e192016-06-07 16:57:05 -07001228 DatabaseSchema dbSchema = schema.get(DATABASENAME);
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001229 TableSchema tableSchema = dbSchema.getTableSchema(tableName);
1230
1231 List<Condition> conditions = Lists.newArrayList();
Jonathan Hart51539b82015-10-29 09:53:04 -07001232 Condition condition = ConditionUtil.isEqual(columnName, Uuid.uuid(uuid));
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001233 conditions.add(condition);
1234
1235 Update update = new Update(tableSchema, row, conditions);
1236
1237 ArrayList<Operation> operations = Lists.newArrayList();
1238 operations.add(update);
1239
Hyunsun Moon1251e192016-06-07 16:57:05 -07001240 transactConfig(DATABASENAME, operations);
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001241 }
1242
1243 /**
1244 * Insert transact config.
1245 *
andreaed976a42015-10-05 14:38:25 -07001246 * @param childTableName child table name
1247 * @param childColumnName child column name
1248 * @param parentTableName parent table name
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001249 * @param parentColumnName parent column
andreaed976a42015-10-05 14:38:25 -07001250 * @param parentUuid parent uuid
1251 * @param row the config data
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001252 * @return uuid, empty if no uuid is find
1253 */
1254 private String insertConfig(String childTableName, String childColumnName,
andreaed976a42015-10-05 14:38:25 -07001255 String parentTableName, String parentColumnName,
1256 String parentUuid, Row row) {
Hyunsun Moon1251e192016-06-07 16:57:05 -07001257 DatabaseSchema dbSchema = schema.get(DATABASENAME);
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001258 TableSchema tableSchema = dbSchema.getTableSchema(childTableName);
1259
Sho SHIMIZUff18f8c2016-03-11 14:43:53 -08001260 Insert insert = new Insert(tableSchema, childTableName, row);
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001261
1262 ArrayList<Operation> operations = Lists.newArrayList();
1263 operations.add(insert);
1264
1265 if (parentTableName != null && parentColumnName != null) {
1266 TableSchema parentTableSchema = dbSchema
1267 .getTableSchema(parentTableName);
1268 ColumnSchema parentColumnSchema = parentTableSchema
1269 .getColumnSchema(parentColumnName);
1270
1271 List<Mutation> mutations = Lists.newArrayList();
1272 Mutation mutation = MutationUtil.insert(parentColumnSchema.name(),
Sho SHIMIZUff18f8c2016-03-11 14:43:53 -08001273 Uuid.uuid(childTableName));
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001274 mutations.add(mutation);
1275
1276 List<Condition> conditions = Lists.newArrayList();
Hyunsun Moon1251e192016-06-07 16:57:05 -07001277 Condition condition = ConditionUtil.isEqual(UUID, Uuid.uuid(parentUuid));
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001278 conditions.add(condition);
1279
1280 Mutate op = new Mutate(parentTableSchema, conditions, mutations);
1281 operations.add(op);
1282 }
Hyunsun Moon1251e192016-06-07 16:57:05 -07001283 if (childTableName.equalsIgnoreCase(PORT)) {
1284 log.debug("Handle port insert");
Hyunsun Moondd14e8e2016-06-09 16:17:32 -07001285 Insert intfInsert = handlePortInsertTable(row);
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001286
1287 if (intfInsert != null) {
1288 operations.add(intfInsert);
1289 }
1290
1291 Insert ins = (Insert) operations.get(0);
Hyunsun Moon1251e192016-06-07 16:57:05 -07001292 ins.getRow().put("interfaces", Uuid.uuid(INTERFACE));
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001293 }
1294
1295 List<OperationResult> results;
1296 try {
jaegonkim01d7c912017-01-22 22:03:38 +09001297 results = transactConfig(DATABASENAME, operations)
1298 .get(TRANSACTCONFIG_TIMEOUT, TimeUnit.SECONDS);
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001299 return results.get(0).getUuid().value();
jaegonkim01d7c912017-01-22 22:03:38 +09001300 } catch (TimeoutException e) {
1301 log.warn("TimeoutException thrown while to get result");
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001302 } catch (InterruptedException e) {
1303 log.warn("Interrupted while waiting to get result");
1304 Thread.currentThread().interrupt();
1305 } catch (ExecutionException e) {
1306 log.error("Exception thrown while to get result");
1307 }
1308
1309 return null;
1310 }
1311
jaegonkim01d7c912017-01-22 22:03:38 +09001312
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001313 /**
1314 * Handles port insert.
1315 *
andreaed976a42015-10-05 14:38:25 -07001316 * @param portRow row of port
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001317 * @return insert, empty if null
1318 */
Hyunsun Moondd14e8e2016-06-09 16:17:32 -07001319 private Insert handlePortInsertTable(Row portRow) {
Hyunsun Moon1251e192016-06-07 16:57:05 -07001320 DatabaseSchema dbSchema = schema.get(DATABASENAME);
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001321
Hyunsun Moon1251e192016-06-07 16:57:05 -07001322 TableSchema portTableSchema = dbSchema.getTableSchema(PORT);
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001323 ColumnSchema portColumnSchema = portTableSchema.getColumnSchema("name");
1324
1325 String portName = (String) portRow.getColumn(portColumnSchema.name()).data();
Hyunsun Moon1251e192016-06-07 16:57:05 -07001326 Interface inf = (Interface) TableGenerator.createTable(dbSchema, OvsdbTable.INTERFACE);
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001327 inf.setName(portName);
1328
Hyunsun Moon1251e192016-06-07 16:57:05 -07001329 TableSchema intfTableSchema = dbSchema.getTableSchema(INTERFACE);
1330 return new Insert(intfTableSchema, INTERFACE, inf.getRow());
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001331 }
1332
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001333 @Override
1334 public ListenableFuture<DatabaseSchema> getOvsdbSchema(String dbName) {
1335 if (dbName == null) {
1336 return null;
1337 }
1338 DatabaseSchema databaseSchema = schema.get(dbName);
1339 if (databaseSchema == null) {
kdarapu71f623c2018-05-10 19:37:53 +05301340 List<String> dbNames = new ArrayList<>();
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001341 dbNames.add(dbName);
Hyunsun Moon1251e192016-06-07 16:57:05 -07001342 Function<JsonNode, DatabaseSchema> rowFunction = input -> {
1343 log.debug("Get ovsdb database schema {}", dbName);
1344 DatabaseSchema dbSchema = FromJsonUtil.jsonNodeToDbSchema(dbName, input);
1345 if (dbSchema == null) {
1346 log.debug("Get ovsdb database schema error");
1347 return null;
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001348 }
Hyunsun Moon1251e192016-06-07 16:57:05 -07001349 schema.put(dbName, dbSchema);
1350 return dbSchema;
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001351 };
1352
1353 ListenableFuture<JsonNode> input = getSchema(dbNames);
1354 if (input != null) {
1355 return Futures.transform(input, rowFunction);
1356 }
1357 return null;
1358 } else {
1359 return Futures.immediateFuture(databaseSchema);
1360 }
1361 }
1362
1363 @Override
1364 public ListenableFuture<TableUpdates> monitorTables(String dbName, String id) {
1365 if (dbName == null) {
1366 return null;
1367 }
1368 DatabaseSchema dbSchema = schema.get(dbName);
1369 if (dbSchema != null) {
Hyunsun Moon1251e192016-06-07 16:57:05 -07001370 Function<JsonNode, TableUpdates> rowFunction = input -> {
1371 log.debug("Get table updates");
1372 TableUpdates updates = FromJsonUtil.jsonNodeToTableUpdates(input, dbSchema);
1373 if (updates == null) {
1374 log.debug("Get table updates error");
1375 return null;
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001376 }
Hyunsun Moon1251e192016-06-07 16:57:05 -07001377 return updates;
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001378 };
1379 return Futures.transform(monitor(dbSchema, id), rowFunction);
1380 }
1381 return null;
1382 }
1383
Hyunsun Moondd14e8e2016-06-09 16:17:32 -07001384 private ListenableFuture<List<OperationResult>> transactConfig(String dbName,
1385 List<Operation> operations) {
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001386 if (dbName == null) {
1387 return null;
1388 }
1389 DatabaseSchema dbSchema = schema.get(dbName);
1390 if (dbSchema != null) {
andreaed976a42015-10-05 14:38:25 -07001391 Function<List<JsonNode>, List<OperationResult>> rowFunction = (input -> {
Jonathan Hart6523e122017-11-14 09:23:49 -08001392 try {
1393 log.debug("Get ovsdb operation result");
1394 List<OperationResult> result = FromJsonUtil.jsonNodeToOperationResult(input, operations);
1395 if (result == null) {
1396 log.debug("The operation result is null");
1397 return null;
1398 }
1399 return result;
1400 } catch (Exception e) {
1401 log.error("Exception while parsing result", e);
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001402 }
Jonathan Hart6523e122017-11-14 09:23:49 -08001403 return null;
andreaed976a42015-10-05 14:38:25 -07001404 });
Hyunsun Moon1251e192016-06-07 16:57:05 -07001405 return Futures.transform(transact(dbSchema, operations), rowFunction);
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001406 }
1407 return null;
1408 }
1409
1410 @Override
1411 public ListenableFuture<JsonNode> getSchema(List<String> dbnames) {
1412 String id = java.util.UUID.randomUUID().toString();
1413 String getSchemaString = JsonRpcWriterUtil.getSchemaStr(id, dbnames);
1414
1415 SettableFuture<JsonNode> sf = SettableFuture.create();
1416 requestResult.put(id, sf);
1417 requestMethod.put(id, "getSchema");
1418
1419 channel.writeAndFlush(getSchemaString);
1420 return sf;
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001421 }
1422
1423 @Override
1424 public ListenableFuture<List<String>> echo() {
1425 String id = java.util.UUID.randomUUID().toString();
1426 String echoString = JsonRpcWriterUtil.echoStr(id);
1427
1428 SettableFuture<List<String>> sf = SettableFuture.create();
1429 requestResult.put(id, sf);
1430 requestMethod.put(id, "echo");
1431
1432 channel.writeAndFlush(echoString);
1433 return sf;
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001434 }
1435
1436 @Override
1437 public ListenableFuture<JsonNode> monitor(DatabaseSchema dbSchema,
1438 String monitorId) {
1439 String id = java.util.UUID.randomUUID().toString();
1440 String monitorString = JsonRpcWriterUtil.monitorStr(id, monitorId,
1441 dbSchema);
1442
1443 SettableFuture<JsonNode> sf = SettableFuture.create();
1444 requestResult.put(id, sf);
1445 requestMethod.put(id, "monitor");
1446
1447 channel.writeAndFlush(monitorString);
1448 return sf;
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001449 }
1450
1451 @Override
1452 public ListenableFuture<List<String>> listDbs() {
1453 String id = java.util.UUID.randomUUID().toString();
1454 String listDbsString = JsonRpcWriterUtil.listDbsStr(id);
1455
1456 SettableFuture<List<String>> sf = SettableFuture.create();
1457 requestResult.put(id, sf);
1458 requestMethod.put(id, "listDbs");
1459
1460 channel.writeAndFlush(listDbsString);
1461 return sf;
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001462 }
1463
1464 @Override
1465 public ListenableFuture<List<JsonNode>> transact(DatabaseSchema dbSchema,
1466 List<Operation> operations) {
1467 String id = java.util.UUID.randomUUID().toString();
1468 String transactString = JsonRpcWriterUtil.transactStr(id, dbSchema,
1469 operations);
1470
1471 SettableFuture<List<JsonNode>> sf = SettableFuture.create();
1472 requestResult.put(id, sf);
1473 requestMethod.put(id, "transact");
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001474 channel.writeAndFlush(transactString);
1475 return sf;
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001476 }
1477
andreaed976a42015-10-05 14:38:25 -07001478 @SuppressWarnings({"rawtypes", "unchecked"})
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001479 @Override
1480 public void processResult(JsonNode response) {
1481 log.debug("Handle result");
1482 String requestId = response.get("id").asText();
1483 SettableFuture sf = requestResult.get(requestId);
1484 if (sf == null) {
1485 log.debug("No such future to process");
1486 return;
1487 }
1488 String methodName = requestMethod.get(requestId);
Hyunsun Moon1251e192016-06-07 16:57:05 -07001489 sf.set(FromJsonUtil.jsonResultParser(response, methodName));
tanbangcheng1afecce2017-11-12 11:41:28 +08001490
1491 requestResult.remove(requestId);
1492 requestMethod.remove(requestId);
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001493 }
1494
1495 @Override
1496 public void processRequest(JsonNode requestJson) {
1497 log.debug("Handle request");
1498 if (requestJson.get("method").asText().equalsIgnoreCase("echo")) {
1499 log.debug("handle echo request");
1500
1501 String replyString = FromJsonUtil.getEchoRequestStr(requestJson);
1502 channel.writeAndFlush(replyString);
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001503 } else {
Hyunsun Moon1251e192016-06-07 16:57:05 -07001504 FromJsonUtil.jsonCallbackRequestParser(requestJson, monitorCallBack);
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001505 }
1506 }
1507
1508 @Override
1509 public void setCallback(Callback monitorCallback) {
1510 this.monitorCallBack = monitorCallback;
1511 }
1512
1513 @Override
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001514 public Set<OvsdbBridge> getBridges() {
Hyunsun Moon1251e192016-06-07 16:57:05 -07001515 Set<OvsdbBridge> ovsdbBridges = new HashSet<>();
1516 OvsdbTableStore tableStore = getTableStore(DATABASENAME);
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001517 if (tableStore == null) {
MaoJianweidac220d2016-07-04 22:37:52 +08001518 return ovsdbBridges;
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001519 }
Hyunsun Moon1251e192016-06-07 16:57:05 -07001520 OvsdbRowStore rowStore = tableStore.getRows(BRIDGE);
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001521 if (rowStore == null) {
MaoJianweidac220d2016-07-04 22:37:52 +08001522 return ovsdbBridges;
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001523 }
1524 ConcurrentMap<String, Row> rows = rowStore.getRowStore();
1525 for (String uuid : rows.keySet()) {
jaegonkim7b77f712018-01-14 17:18:27 +09001526 Row bridgeRow = getRow(DATABASENAME, BRIDGE, uuid);
1527 OvsdbBridge ovsdbBridge = getOvsdbBridge(bridgeRow, Uuid.uuid(uuid));
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001528 if (ovsdbBridge != null) {
1529 ovsdbBridges.add(ovsdbBridge);
1530 }
1531 }
1532 return ovsdbBridges;
1533 }
1534
1535 @Override
andreaed976a42015-10-05 14:38:25 -07001536 public Set<ControllerInfo> getControllers(DeviceId openflowDeviceId) {
Jonathan Hart51539b82015-10-29 09:53:04 -07001537 Uuid bridgeUuid = getBridgeUuid(openflowDeviceId);
andreaed976a42015-10-05 14:38:25 -07001538 if (bridgeUuid == null) {
1539 log.warn("bad bridge Uuid");
1540 return null;
1541 }
1542 List<Controller> controllers = getControllers(bridgeUuid);
1543 if (controllers == null) {
1544 log.warn("bad list of controllers");
1545 return null;
1546 }
Hyunsun Moon1251e192016-06-07 16:57:05 -07001547 return controllers.stream().map(controller -> new ControllerInfo(
1548 (String) controller.getTargetColumn()
1549 .data())).collect(Collectors.toSet());
andreaed976a42015-10-05 14:38:25 -07001550 }
1551
Jonathan Hart51539b82015-10-29 09:53:04 -07001552 private List<Controller> getControllers(Uuid bridgeUuid) {
Hyunsun Moon1251e192016-06-07 16:57:05 -07001553 DatabaseSchema dbSchema = schema.get(DATABASENAME);
andreaed976a42015-10-05 14:38:25 -07001554 if (dbSchema == null) {
1555 return null;
1556 }
Hyunsun Moon1251e192016-06-07 16:57:05 -07001557 OvsdbRowStore rowStore = getRowStore(DATABASENAME, BRIDGE);
andreaed976a42015-10-05 14:38:25 -07001558 if (rowStore == null) {
1559 log.debug("There is no bridge table");
1560 return null;
1561 }
1562
1563 Row bridgeRow = rowStore.getRow(bridgeUuid.value());
1564 Bridge bridge = (Bridge) TableGenerator.
1565 getTable(dbSchema, bridgeRow, OvsdbTable.BRIDGE);
1566
1567 //FIXME remove log
1568 log.warn("type of controller column", bridge.getControllerColumn()
1569 .data().getClass());
Jonathan Hart51539b82015-10-29 09:53:04 -07001570 Set<Uuid> controllerUuids = (Set<Uuid>) ((OvsdbSet) bridge
andreaed976a42015-10-05 14:38:25 -07001571 .getControllerColumn().data()).set();
andreaed976a42015-10-05 14:38:25 -07001572
Hyunsun Moon1251e192016-06-07 16:57:05 -07001573 OvsdbRowStore controllerRowStore = getRowStore(DATABASENAME, CONTROLLER);
andreaed976a42015-10-05 14:38:25 -07001574 if (controllerRowStore == null) {
1575 log.debug("There is no controller table");
1576 return null;
1577 }
1578
1579 List<Controller> ovsdbControllers = new ArrayList<>();
1580 ConcurrentMap<String, Row> controllerTableRows = controllerRowStore.getRowStore();
1581 controllerTableRows.forEach((key, row) -> {
Jonathan Hart51539b82015-10-29 09:53:04 -07001582 if (!controllerUuids.contains(Uuid.uuid(key))) {
andreaed976a42015-10-05 14:38:25 -07001583 return;
1584 }
1585 Controller controller = (Controller) TableGenerator
1586 .getTable(dbSchema, row, OvsdbTable.CONTROLLER);
1587 ovsdbControllers.add(controller);
1588 });
1589 return ovsdbControllers;
1590 }
1591
1592
Jonathan Hart51539b82015-10-29 09:53:04 -07001593 private Uuid getBridgeUuid(DeviceId openflowDeviceId) {
Hyunsun Moon1251e192016-06-07 16:57:05 -07001594 DatabaseSchema dbSchema = schema.get(DATABASENAME);
andreaed976a42015-10-05 14:38:25 -07001595 if (dbSchema == null) {
1596 return null;
1597 }
Hyunsun Moon1251e192016-06-07 16:57:05 -07001598 OvsdbRowStore rowStore = getRowStore(DATABASENAME, BRIDGE);
andreaed976a42015-10-05 14:38:25 -07001599 if (rowStore == null) {
1600 log.debug("There is no bridge table");
1601 return null;
1602 }
1603
1604 ConcurrentMap<String, Row> bridgeTableRows = rowStore.getRowStore();
Jonathan Hart51539b82015-10-29 09:53:04 -07001605 final AtomicReference<Uuid> uuid = new AtomicReference<>();
andreaed976a42015-10-05 14:38:25 -07001606 for (Map.Entry<String, Row> entry : bridgeTableRows.entrySet()) {
Hyunsun Moon1251e192016-06-07 16:57:05 -07001607 Bridge bridge = (Bridge) TableGenerator.getTable(
1608 dbSchema,
1609 entry.getValue(),
1610 OvsdbTable.BRIDGE);
1611
1612 if (matchesDpid(bridge, openflowDeviceId)) {
Jonathan Hart51539b82015-10-29 09:53:04 -07001613 uuid.set(Uuid.uuid(entry.getKey()));
andreaed976a42015-10-05 14:38:25 -07001614 break;
1615 }
1616 }
1617 if (uuid.get() == null) {
1618 log.debug("There is no bridge for {}", openflowDeviceId);
1619 }
1620 return uuid.get();
andreaed976a42015-10-05 14:38:25 -07001621 }
1622
1623 private static boolean matchesDpid(Bridge b, DeviceId deviceId) {
1624 String ofDpid = deviceId.toString().replace("of:", "");
1625 Set ofDeviceIds = ((OvsdbSet) b.getDatapathIdColumn().data()).set();
1626 //TODO Set<String>
1627 return ofDeviceIds.contains(ofDpid);
1628 }
1629
1630 @Override
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001631 public Set<OvsdbPort> getPorts() {
Daniel Park24626382018-08-28 11:25:01 +09001632 return (Set<OvsdbPort>) getElements(this::getOvsdbPort);
1633 }
1634
1635 @Override
1636 public Set<Interface> getInterfaces() {
1637 return (Set<Interface>) getElements(this::getInterface);
1638 }
1639
1640 private Set<?> getElements(Function<Row, ?> method) {
Hyunsun Moon1251e192016-06-07 16:57:05 -07001641 OvsdbTableStore tableStore = getTableStore(DATABASENAME);
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001642 if (tableStore == null) {
1643 return null;
1644 }
Hyunsun Moon1251e192016-06-07 16:57:05 -07001645 OvsdbRowStore rowStore = tableStore.getRows(INTERFACE);
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001646 if (rowStore == null) {
1647 return null;
1648 }
1649 ConcurrentMap<String, Row> rows = rowStore.getRowStore();
Daniel Park24626382018-08-28 11:25:01 +09001650
1651 return rows.keySet()
kdarapu71f623c2018-05-10 19:37:53 +05301652 .stream()
1653 .map(uuid -> getRow(DATABASENAME, INTERFACE, uuid))
Daniel Park24626382018-08-28 11:25:01 +09001654 .map(method)
kdarapu71f623c2018-05-10 19:37:53 +05301655 .filter(Objects::nonNull)
1656 .collect(Collectors.toSet());
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001657 }
1658
1659 @Override
Daniel Park24626382018-08-28 11:25:01 +09001660 public Interface getInterface(String intf) {
1661 return getInterfaces().stream()
1662 .filter(ovsdbIntf -> ovsdbIntf.getName().equals(intf))
1663 .findAny().orElse(null);
1664 }
1665
1666 private Interface getInterface(Row row) {
1667 DatabaseSchema dbSchema = getDatabaseSchema(DATABASENAME);
1668 Interface intf = (Interface) TableGenerator
1669 .getTable(dbSchema, row, OvsdbTable.INTERFACE);
1670 if (intf == null) {
1671 return null;
1672 }
1673 return intf;
1674 }
1675 @Override
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001676 public DatabaseSchema getDatabaseSchema(String dbName) {
1677 return schema.get(dbName);
1678 }
1679
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001680 private OvsdbPort getOvsdbPort(Row row) {
Hyunsun Moon1251e192016-06-07 16:57:05 -07001681 DatabaseSchema dbSchema = getDatabaseSchema(DATABASENAME);
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001682 Interface intf = (Interface) TableGenerator
1683 .getTable(dbSchema, row, OvsdbTable.INTERFACE);
1684 if (intf == null) {
1685 return null;
1686 }
1687 long ofPort = getOfPort(intf);
1688 String portName = intf.getName();
1689 if ((ofPort < 0) || (portName == null)) {
1690 return null;
1691 }
Hyunsun Moon1251e192016-06-07 16:57:05 -07001692 return new OvsdbPort(new OvsdbPortNumber(ofPort), new OvsdbPortName(portName));
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001693 }
1694
jaegonkim7b77f712018-01-14 17:18:27 +09001695 private OvsdbBridge getOvsdbBridge(Row row, Uuid bridgeUuid) {
Hyunsun Moon1251e192016-06-07 16:57:05 -07001696 DatabaseSchema dbSchema = getDatabaseSchema(DATABASENAME);
1697 Bridge bridge = (Bridge) TableGenerator.getTable(dbSchema, row, OvsdbTable.BRIDGE);
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001698 if (bridge == null) {
1699 return null;
1700 }
1701
1702 OvsdbSet datapathIdSet = (OvsdbSet) bridge.getDatapathIdColumn().data();
1703 @SuppressWarnings("unchecked")
1704 Set<String> datapathIds = datapathIdSet.set();
Jon Hallcbd1b392017-01-18 20:15:44 -08001705 if (datapathIds == null || datapathIds.isEmpty()) {
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001706 return null;
1707 }
1708 String datapathId = (String) datapathIds.toArray()[0];
1709 String bridgeName = bridge.getName();
1710 if ((datapathId == null) || (bridgeName == null)) {
1711 return null;
1712 }
jaegonkim7b77f712018-01-14 17:18:27 +09001713
1714 List<Controller> controllers = getControllers(bridgeUuid);
1715
1716 if (controllers != null) {
1717 List<ControllerInfo> controllerInfos = controllers.stream().map(
1718 controller -> new ControllerInfo(
1719 (String) controller.getTargetColumn()
1720 .data())).collect(Collectors.toList());
1721
1722 return OvsdbBridge.builder()
1723 .name(bridgeName)
1724 .datapathId(datapathId)
1725 .controllers(controllerInfos)
1726 .build();
1727 } else {
1728 return OvsdbBridge.builder()
1729 .name(bridgeName)
1730 .datapathId(datapathId)
1731 .build();
1732 }
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001733 }
1734
Frank Wange11a98d2016-10-26 17:04:03 +08001735 private OvsdbQos getOvsdbQos(Row row) {
1736 DatabaseSchema dbSchema = getDatabaseSchema(DATABASENAME);
1737 Qos qos = (Qos) TableGenerator.getTable(dbSchema, row, OvsdbTable.QOS);
1738 if (qos == null) {
1739 return null;
1740 }
1741
1742 String type = (String) qos.getTypeColumn().data();
1743 Map<String, String> otherConfigs;
1744 Map<String, String> externalIds;
1745 Map<Long, String> queues;
1746
1747 otherConfigs = ((OvsdbMap) qos.getOtherConfigColumn().data()).map();
1748 externalIds = ((OvsdbMap) qos.getExternalIdsColumn().data()).map();
1749 queues = ((OvsdbMap) qos.getQueuesColumn().data()).map();
1750 return OvsdbQos.builder().qosType(type).
1751 queues(queues).otherConfigs(otherConfigs).
1752 externalIds(externalIds).build();
1753 }
1754
1755 private OvsdbQueue getOvsdbQueue(Row row) {
1756 DatabaseSchema dbSchema = getDatabaseSchema(DATABASENAME);
1757 Queue queue = (Queue) TableGenerator.getTable(dbSchema, row, OvsdbTable.QUEUE);
1758 if (queue == null) {
1759 return null;
1760 }
1761
1762 OvsdbSet dscpOvsdbSet = ((OvsdbSet) queue.getDscpColumn().data());
1763 @SuppressWarnings("unchecked")
1764 Set<String> dscpSet = dscpOvsdbSet.set();
1765 Long dscp = null;
1766 if (dscpSet != null && !dscpSet.isEmpty()) {
1767 dscp = Long.valueOf((String) dscpSet.toArray()[0]);
1768 }
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();
1849 this.agent.removeConnectedNode(nodeId);
1850 }
Saritha1583a6f2017-06-16 14:42:58 +05301851
1852 @Override
1853 public List<OvsdbPortName> getPorts(List<String> portNames, DeviceId deviceId) {
1854 Uuid bridgeUuid = getBridgeUuid(deviceId);
1855 if (bridgeUuid == null) {
1856 log.error("Can't find the bridge for the deviceId {}", deviceId);
1857 return Collections.emptyList();
1858 }
1859 DatabaseSchema dbSchema = schema.get(DATABASENAME);
1860 Row bridgeRow = getRow(DATABASENAME, BRIDGE, bridgeUuid.value());
1861 Bridge bridge = (Bridge) TableGenerator.getTable(dbSchema, bridgeRow, OvsdbTable.BRIDGE);
1862 if (bridge == null) {
1863 return Collections.emptyList();
1864 }
1865 OvsdbSet setPorts = (OvsdbSet) bridge.getPortsColumn().data();
1866 Set<Uuid> portSet = setPorts.set();
1867 if (portSet.isEmpty()) {
1868 return Collections.emptyList();
1869 }
1870
1871 Map<Uuid, Port> portMap = portSet.stream().collect(Collectors.toMap(
1872 java.util.function.Function.identity(), port -> (Port) TableGenerator
1873 .getTable(dbSchema, getRow(DATABASENAME,
1874 PORT, port.value()), OvsdbTable.PORT)));
1875
1876 List<OvsdbPortName> portList = portMap.entrySet().stream().filter(port -> Objects.nonNull(port.getValue())
1877 && portNames.contains(port.getValue().getName())
1878 && Objects.nonNull(getInterfacebyPort(port.getKey().value(), port.getValue().getName())))
1879 .map(port -> new OvsdbPortName(port.getValue().getName())).collect(Collectors.toList());
1880
1881 return Collections.unmodifiableList(portList);
1882 }
1883
1884 @Override
1885 public boolean getPortError(List<OvsdbPortName> portNames, DeviceId bridgeId) {
1886 Uuid bridgeUuid = getBridgeUuid(bridgeId);
1887
1888 List<Interface> interfaceList = portNames.stream().collect(Collectors
1889 .toMap(java.util.function.Function.identity(),
1890 port -> (Interface) getInterfacebyPort(getPortUuid(port.value(),
1891 bridgeUuid.value()), port.value())))
1892 .entrySet().stream().filter(intf -> Objects.nonNull(intf.getValue())
1893 && ((OvsdbSet) intf.getValue().getOpenFlowPortColumn().data()).set()
1894 .stream().findAny().orElse(OFPORT_ERROR_COMPARISON).equals(OFPORT_ERROR))
kdarapu71f623c2018-05-10 19:37:53 +05301895 .map(Map.Entry::getValue).collect(Collectors.toList());
Saritha1583a6f2017-06-16 14:42:58 +05301896
kdarapu71f623c2018-05-10 19:37:53 +05301897 interfaceList.forEach(intf -> ((Consumer<Interface>) intf1 -> {
1898 try {
1899 Set<String> setErrors = ((OvsdbSet) intf1.getErrorColumn().data()).set();
1900 log.info("Port has errors. ofport value - {}, Interface - {} has error - {} ",
1901 intf1.getOpenFlowPortColumn().data(), intf1.getName(), setErrors.stream()
1902 .findFirst().get());
1903 } catch (ColumnSchemaNotFoundException | VersionMismatchException e) {
1904 log.debug("Port has errors. ofport value - {}, Interface - {} has error - {} ",
1905 intf1.getOpenFlowPortColumn().data(), intf1.getName(), e);
Saritha1583a6f2017-06-16 14:42:58 +05301906 }
kdarapu71f623c2018-05-10 19:37:53 +05301907 }).accept(intf));
Saritha1583a6f2017-06-16 14:42:58 +05301908
1909 return !interfaceList.isEmpty();
1910 }
1911
1912 private Interface getInterfacebyPort(String portUuid, String portName) {
1913 DatabaseSchema dbSchema = schema.get(DATABASENAME);
1914
1915 Row portRow = getRow(DATABASENAME, PORT, portUuid);
1916 Port port = (Port) TableGenerator.getTable(dbSchema, portRow,
1917 OvsdbTable.PORT);
1918 if (port == null) {
1919 return null;
1920 }
1921
1922 OvsdbSet setInterfaces = (OvsdbSet) port.getInterfacesColumn().data();
1923 Set<Uuid> interfaces = setInterfaces.set();
1924
1925 return interfaces.stream().map(intf -> (Interface) TableGenerator
1926 .getTable(dbSchema, getRow(DATABASENAME,
1927 INTERFACE, intf.value()), OvsdbTable.INTERFACE))
1928 .filter(intf -> Objects.nonNull(intf) && portName.equalsIgnoreCase(intf.getName()))
1929 .findFirst().orElse(null);
1930 }
nitinanand9e8f8362018-05-31 15:11:04 +05301931
1932 /**
1933 * Get first row of given table from given db.
1934 *
1935 * @param dbName db name
1936 * @param tblName table name
1937 * @return firstRow, first row of the given table from given db if present
1938 */
1939 @Override
1940 public Optional<Object> getFirstRow(String dbName, OvsdbTable tblName) {
1941
1942 DatabaseSchema dbSchema = getDatabaseSchema(dbName);
1943 if (Objects.isNull(dbSchema)) {
1944 return Optional.empty();
1945 }
1946
1947 OvsdbTableStore tableStore = ovsdbStore.getOvsdbTableStore(dbName);
1948 if (tableStore == null) {
1949 return Optional.empty();
1950 }
1951 OvsdbRowStore rowStore = tableStore.getRows(tblName.tableName());
1952 if (rowStore == null) {
1953 return Optional.empty();
1954 }
1955
1956 ConcurrentMap<String, Row> rows = rowStore.getRowStore();
1957 if (rows == null) {
1958 log.debug("The {} Table Rows is null", tblName);
1959 return Optional.empty();
1960 }
1961
1962 // There should be only 1 row in this table
1963 Optional<String> uuid = rows.keySet().stream().findFirst();
1964 if (uuid.isPresent() && rows.containsKey(uuid.get())) {
1965 return Optional.of(TableGenerator.getTable(dbSchema,
1966 rows.get(uuid.get()), tblName));
1967 } else {
1968 return Optional.empty();
1969 }
1970 }
1971
1972
1973 /**
1974 * Get memory usage of device.
1975 *
1976 * @return memoryStats, empty data as there is no generic way to fetch such stats
1977 */
1978 @Override
1979 public Optional<DeviceMemoryStats> getDeviceMemoryUsage() {
1980 return Optional.empty();
1981 }
1982
1983
1984 /**
1985 * Get cpu usage of device.
1986 *
1987 * @return cpuStats, empty data as there is no generic way to fetch such stats
1988 */
1989 @Override
1990 public Optional<DeviceCpuStats> getDeviceCpuUsage() {
1991 return Optional.empty();
1992 }
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001993}