blob: 38f8ede2bde5fd040a8852fb7bd9d2aed4d6a85d [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;
nitinanandf14dccd2018-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
Jonathan Hart6523e122017-11-14 09:23:49 -0800109import static org.onosproject.ovsdb.controller.OvsdbConstant.*;
Hyunsun Moon1251e192016-06-07 16:57:05 -0700110
Sho SHIMIZUe4efe452015-08-26 15:06:55 -0700111/**
112 * An representation of an ovsdb client.
113 */
Hyunsun Moon1251e192016-06-07 16:57:05 -0700114public class DefaultOvsdbClient implements OvsdbProviderService, OvsdbClientService {
Sho SHIMIZUe4efe452015-08-26 15:06:55 -0700115
jaegonkim01d7c912017-01-22 22:03:38 +0900116 private static final int TRANSACTCONFIG_TIMEOUT = 3; //sec
Saritha1583a6f2017-06-16 14:42:58 +0530117 private static final int OFPORT_ERROR_COMPARISON = 0;
jaegonkim01d7c912017-01-22 22:03:38 +0900118
Hyunsun Moon1251e192016-06-07 16:57:05 -0700119 private final Logger log = LoggerFactory.getLogger(DefaultOvsdbClient.class);
Sho SHIMIZUe4efe452015-08-26 15:06:55 -0700120
121 private Channel channel;
Sho SHIMIZUe4efe452015-08-26 15:06:55 -0700122 private OvsdbAgent agent;
123 private boolean connected;
124 private OvsdbNodeId nodeId;
125 private Callback monitorCallBack;
Sho SHIMIZUe4efe452015-08-26 15:06:55 -0700126 private OvsdbStore ovsdbStore = new OvsdbStore();
127
128 private final Map<String, String> requestMethod = Maps.newHashMap();
Hyunsun Moon1251e192016-06-07 16:57:05 -0700129 private final Map<String, SettableFuture<? extends Object>> requestResult = Maps.newHashMap();
Sho SHIMIZUe4efe452015-08-26 15:06:55 -0700130 private final Map<String, DatabaseSchema> schema = Maps.newHashMap();
Sho SHIMIZUe4efe452015-08-26 15:06:55 -0700131
Pier Ventref5d72362016-07-17 12:02:14 +0200132
Sho SHIMIZUe4efe452015-08-26 15:06:55 -0700133 /**
134 * Creates an OvsdbClient.
135 *
136 * @param nodeId ovsdb node id
137 */
138 public DefaultOvsdbClient(OvsdbNodeId nodeId) {
139 this.nodeId = nodeId;
140 }
141
142 @Override
143 public OvsdbNodeId nodeId() {
144 return nodeId;
145 }
146
147 @Override
148 public void setAgent(OvsdbAgent agent) {
149 if (this.agent == null) {
150 this.agent = agent;
151 }
152 }
153
154 @Override
155 public void setChannel(Channel channel) {
156 this.channel = channel;
157 }
158
159 @Override
160 public void setConnection(boolean connected) {
161 this.connected = connected;
162 }
163
164 @Override
165 public boolean isConnected() {
166 return this.connected;
167 }
168
169 @Override
170 public void nodeAdded() {
171 this.agent.addConnectedNode(nodeId, this);
172 }
173
174 @Override
175 public void nodeRemoved() {
176 this.agent.removeConnectedNode(nodeId);
177 channel.disconnect();
178 }
179
180 /**
181 * Gets the ovsdb table store.
182 *
183 * @param dbName the ovsdb database name
184 * @return ovsTableStore, empty if table store is find
185 */
186 private OvsdbTableStore getTableStore(String dbName) {
187 if (ovsdbStore == null) {
188 return null;
189 }
190 return ovsdbStore.getOvsdbTableStore(dbName);
191 }
192
193 /**
194 * Gets the ovsdb row store.
195 *
andreaed976a42015-10-05 14:38:25 -0700196 * @param dbName the ovsdb database name
Sho SHIMIZUe4efe452015-08-26 15:06:55 -0700197 * @param tableName the ovsdb table name
Hyunsun Moon6125c612015-10-15 10:54:44 -0700198 * @return ovsRowStore, empty store if no rows exist in the table
Sho SHIMIZUe4efe452015-08-26 15:06:55 -0700199 */
200 private OvsdbRowStore getRowStore(String dbName, String tableName) {
201 OvsdbTableStore tableStore = getTableStore(dbName);
202 if (tableStore == null) {
203 return null;
204 }
Hyunsun Moon6125c612015-10-15 10:54:44 -0700205
206 OvsdbRowStore rowStore = tableStore.getRows(tableName);
207 if (rowStore == null) {
208 rowStore = new OvsdbRowStore();
209 }
210 return rowStore;
Sho SHIMIZUe4efe452015-08-26 15:06:55 -0700211 }
212
213 /**
214 * Gets the ovsdb row.
215 *
andreaed976a42015-10-05 14:38:25 -0700216 * @param dbName the ovsdb database name
Sho SHIMIZUe4efe452015-08-26 15:06:55 -0700217 * @param tableName the ovsdb table name
andreaed976a42015-10-05 14:38:25 -0700218 * @param uuid the key of the row
Sho SHIMIZUe4efe452015-08-26 15:06:55 -0700219 * @return row, empty if row is find
220 */
221 @Override
222 public Row getRow(String dbName, String tableName, String uuid) {
223 OvsdbTableStore tableStore = getTableStore(dbName);
224 if (tableStore == null) {
225 return null;
226 }
227 OvsdbRowStore rowStore = tableStore.getRows(tableName);
228 if (rowStore == null) {
229 return null;
230 }
231 return rowStore.getRow(uuid);
232 }
233
234 @Override
235 public void removeRow(String dbName, String tableName, String uuid) {
236 OvsdbTableStore tableStore = getTableStore(dbName);
237 if (tableStore == null) {
238 return;
239 }
240 OvsdbRowStore rowStore = tableStore.getRows(tableName);
241 if (rowStore == null) {
242 return;
243 }
244 rowStore.deleteRow(uuid);
245 }
246
247 @Override
248 public void updateOvsdbStore(String dbName, String tableName, String uuid,
249 Row row) {
250 OvsdbTableStore tableStore = ovsdbStore.getOvsdbTableStore(dbName);
251 if (tableStore == null) {
252 tableStore = new OvsdbTableStore();
253 }
254 OvsdbRowStore rowStore = tableStore.getRows(tableName);
255 if (rowStore == null) {
256 rowStore = new OvsdbRowStore();
257 }
258 rowStore.insertRow(uuid, row);
259 tableStore.createOrUpdateTable(tableName, rowStore);
260 ovsdbStore.createOrUpdateOvsdbStore(dbName, tableStore);
261 }
262
Pier Ventref5d72362016-07-17 12:02:14 +0200263 /**
264 * Gets the Mirror uuid.
265 *
266 * @param mirrorName mirror name
267 * @return mirror uuid, empty if no uuid is found
268 */
269 @Override
270 public String getMirrorUuid(String mirrorName) {
271 DatabaseSchema dbSchema = schema.get(DATABASENAME);
272 OvsdbRowStore rowStore = getRowStore(DATABASENAME, MIRROR);
273 if (rowStore == null) {
274 log.warn("The mirror uuid is null");
275 return null;
276 }
277
278 ConcurrentMap<String, Row> mirrorTableRows = rowStore.getRowStore();
279 if (mirrorTableRows == null) {
280 log.warn("The mirror uuid is null");
281 return null;
282 }
283
284 for (String uuid : mirrorTableRows.keySet()) {
285 Mirror mirror = (Mirror) TableGenerator
286 .getTable(dbSchema, mirrorTableRows.get(uuid), OvsdbTable.MIRROR);
287 String name = mirror.getName();
288 if (name.contains(mirrorName)) {
289 return uuid;
290 }
291 }
292 log.warn("Mirroring not found");
293 return null;
294 }
295
296 /**
297 * Gets mirrors of the device.
298 *
299 * @param deviceId target device id
300 * @return set of mirroring; empty if no mirror is found
301 */
302 @Override
303 public Set<MirroringStatistics> getMirroringStatistics(DeviceId deviceId) {
304 Uuid bridgeUuid = getBridgeUuid(deviceId);
305 if (bridgeUuid == null) {
306 log.warn("Couldn't find bridge {} in {}", deviceId, nodeId.getIpAddress());
307 return null;
308 }
309
310 List<MirroringStatistics> mirrorings = getMirrorings(bridgeUuid);
311 if (mirrorings == null) {
312 log.warn("Couldn't find mirrors in {}", nodeId.getIpAddress());
313 return null;
314 }
315 return ImmutableSet.copyOf(mirrorings);
316 }
317
318 /**
319 * Helper method which retrieves mirrorings statistics using bridge uuid.
320 *
321 * @param bridgeUuid the uuid of the bridge
322 * @return the list of the mirrorings statistics.
323 */
324 private List<MirroringStatistics> getMirrorings(Uuid bridgeUuid) {
325 DatabaseSchema dbSchema = schema.get(DATABASENAME);
326 if (dbSchema == null) {
327 log.warn("Unable to retrieve dbSchema {}", DATABASENAME);
328 return null;
329 }
330 OvsdbRowStore rowStore = getRowStore(DATABASENAME, BRIDGE);
331 if (rowStore == null) {
332 log.warn("Unable to retrieve rowStore {} of {}", BRIDGE, DATABASENAME);
333 return null;
334 }
335
336 Row bridgeRow = rowStore.getRow(bridgeUuid.value());
337 Bridge bridge = (Bridge) TableGenerator.
338 getTable(dbSchema, bridgeRow, OvsdbTable.BRIDGE);
339
340 Set<Uuid> mirroringsUuids = (Set<Uuid>) ((OvsdbSet) bridge
341 .getMirrorsColumn().data()).set();
342
343 OvsdbRowStore mirrorRowStore = getRowStore(DATABASENAME, MIRROR);
344 if (mirrorRowStore == null) {
345 log.warn("Unable to retrieve rowStore {} of {}", MIRROR, DATABASENAME);
346 return null;
347 }
348
349 List<MirroringStatistics> mirroringStatistics = new ArrayList<>();
350 ConcurrentMap<String, Row> mirrorTableRows = mirrorRowStore.getRowStore();
351 mirrorTableRows.forEach((key, row) -> {
352 if (!mirroringsUuids.contains(Uuid.uuid(key))) {
353 return;
354 }
355 Mirror mirror = (Mirror) TableGenerator
356 .getTable(dbSchema, row, OvsdbTable.MIRROR);
357 mirroringStatistics.add(MirroringStatistics.mirroringStatistics(mirror.getName(),
358 (Map<String, Integer>) ((OvsdbMap) mirror
359 .getStatisticsColumn().data()).map()));
360 });
361 return ImmutableList.copyOf(mirroringStatistics);
362 }
363
Sho SHIMIZUe4efe452015-08-26 15:06:55 -0700364 @Override
365 public String getPortUuid(String portName, String bridgeUuid) {
Hyunsun Moon1251e192016-06-07 16:57:05 -0700366 DatabaseSchema dbSchema = schema.get(DATABASENAME);
Sho SHIMIZUe4efe452015-08-26 15:06:55 -0700367
Hyunsun Moon1251e192016-06-07 16:57:05 -0700368 Row bridgeRow = getRow(DATABASENAME, BRIDGE, bridgeUuid);
Sho SHIMIZUe4efe452015-08-26 15:06:55 -0700369 Bridge bridge = (Bridge) TableGenerator.getTable(dbSchema, bridgeRow,
370 OvsdbTable.BRIDGE);
371 if (bridge != null) {
372 OvsdbSet setPorts = (OvsdbSet) bridge.getPortsColumn().data();
373 @SuppressWarnings("unchecked")
Jonathan Hart51539b82015-10-29 09:53:04 -0700374 Set<Uuid> ports = setPorts.set();
Jon Hallcbd1b392017-01-18 20:15:44 -0800375 if (ports == null || ports.isEmpty()) {
Sho SHIMIZUe4efe452015-08-26 15:06:55 -0700376 log.warn("The port uuid is null");
377 return null;
378 }
379
Jonathan Hart51539b82015-10-29 09:53:04 -0700380 for (Uuid uuid : ports) {
Hyunsun Moon1251e192016-06-07 16:57:05 -0700381 Row portRow = getRow(DATABASENAME, PORT, uuid.value());
Sho SHIMIZUe4efe452015-08-26 15:06:55 -0700382 Port port = (Port) TableGenerator.getTable(dbSchema, portRow,
383 OvsdbTable.PORT);
384 if (port != null && portName.equalsIgnoreCase(port.getName())) {
385 return uuid.value();
386 }
387 }
Sho SHIMIZUe4efe452015-08-26 15:06:55 -0700388 }
389 return null;
390 }
391
392 @Override
Sho SHIMIZUe4efe452015-08-26 15:06:55 -0700393 public String getBridgeUuid(String bridgeName) {
Hyunsun Moon1251e192016-06-07 16:57:05 -0700394 DatabaseSchema dbSchema = schema.get(DATABASENAME);
Hyunsun Moon1251e192016-06-07 16:57:05 -0700395 OvsdbRowStore rowStore = getRowStore(DATABASENAME, BRIDGE);
Sho SHIMIZUe4efe452015-08-26 15:06:55 -0700396 if (rowStore == null) {
397 log.debug("The bridge uuid is null");
398 return null;
399 }
400
401 ConcurrentMap<String, Row> bridgeTableRows = rowStore.getRowStore();
402 if (bridgeTableRows == null) {
403 log.debug("The bridge uuid is null");
404 return null;
405 }
406
407 for (String uuid : bridgeTableRows.keySet()) {
408 Bridge bridge = (Bridge) TableGenerator
Hyunsun Moon1251e192016-06-07 16:57:05 -0700409 .getTable(dbSchema, bridgeTableRows.get(uuid), OvsdbTable.BRIDGE);
Sho SHIMIZUe4efe452015-08-26 15:06:55 -0700410 if (bridge.getName().equals(bridgeName)) {
411 return uuid;
412 }
Sho SHIMIZUe4efe452015-08-26 15:06:55 -0700413 }
414 return null;
415 }
416
Hyunsun Moondd14e8e2016-06-09 16:17:32 -0700417 private String getOvsUuid(String dbName) {
Hyunsun Moon1251e192016-06-07 16:57:05 -0700418 OvsdbRowStore rowStore = getRowStore(DATABASENAME, DATABASENAME);
Sho SHIMIZUe4efe452015-08-26 15:06:55 -0700419 if (rowStore == null) {
420 log.debug("The bridge uuid is null");
421 return null;
422 }
423 ConcurrentMap<String, Row> ovsTableRows = rowStore.getRowStore();
424 if (ovsTableRows != null) {
425 for (String uuid : ovsTableRows.keySet()) {
426 Row row = ovsTableRows.get(uuid);
427 String tableName = row.tableName();
428 if (tableName.equals(dbName)) {
429 return uuid;
430 }
431 }
432 }
433 return null;
434 }
435
436 @Override
437 public void createPort(String bridgeName, String portName) {
438 String bridgeUuid = getBridgeUuid(bridgeName);
439 if (bridgeUuid == null) {
Hyunsun Moon1251e192016-06-07 16:57:05 -0700440 log.error("Can't find bridge {} in {}", bridgeName, nodeId.getIpAddress());
Sho SHIMIZUe4efe452015-08-26 15:06:55 -0700441 return;
442 }
443
Hyunsun Moon1251e192016-06-07 16:57:05 -0700444 DatabaseSchema dbSchema = schema.get(DATABASENAME);
Sho SHIMIZUe4efe452015-08-26 15:06:55 -0700445 String portUuid = getPortUuid(portName, bridgeUuid);
Hyunsun Moon1251e192016-06-07 16:57:05 -0700446 Port port = (Port) TableGenerator.createTable(dbSchema, OvsdbTable.PORT);
Sho SHIMIZUe4efe452015-08-26 15:06:55 -0700447 port.setName(portName);
448 if (portUuid == null) {
Hyunsun Moon1251e192016-06-07 16:57:05 -0700449 insertConfig(PORT, UUID, BRIDGE, PORTS, bridgeUuid, port.getRow());
Sho SHIMIZUe4efe452015-08-26 15:06:55 -0700450 }
Sho SHIMIZUe4efe452015-08-26 15:06:55 -0700451 }
452
453 @Override
454 public void dropPort(String bridgeName, String portName) {
455 String bridgeUuid = getBridgeUuid(bridgeName);
456 if (bridgeUuid == null) {
457 log.error("Could not find Bridge {} in {}", bridgeName, nodeId);
458 return;
459 }
460
461 String portUuid = getPortUuid(portName, bridgeUuid);
462 if (portUuid != null) {
463 log.info("Port {} delete", portName);
Frank Wange11a98d2016-10-26 17:04:03 +0800464 deleteConfig(PORT, UUID, portUuid, BRIDGE, PORTS, Uuid.uuid(portUuid));
Sho SHIMIZUe4efe452015-08-26 15:06:55 -0700465 }
466 }
467
lishuai6c56f5e2015-11-17 16:38:19 +0800468 @Override
Hyunsun Moon1251e192016-06-07 16:57:05 -0700469 public boolean createBridge(OvsdbBridge ovsdbBridge) {
470 DatabaseSchema dbSchema = schema.get(DATABASENAME);
471 String ovsUuid = getOvsUuid(DATABASENAME);
Hyunsun Moon646d8c42015-10-08 20:32:44 -0700472
473 if (dbSchema == null || ovsUuid == null) {
Hyunsun Moon1251e192016-06-07 16:57:05 -0700474 log.error("Can't find database Open_vSwitch");
Hyunsun Moon646d8c42015-10-08 20:32:44 -0700475 return false;
476 }
477
Hyunsun Moon646d8c42015-10-08 20:32:44 -0700478 Bridge bridge = (Bridge) TableGenerator.createTable(dbSchema, OvsdbTable.BRIDGE);
Hyunsun Moon1251e192016-06-07 16:57:05 -0700479 bridge.setOtherConfig(ovsdbBridge.otherConfigs());
Hyunsun Moon646d8c42015-10-08 20:32:44 -0700480
Hyunsun Moon1251e192016-06-07 16:57:05 -0700481 if (ovsdbBridge.failMode().isPresent()) {
482 String failMode = ovsdbBridge.failMode().get().name().toLowerCase();
483 bridge.setFailMode(Sets.newHashSet(failMode));
Bob zhoue9795fd2016-05-12 20:18:45 +0800484 }
Hyunsun Moon646d8c42015-10-08 20:32:44 -0700485
jaegonkim80bee532017-05-15 15:16:38 +0900486 if (ovsdbBridge.datapathType().isPresent()) {
487 String datapathType = ovsdbBridge.datapathType().get();
488 bridge.setDatapathType(datapathType);
489 }
490
rohitsharana127ba82018-01-16 02:17:30 +0530491 if (ovsdbBridge.controlProtocols().isPresent()) {
492 bridge.setProtocols(ovsdbBridge.controlProtocols().get().stream()
493 .map(ControlProtocolVersion::toString)
494 .collect(Collectors.toCollection(HashSet::new)));
495 }
496
Hyunsun Moon1251e192016-06-07 16:57:05 -0700497 String bridgeUuid = getBridgeUuid(ovsdbBridge.name());
Hyunsun Moon98025542016-03-08 04:36:02 -0800498 if (bridgeUuid == null) {
Hyunsun Moon1251e192016-06-07 16:57:05 -0700499 bridge.setName(ovsdbBridge.name());
500 bridgeUuid = insertConfig(
501 BRIDGE, UUID, DATABASENAME, BRIDGES,
502 ovsUuid, bridge.getRow());
Hyunsun Moon98025542016-03-08 04:36:02 -0800503 } else {
Hyunsun Moon1251e192016-06-07 16:57:05 -0700504 // update the bridge if it's already existing
505 updateConfig(BRIDGE, UUID, bridgeUuid, bridge.getRow());
Hyunsun Moon98025542016-03-08 04:36:02 -0800506 }
Hyunsun Moon646d8c42015-10-08 20:32:44 -0700507
Hyunsun Moon1251e192016-06-07 16:57:05 -0700508 if (bridgeUuid == null) {
509 log.warn("Failed to create bridge {} on {}", ovsdbBridge.name(), nodeId);
Hyunsun Moon646d8c42015-10-08 20:32:44 -0700510 return false;
511 }
512
Hyunsun Moon1251e192016-06-07 16:57:05 -0700513 createPort(ovsdbBridge.name(), ovsdbBridge.name());
514 setControllersWithUuid(Uuid.uuid(bridgeUuid), ovsdbBridge.controllers());
515
516 log.info("Created bridge {}", ovsdbBridge.name());
Hyunsun Moon646d8c42015-10-08 20:32:44 -0700517 return true;
518 }
519
Hyunsun Moon1251e192016-06-07 16:57:05 -0700520 @Override
521 public ControllerInfo localController() {
522 IpAddress ipAddress = IpAddress.valueOf(((InetSocketAddress)
523 channel.localAddress()).getAddress());
524 return new ControllerInfo(ipAddress, OFPORT, "tcp");
andreaed976a42015-10-05 14:38:25 -0700525 }
526
Hyunsun Moondd14e8e2016-06-09 16:17:32 -0700527 private void setControllersWithUuid(Uuid bridgeUuid, List<ControllerInfo> controllers) {
Hyunsun Moon1251e192016-06-07 16:57:05 -0700528 DatabaseSchema dbSchema = schema.get(DATABASENAME);
andreaed976a42015-10-05 14:38:25 -0700529 if (dbSchema == null) {
530 log.debug("There is no schema");
531 return;
532 }
533 List<Controller> oldControllers = getControllers(bridgeUuid);
534 if (oldControllers == null) {
535 log.warn("There are no controllers");
536 return;
537 }
538
andreaed976a42015-10-05 14:38:25 -0700539 Set<ControllerInfo> newControllers = new HashSet<>(controllers);
540 List<Controller> removeControllers = new ArrayList<>();
541 oldControllers.forEach(controller -> {
542 ControllerInfo controllerInfo = new ControllerInfo((String) controller.getTargetColumn().data());
543 if (newControllers.contains(controllerInfo)) {
544 newControllers.remove(controllerInfo);
andreaed976a42015-10-05 14:38:25 -0700545 } else {
546 removeControllers.add(controller);
547 }
548 });
Hyunsun Moon1251e192016-06-07 16:57:05 -0700549 OvsdbRowStore controllerRowStore = getRowStore(DATABASENAME, CONTROLLER);
andreaed976a42015-10-05 14:38:25 -0700550 if (controllerRowStore == null) {
551 log.debug("There is no controller table");
552 return;
553 }
554
Hyunsun Moon1251e192016-06-07 16:57:05 -0700555 removeControllers.forEach(c -> deleteConfig(CONTROLLER, UUID, c.getRow().uuid().value(),
Saritha8a0c36a2017-07-04 15:01:35 +0530556 BRIDGE, BRIDGE_CONTROLLER, c.getRow().uuid()));
andreaed976a42015-10-05 14:38:25 -0700557 newControllers.stream().map(c -> {
558 Controller controller = (Controller) TableGenerator
559 .createTable(dbSchema, OvsdbTable.CONTROLLER);
560 controller.setTarget(c.target());
561 return controller;
tanbangcheng62cd4492017-11-24 21:57:05 +0800562 }).forEach(c -> insertConfig(CONTROLLER, UUID, BRIDGE, BRIDGE_CONTROLLER,
563 bridgeUuid.value(),
564 c.getRow()));
andreaed976a42015-10-05 14:38:25 -0700565
andreaed976a42015-10-05 14:38:25 -0700566 }
567
andreaed976a42015-10-05 14:38:25 -0700568 @Override
569 public void setControllersWithDeviceId(DeviceId deviceId, List<ControllerInfo> controllers) {
Jonathan Hart51539b82015-10-29 09:53:04 -0700570 setControllersWithUuid(getBridgeUuid(deviceId), controllers);
andreaed976a42015-10-05 14:38:25 -0700571 }
572
Sho SHIMIZUe4efe452015-08-26 15:06:55 -0700573 @Override
574 public void dropBridge(String bridgeName) {
Jonathan Hart51539b82015-10-29 09:53:04 -0700575 String bridgeUuid = getBridgeUuid(bridgeName);
576 if (bridgeUuid == null) {
Sho SHIMIZUe4efe452015-08-26 15:06:55 -0700577 log.warn("Could not find bridge in node", nodeId.getIpAddress());
578 return;
579 }
Frank Wange11a98d2016-10-26 17:04:03 +0800580 deleteConfig(BRIDGE, UUID, bridgeUuid, DATABASENAME, BRIDGES, Uuid.uuid(bridgeUuid));
Hyunsun Moondd14e8e2016-06-09 16:17:32 -0700581 }
582
Frank Wange11a98d2016-10-26 17:04:03 +0800583 @Override
584 public void applyQos(PortNumber portNumber, String qosName) {
585 DatabaseSchema dbSchema = schema.get(DATABASENAME);
586 OvsdbRowStore portRowStore = getRowStore(DATABASENAME, PORT);
587 if (portRowStore == null) {
588 log.debug("The port uuid is null");
589 return;
590 }
591 OvsdbRowStore qosRowStore = getRowStore(DATABASENAME, QOS);
592 if (qosRowStore == null) {
593 log.debug("The qos uuid is null");
594 return;
595 }
596
597 // Due to Qos Table doesn't have a unique identifier except uuid, unlike
598 // Bridge or Port Table has a name column,in order to make the api more
599 // general, put qos name in external_ids column of Qos Table if this qos
600 // created by onos.
601 ConcurrentMap<String, Row> qosTableRows = qosRowStore.getRowStore();
602 ConcurrentMap<String, Row> portTableRows = portRowStore.getRowStore();
603 Row qosRow = qosTableRows.values().stream().filter(r -> {
604 OvsdbMap ovsdbMap = (OvsdbMap) (r.getColumn(EXTERNAL_ID).data());
605 return qosName.equals(ovsdbMap.map().get(QOS_EXTERNAL_ID_KEY));
606 }).findFirst().orElse(null);
607
608 Row portRow = portTableRows.values().stream()
609 .filter(r -> r.getColumn("name").data().equals(portNumber.name()))
610 .findFirst().orElse(null);
611 if (portRow != null && qosRow != null) {
612 String qosId = qosRow.uuid().value();
613 Uuid portUuid = portRow.uuid();
614 Map<String, Column> columns = new HashMap<>();
615 Row newPortRow = new Row(PORT, portUuid, columns);
616 Port newport = new Port(dbSchema, newPortRow);
617 columns.put(Port.PortColumn.QOS.columnName(), newport.getQosColumn());
618 newport.setQos(Uuid.uuid(qosId));
619 updateConfig(PORT, UUID, portUuid.value(), newport.getRow());
620 }
621 }
622
623 @Override
624 public void removeQos(PortNumber portNumber) {
625 DatabaseSchema dbSchema = schema.get(DATABASENAME);
626 OvsdbRowStore rowStore = getRowStore(DATABASENAME, PORT);
627 if (rowStore == null) {
628 log.debug("The qos uuid is null");
629 return;
630 }
631
632 ConcurrentMap<String, Row> ovsTableRows = rowStore.getRowStore();
633 Row portRow = ovsTableRows.values().stream()
634 .filter(r -> r.getColumn("name").data().equals(portNumber.name()))
635 .findFirst().orElse(null);
636 if (portRow == null) {
637 log.warn("Couldn't find port {} in ovsdb port table.", portNumber.name());
638 return;
639 }
640
641 OvsdbSet ovsdbSet = ((OvsdbSet) portRow.getColumn(PORT_QOS).data());
642 @SuppressWarnings("unchecked")
643 Set<Uuid> qosIdSet = ovsdbSet.set();
644 if (qosIdSet == null || qosIdSet.isEmpty()) {
645 return;
646 }
647 Uuid qosUuid = (Uuid) qosIdSet.toArray()[0];
648 Condition condition = ConditionUtil.isEqual(UUID, portRow.uuid());
649 List<Condition> conditions = Lists.newArrayList(condition);
650 Mutation mutation = MutationUtil.delete(PORT_QOS, qosUuid);
651 List<Mutation> mutations = Lists.newArrayList(mutation);
652
653 ArrayList<Operation> operations = Lists.newArrayList();
654 Mutate mutate = new Mutate(dbSchema.getTableSchema(PORT), conditions, mutations);
655 operations.add(mutate);
656 transactConfig(DATABASENAME, operations);
657 }
658
659 @Override
660 public boolean createQos(OvsdbQos ovsdbQos) {
661 DatabaseSchema dbSchema = schema.get(DATABASENAME);
662 Qos qos = (Qos) TableGenerator.createTable(dbSchema, OvsdbTable.QOS);
663 OvsdbRowStore rowStore = getRowStore(DATABASENAME, QOS);
664 if (rowStore == null) {
665 log.debug("The qos uuid is null");
666 return false;
667 }
668
669 ArrayList<Operation> operations = Lists.newArrayList();
670 Set<String> types = Sets.newHashSet();
671 Map<Long, Uuid> queues = Maps.newHashMap();
672
673 types.add(ovsdbQos.qosType());
674 qos.setOtherConfig(ovsdbQos.otherConfigs());
675 qos.setExternalIds(ovsdbQos.externalIds());
676 qos.setType(types);
677 if (ovsdbQos.qosQueues().isPresent()) {
678 for (Map.Entry<Long, String> entry : ovsdbQos.qosQueues().get().entrySet()) {
679 OvsdbRowStore queueRowStore = getRowStore(DATABASENAME, QUEUE);
680 if (queueRowStore != null) {
681 ConcurrentMap<String, Row> queueTableRows = queueRowStore.getRowStore();
682 Row queueRow = queueTableRows.values().stream().filter(r -> {
683 OvsdbMap ovsdbMap = (OvsdbMap) (r.getColumn(EXTERNAL_ID).data());
684 return entry.getValue().equals(ovsdbMap.map().get(QUEUE_EXTERNAL_ID_KEY));
685 }).findFirst().orElse(null);
686 if (queueRow != null) {
687 queues.put(entry.getKey(), queueRow.uuid());
688 }
689 }
690 }
691 qos.setQueues(queues);
692 }
693
694 Insert qosInsert = new Insert(dbSchema.getTableSchema(QOS), QOS, qos.getRow());
695 operations.add(qosInsert);
696 try {
697 transactConfig(DATABASENAME, operations).get();
698 } catch (InterruptedException | ExecutionException e) {
699 return false;
700 }
701 return true;
702 }
703
704 @Override
705 public void dropQos(QosId qosId) {
706 OvsdbRowStore rowStore = getRowStore(DATABASENAME, QOS);
707 if (rowStore != null) {
708 ConcurrentMap<String, Row> qosTableRows = rowStore.getRowStore();
709 Row qosRow = qosTableRows.values().stream().filter(r -> {
710 OvsdbMap ovsdbMap = (OvsdbMap) (r.getColumn(EXTERNAL_ID).data());
711 return qosId.name().equals(ovsdbMap.map().get(QOS_EXTERNAL_ID_KEY));
712 }).findFirst().orElse(null);
713 if (qosRow != null) {
714 deleteConfig(QOS, UUID, qosRow.uuid().value(), PORT, PORT_QOS, qosRow.uuid());
715 }
716 }
717 }
718 @Override
719 public OvsdbQos getQos(QosId qosId) {
720 Set<OvsdbQos> ovsdbQoses = getQoses();
721 return ovsdbQoses.stream().filter(r ->
722 qosId.name().equals(r.externalIds().get(QOS_EXTERNAL_ID_KEY))).
723 findFirst().orElse(null);
724 }
725
726 @Override
727 public Set<OvsdbQos> getQoses() {
728 Set<OvsdbQos> ovsdbQoses = new HashSet<>();
729 OvsdbRowStore rowStore = getRowStore(DATABASENAME, QOS);
730 if (rowStore == null) {
731 log.debug("The qos uuid is null");
732 return ovsdbQoses;
733 }
734 ConcurrentMap<String, Row> rows = rowStore.getRowStore();
kdarapufce5abb2018-05-10 19:37:53 +0530735 ovsdbQoses = rows.keySet().stream()
736 .map(uuid -> getRow(DATABASENAME, QOS, uuid))
737 .map(this::getOvsdbQos)
738 .filter(Objects::nonNull)
739 .collect(Collectors.toSet());
Frank Wange11a98d2016-10-26 17:04:03 +0800740 return ovsdbQoses;
741 }
742
743 @Override
tanbangchengc944c282017-11-12 20:42:59 +0800744 public void bindQueues(QosId qosId, Map<Long, QueueDescription> queues) {
745 DatabaseSchema dbSchema = schema.get(DATABASENAME);
746 OvsdbRowStore qosRowStore = getRowStore(DATABASENAME, QOS);
747 if (qosRowStore == null) {
748 log.debug("The qos uuid is null");
749 return;
750 }
751 OvsdbRowStore queueRowStore = getRowStore(DATABASENAME, QUEUE);
752 if (queueRowStore == null) {
753 log.debug("The queue uuid is null");
754 return;
755 }
756
757 ConcurrentMap<String, Row> qosTableRows = qosRowStore.getRowStore();
758 ConcurrentMap<String, Row> queueTableRows = queueRowStore.getRowStore();
759
760 Row qosRow = qosTableRows.values().stream().filter(r -> {
761 OvsdbMap ovsdbMap = (OvsdbMap) (r.getColumn(EXTERNAL_ID).data());
762 return qosId.name().equals(ovsdbMap.map().get(QOS_EXTERNAL_ID_KEY));
763 }).findFirst().orElse(null);
764
765 if (qosRow == null) {
766 log.warn("Can't find QoS {}", qosId);
767 return;
768 }
769
770 Uuid qosUuid = qosRow.uuid();
771
kdarapufce5abb2018-05-10 19:37:53 +0530772 Map<Long, Uuid> newQueues = new HashMap<>();
tanbangchengc944c282017-11-12 20:42:59 +0800773 for (Map.Entry<Long, QueueDescription> entry : queues.entrySet()) {
774 Row queueRow = queueTableRows.values().stream().filter(r -> {
775 OvsdbMap ovsdbMap = (OvsdbMap) (r.getColumn(EXTERNAL_ID).data());
776 return entry.getValue().queueId().name().equals(ovsdbMap.map().get(QUEUE_EXTERNAL_ID_KEY));
777 }).findFirst().orElse(null);
778 if (queueRow != null) {
779 newQueues.put(entry.getKey(), queueRow.uuid());
780 }
781 }
782
783 // update the qos table
784 ArrayList<Operation> operations = Lists.newArrayList();
785 Condition condition = ConditionUtil.isEqual(UUID, qosUuid);
786 Mutation mutation = MutationUtil.insert(QUEUES, newQueues);
787 List<Condition> conditions = Collections.singletonList(condition);
788 List<Mutation> mutations = Collections.singletonList(mutation);
789 operations.add(new Mutate(dbSchema.getTableSchema(QOS), conditions, mutations));
790
791 transactConfig(DATABASENAME, operations);
792 }
793
794
795 @SuppressWarnings("unchecked")
796 @Override
797 public void unbindQueues(QosId qosId, List<Long> queueKeys) {
798 DatabaseSchema dbSchema = schema.get(DATABASENAME);
799 OvsdbRowStore qosRowStore = getRowStore(DATABASENAME, QOS);
800 if (qosRowStore == null) {
801 return;
802 }
803
804 ConcurrentMap<String, Row> qosTableRows = qosRowStore.getRowStore();
805
806 Row qosRow = qosTableRows.values().stream().filter(r -> {
807 OvsdbMap ovsdbMap = (OvsdbMap) (r.getColumn(EXTERNAL_ID).data());
808 return qosId.name().equals(ovsdbMap.map().get(QOS_EXTERNAL_ID_KEY));
809 }).findFirst().orElse(null);
810
811 if (qosRow == null) {
812 log.warn("Can't find QoS {}", qosId);
813 return;
814 }
815
kdarapufce5abb2018-05-10 19:37:53 +0530816 Map<Long, Uuid> deleteQueuesMap;
tanbangchengc944c282017-11-12 20:42:59 +0800817 Map<Integer, Uuid> queuesMap = ((OvsdbMap) qosRow.getColumn(QUEUES).data()).map();
818
kdarapufce5abb2018-05-10 19:37:53 +0530819 deleteQueuesMap = queueKeys.stream()
820 .filter(key -> queuesMap.containsKey(key.intValue()))
821 .collect(Collectors.toMap(key -> key, key -> queuesMap.get(key.intValue()), (a, b) -> b));
tanbangchengc944c282017-11-12 20:42:59 +0800822
823 if (deleteQueuesMap.size() != 0) {
824 TableSchema parentTableSchema = dbSchema
825 .getTableSchema(QOS);
826 ColumnSchema parentColumnSchema = parentTableSchema
827 .getColumnSchema(QUEUES);
828
829 Mutation mutation = MutationUtil.delete(parentColumnSchema.name(), OvsdbMap.ovsdbMap(deleteQueuesMap));
830 List<Mutation> mutations = Collections.singletonList(mutation);
831
832 Condition condition = ConditionUtil.isEqual(UUID, qosRow.uuid());
833 List<Condition> conditionList = Collections.singletonList(condition);
834 List<Operation> operations = Collections.singletonList(
835 new Mutate(parentTableSchema, conditionList, mutations));
836
837 transactConfig(DATABASENAME, operations);
838 }
839 }
840
841
842 @Override
Frank Wange11a98d2016-10-26 17:04:03 +0800843 public boolean createQueue(OvsdbQueue ovsdbQueue) {
844 DatabaseSchema dbSchema = schema.get(DATABASENAME);
845 Queue queue = (Queue) TableGenerator.createTable(dbSchema, OvsdbTable.QUEUE);
846 ArrayList<Operation> operations = Lists.newArrayList();
847 OvsdbRowStore rowStore = getRowStore(DATABASENAME, QUEUE);
848 if (rowStore == null) {
849 log.debug("The queue uuid is null");
850 return false;
851 }
852
853 if (ovsdbQueue.dscp().isPresent()) {
854 queue.setDscp(ImmutableSet.of(ovsdbQueue.dscp().get()));
855 }
856 queue.setOtherConfig(ovsdbQueue.otherConfigs());
857 queue.setExternalIds(ovsdbQueue.externalIds());
858 Insert queueInsert = new Insert(dbSchema.getTableSchema(QUEUE), QUEUE, queue.getRow());
859 operations.add(queueInsert);
860
861 try {
862 transactConfig(DATABASENAME, operations).get();
863 } catch (InterruptedException | ExecutionException e) {
864 log.error("createQueue transactConfig get exception !");
865 }
866 return true;
867 }
868
869 @Override
870 public void dropQueue(QueueId queueId) {
871 OvsdbRowStore queueRowStore = getRowStore(DATABASENAME, QUEUE);
872 if (queueRowStore == null) {
873 return;
874 }
875
876 ConcurrentMap<String, Row> queueTableRows = queueRowStore.getRowStore();
877 Row queueRow = queueTableRows.values().stream().filter(r -> {
878 OvsdbMap ovsdbMap = (OvsdbMap) (r.getColumn(EXTERNAL_ID).data());
879 return queueId.name().equals(ovsdbMap.map().get(QUEUE_EXTERNAL_ID_KEY));
880 }).findFirst().orElse(null);
881 if (queueRow == null) {
882 return;
883 }
884
885 String queueUuid = queueRow.uuid().value();
886 OvsdbRowStore qosRowStore = getRowStore(DATABASENAME, QOS);
887 if (qosRowStore != null) {
888 Map<Long, Uuid> queueMap = new HashMap<>();
889 ConcurrentMap<String, Row> qosTableRows = qosRowStore.getRowStore();
890 qosTableRows.values().stream().filter(r -> {
891 Map<Integer, Uuid> ovsdbMap = ((OvsdbMap) r.getColumn(QUEUES).data()).map();
892 Set<Integer> keySet = ovsdbMap.keySet();
893 for (Integer keyId : keySet) {
894 if (ovsdbMap.get(keyId).equals(Uuid.uuid(queueUuid))) {
895 queueMap.put(keyId.longValue(), Uuid.uuid(queueUuid));
896 return true;
897 }
898 }
899 return false;
900 }).findFirst().orElse(null);
901 deleteConfig(QUEUE, UUID, queueUuid, QOS, QUEUES, OvsdbMap.ovsdbMap(queueMap));
902 } else {
903 deleteConfig(QUEUE, UUID, queueUuid, null, null, null);
904 }
905 }
906 @Override
907 public OvsdbQueue getQueue(QueueId queueId) {
908 Set<OvsdbQueue> ovsdbQueues = getQueues();
909 return ovsdbQueues.stream().filter(r ->
910 queueId.name().equals(r.externalIds().get(QUEUE_EXTERNAL_ID_KEY))).
911 findFirst().orElse(null);
912 }
913
914 @Override
915 public Set<OvsdbQueue> getQueues() {
916 Set<OvsdbQueue> ovsdbqueues = new HashSet<>();
917 OvsdbRowStore rowStore = getRowStore(DATABASENAME, QUEUE);
918 if (rowStore == null) {
919 log.debug("The queue uuid is null");
920 return ovsdbqueues;
921 }
922 ConcurrentMap<String, Row> rows = rowStore.getRowStore();
kdarapufce5abb2018-05-10 19:37:53 +0530923 ovsdbqueues = rows.keySet()
924 .stream()
925 .map(uuid -> getRow(DATABASENAME, QUEUE, uuid))
926 .map(this::getOvsdbQueue)
927 .filter(Objects::nonNull)
928 .collect(Collectors.toSet());
Frank Wange11a98d2016-10-26 17:04:03 +0800929 return ovsdbqueues;
930 }
Pier Ventref5d72362016-07-17 12:02:14 +0200931 /**
932 * Creates a mirror port. Mirrors the traffic
933 * that goes to selectDstPort or comes from
934 * selectSrcPort or packets containing selectVlan
935 * to mirrorPort or to all ports that trunk mirrorVlan.
936 *
937 * @param mirror the OVSDB mirror description
938 * @return true if mirror creation is successful, false otherwise
939 */
940 @Override
941 public boolean createMirror(String bridgeName, OvsdbMirror mirror) {
942
943 /**
944 * Retrieves bridge's uuid. It is necessary to update
945 * Bridge table.
946 */
947 String bridgeUuid = getBridgeUuid(bridgeName);
948 if (bridgeUuid == null) {
949 log.warn("Couldn't find bridge {} in {}", bridgeName, nodeId.getIpAddress());
950 return false;
951 }
952
953 OvsdbMirror.Builder mirrorBuilder = OvsdbMirror.builder();
954
955 mirrorBuilder.mirroringName(mirror.mirroringName());
956 mirrorBuilder.selectAll(mirror.selectAll());
957
958 /**
959 * Retrieves the uuid of the monitored dst ports.
960 */
961 mirrorBuilder.monitorDstPorts(mirror.monitorDstPorts().parallelStream()
962 .map(dstPort -> {
963 String dstPortUuid = getPortUuid(dstPort.value(), bridgeUuid);
964 if (dstPortUuid != null) {
965 return Uuid.uuid(dstPortUuid);
966 }
967 log.warn("Couldn't find port {} in {}",
968 dstPort.value(), nodeId.getIpAddress());
969 return null;
970 })
971 .filter(Objects::nonNull)
972 .collect(Collectors.toSet())
973 );
974
975 /**
976 * Retrieves the uuid of the monitored src ports.
977 */
978 mirrorBuilder.monitorSrcPorts(mirror.monitorSrcPorts().parallelStream()
979 .map(srcPort -> {
980 String srcPortUuid = getPortUuid(srcPort.value(), bridgeUuid);
981 if (srcPortUuid != null) {
982 return Uuid.uuid(srcPortUuid);
983 }
984 log.warn("Couldn't find port {} in {}",
985 srcPort.value(), nodeId.getIpAddress());
986 return null;
987 }).filter(Objects::nonNull)
988 .collect(Collectors.toSet())
989 );
990
991 mirrorBuilder.monitorVlans(mirror.monitorVlans());
992 mirrorBuilder.mirrorPort(mirror.mirrorPort());
993 mirrorBuilder.mirrorVlan(mirror.mirrorVlan());
994 mirrorBuilder.externalIds(mirror.externalIds());
995 mirror = mirrorBuilder.build();
996
Jon Hallcbd1b392017-01-18 20:15:44 -0800997 if (mirror.monitorDstPorts().isEmpty() &&
998 mirror.monitorSrcPorts().isEmpty() &&
999 mirror.monitorVlans().isEmpty()) {
Pier Ventref5d72362016-07-17 12:02:14 +02001000 log.warn("Invalid monitoring data");
1001 return false;
1002 }
1003
1004 DatabaseSchema dbSchema = schema.get(DATABASENAME);
1005
1006 Mirror mirrorEntry = (Mirror) TableGenerator.createTable(dbSchema, OvsdbTable.MIRROR);
1007 mirrorEntry.setName(mirror.mirroringName());
1008 mirrorEntry.setSelectDstPort(mirror.monitorDstPorts());
1009 mirrorEntry.setSelectSrcPort(mirror.monitorSrcPorts());
1010 mirrorEntry.setSelectVlan(mirror.monitorVlans());
1011 mirrorEntry.setExternalIds(mirror.externalIds());
1012
1013 /**
1014 * If mirror port, retrieves the uuid of the mirror port.
1015 */
1016 if (mirror.mirrorPort() != null) {
1017
1018 String outputPortUuid = getPortUuid(mirror.mirrorPort().value(), bridgeUuid);
1019 if (outputPortUuid == null) {
1020 log.warn("Couldn't find port {} in {}", mirror.mirrorPort().value(), nodeId.getIpAddress());
1021 return false;
1022 }
1023
1024 mirrorEntry.setOutputPort(Uuid.uuid(outputPortUuid));
1025
1026 } else if (mirror.mirrorVlan() != null) {
1027
1028 mirrorEntry.setOutputVlan(mirror.mirrorVlan());
1029
1030 } else {
1031 log.warn("Invalid mirror, no mirror port and no mirror vlan");
1032 return false;
1033 }
1034
1035 ArrayList<Operation> operations = Lists.newArrayList();
1036 Insert mirrorInsert = new Insert(dbSchema.getTableSchema("Mirror"), "Mirror", mirrorEntry.getRow());
1037 operations.add(mirrorInsert);
1038
1039 // update the bridge table
1040 Condition condition = ConditionUtil.isEqual(UUID, Uuid.uuid(bridgeUuid));
1041 Mutation mutation = MutationUtil.insert(MIRRORS, Uuid.uuid("Mirror"));
1042 List<Condition> conditions = Lists.newArrayList(condition);
1043 List<Mutation> mutations = Lists.newArrayList(mutation);
1044 operations.add(new Mutate(dbSchema.getTableSchema("Bridge"), conditions, mutations));
1045
1046 transactConfig(DATABASENAME, operations);
1047 log.info("Created mirror {}", mirror.mirroringName());
1048 return true;
1049 }
1050
1051 /**
1052 * Drops the configuration for mirror.
1053 *
Ray Milkeyef794342016-11-09 16:20:29 -08001054 * @param mirroringName name of mirror to drop
Pier Ventref5d72362016-07-17 12:02:14 +02001055 */
1056 @Override
1057 public void dropMirror(MirroringName mirroringName) {
1058 String mirrorUuid = getMirrorUuid(mirroringName.name());
1059 if (mirrorUuid != null) {
1060 log.info("Deleted mirror {}", mirroringName.name());
Frank Wange11a98d2016-10-26 17:04:03 +08001061 deleteConfig(MIRROR, UUID, mirrorUuid, BRIDGE, MIRRORS, Uuid.uuid(mirrorUuid));
Pier Ventref5d72362016-07-17 12:02:14 +02001062 }
1063 log.warn("Unable to delete {}", mirroringName.name());
1064 return;
1065 }
1066
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001067 @Override
Hyunsun Moondd14e8e2016-06-09 16:17:32 -07001068 public boolean createInterface(String bridgeName, OvsdbInterface ovsdbIface) {
Hyunsun Moon646d8c42015-10-08 20:32:44 -07001069 String bridgeUuid = getBridgeUuid(bridgeName);
1070 if (bridgeUuid == null) {
1071 log.warn("Couldn't find bridge {} in {}", bridgeName, nodeId.getIpAddress());
1072 return false;
1073 }
1074
Hyunsun Moondd14e8e2016-06-09 16:17:32 -07001075 if (getPortUuid(ovsdbIface.name(), bridgeUuid) != null) {
1076 log.warn("Interface {} already exists", ovsdbIface.name());
Hyunsun Moon646d8c42015-10-08 20:32:44 -07001077 // remove existing one and re-create?
1078 return false;
1079 }
1080
1081 ArrayList<Operation> operations = Lists.newArrayList();
Hyunsun Moon1251e192016-06-07 16:57:05 -07001082 DatabaseSchema dbSchema = schema.get(DATABASENAME);
Hyunsun Moon646d8c42015-10-08 20:32:44 -07001083
Hyunsun Moon89478662016-06-09 17:52:34 -07001084 // insert a new port with the interface name
Hyunsun Moon646d8c42015-10-08 20:32:44 -07001085 Port port = (Port) TableGenerator.createTable(dbSchema, OvsdbTable.PORT);
Hyunsun Moondd14e8e2016-06-09 16:17:32 -07001086 port.setName(ovsdbIface.name());
1087 Insert portInsert = new Insert(dbSchema.getTableSchema(PORT), PORT, port.getRow());
1088 portInsert.getRow().put(INTERFACES, Uuid.uuid(INTERFACE));
Hyunsun Moon646d8c42015-10-08 20:32:44 -07001089 operations.add(portInsert);
1090
Hyunsun Moon89478662016-06-09 17:52:34 -07001091 // update the bridge table with the new port
Hyunsun Moon1251e192016-06-07 16:57:05 -07001092 Condition condition = ConditionUtil.isEqual(UUID, Uuid.uuid(bridgeUuid));
Hyunsun Moondd14e8e2016-06-09 16:17:32 -07001093 Mutation mutation = MutationUtil.insert(PORTS, Uuid.uuid(PORT));
1094 List<Condition> conditions = Lists.newArrayList(condition);
1095 List<Mutation> mutations = Lists.newArrayList(mutation);
1096 operations.add(new Mutate(dbSchema.getTableSchema(BRIDGE), conditions, mutations));
Hyunsun Moon646d8c42015-10-08 20:32:44 -07001097
Hyunsun Moon89478662016-06-09 17:52:34 -07001098 // insert an interface
Hyunsun Moon646d8c42015-10-08 20:32:44 -07001099 Interface intf = (Interface) TableGenerator.createTable(dbSchema, OvsdbTable.INTERFACE);
Hyunsun Moondd14e8e2016-06-09 16:17:32 -07001100 intf.setName(ovsdbIface.name());
jaegonkim256f2c12017-05-26 00:03:42 +09001101
Hyunsun Moondd14e8e2016-06-09 16:17:32 -07001102 intf.setType(ovsdbIface.typeToString());
jaegonkim256f2c12017-05-26 00:03:42 +09001103
1104 if (ovsdbIface.mtu().isPresent()) {
1105 Set<Long> mtuSet = Sets.newConcurrentHashSet();
1106 mtuSet.add(ovsdbIface.mtu().get());
1107 intf.setMtu(mtuSet);
1108 intf.setMtuRequest(mtuSet);
1109 }
1110
Hyunsun Moondd14e8e2016-06-09 16:17:32 -07001111 intf.setOptions(ovsdbIface.options());
1112 Insert intfInsert = new Insert(dbSchema.getTableSchema(INTERFACE), INTERFACE, intf.getRow());
Hyunsun Moon646d8c42015-10-08 20:32:44 -07001113 operations.add(intfInsert);
1114
Hyunsun Moon1251e192016-06-07 16:57:05 -07001115 transactConfig(DATABASENAME, operations);
Hyunsun Moon89478662016-06-09 17:52:34 -07001116 log.info("Created interface {}", ovsdbIface);
Hyunsun Moon646d8c42015-10-08 20:32:44 -07001117 return true;
1118 }
1119
1120 @Override
Hyunsun Moondd14e8e2016-06-09 16:17:32 -07001121 public boolean dropInterface(String ifaceName) {
1122 OvsdbRowStore rowStore = getRowStore(DATABASENAME, BRIDGE);
1123 if (rowStore == null) {
1124 log.warn("Failed to get BRIDGE table");
1125 return false;
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001126 }
1127
Hyunsun Moondd14e8e2016-06-09 16:17:32 -07001128 ConcurrentMap<String, Row> bridgeTableRows = rowStore.getRowStore();
1129 if (bridgeTableRows == null) {
1130 log.warn("Failed to get BRIDGE table rows");
1131 return false;
1132 }
1133
1134 // interface name is unique
1135 Optional<String> bridgeId = bridgeTableRows.keySet().stream()
1136 .filter(uuid -> getPortUuid(ifaceName, uuid) != null)
1137 .findFirst();
1138
1139 if (bridgeId.isPresent()) {
1140 String portId = getPortUuid(ifaceName, bridgeId.get());
Frank Wange11a98d2016-10-26 17:04:03 +08001141 deleteConfig(PORT, UUID, portId, BRIDGE, PORTS, Uuid.uuid(portId));
Hyunsun Moondd14e8e2016-06-09 16:17:32 -07001142 return true;
1143 } else {
1144 log.warn("Unable to find the interface with name {}", ifaceName);
1145 return false;
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001146 }
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001147 }
1148
1149 /**
1150 * Delete transact config.
1151 *
andreaed976a42015-10-05 14:38:25 -07001152 * @param childTableName child table name
1153 * @param childColumnName child column name
1154 * @param childUuid child row uuid
1155 * @param parentTableName parent table name
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001156 * @param parentColumnName parent column
Frank Wange11a98d2016-10-26 17:04:03 +08001157 * @param referencedValue referenced value
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001158 */
1159 private void deleteConfig(String childTableName, String childColumnName,
andreaed976a42015-10-05 14:38:25 -07001160 String childUuid, String parentTableName,
Frank Wange11a98d2016-10-26 17:04:03 +08001161 String parentColumnName, Object referencedValue) {
Hyunsun Moon1251e192016-06-07 16:57:05 -07001162 DatabaseSchema dbSchema = schema.get(DATABASENAME);
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001163 TableSchema childTableSchema = dbSchema.getTableSchema(childTableName);
1164
1165 ArrayList<Operation> operations = Lists.newArrayList();
Frank Wange11a98d2016-10-26 17:04:03 +08001166 if (parentTableName != null && parentColumnName != null && referencedValue != null) {
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001167 TableSchema parentTableSchema = dbSchema
1168 .getTableSchema(parentTableName);
1169 ColumnSchema parentColumnSchema = parentTableSchema
1170 .getColumnSchema(parentColumnName);
1171 List<Mutation> mutations = Lists.newArrayList();
Frank Wange11a98d2016-10-26 17:04:03 +08001172 Mutation mutation = MutationUtil.delete(parentColumnSchema.name(), referencedValue);
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001173 mutations.add(mutation);
1174 List<Condition> conditions = Lists.newArrayList();
Frank Wange11a98d2016-10-26 17:04:03 +08001175 Condition condition = ConditionUtil.includes(parentColumnName, referencedValue);
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001176 conditions.add(condition);
1177 Mutate op = new Mutate(parentTableSchema, conditions, mutations);
1178 operations.add(op);
1179 }
1180
1181 List<Condition> conditions = Lists.newArrayList();
Jonathan Hart51539b82015-10-29 09:53:04 -07001182 Condition condition = ConditionUtil.isEqual(childColumnName, Uuid.uuid(childUuid));
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001183 conditions.add(condition);
1184 Delete del = new Delete(childTableSchema, conditions);
1185 operations.add(del);
Hyunsun Moon1251e192016-06-07 16:57:05 -07001186 transactConfig(DATABASENAME, operations);
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001187 }
1188
1189 /**
1190 * Update transact config.
1191 *
andreaed976a42015-10-05 14:38:25 -07001192 * @param tableName table name
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001193 * @param columnName column name
andreaed976a42015-10-05 14:38:25 -07001194 * @param uuid uuid
1195 * @param row the config data
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001196 */
1197 private void updateConfig(String tableName, String columnName, String uuid,
andreaed976a42015-10-05 14:38:25 -07001198 Row row) {
Hyunsun Moon1251e192016-06-07 16:57:05 -07001199 DatabaseSchema dbSchema = schema.get(DATABASENAME);
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001200 TableSchema tableSchema = dbSchema.getTableSchema(tableName);
1201
1202 List<Condition> conditions = Lists.newArrayList();
Jonathan Hart51539b82015-10-29 09:53:04 -07001203 Condition condition = ConditionUtil.isEqual(columnName, Uuid.uuid(uuid));
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001204 conditions.add(condition);
1205
1206 Update update = new Update(tableSchema, row, conditions);
1207
1208 ArrayList<Operation> operations = Lists.newArrayList();
1209 operations.add(update);
1210
Hyunsun Moon1251e192016-06-07 16:57:05 -07001211 transactConfig(DATABASENAME, operations);
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001212 }
1213
1214 /**
1215 * Insert transact config.
1216 *
andreaed976a42015-10-05 14:38:25 -07001217 * @param childTableName child table name
1218 * @param childColumnName child column name
1219 * @param parentTableName parent table name
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001220 * @param parentColumnName parent column
andreaed976a42015-10-05 14:38:25 -07001221 * @param parentUuid parent uuid
1222 * @param row the config data
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001223 * @return uuid, empty if no uuid is find
1224 */
1225 private String insertConfig(String childTableName, String childColumnName,
andreaed976a42015-10-05 14:38:25 -07001226 String parentTableName, String parentColumnName,
1227 String parentUuid, 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(childTableName);
1230
Sho SHIMIZUff18f8c2016-03-11 14:43:53 -08001231 Insert insert = new Insert(tableSchema, childTableName, row);
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001232
1233 ArrayList<Operation> operations = Lists.newArrayList();
1234 operations.add(insert);
1235
1236 if (parentTableName != null && parentColumnName != null) {
1237 TableSchema parentTableSchema = dbSchema
1238 .getTableSchema(parentTableName);
1239 ColumnSchema parentColumnSchema = parentTableSchema
1240 .getColumnSchema(parentColumnName);
1241
1242 List<Mutation> mutations = Lists.newArrayList();
1243 Mutation mutation = MutationUtil.insert(parentColumnSchema.name(),
Sho SHIMIZUff18f8c2016-03-11 14:43:53 -08001244 Uuid.uuid(childTableName));
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001245 mutations.add(mutation);
1246
1247 List<Condition> conditions = Lists.newArrayList();
Hyunsun Moon1251e192016-06-07 16:57:05 -07001248 Condition condition = ConditionUtil.isEqual(UUID, Uuid.uuid(parentUuid));
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001249 conditions.add(condition);
1250
1251 Mutate op = new Mutate(parentTableSchema, conditions, mutations);
1252 operations.add(op);
1253 }
Hyunsun Moon1251e192016-06-07 16:57:05 -07001254 if (childTableName.equalsIgnoreCase(PORT)) {
1255 log.debug("Handle port insert");
Hyunsun Moondd14e8e2016-06-09 16:17:32 -07001256 Insert intfInsert = handlePortInsertTable(row);
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001257
1258 if (intfInsert != null) {
1259 operations.add(intfInsert);
1260 }
1261
1262 Insert ins = (Insert) operations.get(0);
Hyunsun Moon1251e192016-06-07 16:57:05 -07001263 ins.getRow().put("interfaces", Uuid.uuid(INTERFACE));
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001264 }
1265
1266 List<OperationResult> results;
1267 try {
jaegonkim01d7c912017-01-22 22:03:38 +09001268 results = transactConfig(DATABASENAME, operations)
1269 .get(TRANSACTCONFIG_TIMEOUT, TimeUnit.SECONDS);
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001270 return results.get(0).getUuid().value();
jaegonkim01d7c912017-01-22 22:03:38 +09001271 } catch (TimeoutException e) {
1272 log.warn("TimeoutException thrown while to get result");
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001273 } catch (InterruptedException e) {
1274 log.warn("Interrupted while waiting to get result");
1275 Thread.currentThread().interrupt();
1276 } catch (ExecutionException e) {
1277 log.error("Exception thrown while to get result");
1278 }
1279
1280 return null;
1281 }
1282
jaegonkim01d7c912017-01-22 22:03:38 +09001283
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001284 /**
1285 * Handles port insert.
1286 *
andreaed976a42015-10-05 14:38:25 -07001287 * @param portRow row of port
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001288 * @return insert, empty if null
1289 */
Hyunsun Moondd14e8e2016-06-09 16:17:32 -07001290 private Insert handlePortInsertTable(Row portRow) {
Hyunsun Moon1251e192016-06-07 16:57:05 -07001291 DatabaseSchema dbSchema = schema.get(DATABASENAME);
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001292
Hyunsun Moon1251e192016-06-07 16:57:05 -07001293 TableSchema portTableSchema = dbSchema.getTableSchema(PORT);
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001294 ColumnSchema portColumnSchema = portTableSchema.getColumnSchema("name");
1295
1296 String portName = (String) portRow.getColumn(portColumnSchema.name()).data();
Hyunsun Moon1251e192016-06-07 16:57:05 -07001297 Interface inf = (Interface) TableGenerator.createTable(dbSchema, OvsdbTable.INTERFACE);
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001298 inf.setName(portName);
1299
Hyunsun Moon1251e192016-06-07 16:57:05 -07001300 TableSchema intfTableSchema = dbSchema.getTableSchema(INTERFACE);
1301 return new Insert(intfTableSchema, INTERFACE, inf.getRow());
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001302 }
1303
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001304 @Override
1305 public ListenableFuture<DatabaseSchema> getOvsdbSchema(String dbName) {
1306 if (dbName == null) {
1307 return null;
1308 }
1309 DatabaseSchema databaseSchema = schema.get(dbName);
1310 if (databaseSchema == null) {
kdarapufce5abb2018-05-10 19:37:53 +05301311 List<String> dbNames = new ArrayList<>();
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001312 dbNames.add(dbName);
Hyunsun Moon1251e192016-06-07 16:57:05 -07001313 Function<JsonNode, DatabaseSchema> rowFunction = input -> {
1314 log.debug("Get ovsdb database schema {}", dbName);
1315 DatabaseSchema dbSchema = FromJsonUtil.jsonNodeToDbSchema(dbName, input);
1316 if (dbSchema == null) {
1317 log.debug("Get ovsdb database schema error");
1318 return null;
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001319 }
Hyunsun Moon1251e192016-06-07 16:57:05 -07001320 schema.put(dbName, dbSchema);
1321 return dbSchema;
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001322 };
1323
1324 ListenableFuture<JsonNode> input = getSchema(dbNames);
1325 if (input != null) {
1326 return Futures.transform(input, rowFunction);
1327 }
1328 return null;
1329 } else {
1330 return Futures.immediateFuture(databaseSchema);
1331 }
1332 }
1333
1334 @Override
1335 public ListenableFuture<TableUpdates> monitorTables(String dbName, String id) {
1336 if (dbName == null) {
1337 return null;
1338 }
1339 DatabaseSchema dbSchema = schema.get(dbName);
1340 if (dbSchema != null) {
Hyunsun Moon1251e192016-06-07 16:57:05 -07001341 Function<JsonNode, TableUpdates> rowFunction = input -> {
1342 log.debug("Get table updates");
1343 TableUpdates updates = FromJsonUtil.jsonNodeToTableUpdates(input, dbSchema);
1344 if (updates == null) {
1345 log.debug("Get table updates error");
1346 return null;
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001347 }
Hyunsun Moon1251e192016-06-07 16:57:05 -07001348 return updates;
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001349 };
1350 return Futures.transform(monitor(dbSchema, id), rowFunction);
1351 }
1352 return null;
1353 }
1354
Hyunsun Moondd14e8e2016-06-09 16:17:32 -07001355 private ListenableFuture<List<OperationResult>> transactConfig(String dbName,
1356 List<Operation> operations) {
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001357 if (dbName == null) {
1358 return null;
1359 }
1360 DatabaseSchema dbSchema = schema.get(dbName);
1361 if (dbSchema != null) {
andreaed976a42015-10-05 14:38:25 -07001362 Function<List<JsonNode>, List<OperationResult>> rowFunction = (input -> {
Jonathan Hart6523e122017-11-14 09:23:49 -08001363 try {
1364 log.debug("Get ovsdb operation result");
1365 List<OperationResult> result = FromJsonUtil.jsonNodeToOperationResult(input, operations);
1366 if (result == null) {
1367 log.debug("The operation result is null");
1368 return null;
1369 }
1370 return result;
1371 } catch (Exception e) {
1372 log.error("Exception while parsing result", e);
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001373 }
Jonathan Hart6523e122017-11-14 09:23:49 -08001374 return null;
andreaed976a42015-10-05 14:38:25 -07001375 });
Hyunsun Moon1251e192016-06-07 16:57:05 -07001376 return Futures.transform(transact(dbSchema, operations), rowFunction);
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001377 }
1378 return null;
1379 }
1380
1381 @Override
1382 public ListenableFuture<JsonNode> getSchema(List<String> dbnames) {
1383 String id = java.util.UUID.randomUUID().toString();
1384 String getSchemaString = JsonRpcWriterUtil.getSchemaStr(id, dbnames);
1385
1386 SettableFuture<JsonNode> sf = SettableFuture.create();
1387 requestResult.put(id, sf);
1388 requestMethod.put(id, "getSchema");
1389
1390 channel.writeAndFlush(getSchemaString);
1391 return sf;
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001392 }
1393
1394 @Override
1395 public ListenableFuture<List<String>> echo() {
1396 String id = java.util.UUID.randomUUID().toString();
1397 String echoString = JsonRpcWriterUtil.echoStr(id);
1398
1399 SettableFuture<List<String>> sf = SettableFuture.create();
1400 requestResult.put(id, sf);
1401 requestMethod.put(id, "echo");
1402
1403 channel.writeAndFlush(echoString);
1404 return sf;
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001405 }
1406
1407 @Override
1408 public ListenableFuture<JsonNode> monitor(DatabaseSchema dbSchema,
1409 String monitorId) {
1410 String id = java.util.UUID.randomUUID().toString();
1411 String monitorString = JsonRpcWriterUtil.monitorStr(id, monitorId,
1412 dbSchema);
1413
1414 SettableFuture<JsonNode> sf = SettableFuture.create();
1415 requestResult.put(id, sf);
1416 requestMethod.put(id, "monitor");
1417
1418 channel.writeAndFlush(monitorString);
1419 return sf;
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001420 }
1421
1422 @Override
1423 public ListenableFuture<List<String>> listDbs() {
1424 String id = java.util.UUID.randomUUID().toString();
1425 String listDbsString = JsonRpcWriterUtil.listDbsStr(id);
1426
1427 SettableFuture<List<String>> sf = SettableFuture.create();
1428 requestResult.put(id, sf);
1429 requestMethod.put(id, "listDbs");
1430
1431 channel.writeAndFlush(listDbsString);
1432 return sf;
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001433 }
1434
1435 @Override
1436 public ListenableFuture<List<JsonNode>> transact(DatabaseSchema dbSchema,
1437 List<Operation> operations) {
1438 String id = java.util.UUID.randomUUID().toString();
1439 String transactString = JsonRpcWriterUtil.transactStr(id, dbSchema,
1440 operations);
1441
1442 SettableFuture<List<JsonNode>> sf = SettableFuture.create();
1443 requestResult.put(id, sf);
1444 requestMethod.put(id, "transact");
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001445 channel.writeAndFlush(transactString);
1446 return sf;
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001447 }
1448
andreaed976a42015-10-05 14:38:25 -07001449 @SuppressWarnings({"rawtypes", "unchecked"})
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001450 @Override
1451 public void processResult(JsonNode response) {
1452 log.debug("Handle result");
1453 String requestId = response.get("id").asText();
1454 SettableFuture sf = requestResult.get(requestId);
1455 if (sf == null) {
1456 log.debug("No such future to process");
1457 return;
1458 }
1459 String methodName = requestMethod.get(requestId);
Hyunsun Moon1251e192016-06-07 16:57:05 -07001460 sf.set(FromJsonUtil.jsonResultParser(response, methodName));
tanbangcheng1afecce2017-11-12 11:41:28 +08001461
1462 requestResult.remove(requestId);
1463 requestMethod.remove(requestId);
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001464 }
1465
1466 @Override
1467 public void processRequest(JsonNode requestJson) {
1468 log.debug("Handle request");
1469 if (requestJson.get("method").asText().equalsIgnoreCase("echo")) {
1470 log.debug("handle echo request");
1471
1472 String replyString = FromJsonUtil.getEchoRequestStr(requestJson);
1473 channel.writeAndFlush(replyString);
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001474 } else {
Hyunsun Moon1251e192016-06-07 16:57:05 -07001475 FromJsonUtil.jsonCallbackRequestParser(requestJson, monitorCallBack);
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001476 }
1477 }
1478
1479 @Override
1480 public void setCallback(Callback monitorCallback) {
1481 this.monitorCallBack = monitorCallback;
1482 }
1483
1484 @Override
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001485 public Set<OvsdbBridge> getBridges() {
Hyunsun Moon1251e192016-06-07 16:57:05 -07001486 Set<OvsdbBridge> ovsdbBridges = new HashSet<>();
1487 OvsdbTableStore tableStore = getTableStore(DATABASENAME);
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001488 if (tableStore == null) {
MaoJianweidac220d2016-07-04 22:37:52 +08001489 return ovsdbBridges;
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001490 }
Hyunsun Moon1251e192016-06-07 16:57:05 -07001491 OvsdbRowStore rowStore = tableStore.getRows(BRIDGE);
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001492 if (rowStore == null) {
MaoJianweidac220d2016-07-04 22:37:52 +08001493 return ovsdbBridges;
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001494 }
1495 ConcurrentMap<String, Row> rows = rowStore.getRowStore();
1496 for (String uuid : rows.keySet()) {
jaegonkim7b77f712018-01-14 17:18:27 +09001497 Row bridgeRow = getRow(DATABASENAME, BRIDGE, uuid);
1498 OvsdbBridge ovsdbBridge = getOvsdbBridge(bridgeRow, Uuid.uuid(uuid));
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001499 if (ovsdbBridge != null) {
1500 ovsdbBridges.add(ovsdbBridge);
1501 }
1502 }
1503 return ovsdbBridges;
1504 }
1505
1506 @Override
andreaed976a42015-10-05 14:38:25 -07001507 public Set<ControllerInfo> getControllers(DeviceId openflowDeviceId) {
Jonathan Hart51539b82015-10-29 09:53:04 -07001508 Uuid bridgeUuid = getBridgeUuid(openflowDeviceId);
andreaed976a42015-10-05 14:38:25 -07001509 if (bridgeUuid == null) {
1510 log.warn("bad bridge Uuid");
1511 return null;
1512 }
1513 List<Controller> controllers = getControllers(bridgeUuid);
1514 if (controllers == null) {
1515 log.warn("bad list of controllers");
1516 return null;
1517 }
Hyunsun Moon1251e192016-06-07 16:57:05 -07001518 return controllers.stream().map(controller -> new ControllerInfo(
1519 (String) controller.getTargetColumn()
1520 .data())).collect(Collectors.toSet());
andreaed976a42015-10-05 14:38:25 -07001521 }
1522
Jonathan Hart51539b82015-10-29 09:53:04 -07001523 private List<Controller> getControllers(Uuid bridgeUuid) {
Hyunsun Moon1251e192016-06-07 16:57:05 -07001524 DatabaseSchema dbSchema = schema.get(DATABASENAME);
andreaed976a42015-10-05 14:38:25 -07001525 if (dbSchema == null) {
1526 return null;
1527 }
Hyunsun Moon1251e192016-06-07 16:57:05 -07001528 OvsdbRowStore rowStore = getRowStore(DATABASENAME, BRIDGE);
andreaed976a42015-10-05 14:38:25 -07001529 if (rowStore == null) {
1530 log.debug("There is no bridge table");
1531 return null;
1532 }
1533
1534 Row bridgeRow = rowStore.getRow(bridgeUuid.value());
1535 Bridge bridge = (Bridge) TableGenerator.
1536 getTable(dbSchema, bridgeRow, OvsdbTable.BRIDGE);
1537
1538 //FIXME remove log
1539 log.warn("type of controller column", bridge.getControllerColumn()
1540 .data().getClass());
Jonathan Hart51539b82015-10-29 09:53:04 -07001541 Set<Uuid> controllerUuids = (Set<Uuid>) ((OvsdbSet) bridge
andreaed976a42015-10-05 14:38:25 -07001542 .getControllerColumn().data()).set();
andreaed976a42015-10-05 14:38:25 -07001543
Hyunsun Moon1251e192016-06-07 16:57:05 -07001544 OvsdbRowStore controllerRowStore = getRowStore(DATABASENAME, CONTROLLER);
andreaed976a42015-10-05 14:38:25 -07001545 if (controllerRowStore == null) {
1546 log.debug("There is no controller table");
1547 return null;
1548 }
1549
1550 List<Controller> ovsdbControllers = new ArrayList<>();
1551 ConcurrentMap<String, Row> controllerTableRows = controllerRowStore.getRowStore();
1552 controllerTableRows.forEach((key, row) -> {
Jonathan Hart51539b82015-10-29 09:53:04 -07001553 if (!controllerUuids.contains(Uuid.uuid(key))) {
andreaed976a42015-10-05 14:38:25 -07001554 return;
1555 }
1556 Controller controller = (Controller) TableGenerator
1557 .getTable(dbSchema, row, OvsdbTable.CONTROLLER);
1558 ovsdbControllers.add(controller);
1559 });
1560 return ovsdbControllers;
1561 }
1562
1563
Jonathan Hart51539b82015-10-29 09:53:04 -07001564 private Uuid getBridgeUuid(DeviceId openflowDeviceId) {
Hyunsun Moon1251e192016-06-07 16:57:05 -07001565 DatabaseSchema dbSchema = schema.get(DATABASENAME);
andreaed976a42015-10-05 14:38:25 -07001566 if (dbSchema == null) {
1567 return null;
1568 }
Hyunsun Moon1251e192016-06-07 16:57:05 -07001569 OvsdbRowStore rowStore = getRowStore(DATABASENAME, BRIDGE);
andreaed976a42015-10-05 14:38:25 -07001570 if (rowStore == null) {
1571 log.debug("There is no bridge table");
1572 return null;
1573 }
1574
1575 ConcurrentMap<String, Row> bridgeTableRows = rowStore.getRowStore();
Jonathan Hart51539b82015-10-29 09:53:04 -07001576 final AtomicReference<Uuid> uuid = new AtomicReference<>();
andreaed976a42015-10-05 14:38:25 -07001577 for (Map.Entry<String, Row> entry : bridgeTableRows.entrySet()) {
Hyunsun Moon1251e192016-06-07 16:57:05 -07001578 Bridge bridge = (Bridge) TableGenerator.getTable(
1579 dbSchema,
1580 entry.getValue(),
1581 OvsdbTable.BRIDGE);
1582
1583 if (matchesDpid(bridge, openflowDeviceId)) {
Jonathan Hart51539b82015-10-29 09:53:04 -07001584 uuid.set(Uuid.uuid(entry.getKey()));
andreaed976a42015-10-05 14:38:25 -07001585 break;
1586 }
1587 }
1588 if (uuid.get() == null) {
1589 log.debug("There is no bridge for {}", openflowDeviceId);
1590 }
1591 return uuid.get();
andreaed976a42015-10-05 14:38:25 -07001592 }
1593
1594 private static boolean matchesDpid(Bridge b, DeviceId deviceId) {
1595 String ofDpid = deviceId.toString().replace("of:", "");
1596 Set ofDeviceIds = ((OvsdbSet) b.getDatapathIdColumn().data()).set();
1597 //TODO Set<String>
1598 return ofDeviceIds.contains(ofDpid);
1599 }
1600
1601 @Override
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001602 public Set<OvsdbPort> getPorts() {
kdarapufce5abb2018-05-10 19:37:53 +05301603 Set<OvsdbPort> ovsdbPorts;
Hyunsun Moon1251e192016-06-07 16:57:05 -07001604 OvsdbTableStore tableStore = getTableStore(DATABASENAME);
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001605 if (tableStore == null) {
1606 return null;
1607 }
Hyunsun Moon1251e192016-06-07 16:57:05 -07001608 OvsdbRowStore rowStore = tableStore.getRows(INTERFACE);
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001609 if (rowStore == null) {
1610 return null;
1611 }
1612 ConcurrentMap<String, Row> rows = rowStore.getRowStore();
kdarapufce5abb2018-05-10 19:37:53 +05301613 ovsdbPorts = rows.keySet()
1614 .stream()
1615 .map(uuid -> getRow(DATABASENAME, INTERFACE, uuid))
1616 .map(this::getOvsdbPort)
1617 .filter(Objects::nonNull)
1618 .collect(Collectors.toSet());
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001619 return ovsdbPorts;
1620 }
1621
1622 @Override
1623 public DatabaseSchema getDatabaseSchema(String dbName) {
1624 return schema.get(dbName);
1625 }
1626
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001627 private OvsdbPort getOvsdbPort(Row row) {
Hyunsun Moon1251e192016-06-07 16:57:05 -07001628 DatabaseSchema dbSchema = getDatabaseSchema(DATABASENAME);
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001629 Interface intf = (Interface) TableGenerator
1630 .getTable(dbSchema, row, OvsdbTable.INTERFACE);
1631 if (intf == null) {
1632 return null;
1633 }
1634 long ofPort = getOfPort(intf);
1635 String portName = intf.getName();
1636 if ((ofPort < 0) || (portName == null)) {
1637 return null;
1638 }
Hyunsun Moon1251e192016-06-07 16:57:05 -07001639 return new OvsdbPort(new OvsdbPortNumber(ofPort), new OvsdbPortName(portName));
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001640 }
1641
jaegonkim7b77f712018-01-14 17:18:27 +09001642 private OvsdbBridge getOvsdbBridge(Row row, Uuid bridgeUuid) {
Hyunsun Moon1251e192016-06-07 16:57:05 -07001643 DatabaseSchema dbSchema = getDatabaseSchema(DATABASENAME);
1644 Bridge bridge = (Bridge) TableGenerator.getTable(dbSchema, row, OvsdbTable.BRIDGE);
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001645 if (bridge == null) {
1646 return null;
1647 }
1648
1649 OvsdbSet datapathIdSet = (OvsdbSet) bridge.getDatapathIdColumn().data();
1650 @SuppressWarnings("unchecked")
1651 Set<String> datapathIds = datapathIdSet.set();
Jon Hallcbd1b392017-01-18 20:15:44 -08001652 if (datapathIds == null || datapathIds.isEmpty()) {
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001653 return null;
1654 }
1655 String datapathId = (String) datapathIds.toArray()[0];
1656 String bridgeName = bridge.getName();
1657 if ((datapathId == null) || (bridgeName == null)) {
1658 return null;
1659 }
jaegonkim7b77f712018-01-14 17:18:27 +09001660
1661 List<Controller> controllers = getControllers(bridgeUuid);
1662
1663 if (controllers != null) {
1664 List<ControllerInfo> controllerInfos = controllers.stream().map(
1665 controller -> new ControllerInfo(
1666 (String) controller.getTargetColumn()
1667 .data())).collect(Collectors.toList());
1668
1669 return OvsdbBridge.builder()
1670 .name(bridgeName)
1671 .datapathId(datapathId)
1672 .controllers(controllerInfos)
1673 .build();
1674 } else {
1675 return OvsdbBridge.builder()
1676 .name(bridgeName)
1677 .datapathId(datapathId)
1678 .build();
1679 }
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001680 }
1681
Frank Wange11a98d2016-10-26 17:04:03 +08001682 private OvsdbQos getOvsdbQos(Row row) {
1683 DatabaseSchema dbSchema = getDatabaseSchema(DATABASENAME);
1684 Qos qos = (Qos) TableGenerator.getTable(dbSchema, row, OvsdbTable.QOS);
1685 if (qos == null) {
1686 return null;
1687 }
1688
1689 String type = (String) qos.getTypeColumn().data();
1690 Map<String, String> otherConfigs;
1691 Map<String, String> externalIds;
1692 Map<Long, String> queues;
1693
1694 otherConfigs = ((OvsdbMap) qos.getOtherConfigColumn().data()).map();
1695 externalIds = ((OvsdbMap) qos.getExternalIdsColumn().data()).map();
1696 queues = ((OvsdbMap) qos.getQueuesColumn().data()).map();
1697 return OvsdbQos.builder().qosType(type).
1698 queues(queues).otherConfigs(otherConfigs).
1699 externalIds(externalIds).build();
1700 }
1701
1702 private OvsdbQueue getOvsdbQueue(Row row) {
1703 DatabaseSchema dbSchema = getDatabaseSchema(DATABASENAME);
1704 Queue queue = (Queue) TableGenerator.getTable(dbSchema, row, OvsdbTable.QUEUE);
1705 if (queue == null) {
1706 return null;
1707 }
1708
1709 OvsdbSet dscpOvsdbSet = ((OvsdbSet) queue.getDscpColumn().data());
Kamal Krishna Bhattdbef16f2018-06-04 13:25:58 +02001710 Set dscpSet = dscpOvsdbSet.set();
Frank Wange11a98d2016-10-26 17:04:03 +08001711 Long dscp = null;
1712 if (dscpSet != null && !dscpSet.isEmpty()) {
Kamal Krishna Bhattdbef16f2018-06-04 13:25:58 +02001713 dscp = Long.valueOf(dscpSet.toArray()[0].toString());
Frank Wange11a98d2016-10-26 17:04:03 +08001714 }
1715
1716 Map<String, String> otherConfigs;
1717 Map<String, String> externalIds;
1718
1719 otherConfigs = ((OvsdbMap) queue.getOtherConfigColumn().data()).map();
1720 externalIds = ((OvsdbMap) queue.getExternalIdsColumn().data()).map();
1721 return OvsdbQueue.builder().dscp(dscp).
1722 otherConfigs(otherConfigs).externalIds(externalIds).build();
1723 }
1724
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001725 private long getOfPort(Interface intf) {
1726 OvsdbSet ofPortSet = (OvsdbSet) intf.getOpenFlowPortColumn().data();
1727 @SuppressWarnings("unchecked")
1728 Set<Integer> ofPorts = ofPortSet.set();
Jon Hallcbd1b392017-01-18 20:15:44 -08001729 if (ofPorts == null || ofPorts.isEmpty()) {
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001730 log.debug("The ofport is null in {}", intf.getName());
1731 return -1;
1732 }
1733 // return (long) ofPorts.toArray()[0];
1734 Iterator<Integer> it = ofPorts.iterator();
1735 return Long.parseLong(it.next().toString());
1736 }
CNluciusa66c3972015-09-06 20:31:29 +08001737
1738 @Override
1739 public Set<OvsdbPort> getLocalPorts(Iterable<String> ifaceids) {
Hyunsun Moon1251e192016-06-07 16:57:05 -07001740 Set<OvsdbPort> ovsdbPorts = new HashSet<>();
1741 OvsdbTableStore tableStore = getTableStore(DATABASENAME);
CNluciusa66c3972015-09-06 20:31:29 +08001742 if (tableStore == null) {
1743 return null;
1744 }
Hyunsun Moon1251e192016-06-07 16:57:05 -07001745 OvsdbRowStore rowStore = tableStore.getRows(INTERFACE);
CNluciusa66c3972015-09-06 20:31:29 +08001746 if (rowStore == null) {
1747 return null;
1748 }
1749 ConcurrentMap<String, Row> rows = rowStore.getRowStore();
1750 for (String uuid : rows.keySet()) {
Hyunsun Moon1251e192016-06-07 16:57:05 -07001751 Row row = getRow(DATABASENAME, INTERFACE, uuid);
1752 DatabaseSchema dbSchema = getDatabaseSchema(DATABASENAME);
CNluciusa66c3972015-09-06 20:31:29 +08001753 Interface intf = (Interface) TableGenerator
1754 .getTable(dbSchema, row, OvsdbTable.INTERFACE);
1755 if (intf == null || getIfaceid(intf) == null) {
1756 continue;
1757 }
1758 String portName = intf.getName();
Hyunsun Moon1251e192016-06-07 16:57:05 -07001759 if (portName == null) {
1760 continue;
1761 }
CNluciusa66c3972015-09-06 20:31:29 +08001762 Set<String> ifaceidSet = Sets.newHashSet(ifaceids);
Hyunsun Moon1251e192016-06-07 16:57:05 -07001763 if (portName.startsWith(TYPEVXLAN) || !ifaceidSet.contains(getIfaceid(intf))) {
CNluciusa66c3972015-09-06 20:31:29 +08001764 continue;
1765 }
1766 long ofPort = getOfPort(intf);
Hyunsun Moon1251e192016-06-07 16:57:05 -07001767 if (ofPort < 0) {
CNluciusa66c3972015-09-06 20:31:29 +08001768 continue;
1769 }
Hyunsun Moon1251e192016-06-07 16:57:05 -07001770 ovsdbPorts.add(new OvsdbPort(new OvsdbPortNumber(ofPort),
1771 new OvsdbPortName(portName)));
CNluciusa66c3972015-09-06 20:31:29 +08001772 }
1773 return ovsdbPorts;
1774 }
1775
1776 private String getIfaceid(Interface intf) {
1777 OvsdbMap ovsdbMap = (OvsdbMap) intf.getExternalIdsColumn().data();
1778 @SuppressWarnings("unchecked")
1779 Map<String, String> externalIds = ovsdbMap.map();
1780 if (externalIds.isEmpty()) {
1781 log.warn("The external_ids is null");
1782 return null;
1783 }
Hyunsun Moon1251e192016-06-07 16:57:05 -07001784 String ifaceid = externalIds.get(EXTERNAL_ID_INTERFACE_ID);
CNluciusa66c3972015-09-06 20:31:29 +08001785 if (ifaceid == null) {
1786 log.warn("The ifaceid is null");
1787 return null;
1788 }
1789 return ifaceid;
1790 }
Hyunsun Moon5fb20a52015-09-25 17:02:33 -07001791
1792 @Override
1793 public void disconnect() {
1794 channel.disconnect();
Hyunsun Moon5fb20a52015-09-25 17:02:33 -07001795 }
Saritha1583a6f2017-06-16 14:42:58 +05301796
1797 @Override
1798 public List<OvsdbPortName> getPorts(List<String> portNames, DeviceId deviceId) {
1799 Uuid bridgeUuid = getBridgeUuid(deviceId);
1800 if (bridgeUuid == null) {
1801 log.error("Can't find the bridge for the deviceId {}", deviceId);
1802 return Collections.emptyList();
1803 }
1804 DatabaseSchema dbSchema = schema.get(DATABASENAME);
1805 Row bridgeRow = getRow(DATABASENAME, BRIDGE, bridgeUuid.value());
1806 Bridge bridge = (Bridge) TableGenerator.getTable(dbSchema, bridgeRow, OvsdbTable.BRIDGE);
1807 if (bridge == null) {
1808 return Collections.emptyList();
1809 }
1810 OvsdbSet setPorts = (OvsdbSet) bridge.getPortsColumn().data();
1811 Set<Uuid> portSet = setPorts.set();
1812 if (portSet.isEmpty()) {
1813 return Collections.emptyList();
1814 }
1815
1816 Map<Uuid, Port> portMap = portSet.stream().collect(Collectors.toMap(
1817 java.util.function.Function.identity(), port -> (Port) TableGenerator
1818 .getTable(dbSchema, getRow(DATABASENAME,
1819 PORT, port.value()), OvsdbTable.PORT)));
1820
1821 List<OvsdbPortName> portList = portMap.entrySet().stream().filter(port -> Objects.nonNull(port.getValue())
1822 && portNames.contains(port.getValue().getName())
1823 && Objects.nonNull(getInterfacebyPort(port.getKey().value(), port.getValue().getName())))
1824 .map(port -> new OvsdbPortName(port.getValue().getName())).collect(Collectors.toList());
1825
1826 return Collections.unmodifiableList(portList);
1827 }
1828
1829 @Override
1830 public boolean getPortError(List<OvsdbPortName> portNames, DeviceId bridgeId) {
1831 Uuid bridgeUuid = getBridgeUuid(bridgeId);
1832
1833 List<Interface> interfaceList = portNames.stream().collect(Collectors
1834 .toMap(java.util.function.Function.identity(),
1835 port -> (Interface) getInterfacebyPort(getPortUuid(port.value(),
1836 bridgeUuid.value()), port.value())))
1837 .entrySet().stream().filter(intf -> Objects.nonNull(intf.getValue())
1838 && ((OvsdbSet) intf.getValue().getOpenFlowPortColumn().data()).set()
1839 .stream().findAny().orElse(OFPORT_ERROR_COMPARISON).equals(OFPORT_ERROR))
kdarapufce5abb2018-05-10 19:37:53 +05301840 .map(Map.Entry::getValue).collect(Collectors.toList());
Saritha1583a6f2017-06-16 14:42:58 +05301841
kdarapufce5abb2018-05-10 19:37:53 +05301842 interfaceList.forEach(intf -> ((Consumer<Interface>) intf1 -> {
1843 try {
1844 Set<String> setErrors = ((OvsdbSet) intf1.getErrorColumn().data()).set();
1845 log.info("Port has errors. ofport value - {}, Interface - {} has error - {} ",
1846 intf1.getOpenFlowPortColumn().data(), intf1.getName(), setErrors.stream()
1847 .findFirst().get());
1848 } catch (ColumnSchemaNotFoundException | VersionMismatchException e) {
1849 log.debug("Port has errors. ofport value - {}, Interface - {} has error - {} ",
1850 intf1.getOpenFlowPortColumn().data(), intf1.getName(), e);
Saritha1583a6f2017-06-16 14:42:58 +05301851 }
kdarapufce5abb2018-05-10 19:37:53 +05301852 }).accept(intf));
Saritha1583a6f2017-06-16 14:42:58 +05301853
1854 return !interfaceList.isEmpty();
1855 }
1856
1857 private Interface getInterfacebyPort(String portUuid, String portName) {
1858 DatabaseSchema dbSchema = schema.get(DATABASENAME);
1859
1860 Row portRow = getRow(DATABASENAME, PORT, portUuid);
1861 Port port = (Port) TableGenerator.getTable(dbSchema, portRow,
1862 OvsdbTable.PORT);
1863 if (port == null) {
1864 return null;
1865 }
1866
1867 OvsdbSet setInterfaces = (OvsdbSet) port.getInterfacesColumn().data();
1868 Set<Uuid> interfaces = setInterfaces.set();
1869
1870 return interfaces.stream().map(intf -> (Interface) TableGenerator
1871 .getTable(dbSchema, getRow(DATABASENAME,
1872 INTERFACE, intf.value()), OvsdbTable.INTERFACE))
1873 .filter(intf -> Objects.nonNull(intf) && portName.equalsIgnoreCase(intf.getName()))
1874 .findFirst().orElse(null);
1875 }
nitinanandf14dccd2018-05-31 15:11:04 +05301876
1877 /**
1878 * Get first row of given table from given db.
1879 *
1880 * @param dbName db name
1881 * @param tblName table name
1882 * @return firstRow, first row of the given table from given db if present
1883 */
1884 @Override
1885 public Optional<Object> getFirstRow(String dbName, OvsdbTable tblName) {
1886
1887 DatabaseSchema dbSchema = getDatabaseSchema(dbName);
1888 if (Objects.isNull(dbSchema)) {
1889 return Optional.empty();
1890 }
1891
1892 OvsdbTableStore tableStore = ovsdbStore.getOvsdbTableStore(dbName);
1893 if (tableStore == null) {
1894 return Optional.empty();
1895 }
1896 OvsdbRowStore rowStore = tableStore.getRows(tblName.tableName());
1897 if (rowStore == null) {
1898 return Optional.empty();
1899 }
1900
1901 ConcurrentMap<String, Row> rows = rowStore.getRowStore();
1902 if (rows == null) {
1903 log.debug("The {} Table Rows is null", tblName);
1904 return Optional.empty();
1905 }
1906
1907 // There should be only 1 row in this table
1908 Optional<String> uuid = rows.keySet().stream().findFirst();
1909 if (uuid.isPresent() && rows.containsKey(uuid.get())) {
1910 return Optional.of(TableGenerator.getTable(dbSchema,
1911 rows.get(uuid.get()), tblName));
1912 } else {
1913 return Optional.empty();
1914 }
1915 }
1916
1917
1918 /**
1919 * Get memory usage of device.
1920 *
1921 * @return memoryStats, empty data as there is no generic way to fetch such stats
1922 */
1923 @Override
1924 public Optional<DeviceMemoryStats> getDeviceMemoryUsage() {
1925 return Optional.empty();
1926 }
1927
1928
1929 /**
1930 * Get cpu usage of device.
1931 *
1932 * @return cpuStats, empty data as there is no generic way to fetch such stats
1933 */
1934 @Override
1935 public Optional<DeviceCpuStats> getDeviceCpuUsage() {
1936 return Optional.empty();
1937 }
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001938}