blob: b36032b2cd94d4961d4ca86fbc4d9b553db2885e [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;
andreaed976a42015-10-05 14:38:25 -070032import org.onosproject.net.behaviour.ControllerInfo;
Pier Ventref5d72362016-07-17 12:02:14 +020033import org.onosproject.net.behaviour.MirroringName;
Ray Milkeyb1250322017-06-05 17:18:17 -070034import org.onosproject.net.behaviour.MirroringStatistics;
Frank Wange11a98d2016-10-26 17:04:03 +080035import org.onosproject.net.behaviour.QosId;
tanbangchengc944c282017-11-12 20:42:59 +080036import org.onosproject.net.behaviour.QueueDescription;
Frank Wange11a98d2016-10-26 17:04:03 +080037import org.onosproject.net.behaviour.QueueId;
Sho SHIMIZUe4efe452015-08-26 15:06:55 -070038import org.onosproject.ovsdb.controller.OvsdbBridge;
Sho SHIMIZUe4efe452015-08-26 15:06:55 -070039import org.onosproject.ovsdb.controller.OvsdbClientService;
Hyunsun Moondd14e8e2016-06-09 16:17:32 -070040import org.onosproject.ovsdb.controller.OvsdbInterface;
Pier Ventref5d72362016-07-17 12:02:14 +020041import org.onosproject.ovsdb.controller.OvsdbMirror;
Sho SHIMIZUe4efe452015-08-26 15:06:55 -070042import org.onosproject.ovsdb.controller.OvsdbNodeId;
43import org.onosproject.ovsdb.controller.OvsdbPort;
44import org.onosproject.ovsdb.controller.OvsdbPortName;
45import org.onosproject.ovsdb.controller.OvsdbPortNumber;
Frank Wange11a98d2016-10-26 17:04:03 +080046import org.onosproject.ovsdb.controller.OvsdbQos;
47import org.onosproject.ovsdb.controller.OvsdbQueue;
Sho SHIMIZUe4efe452015-08-26 15:06:55 -070048import org.onosproject.ovsdb.controller.OvsdbRowStore;
49import org.onosproject.ovsdb.controller.OvsdbStore;
50import org.onosproject.ovsdb.controller.OvsdbTableStore;
Saritha1583a6f2017-06-16 14:42:58 +053051import org.onosproject.ovsdb.rfc.exception.ColumnSchemaNotFoundException;
52import org.onosproject.ovsdb.rfc.exception.VersionMismatchException;
Sho SHIMIZUe4efe452015-08-26 15:06:55 -070053import org.onosproject.ovsdb.rfc.jsonrpc.Callback;
54import org.onosproject.ovsdb.rfc.message.OperationResult;
55import org.onosproject.ovsdb.rfc.message.TableUpdates;
Frank Wange11a98d2016-10-26 17:04:03 +080056import org.onosproject.ovsdb.rfc.notation.Column;
Sho SHIMIZUe4efe452015-08-26 15:06:55 -070057import org.onosproject.ovsdb.rfc.notation.Condition;
58import org.onosproject.ovsdb.rfc.notation.Mutation;
CNluciusa66c3972015-09-06 20:31:29 +080059import org.onosproject.ovsdb.rfc.notation.OvsdbMap;
Sho SHIMIZUe4efe452015-08-26 15:06:55 -070060import org.onosproject.ovsdb.rfc.notation.OvsdbSet;
61import org.onosproject.ovsdb.rfc.notation.Row;
Jonathan Hart51539b82015-10-29 09:53:04 -070062import org.onosproject.ovsdb.rfc.notation.Uuid;
Sho SHIMIZUe4efe452015-08-26 15:06:55 -070063import org.onosproject.ovsdb.rfc.operations.Delete;
64import org.onosproject.ovsdb.rfc.operations.Insert;
65import org.onosproject.ovsdb.rfc.operations.Mutate;
66import org.onosproject.ovsdb.rfc.operations.Operation;
67import org.onosproject.ovsdb.rfc.operations.Update;
68import org.onosproject.ovsdb.rfc.schema.ColumnSchema;
69import org.onosproject.ovsdb.rfc.schema.DatabaseSchema;
70import org.onosproject.ovsdb.rfc.schema.TableSchema;
71import org.onosproject.ovsdb.rfc.table.Bridge;
72import org.onosproject.ovsdb.rfc.table.Controller;
73import org.onosproject.ovsdb.rfc.table.Interface;
Pier Ventref5d72362016-07-17 12:02:14 +020074import org.onosproject.ovsdb.rfc.table.Mirror;
Sho SHIMIZUe4efe452015-08-26 15:06:55 -070075import org.onosproject.ovsdb.rfc.table.OvsdbTable;
76import org.onosproject.ovsdb.rfc.table.Port;
Frank Wange11a98d2016-10-26 17:04:03 +080077import org.onosproject.ovsdb.rfc.table.Qos;
78import org.onosproject.ovsdb.rfc.table.Queue;
Sho SHIMIZUe4efe452015-08-26 15:06:55 -070079import org.onosproject.ovsdb.rfc.table.TableGenerator;
80import org.onosproject.ovsdb.rfc.utils.ConditionUtil;
81import org.onosproject.ovsdb.rfc.utils.FromJsonUtil;
82import org.onosproject.ovsdb.rfc.utils.JsonRpcWriterUtil;
83import org.onosproject.ovsdb.rfc.utils.MutationUtil;
84import org.slf4j.Logger;
85import org.slf4j.LoggerFactory;
86
Jonathan Hart6523e122017-11-14 09:23:49 -080087import java.net.InetSocketAddress;
88import java.util.ArrayList;
89import java.util.Collections;
90import java.util.HashMap;
91import java.util.HashSet;
92import java.util.Iterator;
93import java.util.List;
94import java.util.Map;
95import java.util.Objects;
96import java.util.Optional;
97import java.util.Set;
98import java.util.concurrent.ConcurrentMap;
99import java.util.concurrent.ExecutionException;
100import java.util.concurrent.TimeUnit;
101import java.util.concurrent.TimeoutException;
102import java.util.concurrent.atomic.AtomicReference;
103import java.util.function.Consumer;
104import java.util.stream.Collectors;
Pier Ventref5d72362016-07-17 12:02:14 +0200105
Jonathan Hart6523e122017-11-14 09:23:49 -0800106import static org.onosproject.ovsdb.controller.OvsdbConstant.*;
Hyunsun Moon1251e192016-06-07 16:57:05 -0700107
Sho SHIMIZUe4efe452015-08-26 15:06:55 -0700108/**
109 * An representation of an ovsdb client.
110 */
Hyunsun Moon1251e192016-06-07 16:57:05 -0700111public class DefaultOvsdbClient implements OvsdbProviderService, OvsdbClientService {
Sho SHIMIZUe4efe452015-08-26 15:06:55 -0700112
jaegonkim01d7c912017-01-22 22:03:38 +0900113 private static final int TRANSACTCONFIG_TIMEOUT = 3; //sec
Saritha1583a6f2017-06-16 14:42:58 +0530114 private static final int OFPORT_ERROR_COMPARISON = 0;
jaegonkim01d7c912017-01-22 22:03:38 +0900115
Hyunsun Moon1251e192016-06-07 16:57:05 -0700116 private final Logger log = LoggerFactory.getLogger(DefaultOvsdbClient.class);
Sho SHIMIZUe4efe452015-08-26 15:06:55 -0700117
118 private Channel channel;
Sho SHIMIZUe4efe452015-08-26 15:06:55 -0700119 private OvsdbAgent agent;
120 private boolean connected;
121 private OvsdbNodeId nodeId;
122 private Callback monitorCallBack;
Sho SHIMIZUe4efe452015-08-26 15:06:55 -0700123 private OvsdbStore ovsdbStore = new OvsdbStore();
124
125 private final Map<String, String> requestMethod = Maps.newHashMap();
Hyunsun Moon1251e192016-06-07 16:57:05 -0700126 private final Map<String, SettableFuture<? extends Object>> requestResult = Maps.newHashMap();
Sho SHIMIZUe4efe452015-08-26 15:06:55 -0700127 private final Map<String, DatabaseSchema> schema = Maps.newHashMap();
Sho SHIMIZUe4efe452015-08-26 15:06:55 -0700128
Pier Ventref5d72362016-07-17 12:02:14 +0200129
Sho SHIMIZUe4efe452015-08-26 15:06:55 -0700130 /**
131 * Creates an OvsdbClient.
132 *
133 * @param nodeId ovsdb node id
134 */
135 public DefaultOvsdbClient(OvsdbNodeId nodeId) {
136 this.nodeId = nodeId;
137 }
138
139 @Override
140 public OvsdbNodeId nodeId() {
141 return nodeId;
142 }
143
144 @Override
145 public void setAgent(OvsdbAgent agent) {
146 if (this.agent == null) {
147 this.agent = agent;
148 }
149 }
150
151 @Override
152 public void setChannel(Channel channel) {
153 this.channel = channel;
154 }
155
156 @Override
157 public void setConnection(boolean connected) {
158 this.connected = connected;
159 }
160
161 @Override
162 public boolean isConnected() {
163 return this.connected;
164 }
165
166 @Override
167 public void nodeAdded() {
168 this.agent.addConnectedNode(nodeId, this);
169 }
170
171 @Override
172 public void nodeRemoved() {
173 this.agent.removeConnectedNode(nodeId);
174 channel.disconnect();
175 }
176
177 /**
178 * Gets the ovsdb table store.
179 *
180 * @param dbName the ovsdb database name
181 * @return ovsTableStore, empty if table store is find
182 */
183 private OvsdbTableStore getTableStore(String dbName) {
184 if (ovsdbStore == null) {
185 return null;
186 }
187 return ovsdbStore.getOvsdbTableStore(dbName);
188 }
189
190 /**
191 * Gets the ovsdb row store.
192 *
andreaed976a42015-10-05 14:38:25 -0700193 * @param dbName the ovsdb database name
Sho SHIMIZUe4efe452015-08-26 15:06:55 -0700194 * @param tableName the ovsdb table name
Hyunsun Moon6125c612015-10-15 10:54:44 -0700195 * @return ovsRowStore, empty store if no rows exist in the table
Sho SHIMIZUe4efe452015-08-26 15:06:55 -0700196 */
197 private OvsdbRowStore getRowStore(String dbName, String tableName) {
198 OvsdbTableStore tableStore = getTableStore(dbName);
199 if (tableStore == null) {
200 return null;
201 }
Hyunsun Moon6125c612015-10-15 10:54:44 -0700202
203 OvsdbRowStore rowStore = tableStore.getRows(tableName);
204 if (rowStore == null) {
205 rowStore = new OvsdbRowStore();
206 }
207 return rowStore;
Sho SHIMIZUe4efe452015-08-26 15:06:55 -0700208 }
209
210 /**
211 * Gets the ovsdb row.
212 *
andreaed976a42015-10-05 14:38:25 -0700213 * @param dbName the ovsdb database name
Sho SHIMIZUe4efe452015-08-26 15:06:55 -0700214 * @param tableName the ovsdb table name
andreaed976a42015-10-05 14:38:25 -0700215 * @param uuid the key of the row
Sho SHIMIZUe4efe452015-08-26 15:06:55 -0700216 * @return row, empty if row is find
217 */
218 @Override
219 public Row getRow(String dbName, String tableName, String uuid) {
220 OvsdbTableStore tableStore = getTableStore(dbName);
221 if (tableStore == null) {
222 return null;
223 }
224 OvsdbRowStore rowStore = tableStore.getRows(tableName);
225 if (rowStore == null) {
226 return null;
227 }
228 return rowStore.getRow(uuid);
229 }
230
231 @Override
232 public void removeRow(String dbName, String tableName, String uuid) {
233 OvsdbTableStore tableStore = getTableStore(dbName);
234 if (tableStore == null) {
235 return;
236 }
237 OvsdbRowStore rowStore = tableStore.getRows(tableName);
238 if (rowStore == null) {
239 return;
240 }
241 rowStore.deleteRow(uuid);
242 }
243
244 @Override
245 public void updateOvsdbStore(String dbName, String tableName, String uuid,
246 Row row) {
247 OvsdbTableStore tableStore = ovsdbStore.getOvsdbTableStore(dbName);
248 if (tableStore == null) {
249 tableStore = new OvsdbTableStore();
250 }
251 OvsdbRowStore rowStore = tableStore.getRows(tableName);
252 if (rowStore == null) {
253 rowStore = new OvsdbRowStore();
254 }
255 rowStore.insertRow(uuid, row);
256 tableStore.createOrUpdateTable(tableName, rowStore);
257 ovsdbStore.createOrUpdateOvsdbStore(dbName, tableStore);
258 }
259
Pier Ventref5d72362016-07-17 12:02:14 +0200260 /**
261 * Gets the Mirror uuid.
262 *
263 * @param mirrorName mirror name
264 * @return mirror uuid, empty if no uuid is found
265 */
266 @Override
267 public String getMirrorUuid(String mirrorName) {
268 DatabaseSchema dbSchema = schema.get(DATABASENAME);
269 OvsdbRowStore rowStore = getRowStore(DATABASENAME, MIRROR);
270 if (rowStore == null) {
271 log.warn("The mirror uuid is null");
272 return null;
273 }
274
275 ConcurrentMap<String, Row> mirrorTableRows = rowStore.getRowStore();
276 if (mirrorTableRows == null) {
277 log.warn("The mirror uuid is null");
278 return null;
279 }
280
281 for (String uuid : mirrorTableRows.keySet()) {
282 Mirror mirror = (Mirror) TableGenerator
283 .getTable(dbSchema, mirrorTableRows.get(uuid), OvsdbTable.MIRROR);
284 String name = mirror.getName();
285 if (name.contains(mirrorName)) {
286 return uuid;
287 }
288 }
289 log.warn("Mirroring not found");
290 return null;
291 }
292
293 /**
294 * Gets mirrors of the device.
295 *
296 * @param deviceId target device id
297 * @return set of mirroring; empty if no mirror is found
298 */
299 @Override
300 public Set<MirroringStatistics> getMirroringStatistics(DeviceId deviceId) {
301 Uuid bridgeUuid = getBridgeUuid(deviceId);
302 if (bridgeUuid == null) {
303 log.warn("Couldn't find bridge {} in {}", deviceId, nodeId.getIpAddress());
304 return null;
305 }
306
307 List<MirroringStatistics> mirrorings = getMirrorings(bridgeUuid);
308 if (mirrorings == null) {
309 log.warn("Couldn't find mirrors in {}", nodeId.getIpAddress());
310 return null;
311 }
312 return ImmutableSet.copyOf(mirrorings);
313 }
314
315 /**
316 * Helper method which retrieves mirrorings statistics using bridge uuid.
317 *
318 * @param bridgeUuid the uuid of the bridge
319 * @return the list of the mirrorings statistics.
320 */
321 private List<MirroringStatistics> getMirrorings(Uuid bridgeUuid) {
322 DatabaseSchema dbSchema = schema.get(DATABASENAME);
323 if (dbSchema == null) {
324 log.warn("Unable to retrieve dbSchema {}", DATABASENAME);
325 return null;
326 }
327 OvsdbRowStore rowStore = getRowStore(DATABASENAME, BRIDGE);
328 if (rowStore == null) {
329 log.warn("Unable to retrieve rowStore {} of {}", BRIDGE, DATABASENAME);
330 return null;
331 }
332
333 Row bridgeRow = rowStore.getRow(bridgeUuid.value());
334 Bridge bridge = (Bridge) TableGenerator.
335 getTable(dbSchema, bridgeRow, OvsdbTable.BRIDGE);
336
337 Set<Uuid> mirroringsUuids = (Set<Uuid>) ((OvsdbSet) bridge
338 .getMirrorsColumn().data()).set();
339
340 OvsdbRowStore mirrorRowStore = getRowStore(DATABASENAME, MIRROR);
341 if (mirrorRowStore == null) {
342 log.warn("Unable to retrieve rowStore {} of {}", MIRROR, DATABASENAME);
343 return null;
344 }
345
346 List<MirroringStatistics> mirroringStatistics = new ArrayList<>();
347 ConcurrentMap<String, Row> mirrorTableRows = mirrorRowStore.getRowStore();
348 mirrorTableRows.forEach((key, row) -> {
349 if (!mirroringsUuids.contains(Uuid.uuid(key))) {
350 return;
351 }
352 Mirror mirror = (Mirror) TableGenerator
353 .getTable(dbSchema, row, OvsdbTable.MIRROR);
354 mirroringStatistics.add(MirroringStatistics.mirroringStatistics(mirror.getName(),
355 (Map<String, Integer>) ((OvsdbMap) mirror
356 .getStatisticsColumn().data()).map()));
357 });
358 return ImmutableList.copyOf(mirroringStatistics);
359 }
360
Sho SHIMIZUe4efe452015-08-26 15:06:55 -0700361 @Override
362 public String getPortUuid(String portName, String bridgeUuid) {
Hyunsun Moon1251e192016-06-07 16:57:05 -0700363 DatabaseSchema dbSchema = schema.get(DATABASENAME);
Sho SHIMIZUe4efe452015-08-26 15:06:55 -0700364
Hyunsun Moon1251e192016-06-07 16:57:05 -0700365 Row bridgeRow = getRow(DATABASENAME, BRIDGE, bridgeUuid);
Sho SHIMIZUe4efe452015-08-26 15:06:55 -0700366 Bridge bridge = (Bridge) TableGenerator.getTable(dbSchema, bridgeRow,
367 OvsdbTable.BRIDGE);
368 if (bridge != null) {
369 OvsdbSet setPorts = (OvsdbSet) bridge.getPortsColumn().data();
370 @SuppressWarnings("unchecked")
Jonathan Hart51539b82015-10-29 09:53:04 -0700371 Set<Uuid> ports = setPorts.set();
Jon Hallcbd1b392017-01-18 20:15:44 -0800372 if (ports == null || ports.isEmpty()) {
Sho SHIMIZUe4efe452015-08-26 15:06:55 -0700373 log.warn("The port uuid is null");
374 return null;
375 }
376
Jonathan Hart51539b82015-10-29 09:53:04 -0700377 for (Uuid uuid : ports) {
Hyunsun Moon1251e192016-06-07 16:57:05 -0700378 Row portRow = getRow(DATABASENAME, PORT, uuid.value());
Sho SHIMIZUe4efe452015-08-26 15:06:55 -0700379 Port port = (Port) TableGenerator.getTable(dbSchema, portRow,
380 OvsdbTable.PORT);
381 if (port != null && portName.equalsIgnoreCase(port.getName())) {
382 return uuid.value();
383 }
384 }
Sho SHIMIZUe4efe452015-08-26 15:06:55 -0700385 }
386 return null;
387 }
388
389 @Override
Sho SHIMIZUe4efe452015-08-26 15:06:55 -0700390 public String getBridgeUuid(String bridgeName) {
Hyunsun Moon1251e192016-06-07 16:57:05 -0700391 DatabaseSchema dbSchema = schema.get(DATABASENAME);
Hyunsun Moon1251e192016-06-07 16:57:05 -0700392 OvsdbRowStore rowStore = getRowStore(DATABASENAME, BRIDGE);
Sho SHIMIZUe4efe452015-08-26 15:06:55 -0700393 if (rowStore == null) {
394 log.debug("The bridge uuid is null");
395 return null;
396 }
397
398 ConcurrentMap<String, Row> bridgeTableRows = rowStore.getRowStore();
399 if (bridgeTableRows == null) {
400 log.debug("The bridge uuid is null");
401 return null;
402 }
403
404 for (String uuid : bridgeTableRows.keySet()) {
405 Bridge bridge = (Bridge) TableGenerator
Hyunsun Moon1251e192016-06-07 16:57:05 -0700406 .getTable(dbSchema, bridgeTableRows.get(uuid), OvsdbTable.BRIDGE);
Sho SHIMIZUe4efe452015-08-26 15:06:55 -0700407 if (bridge.getName().equals(bridgeName)) {
408 return uuid;
409 }
Sho SHIMIZUe4efe452015-08-26 15:06:55 -0700410 }
411 return null;
412 }
413
Hyunsun Moondd14e8e2016-06-09 16:17:32 -0700414 private String getOvsUuid(String dbName) {
Hyunsun Moon1251e192016-06-07 16:57:05 -0700415 OvsdbRowStore rowStore = getRowStore(DATABASENAME, DATABASENAME);
Sho SHIMIZUe4efe452015-08-26 15:06:55 -0700416 if (rowStore == null) {
417 log.debug("The bridge uuid is null");
418 return null;
419 }
420 ConcurrentMap<String, Row> ovsTableRows = rowStore.getRowStore();
421 if (ovsTableRows != null) {
422 for (String uuid : ovsTableRows.keySet()) {
423 Row row = ovsTableRows.get(uuid);
424 String tableName = row.tableName();
425 if (tableName.equals(dbName)) {
426 return uuid;
427 }
428 }
429 }
430 return null;
431 }
432
433 @Override
434 public void createPort(String bridgeName, String portName) {
435 String bridgeUuid = getBridgeUuid(bridgeName);
436 if (bridgeUuid == null) {
Hyunsun Moon1251e192016-06-07 16:57:05 -0700437 log.error("Can't find bridge {} in {}", bridgeName, nodeId.getIpAddress());
Sho SHIMIZUe4efe452015-08-26 15:06:55 -0700438 return;
439 }
440
Hyunsun Moon1251e192016-06-07 16:57:05 -0700441 DatabaseSchema dbSchema = schema.get(DATABASENAME);
Sho SHIMIZUe4efe452015-08-26 15:06:55 -0700442 String portUuid = getPortUuid(portName, bridgeUuid);
Hyunsun Moon1251e192016-06-07 16:57:05 -0700443 Port port = (Port) TableGenerator.createTable(dbSchema, OvsdbTable.PORT);
Sho SHIMIZUe4efe452015-08-26 15:06:55 -0700444 port.setName(portName);
445 if (portUuid == null) {
Hyunsun Moon1251e192016-06-07 16:57:05 -0700446 insertConfig(PORT, UUID, BRIDGE, PORTS, bridgeUuid, port.getRow());
Sho SHIMIZUe4efe452015-08-26 15:06:55 -0700447 }
Sho SHIMIZUe4efe452015-08-26 15:06:55 -0700448 }
449
450 @Override
451 public void dropPort(String bridgeName, String portName) {
452 String bridgeUuid = getBridgeUuid(bridgeName);
453 if (bridgeUuid == null) {
454 log.error("Could not find Bridge {} in {}", bridgeName, nodeId);
455 return;
456 }
457
458 String portUuid = getPortUuid(portName, bridgeUuid);
459 if (portUuid != null) {
460 log.info("Port {} delete", portName);
Frank Wange11a98d2016-10-26 17:04:03 +0800461 deleteConfig(PORT, UUID, portUuid, BRIDGE, PORTS, Uuid.uuid(portUuid));
Sho SHIMIZUe4efe452015-08-26 15:06:55 -0700462 }
463 }
464
lishuai6c56f5e2015-11-17 16:38:19 +0800465 @Override
Hyunsun Moon1251e192016-06-07 16:57:05 -0700466 public boolean createBridge(OvsdbBridge ovsdbBridge) {
467 DatabaseSchema dbSchema = schema.get(DATABASENAME);
468 String ovsUuid = getOvsUuid(DATABASENAME);
Hyunsun Moon646d8c42015-10-08 20:32:44 -0700469
470 if (dbSchema == null || ovsUuid == null) {
Hyunsun Moon1251e192016-06-07 16:57:05 -0700471 log.error("Can't find database Open_vSwitch");
Hyunsun Moon646d8c42015-10-08 20:32:44 -0700472 return false;
473 }
474
Hyunsun Moon646d8c42015-10-08 20:32:44 -0700475 Bridge bridge = (Bridge) TableGenerator.createTable(dbSchema, OvsdbTable.BRIDGE);
Hyunsun Moon1251e192016-06-07 16:57:05 -0700476 bridge.setOtherConfig(ovsdbBridge.otherConfigs());
Hyunsun Moon646d8c42015-10-08 20:32:44 -0700477
Hyunsun Moon1251e192016-06-07 16:57:05 -0700478 if (ovsdbBridge.failMode().isPresent()) {
479 String failMode = ovsdbBridge.failMode().get().name().toLowerCase();
480 bridge.setFailMode(Sets.newHashSet(failMode));
Bob zhoue9795fd2016-05-12 20:18:45 +0800481 }
Hyunsun Moon646d8c42015-10-08 20:32:44 -0700482
jaegonkim80bee532017-05-15 15:16:38 +0900483 if (ovsdbBridge.datapathType().isPresent()) {
484 String datapathType = ovsdbBridge.datapathType().get();
485 bridge.setDatapathType(datapathType);
486 }
487
Hyunsun Moon1251e192016-06-07 16:57:05 -0700488 String bridgeUuid = getBridgeUuid(ovsdbBridge.name());
Hyunsun Moon98025542016-03-08 04:36:02 -0800489 if (bridgeUuid == null) {
Hyunsun Moon1251e192016-06-07 16:57:05 -0700490 bridge.setName(ovsdbBridge.name());
491 bridgeUuid = insertConfig(
492 BRIDGE, UUID, DATABASENAME, BRIDGES,
493 ovsUuid, bridge.getRow());
Hyunsun Moon98025542016-03-08 04:36:02 -0800494 } else {
Hyunsun Moon1251e192016-06-07 16:57:05 -0700495 // update the bridge if it's already existing
496 updateConfig(BRIDGE, UUID, bridgeUuid, bridge.getRow());
Hyunsun Moon98025542016-03-08 04:36:02 -0800497 }
Hyunsun Moon646d8c42015-10-08 20:32:44 -0700498
Hyunsun Moon1251e192016-06-07 16:57:05 -0700499 if (bridgeUuid == null) {
500 log.warn("Failed to create bridge {} on {}", ovsdbBridge.name(), nodeId);
Hyunsun Moon646d8c42015-10-08 20:32:44 -0700501 return false;
502 }
503
Hyunsun Moon1251e192016-06-07 16:57:05 -0700504 createPort(ovsdbBridge.name(), ovsdbBridge.name());
505 setControllersWithUuid(Uuid.uuid(bridgeUuid), ovsdbBridge.controllers());
506
507 log.info("Created bridge {}", ovsdbBridge.name());
Hyunsun Moon646d8c42015-10-08 20:32:44 -0700508 return true;
509 }
510
Hyunsun Moon1251e192016-06-07 16:57:05 -0700511 @Override
512 public ControllerInfo localController() {
513 IpAddress ipAddress = IpAddress.valueOf(((InetSocketAddress)
514 channel.localAddress()).getAddress());
515 return new ControllerInfo(ipAddress, OFPORT, "tcp");
andreaed976a42015-10-05 14:38:25 -0700516 }
517
Hyunsun Moondd14e8e2016-06-09 16:17:32 -0700518 private void setControllersWithUuid(Uuid bridgeUuid, List<ControllerInfo> controllers) {
Hyunsun Moon1251e192016-06-07 16:57:05 -0700519 DatabaseSchema dbSchema = schema.get(DATABASENAME);
andreaed976a42015-10-05 14:38:25 -0700520 if (dbSchema == null) {
521 log.debug("There is no schema");
522 return;
523 }
524 List<Controller> oldControllers = getControllers(bridgeUuid);
525 if (oldControllers == null) {
526 log.warn("There are no controllers");
527 return;
528 }
529
Jonathan Hart51539b82015-10-29 09:53:04 -0700530 Set<Uuid> newControllerUuids = new HashSet<>();
andreaed976a42015-10-05 14:38:25 -0700531
532 Set<ControllerInfo> newControllers = new HashSet<>(controllers);
533 List<Controller> removeControllers = new ArrayList<>();
534 oldControllers.forEach(controller -> {
535 ControllerInfo controllerInfo = new ControllerInfo((String) controller.getTargetColumn().data());
536 if (newControllers.contains(controllerInfo)) {
537 newControllers.remove(controllerInfo);
538 newControllerUuids.add(controller.getRow().uuid());
539 } else {
540 removeControllers.add(controller);
541 }
542 });
Hyunsun Moon1251e192016-06-07 16:57:05 -0700543 OvsdbRowStore controllerRowStore = getRowStore(DATABASENAME, CONTROLLER);
andreaed976a42015-10-05 14:38:25 -0700544 if (controllerRowStore == null) {
545 log.debug("There is no controller table");
546 return;
547 }
548
Hyunsun Moon1251e192016-06-07 16:57:05 -0700549 removeControllers.forEach(c -> deleteConfig(CONTROLLER, UUID, c.getRow().uuid().value(),
Saritha8a0c36a2017-07-04 15:01:35 +0530550 BRIDGE, BRIDGE_CONTROLLER, c.getRow().uuid()));
andreaed976a42015-10-05 14:38:25 -0700551 newControllers.stream().map(c -> {
552 Controller controller = (Controller) TableGenerator
553 .createTable(dbSchema, OvsdbTable.CONTROLLER);
554 controller.setTarget(c.target());
555 return controller;
556 }).forEach(c -> {
Saritha8a0c36a2017-07-04 15:01:35 +0530557 String uuid = insertConfig(CONTROLLER, UUID, BRIDGE, BRIDGE_CONTROLLER, bridgeUuid.value(),
andreaed976a42015-10-05 14:38:25 -0700558 c.getRow());
Jonathan Hart51539b82015-10-29 09:53:04 -0700559 newControllerUuids.add(Uuid.uuid(uuid));
andreaed976a42015-10-05 14:38:25 -0700560
561 });
562
Hyunsun Moon1251e192016-06-07 16:57:05 -0700563 OvsdbRowStore rowStore = getRowStore(DATABASENAME, BRIDGE);
andreaed976a42015-10-05 14:38:25 -0700564 if (rowStore == null) {
565 log.debug("There is no bridge table");
566 return;
567 }
568
569 Row bridgeRow = rowStore.getRow(bridgeUuid.value());
570 Bridge bridge = (Bridge) TableGenerator.getTable(dbSchema, bridgeRow, OvsdbTable.BRIDGE);
571 bridge.setController(OvsdbSet.ovsdbSet(newControllerUuids));
Hyunsun Moon1251e192016-06-07 16:57:05 -0700572 updateConfig(BRIDGE, UUID, bridgeUuid.value(), bridge.getRow());
andreaed976a42015-10-05 14:38:25 -0700573 }
574
andreaed976a42015-10-05 14:38:25 -0700575 @Override
576 public void setControllersWithDeviceId(DeviceId deviceId, List<ControllerInfo> controllers) {
Jonathan Hart51539b82015-10-29 09:53:04 -0700577 setControllersWithUuid(getBridgeUuid(deviceId), controllers);
andreaed976a42015-10-05 14:38:25 -0700578 }
579
Sho SHIMIZUe4efe452015-08-26 15:06:55 -0700580 @Override
581 public void dropBridge(String bridgeName) {
Jonathan Hart51539b82015-10-29 09:53:04 -0700582 String bridgeUuid = getBridgeUuid(bridgeName);
583 if (bridgeUuid == null) {
Sho SHIMIZUe4efe452015-08-26 15:06:55 -0700584 log.warn("Could not find bridge in node", nodeId.getIpAddress());
585 return;
586 }
Frank Wange11a98d2016-10-26 17:04:03 +0800587 deleteConfig(BRIDGE, UUID, bridgeUuid, DATABASENAME, BRIDGES, Uuid.uuid(bridgeUuid));
Hyunsun Moondd14e8e2016-06-09 16:17:32 -0700588 }
589
Frank Wange11a98d2016-10-26 17:04:03 +0800590 @Override
591 public void applyQos(PortNumber portNumber, String qosName) {
592 DatabaseSchema dbSchema = schema.get(DATABASENAME);
593 OvsdbRowStore portRowStore = getRowStore(DATABASENAME, PORT);
594 if (portRowStore == null) {
595 log.debug("The port uuid is null");
596 return;
597 }
598 OvsdbRowStore qosRowStore = getRowStore(DATABASENAME, QOS);
599 if (qosRowStore == null) {
600 log.debug("The qos uuid is null");
601 return;
602 }
603
604 // Due to Qos Table doesn't have a unique identifier except uuid, unlike
605 // Bridge or Port Table has a name column,in order to make the api more
606 // general, put qos name in external_ids column of Qos Table if this qos
607 // created by onos.
608 ConcurrentMap<String, Row> qosTableRows = qosRowStore.getRowStore();
609 ConcurrentMap<String, Row> portTableRows = portRowStore.getRowStore();
610 Row qosRow = qosTableRows.values().stream().filter(r -> {
611 OvsdbMap ovsdbMap = (OvsdbMap) (r.getColumn(EXTERNAL_ID).data());
612 return qosName.equals(ovsdbMap.map().get(QOS_EXTERNAL_ID_KEY));
613 }).findFirst().orElse(null);
614
615 Row portRow = portTableRows.values().stream()
616 .filter(r -> r.getColumn("name").data().equals(portNumber.name()))
617 .findFirst().orElse(null);
618 if (portRow != null && qosRow != null) {
619 String qosId = qosRow.uuid().value();
620 Uuid portUuid = portRow.uuid();
621 Map<String, Column> columns = new HashMap<>();
622 Row newPortRow = new Row(PORT, portUuid, columns);
623 Port newport = new Port(dbSchema, newPortRow);
624 columns.put(Port.PortColumn.QOS.columnName(), newport.getQosColumn());
625 newport.setQos(Uuid.uuid(qosId));
626 updateConfig(PORT, UUID, portUuid.value(), newport.getRow());
627 }
628 }
629
630 @Override
631 public void removeQos(PortNumber portNumber) {
632 DatabaseSchema dbSchema = schema.get(DATABASENAME);
633 OvsdbRowStore rowStore = getRowStore(DATABASENAME, PORT);
634 if (rowStore == null) {
635 log.debug("The qos uuid is null");
636 return;
637 }
638
639 ConcurrentMap<String, Row> ovsTableRows = rowStore.getRowStore();
640 Row portRow = ovsTableRows.values().stream()
641 .filter(r -> r.getColumn("name").data().equals(portNumber.name()))
642 .findFirst().orElse(null);
643 if (portRow == null) {
644 log.warn("Couldn't find port {} in ovsdb port table.", portNumber.name());
645 return;
646 }
647
648 OvsdbSet ovsdbSet = ((OvsdbSet) portRow.getColumn(PORT_QOS).data());
649 @SuppressWarnings("unchecked")
650 Set<Uuid> qosIdSet = ovsdbSet.set();
651 if (qosIdSet == null || qosIdSet.isEmpty()) {
652 return;
653 }
654 Uuid qosUuid = (Uuid) qosIdSet.toArray()[0];
655 Condition condition = ConditionUtil.isEqual(UUID, portRow.uuid());
656 List<Condition> conditions = Lists.newArrayList(condition);
657 Mutation mutation = MutationUtil.delete(PORT_QOS, qosUuid);
658 List<Mutation> mutations = Lists.newArrayList(mutation);
659
660 ArrayList<Operation> operations = Lists.newArrayList();
661 Mutate mutate = new Mutate(dbSchema.getTableSchema(PORT), conditions, mutations);
662 operations.add(mutate);
663 transactConfig(DATABASENAME, operations);
664 }
665
666 @Override
667 public boolean createQos(OvsdbQos ovsdbQos) {
668 DatabaseSchema dbSchema = schema.get(DATABASENAME);
669 Qos qos = (Qos) TableGenerator.createTable(dbSchema, OvsdbTable.QOS);
670 OvsdbRowStore rowStore = getRowStore(DATABASENAME, QOS);
671 if (rowStore == null) {
672 log.debug("The qos uuid is null");
673 return false;
674 }
675
676 ArrayList<Operation> operations = Lists.newArrayList();
677 Set<String> types = Sets.newHashSet();
678 Map<Long, Uuid> queues = Maps.newHashMap();
679
680 types.add(ovsdbQos.qosType());
681 qos.setOtherConfig(ovsdbQos.otherConfigs());
682 qos.setExternalIds(ovsdbQos.externalIds());
683 qos.setType(types);
684 if (ovsdbQos.qosQueues().isPresent()) {
685 for (Map.Entry<Long, String> entry : ovsdbQos.qosQueues().get().entrySet()) {
686 OvsdbRowStore queueRowStore = getRowStore(DATABASENAME, QUEUE);
687 if (queueRowStore != null) {
688 ConcurrentMap<String, Row> queueTableRows = queueRowStore.getRowStore();
689 Row queueRow = queueTableRows.values().stream().filter(r -> {
690 OvsdbMap ovsdbMap = (OvsdbMap) (r.getColumn(EXTERNAL_ID).data());
691 return entry.getValue().equals(ovsdbMap.map().get(QUEUE_EXTERNAL_ID_KEY));
692 }).findFirst().orElse(null);
693 if (queueRow != null) {
694 queues.put(entry.getKey(), queueRow.uuid());
695 }
696 }
697 }
698 qos.setQueues(queues);
699 }
700
701 Insert qosInsert = new Insert(dbSchema.getTableSchema(QOS), QOS, qos.getRow());
702 operations.add(qosInsert);
703 try {
704 transactConfig(DATABASENAME, operations).get();
705 } catch (InterruptedException | ExecutionException e) {
706 return false;
707 }
708 return true;
709 }
710
711 @Override
712 public void dropQos(QosId qosId) {
713 OvsdbRowStore rowStore = getRowStore(DATABASENAME, QOS);
714 if (rowStore != null) {
715 ConcurrentMap<String, Row> qosTableRows = rowStore.getRowStore();
716 Row qosRow = qosTableRows.values().stream().filter(r -> {
717 OvsdbMap ovsdbMap = (OvsdbMap) (r.getColumn(EXTERNAL_ID).data());
718 return qosId.name().equals(ovsdbMap.map().get(QOS_EXTERNAL_ID_KEY));
719 }).findFirst().orElse(null);
720 if (qosRow != null) {
721 deleteConfig(QOS, UUID, qosRow.uuid().value(), PORT, PORT_QOS, qosRow.uuid());
722 }
723 }
724 }
725 @Override
726 public OvsdbQos getQos(QosId qosId) {
727 Set<OvsdbQos> ovsdbQoses = getQoses();
728 return ovsdbQoses.stream().filter(r ->
729 qosId.name().equals(r.externalIds().get(QOS_EXTERNAL_ID_KEY))).
730 findFirst().orElse(null);
731 }
732
733 @Override
734 public Set<OvsdbQos> getQoses() {
735 Set<OvsdbQos> ovsdbQoses = new HashSet<>();
736 OvsdbRowStore rowStore = getRowStore(DATABASENAME, QOS);
737 if (rowStore == null) {
738 log.debug("The qos uuid is null");
739 return ovsdbQoses;
740 }
741 ConcurrentMap<String, Row> rows = rowStore.getRowStore();
742 for (String uuid : rows.keySet()) {
743 Row row = getRow(DATABASENAME, QOS, uuid);
744 OvsdbQos ovsdbQos = getOvsdbQos(row);
745 if (ovsdbQos != null) {
746 ovsdbQoses.add(ovsdbQos);
747 }
748 }
749 return ovsdbQoses;
750 }
751
752 @Override
tanbangchengc944c282017-11-12 20:42:59 +0800753 public void bindQueues(QosId qosId, Map<Long, QueueDescription> queues) {
754 DatabaseSchema dbSchema = schema.get(DATABASENAME);
755 OvsdbRowStore qosRowStore = getRowStore(DATABASENAME, QOS);
756 if (qosRowStore == null) {
757 log.debug("The qos uuid is null");
758 return;
759 }
760 OvsdbRowStore queueRowStore = getRowStore(DATABASENAME, QUEUE);
761 if (queueRowStore == null) {
762 log.debug("The queue uuid is null");
763 return;
764 }
765
766 ConcurrentMap<String, Row> qosTableRows = qosRowStore.getRowStore();
767 ConcurrentMap<String, Row> queueTableRows = queueRowStore.getRowStore();
768
769 Row qosRow = qosTableRows.values().stream().filter(r -> {
770 OvsdbMap ovsdbMap = (OvsdbMap) (r.getColumn(EXTERNAL_ID).data());
771 return qosId.name().equals(ovsdbMap.map().get(QOS_EXTERNAL_ID_KEY));
772 }).findFirst().orElse(null);
773
774 if (qosRow == null) {
775 log.warn("Can't find QoS {}", qosId);
776 return;
777 }
778
779 Uuid qosUuid = qosRow.uuid();
780
781 Map<Long, Uuid> newQueues = new HashMap<Long, Uuid>();
782 for (Map.Entry<Long, QueueDescription> entry : queues.entrySet()) {
783 Row queueRow = queueTableRows.values().stream().filter(r -> {
784 OvsdbMap ovsdbMap = (OvsdbMap) (r.getColumn(EXTERNAL_ID).data());
785 return entry.getValue().queueId().name().equals(ovsdbMap.map().get(QUEUE_EXTERNAL_ID_KEY));
786 }).findFirst().orElse(null);
787 if (queueRow != null) {
788 newQueues.put(entry.getKey(), queueRow.uuid());
789 }
790 }
791
792 // update the qos table
793 ArrayList<Operation> operations = Lists.newArrayList();
794 Condition condition = ConditionUtil.isEqual(UUID, qosUuid);
795 Mutation mutation = MutationUtil.insert(QUEUES, newQueues);
796 List<Condition> conditions = Collections.singletonList(condition);
797 List<Mutation> mutations = Collections.singletonList(mutation);
798 operations.add(new Mutate(dbSchema.getTableSchema(QOS), conditions, mutations));
799
800 transactConfig(DATABASENAME, operations);
801 }
802
803
804 @SuppressWarnings("unchecked")
805 @Override
806 public void unbindQueues(QosId qosId, List<Long> queueKeys) {
807 DatabaseSchema dbSchema = schema.get(DATABASENAME);
808 OvsdbRowStore qosRowStore = getRowStore(DATABASENAME, QOS);
809 if (qosRowStore == null) {
810 return;
811 }
812
813 ConcurrentMap<String, Row> qosTableRows = qosRowStore.getRowStore();
814
815 Row qosRow = qosTableRows.values().stream().filter(r -> {
816 OvsdbMap ovsdbMap = (OvsdbMap) (r.getColumn(EXTERNAL_ID).data());
817 return qosId.name().equals(ovsdbMap.map().get(QOS_EXTERNAL_ID_KEY));
818 }).findFirst().orElse(null);
819
820 if (qosRow == null) {
821 log.warn("Can't find QoS {}", qosId);
822 return;
823 }
824
825 Map<Long, Uuid> deleteQueuesMap = new HashMap<>();
826 Map<Integer, Uuid> queuesMap = ((OvsdbMap) qosRow.getColumn(QUEUES).data()).map();
827
828 queueKeys.forEach(key -> {
829 if (queuesMap.containsKey(key.intValue())) {
830 deleteQueuesMap.put(key, queuesMap.get(key.intValue()));
831 }
832 });
833
834 if (deleteQueuesMap.size() != 0) {
835 TableSchema parentTableSchema = dbSchema
836 .getTableSchema(QOS);
837 ColumnSchema parentColumnSchema = parentTableSchema
838 .getColumnSchema(QUEUES);
839
840 Mutation mutation = MutationUtil.delete(parentColumnSchema.name(), OvsdbMap.ovsdbMap(deleteQueuesMap));
841 List<Mutation> mutations = Collections.singletonList(mutation);
842
843 Condition condition = ConditionUtil.isEqual(UUID, qosRow.uuid());
844 List<Condition> conditionList = Collections.singletonList(condition);
845 List<Operation> operations = Collections.singletonList(
846 new Mutate(parentTableSchema, conditionList, mutations));
847
848 transactConfig(DATABASENAME, operations);
849 }
850 }
851
852
853 @Override
Frank Wange11a98d2016-10-26 17:04:03 +0800854 public boolean createQueue(OvsdbQueue ovsdbQueue) {
855 DatabaseSchema dbSchema = schema.get(DATABASENAME);
856 Queue queue = (Queue) TableGenerator.createTable(dbSchema, OvsdbTable.QUEUE);
857 ArrayList<Operation> operations = Lists.newArrayList();
858 OvsdbRowStore rowStore = getRowStore(DATABASENAME, QUEUE);
859 if (rowStore == null) {
860 log.debug("The queue uuid is null");
861 return false;
862 }
863
864 if (ovsdbQueue.dscp().isPresent()) {
865 queue.setDscp(ImmutableSet.of(ovsdbQueue.dscp().get()));
866 }
867 queue.setOtherConfig(ovsdbQueue.otherConfigs());
868 queue.setExternalIds(ovsdbQueue.externalIds());
869 Insert queueInsert = new Insert(dbSchema.getTableSchema(QUEUE), QUEUE, queue.getRow());
870 operations.add(queueInsert);
871
872 try {
873 transactConfig(DATABASENAME, operations).get();
874 } catch (InterruptedException | ExecutionException e) {
875 log.error("createQueue transactConfig get exception !");
876 }
877 return true;
878 }
879
880 @Override
881 public void dropQueue(QueueId queueId) {
882 OvsdbRowStore queueRowStore = getRowStore(DATABASENAME, QUEUE);
883 if (queueRowStore == null) {
884 return;
885 }
886
887 ConcurrentMap<String, Row> queueTableRows = queueRowStore.getRowStore();
888 Row queueRow = queueTableRows.values().stream().filter(r -> {
889 OvsdbMap ovsdbMap = (OvsdbMap) (r.getColumn(EXTERNAL_ID).data());
890 return queueId.name().equals(ovsdbMap.map().get(QUEUE_EXTERNAL_ID_KEY));
891 }).findFirst().orElse(null);
892 if (queueRow == null) {
893 return;
894 }
895
896 String queueUuid = queueRow.uuid().value();
897 OvsdbRowStore qosRowStore = getRowStore(DATABASENAME, QOS);
898 if (qosRowStore != null) {
899 Map<Long, Uuid> queueMap = new HashMap<>();
900 ConcurrentMap<String, Row> qosTableRows = qosRowStore.getRowStore();
901 qosTableRows.values().stream().filter(r -> {
902 Map<Integer, Uuid> ovsdbMap = ((OvsdbMap) r.getColumn(QUEUES).data()).map();
903 Set<Integer> keySet = ovsdbMap.keySet();
904 for (Integer keyId : keySet) {
905 if (ovsdbMap.get(keyId).equals(Uuid.uuid(queueUuid))) {
906 queueMap.put(keyId.longValue(), Uuid.uuid(queueUuid));
907 return true;
908 }
909 }
910 return false;
911 }).findFirst().orElse(null);
912 deleteConfig(QUEUE, UUID, queueUuid, QOS, QUEUES, OvsdbMap.ovsdbMap(queueMap));
913 } else {
914 deleteConfig(QUEUE, UUID, queueUuid, null, null, null);
915 }
916 }
917 @Override
918 public OvsdbQueue getQueue(QueueId queueId) {
919 Set<OvsdbQueue> ovsdbQueues = getQueues();
920 return ovsdbQueues.stream().filter(r ->
921 queueId.name().equals(r.externalIds().get(QUEUE_EXTERNAL_ID_KEY))).
922 findFirst().orElse(null);
923 }
924
925 @Override
926 public Set<OvsdbQueue> getQueues() {
927 Set<OvsdbQueue> ovsdbqueues = new HashSet<>();
928 OvsdbRowStore rowStore = getRowStore(DATABASENAME, QUEUE);
929 if (rowStore == null) {
930 log.debug("The queue uuid is null");
931 return ovsdbqueues;
932 }
933 ConcurrentMap<String, Row> rows = rowStore.getRowStore();
934 for (String uuid : rows.keySet()) {
935 Row row = getRow(DATABASENAME, QUEUE, uuid);
936 OvsdbQueue ovsdbQueue = getOvsdbQueue(row);
937 if (ovsdbQueue != null) {
938 ovsdbqueues.add(ovsdbQueue);
939 }
940 }
941 return ovsdbqueues;
942 }
Pier Ventref5d72362016-07-17 12:02:14 +0200943 /**
944 * Creates a mirror port. Mirrors the traffic
945 * that goes to selectDstPort or comes from
946 * selectSrcPort or packets containing selectVlan
947 * to mirrorPort or to all ports that trunk mirrorVlan.
948 *
949 * @param mirror the OVSDB mirror description
950 * @return true if mirror creation is successful, false otherwise
951 */
952 @Override
953 public boolean createMirror(String bridgeName, OvsdbMirror mirror) {
954
955 /**
956 * Retrieves bridge's uuid. It is necessary to update
957 * Bridge table.
958 */
959 String bridgeUuid = getBridgeUuid(bridgeName);
960 if (bridgeUuid == null) {
961 log.warn("Couldn't find bridge {} in {}", bridgeName, nodeId.getIpAddress());
962 return false;
963 }
964
965 OvsdbMirror.Builder mirrorBuilder = OvsdbMirror.builder();
966
967 mirrorBuilder.mirroringName(mirror.mirroringName());
968 mirrorBuilder.selectAll(mirror.selectAll());
969
970 /**
971 * Retrieves the uuid of the monitored dst ports.
972 */
973 mirrorBuilder.monitorDstPorts(mirror.monitorDstPorts().parallelStream()
974 .map(dstPort -> {
975 String dstPortUuid = getPortUuid(dstPort.value(), bridgeUuid);
976 if (dstPortUuid != null) {
977 return Uuid.uuid(dstPortUuid);
978 }
979 log.warn("Couldn't find port {} in {}",
980 dstPort.value(), nodeId.getIpAddress());
981 return null;
982 })
983 .filter(Objects::nonNull)
984 .collect(Collectors.toSet())
985 );
986
987 /**
988 * Retrieves the uuid of the monitored src ports.
989 */
990 mirrorBuilder.monitorSrcPorts(mirror.monitorSrcPorts().parallelStream()
991 .map(srcPort -> {
992 String srcPortUuid = getPortUuid(srcPort.value(), bridgeUuid);
993 if (srcPortUuid != null) {
994 return Uuid.uuid(srcPortUuid);
995 }
996 log.warn("Couldn't find port {} in {}",
997 srcPort.value(), nodeId.getIpAddress());
998 return null;
999 }).filter(Objects::nonNull)
1000 .collect(Collectors.toSet())
1001 );
1002
1003 mirrorBuilder.monitorVlans(mirror.monitorVlans());
1004 mirrorBuilder.mirrorPort(mirror.mirrorPort());
1005 mirrorBuilder.mirrorVlan(mirror.mirrorVlan());
1006 mirrorBuilder.externalIds(mirror.externalIds());
1007 mirror = mirrorBuilder.build();
1008
Jon Hallcbd1b392017-01-18 20:15:44 -08001009 if (mirror.monitorDstPorts().isEmpty() &&
1010 mirror.monitorSrcPorts().isEmpty() &&
1011 mirror.monitorVlans().isEmpty()) {
Pier Ventref5d72362016-07-17 12:02:14 +02001012 log.warn("Invalid monitoring data");
1013 return false;
1014 }
1015
1016 DatabaseSchema dbSchema = schema.get(DATABASENAME);
1017
1018 Mirror mirrorEntry = (Mirror) TableGenerator.createTable(dbSchema, OvsdbTable.MIRROR);
1019 mirrorEntry.setName(mirror.mirroringName());
1020 mirrorEntry.setSelectDstPort(mirror.monitorDstPorts());
1021 mirrorEntry.setSelectSrcPort(mirror.monitorSrcPorts());
1022 mirrorEntry.setSelectVlan(mirror.monitorVlans());
1023 mirrorEntry.setExternalIds(mirror.externalIds());
1024
1025 /**
1026 * If mirror port, retrieves the uuid of the mirror port.
1027 */
1028 if (mirror.mirrorPort() != null) {
1029
1030 String outputPortUuid = getPortUuid(mirror.mirrorPort().value(), bridgeUuid);
1031 if (outputPortUuid == null) {
1032 log.warn("Couldn't find port {} in {}", mirror.mirrorPort().value(), nodeId.getIpAddress());
1033 return false;
1034 }
1035
1036 mirrorEntry.setOutputPort(Uuid.uuid(outputPortUuid));
1037
1038 } else if (mirror.mirrorVlan() != null) {
1039
1040 mirrorEntry.setOutputVlan(mirror.mirrorVlan());
1041
1042 } else {
1043 log.warn("Invalid mirror, no mirror port and no mirror vlan");
1044 return false;
1045 }
1046
1047 ArrayList<Operation> operations = Lists.newArrayList();
1048 Insert mirrorInsert = new Insert(dbSchema.getTableSchema("Mirror"), "Mirror", mirrorEntry.getRow());
1049 operations.add(mirrorInsert);
1050
1051 // update the bridge table
1052 Condition condition = ConditionUtil.isEqual(UUID, Uuid.uuid(bridgeUuid));
1053 Mutation mutation = MutationUtil.insert(MIRRORS, Uuid.uuid("Mirror"));
1054 List<Condition> conditions = Lists.newArrayList(condition);
1055 List<Mutation> mutations = Lists.newArrayList(mutation);
1056 operations.add(new Mutate(dbSchema.getTableSchema("Bridge"), conditions, mutations));
1057
1058 transactConfig(DATABASENAME, operations);
1059 log.info("Created mirror {}", mirror.mirroringName());
1060 return true;
1061 }
1062
1063 /**
1064 * Drops the configuration for mirror.
1065 *
Ray Milkeyef794342016-11-09 16:20:29 -08001066 * @param mirroringName name of mirror to drop
Pier Ventref5d72362016-07-17 12:02:14 +02001067 */
1068 @Override
1069 public void dropMirror(MirroringName mirroringName) {
1070 String mirrorUuid = getMirrorUuid(mirroringName.name());
1071 if (mirrorUuid != null) {
1072 log.info("Deleted mirror {}", mirroringName.name());
Frank Wange11a98d2016-10-26 17:04:03 +08001073 deleteConfig(MIRROR, UUID, mirrorUuid, BRIDGE, MIRRORS, Uuid.uuid(mirrorUuid));
Pier Ventref5d72362016-07-17 12:02:14 +02001074 }
1075 log.warn("Unable to delete {}", mirroringName.name());
1076 return;
1077 }
1078
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001079 @Override
Hyunsun Moondd14e8e2016-06-09 16:17:32 -07001080 public boolean createInterface(String bridgeName, OvsdbInterface ovsdbIface) {
Hyunsun Moon646d8c42015-10-08 20:32:44 -07001081 String bridgeUuid = getBridgeUuid(bridgeName);
1082 if (bridgeUuid == null) {
1083 log.warn("Couldn't find bridge {} in {}", bridgeName, nodeId.getIpAddress());
1084 return false;
1085 }
1086
Hyunsun Moondd14e8e2016-06-09 16:17:32 -07001087 if (getPortUuid(ovsdbIface.name(), bridgeUuid) != null) {
1088 log.warn("Interface {} already exists", ovsdbIface.name());
Hyunsun Moon646d8c42015-10-08 20:32:44 -07001089 // remove existing one and re-create?
1090 return false;
1091 }
1092
1093 ArrayList<Operation> operations = Lists.newArrayList();
Hyunsun Moon1251e192016-06-07 16:57:05 -07001094 DatabaseSchema dbSchema = schema.get(DATABASENAME);
Hyunsun Moon646d8c42015-10-08 20:32:44 -07001095
Hyunsun Moon89478662016-06-09 17:52:34 -07001096 // insert a new port with the interface name
Hyunsun Moon646d8c42015-10-08 20:32:44 -07001097 Port port = (Port) TableGenerator.createTable(dbSchema, OvsdbTable.PORT);
Hyunsun Moondd14e8e2016-06-09 16:17:32 -07001098 port.setName(ovsdbIface.name());
1099 Insert portInsert = new Insert(dbSchema.getTableSchema(PORT), PORT, port.getRow());
1100 portInsert.getRow().put(INTERFACES, Uuid.uuid(INTERFACE));
Hyunsun Moon646d8c42015-10-08 20:32:44 -07001101 operations.add(portInsert);
1102
Hyunsun Moon89478662016-06-09 17:52:34 -07001103 // update the bridge table with the new port
Hyunsun Moon1251e192016-06-07 16:57:05 -07001104 Condition condition = ConditionUtil.isEqual(UUID, Uuid.uuid(bridgeUuid));
Hyunsun Moondd14e8e2016-06-09 16:17:32 -07001105 Mutation mutation = MutationUtil.insert(PORTS, Uuid.uuid(PORT));
1106 List<Condition> conditions = Lists.newArrayList(condition);
1107 List<Mutation> mutations = Lists.newArrayList(mutation);
1108 operations.add(new Mutate(dbSchema.getTableSchema(BRIDGE), conditions, mutations));
Hyunsun Moon646d8c42015-10-08 20:32:44 -07001109
Hyunsun Moon89478662016-06-09 17:52:34 -07001110 // insert an interface
Hyunsun Moon646d8c42015-10-08 20:32:44 -07001111 Interface intf = (Interface) TableGenerator.createTable(dbSchema, OvsdbTable.INTERFACE);
Hyunsun Moondd14e8e2016-06-09 16:17:32 -07001112 intf.setName(ovsdbIface.name());
jaegonkim256f2c12017-05-26 00:03:42 +09001113
Hyunsun Moondd14e8e2016-06-09 16:17:32 -07001114 intf.setType(ovsdbIface.typeToString());
jaegonkim256f2c12017-05-26 00:03:42 +09001115
1116 if (ovsdbIface.mtu().isPresent()) {
1117 Set<Long> mtuSet = Sets.newConcurrentHashSet();
1118 mtuSet.add(ovsdbIface.mtu().get());
1119 intf.setMtu(mtuSet);
1120 intf.setMtuRequest(mtuSet);
1121 }
1122
Hyunsun Moondd14e8e2016-06-09 16:17:32 -07001123 intf.setOptions(ovsdbIface.options());
1124 Insert intfInsert = new Insert(dbSchema.getTableSchema(INTERFACE), INTERFACE, intf.getRow());
Hyunsun Moon646d8c42015-10-08 20:32:44 -07001125 operations.add(intfInsert);
1126
Hyunsun Moon1251e192016-06-07 16:57:05 -07001127 transactConfig(DATABASENAME, operations);
Hyunsun Moon89478662016-06-09 17:52:34 -07001128 log.info("Created interface {}", ovsdbIface);
Hyunsun Moon646d8c42015-10-08 20:32:44 -07001129 return true;
1130 }
1131
1132 @Override
Hyunsun Moondd14e8e2016-06-09 16:17:32 -07001133 public boolean dropInterface(String ifaceName) {
1134 OvsdbRowStore rowStore = getRowStore(DATABASENAME, BRIDGE);
1135 if (rowStore == null) {
1136 log.warn("Failed to get BRIDGE table");
1137 return false;
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001138 }
1139
Hyunsun Moondd14e8e2016-06-09 16:17:32 -07001140 ConcurrentMap<String, Row> bridgeTableRows = rowStore.getRowStore();
1141 if (bridgeTableRows == null) {
1142 log.warn("Failed to get BRIDGE table rows");
1143 return false;
1144 }
1145
1146 // interface name is unique
1147 Optional<String> bridgeId = bridgeTableRows.keySet().stream()
1148 .filter(uuid -> getPortUuid(ifaceName, uuid) != null)
1149 .findFirst();
1150
1151 if (bridgeId.isPresent()) {
1152 String portId = getPortUuid(ifaceName, bridgeId.get());
Frank Wange11a98d2016-10-26 17:04:03 +08001153 deleteConfig(PORT, UUID, portId, BRIDGE, PORTS, Uuid.uuid(portId));
Hyunsun Moondd14e8e2016-06-09 16:17:32 -07001154 return true;
1155 } else {
1156 log.warn("Unable to find the interface with name {}", ifaceName);
1157 return false;
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001158 }
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001159 }
1160
1161 /**
1162 * Delete transact config.
1163 *
andreaed976a42015-10-05 14:38:25 -07001164 * @param childTableName child table name
1165 * @param childColumnName child column name
1166 * @param childUuid child row uuid
1167 * @param parentTableName parent table name
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001168 * @param parentColumnName parent column
Frank Wange11a98d2016-10-26 17:04:03 +08001169 * @param referencedValue referenced value
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001170 */
1171 private void deleteConfig(String childTableName, String childColumnName,
andreaed976a42015-10-05 14:38:25 -07001172 String childUuid, String parentTableName,
Frank Wange11a98d2016-10-26 17:04:03 +08001173 String parentColumnName, Object referencedValue) {
Hyunsun Moon1251e192016-06-07 16:57:05 -07001174 DatabaseSchema dbSchema = schema.get(DATABASENAME);
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001175 TableSchema childTableSchema = dbSchema.getTableSchema(childTableName);
1176
1177 ArrayList<Operation> operations = Lists.newArrayList();
Frank Wange11a98d2016-10-26 17:04:03 +08001178 if (parentTableName != null && parentColumnName != null && referencedValue != null) {
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001179 TableSchema parentTableSchema = dbSchema
1180 .getTableSchema(parentTableName);
1181 ColumnSchema parentColumnSchema = parentTableSchema
1182 .getColumnSchema(parentColumnName);
1183 List<Mutation> mutations = Lists.newArrayList();
Frank Wange11a98d2016-10-26 17:04:03 +08001184 Mutation mutation = MutationUtil.delete(parentColumnSchema.name(), referencedValue);
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001185 mutations.add(mutation);
1186 List<Condition> conditions = Lists.newArrayList();
Frank Wange11a98d2016-10-26 17:04:03 +08001187 Condition condition = ConditionUtil.includes(parentColumnName, referencedValue);
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001188 conditions.add(condition);
1189 Mutate op = new Mutate(parentTableSchema, conditions, mutations);
1190 operations.add(op);
1191 }
1192
1193 List<Condition> conditions = Lists.newArrayList();
Jonathan Hart51539b82015-10-29 09:53:04 -07001194 Condition condition = ConditionUtil.isEqual(childColumnName, Uuid.uuid(childUuid));
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001195 conditions.add(condition);
1196 Delete del = new Delete(childTableSchema, conditions);
1197 operations.add(del);
Hyunsun Moon1251e192016-06-07 16:57:05 -07001198 transactConfig(DATABASENAME, operations);
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001199 }
1200
1201 /**
1202 * Update transact config.
1203 *
andreaed976a42015-10-05 14:38:25 -07001204 * @param tableName table name
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001205 * @param columnName column name
andreaed976a42015-10-05 14:38:25 -07001206 * @param uuid uuid
1207 * @param row the config data
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001208 */
1209 private void updateConfig(String tableName, String columnName, String uuid,
andreaed976a42015-10-05 14:38:25 -07001210 Row row) {
Hyunsun Moon1251e192016-06-07 16:57:05 -07001211 DatabaseSchema dbSchema = schema.get(DATABASENAME);
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001212 TableSchema tableSchema = dbSchema.getTableSchema(tableName);
1213
1214 List<Condition> conditions = Lists.newArrayList();
Jonathan Hart51539b82015-10-29 09:53:04 -07001215 Condition condition = ConditionUtil.isEqual(columnName, Uuid.uuid(uuid));
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001216 conditions.add(condition);
1217
1218 Update update = new Update(tableSchema, row, conditions);
1219
1220 ArrayList<Operation> operations = Lists.newArrayList();
1221 operations.add(update);
1222
Hyunsun Moon1251e192016-06-07 16:57:05 -07001223 transactConfig(DATABASENAME, operations);
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001224 }
1225
1226 /**
1227 * Insert transact config.
1228 *
andreaed976a42015-10-05 14:38:25 -07001229 * @param childTableName child table name
1230 * @param childColumnName child column name
1231 * @param parentTableName parent table name
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001232 * @param parentColumnName parent column
andreaed976a42015-10-05 14:38:25 -07001233 * @param parentUuid parent uuid
1234 * @param row the config data
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001235 * @return uuid, empty if no uuid is find
1236 */
1237 private String insertConfig(String childTableName, String childColumnName,
andreaed976a42015-10-05 14:38:25 -07001238 String parentTableName, String parentColumnName,
1239 String parentUuid, Row row) {
Hyunsun Moon1251e192016-06-07 16:57:05 -07001240 DatabaseSchema dbSchema = schema.get(DATABASENAME);
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001241 TableSchema tableSchema = dbSchema.getTableSchema(childTableName);
1242
Sho SHIMIZUff18f8c2016-03-11 14:43:53 -08001243 Insert insert = new Insert(tableSchema, childTableName, row);
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001244
1245 ArrayList<Operation> operations = Lists.newArrayList();
1246 operations.add(insert);
1247
1248 if (parentTableName != null && parentColumnName != null) {
1249 TableSchema parentTableSchema = dbSchema
1250 .getTableSchema(parentTableName);
1251 ColumnSchema parentColumnSchema = parentTableSchema
1252 .getColumnSchema(parentColumnName);
1253
1254 List<Mutation> mutations = Lists.newArrayList();
1255 Mutation mutation = MutationUtil.insert(parentColumnSchema.name(),
Sho SHIMIZUff18f8c2016-03-11 14:43:53 -08001256 Uuid.uuid(childTableName));
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001257 mutations.add(mutation);
1258
1259 List<Condition> conditions = Lists.newArrayList();
Hyunsun Moon1251e192016-06-07 16:57:05 -07001260 Condition condition = ConditionUtil.isEqual(UUID, Uuid.uuid(parentUuid));
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001261 conditions.add(condition);
1262
1263 Mutate op = new Mutate(parentTableSchema, conditions, mutations);
1264 operations.add(op);
1265 }
Hyunsun Moon1251e192016-06-07 16:57:05 -07001266 if (childTableName.equalsIgnoreCase(PORT)) {
1267 log.debug("Handle port insert");
Hyunsun Moondd14e8e2016-06-09 16:17:32 -07001268 Insert intfInsert = handlePortInsertTable(row);
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001269
1270 if (intfInsert != null) {
1271 operations.add(intfInsert);
1272 }
1273
1274 Insert ins = (Insert) operations.get(0);
Hyunsun Moon1251e192016-06-07 16:57:05 -07001275 ins.getRow().put("interfaces", Uuid.uuid(INTERFACE));
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001276 }
1277
1278 List<OperationResult> results;
1279 try {
jaegonkim01d7c912017-01-22 22:03:38 +09001280 results = transactConfig(DATABASENAME, operations)
1281 .get(TRANSACTCONFIG_TIMEOUT, TimeUnit.SECONDS);
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001282 return results.get(0).getUuid().value();
jaegonkim01d7c912017-01-22 22:03:38 +09001283 } catch (TimeoutException e) {
1284 log.warn("TimeoutException thrown while to get result");
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001285 } catch (InterruptedException e) {
1286 log.warn("Interrupted while waiting to get result");
1287 Thread.currentThread().interrupt();
1288 } catch (ExecutionException e) {
1289 log.error("Exception thrown while to get result");
1290 }
1291
1292 return null;
1293 }
1294
jaegonkim01d7c912017-01-22 22:03:38 +09001295
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001296 /**
1297 * Handles port insert.
1298 *
andreaed976a42015-10-05 14:38:25 -07001299 * @param portRow row of port
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001300 * @return insert, empty if null
1301 */
Hyunsun Moondd14e8e2016-06-09 16:17:32 -07001302 private Insert handlePortInsertTable(Row portRow) {
Hyunsun Moon1251e192016-06-07 16:57:05 -07001303 DatabaseSchema dbSchema = schema.get(DATABASENAME);
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001304
Hyunsun Moon1251e192016-06-07 16:57:05 -07001305 TableSchema portTableSchema = dbSchema.getTableSchema(PORT);
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001306 ColumnSchema portColumnSchema = portTableSchema.getColumnSchema("name");
1307
1308 String portName = (String) portRow.getColumn(portColumnSchema.name()).data();
Hyunsun Moon1251e192016-06-07 16:57:05 -07001309 Interface inf = (Interface) TableGenerator.createTable(dbSchema, OvsdbTable.INTERFACE);
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001310 inf.setName(portName);
1311
Hyunsun Moon1251e192016-06-07 16:57:05 -07001312 TableSchema intfTableSchema = dbSchema.getTableSchema(INTERFACE);
1313 return new Insert(intfTableSchema, INTERFACE, inf.getRow());
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001314 }
1315
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001316 @Override
1317 public ListenableFuture<DatabaseSchema> getOvsdbSchema(String dbName) {
1318 if (dbName == null) {
1319 return null;
1320 }
1321 DatabaseSchema databaseSchema = schema.get(dbName);
1322 if (databaseSchema == null) {
1323 List<String> dbNames = new ArrayList<String>();
1324 dbNames.add(dbName);
Hyunsun Moon1251e192016-06-07 16:57:05 -07001325 Function<JsonNode, DatabaseSchema> rowFunction = input -> {
1326 log.debug("Get ovsdb database schema {}", dbName);
1327 DatabaseSchema dbSchema = FromJsonUtil.jsonNodeToDbSchema(dbName, input);
1328 if (dbSchema == null) {
1329 log.debug("Get ovsdb database schema error");
1330 return null;
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001331 }
Hyunsun Moon1251e192016-06-07 16:57:05 -07001332 schema.put(dbName, dbSchema);
1333 return dbSchema;
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001334 };
1335
1336 ListenableFuture<JsonNode> input = getSchema(dbNames);
1337 if (input != null) {
1338 return Futures.transform(input, rowFunction);
1339 }
1340 return null;
1341 } else {
1342 return Futures.immediateFuture(databaseSchema);
1343 }
1344 }
1345
1346 @Override
1347 public ListenableFuture<TableUpdates> monitorTables(String dbName, String id) {
1348 if (dbName == null) {
1349 return null;
1350 }
1351 DatabaseSchema dbSchema = schema.get(dbName);
1352 if (dbSchema != null) {
Hyunsun Moon1251e192016-06-07 16:57:05 -07001353 Function<JsonNode, TableUpdates> rowFunction = input -> {
1354 log.debug("Get table updates");
1355 TableUpdates updates = FromJsonUtil.jsonNodeToTableUpdates(input, dbSchema);
1356 if (updates == null) {
1357 log.debug("Get table updates error");
1358 return null;
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001359 }
Hyunsun Moon1251e192016-06-07 16:57:05 -07001360 return updates;
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001361 };
1362 return Futures.transform(monitor(dbSchema, id), rowFunction);
1363 }
1364 return null;
1365 }
1366
Hyunsun Moondd14e8e2016-06-09 16:17:32 -07001367 private ListenableFuture<List<OperationResult>> transactConfig(String dbName,
1368 List<Operation> operations) {
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001369 if (dbName == null) {
1370 return null;
1371 }
1372 DatabaseSchema dbSchema = schema.get(dbName);
1373 if (dbSchema != null) {
andreaed976a42015-10-05 14:38:25 -07001374 Function<List<JsonNode>, List<OperationResult>> rowFunction = (input -> {
Jonathan Hart6523e122017-11-14 09:23:49 -08001375 try {
1376 log.debug("Get ovsdb operation result");
1377 List<OperationResult> result = FromJsonUtil.jsonNodeToOperationResult(input, operations);
1378 if (result == null) {
1379 log.debug("The operation result is null");
1380 return null;
1381 }
1382 return result;
1383 } catch (Exception e) {
1384 log.error("Exception while parsing result", e);
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001385 }
Jonathan Hart6523e122017-11-14 09:23:49 -08001386 return null;
andreaed976a42015-10-05 14:38:25 -07001387 });
Hyunsun Moon1251e192016-06-07 16:57:05 -07001388 return Futures.transform(transact(dbSchema, operations), rowFunction);
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001389 }
1390 return null;
1391 }
1392
1393 @Override
1394 public ListenableFuture<JsonNode> getSchema(List<String> dbnames) {
1395 String id = java.util.UUID.randomUUID().toString();
1396 String getSchemaString = JsonRpcWriterUtil.getSchemaStr(id, dbnames);
1397
1398 SettableFuture<JsonNode> sf = SettableFuture.create();
1399 requestResult.put(id, sf);
1400 requestMethod.put(id, "getSchema");
1401
1402 channel.writeAndFlush(getSchemaString);
1403 return sf;
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001404 }
1405
1406 @Override
1407 public ListenableFuture<List<String>> echo() {
1408 String id = java.util.UUID.randomUUID().toString();
1409 String echoString = JsonRpcWriterUtil.echoStr(id);
1410
1411 SettableFuture<List<String>> sf = SettableFuture.create();
1412 requestResult.put(id, sf);
1413 requestMethod.put(id, "echo");
1414
1415 channel.writeAndFlush(echoString);
1416 return sf;
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001417 }
1418
1419 @Override
1420 public ListenableFuture<JsonNode> monitor(DatabaseSchema dbSchema,
1421 String monitorId) {
1422 String id = java.util.UUID.randomUUID().toString();
1423 String monitorString = JsonRpcWriterUtil.monitorStr(id, monitorId,
1424 dbSchema);
1425
1426 SettableFuture<JsonNode> sf = SettableFuture.create();
1427 requestResult.put(id, sf);
1428 requestMethod.put(id, "monitor");
1429
1430 channel.writeAndFlush(monitorString);
1431 return sf;
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001432 }
1433
1434 @Override
1435 public ListenableFuture<List<String>> listDbs() {
1436 String id = java.util.UUID.randomUUID().toString();
1437 String listDbsString = JsonRpcWriterUtil.listDbsStr(id);
1438
1439 SettableFuture<List<String>> sf = SettableFuture.create();
1440 requestResult.put(id, sf);
1441 requestMethod.put(id, "listDbs");
1442
1443 channel.writeAndFlush(listDbsString);
1444 return sf;
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001445 }
1446
1447 @Override
1448 public ListenableFuture<List<JsonNode>> transact(DatabaseSchema dbSchema,
1449 List<Operation> operations) {
1450 String id = java.util.UUID.randomUUID().toString();
1451 String transactString = JsonRpcWriterUtil.transactStr(id, dbSchema,
1452 operations);
1453
1454 SettableFuture<List<JsonNode>> sf = SettableFuture.create();
1455 requestResult.put(id, sf);
1456 requestMethod.put(id, "transact");
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001457 channel.writeAndFlush(transactString);
1458 return sf;
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001459 }
1460
andreaed976a42015-10-05 14:38:25 -07001461 @SuppressWarnings({"rawtypes", "unchecked"})
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001462 @Override
1463 public void processResult(JsonNode response) {
1464 log.debug("Handle result");
1465 String requestId = response.get("id").asText();
1466 SettableFuture sf = requestResult.get(requestId);
1467 if (sf == null) {
1468 log.debug("No such future to process");
1469 return;
1470 }
1471 String methodName = requestMethod.get(requestId);
Hyunsun Moon1251e192016-06-07 16:57:05 -07001472 sf.set(FromJsonUtil.jsonResultParser(response, methodName));
tanbangcheng1afecce2017-11-12 11:41:28 +08001473
1474 requestResult.remove(requestId);
1475 requestMethod.remove(requestId);
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001476 }
1477
1478 @Override
1479 public void processRequest(JsonNode requestJson) {
1480 log.debug("Handle request");
1481 if (requestJson.get("method").asText().equalsIgnoreCase("echo")) {
1482 log.debug("handle echo request");
1483
1484 String replyString = FromJsonUtil.getEchoRequestStr(requestJson);
1485 channel.writeAndFlush(replyString);
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001486 } else {
Hyunsun Moon1251e192016-06-07 16:57:05 -07001487 FromJsonUtil.jsonCallbackRequestParser(requestJson, monitorCallBack);
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001488 }
1489 }
1490
1491 @Override
1492 public void setCallback(Callback monitorCallback) {
1493 this.monitorCallBack = monitorCallback;
1494 }
1495
1496 @Override
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001497 public Set<OvsdbBridge> getBridges() {
Hyunsun Moon1251e192016-06-07 16:57:05 -07001498 Set<OvsdbBridge> ovsdbBridges = new HashSet<>();
1499 OvsdbTableStore tableStore = getTableStore(DATABASENAME);
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001500 if (tableStore == null) {
MaoJianweidac220d2016-07-04 22:37:52 +08001501 return ovsdbBridges;
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001502 }
Hyunsun Moon1251e192016-06-07 16:57:05 -07001503 OvsdbRowStore rowStore = tableStore.getRows(BRIDGE);
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001504 if (rowStore == null) {
MaoJianweidac220d2016-07-04 22:37:52 +08001505 return ovsdbBridges;
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001506 }
1507 ConcurrentMap<String, Row> rows = rowStore.getRowStore();
1508 for (String uuid : rows.keySet()) {
jaegonkim7b77f712018-01-14 17:18:27 +09001509 Row bridgeRow = getRow(DATABASENAME, BRIDGE, uuid);
1510 OvsdbBridge ovsdbBridge = getOvsdbBridge(bridgeRow, Uuid.uuid(uuid));
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001511 if (ovsdbBridge != null) {
1512 ovsdbBridges.add(ovsdbBridge);
1513 }
1514 }
1515 return ovsdbBridges;
1516 }
1517
1518 @Override
andreaed976a42015-10-05 14:38:25 -07001519 public Set<ControllerInfo> getControllers(DeviceId openflowDeviceId) {
Jonathan Hart51539b82015-10-29 09:53:04 -07001520 Uuid bridgeUuid = getBridgeUuid(openflowDeviceId);
andreaed976a42015-10-05 14:38:25 -07001521 if (bridgeUuid == null) {
1522 log.warn("bad bridge Uuid");
1523 return null;
1524 }
1525 List<Controller> controllers = getControllers(bridgeUuid);
1526 if (controllers == null) {
1527 log.warn("bad list of controllers");
1528 return null;
1529 }
Hyunsun Moon1251e192016-06-07 16:57:05 -07001530 return controllers.stream().map(controller -> new ControllerInfo(
1531 (String) controller.getTargetColumn()
1532 .data())).collect(Collectors.toSet());
andreaed976a42015-10-05 14:38:25 -07001533 }
1534
Jonathan Hart51539b82015-10-29 09:53:04 -07001535 private List<Controller> getControllers(Uuid bridgeUuid) {
Hyunsun Moon1251e192016-06-07 16:57:05 -07001536 DatabaseSchema dbSchema = schema.get(DATABASENAME);
andreaed976a42015-10-05 14:38:25 -07001537 if (dbSchema == null) {
1538 return null;
1539 }
Hyunsun Moon1251e192016-06-07 16:57:05 -07001540 OvsdbRowStore rowStore = getRowStore(DATABASENAME, BRIDGE);
andreaed976a42015-10-05 14:38:25 -07001541 if (rowStore == null) {
1542 log.debug("There is no bridge table");
1543 return null;
1544 }
1545
1546 Row bridgeRow = rowStore.getRow(bridgeUuid.value());
1547 Bridge bridge = (Bridge) TableGenerator.
1548 getTable(dbSchema, bridgeRow, OvsdbTable.BRIDGE);
1549
1550 //FIXME remove log
1551 log.warn("type of controller column", bridge.getControllerColumn()
1552 .data().getClass());
Jonathan Hart51539b82015-10-29 09:53:04 -07001553 Set<Uuid> controllerUuids = (Set<Uuid>) ((OvsdbSet) bridge
andreaed976a42015-10-05 14:38:25 -07001554 .getControllerColumn().data()).set();
andreaed976a42015-10-05 14:38:25 -07001555
Hyunsun Moon1251e192016-06-07 16:57:05 -07001556 OvsdbRowStore controllerRowStore = getRowStore(DATABASENAME, CONTROLLER);
andreaed976a42015-10-05 14:38:25 -07001557 if (controllerRowStore == null) {
1558 log.debug("There is no controller table");
1559 return null;
1560 }
1561
1562 List<Controller> ovsdbControllers = new ArrayList<>();
1563 ConcurrentMap<String, Row> controllerTableRows = controllerRowStore.getRowStore();
1564 controllerTableRows.forEach((key, row) -> {
Jonathan Hart51539b82015-10-29 09:53:04 -07001565 if (!controllerUuids.contains(Uuid.uuid(key))) {
andreaed976a42015-10-05 14:38:25 -07001566 return;
1567 }
1568 Controller controller = (Controller) TableGenerator
1569 .getTable(dbSchema, row, OvsdbTable.CONTROLLER);
1570 ovsdbControllers.add(controller);
1571 });
1572 return ovsdbControllers;
1573 }
1574
1575
Jonathan Hart51539b82015-10-29 09:53:04 -07001576 private Uuid getBridgeUuid(DeviceId openflowDeviceId) {
Hyunsun Moon1251e192016-06-07 16:57:05 -07001577 DatabaseSchema dbSchema = schema.get(DATABASENAME);
andreaed976a42015-10-05 14:38:25 -07001578 if (dbSchema == null) {
1579 return null;
1580 }
Hyunsun Moon1251e192016-06-07 16:57:05 -07001581 OvsdbRowStore rowStore = getRowStore(DATABASENAME, BRIDGE);
andreaed976a42015-10-05 14:38:25 -07001582 if (rowStore == null) {
1583 log.debug("There is no bridge table");
1584 return null;
1585 }
1586
1587 ConcurrentMap<String, Row> bridgeTableRows = rowStore.getRowStore();
Jonathan Hart51539b82015-10-29 09:53:04 -07001588 final AtomicReference<Uuid> uuid = new AtomicReference<>();
andreaed976a42015-10-05 14:38:25 -07001589 for (Map.Entry<String, Row> entry : bridgeTableRows.entrySet()) {
Hyunsun Moon1251e192016-06-07 16:57:05 -07001590 Bridge bridge = (Bridge) TableGenerator.getTable(
1591 dbSchema,
1592 entry.getValue(),
1593 OvsdbTable.BRIDGE);
1594
1595 if (matchesDpid(bridge, openflowDeviceId)) {
Jonathan Hart51539b82015-10-29 09:53:04 -07001596 uuid.set(Uuid.uuid(entry.getKey()));
andreaed976a42015-10-05 14:38:25 -07001597 break;
1598 }
1599 }
1600 if (uuid.get() == null) {
1601 log.debug("There is no bridge for {}", openflowDeviceId);
1602 }
1603 return uuid.get();
andreaed976a42015-10-05 14:38:25 -07001604 }
1605
1606 private static boolean matchesDpid(Bridge b, DeviceId deviceId) {
1607 String ofDpid = deviceId.toString().replace("of:", "");
1608 Set ofDeviceIds = ((OvsdbSet) b.getDatapathIdColumn().data()).set();
1609 //TODO Set<String>
1610 return ofDeviceIds.contains(ofDpid);
1611 }
1612
1613 @Override
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001614 public Set<OvsdbPort> getPorts() {
Hyunsun Moon1251e192016-06-07 16:57:05 -07001615 Set<OvsdbPort> ovsdbPorts = new HashSet<>();
1616 OvsdbTableStore tableStore = getTableStore(DATABASENAME);
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001617 if (tableStore == null) {
1618 return null;
1619 }
Hyunsun Moon1251e192016-06-07 16:57:05 -07001620 OvsdbRowStore rowStore = tableStore.getRows(INTERFACE);
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001621 if (rowStore == null) {
1622 return null;
1623 }
1624 ConcurrentMap<String, Row> rows = rowStore.getRowStore();
1625 for (String uuid : rows.keySet()) {
Hyunsun Moon1251e192016-06-07 16:57:05 -07001626 Row row = getRow(DATABASENAME, INTERFACE, uuid);
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001627 OvsdbPort ovsdbPort = getOvsdbPort(row);
1628 if (ovsdbPort != null) {
1629 ovsdbPorts.add(ovsdbPort);
1630 }
1631 }
1632 return ovsdbPorts;
1633 }
1634
1635 @Override
1636 public DatabaseSchema getDatabaseSchema(String dbName) {
1637 return schema.get(dbName);
1638 }
1639
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001640 private OvsdbPort getOvsdbPort(Row row) {
Hyunsun Moon1251e192016-06-07 16:57:05 -07001641 DatabaseSchema dbSchema = getDatabaseSchema(DATABASENAME);
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001642 Interface intf = (Interface) TableGenerator
1643 .getTable(dbSchema, row, OvsdbTable.INTERFACE);
1644 if (intf == null) {
1645 return null;
1646 }
1647 long ofPort = getOfPort(intf);
1648 String portName = intf.getName();
1649 if ((ofPort < 0) || (portName == null)) {
1650 return null;
1651 }
Hyunsun Moon1251e192016-06-07 16:57:05 -07001652 return new OvsdbPort(new OvsdbPortNumber(ofPort), new OvsdbPortName(portName));
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001653 }
1654
jaegonkim7b77f712018-01-14 17:18:27 +09001655 private OvsdbBridge getOvsdbBridge(Row row, Uuid bridgeUuid) {
Hyunsun Moon1251e192016-06-07 16:57:05 -07001656 DatabaseSchema dbSchema = getDatabaseSchema(DATABASENAME);
1657 Bridge bridge = (Bridge) TableGenerator.getTable(dbSchema, row, OvsdbTable.BRIDGE);
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001658 if (bridge == null) {
1659 return null;
1660 }
1661
1662 OvsdbSet datapathIdSet = (OvsdbSet) bridge.getDatapathIdColumn().data();
1663 @SuppressWarnings("unchecked")
1664 Set<String> datapathIds = datapathIdSet.set();
Jon Hallcbd1b392017-01-18 20:15:44 -08001665 if (datapathIds == null || datapathIds.isEmpty()) {
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001666 return null;
1667 }
1668 String datapathId = (String) datapathIds.toArray()[0];
1669 String bridgeName = bridge.getName();
1670 if ((datapathId == null) || (bridgeName == null)) {
1671 return null;
1672 }
jaegonkim7b77f712018-01-14 17:18:27 +09001673
1674 List<Controller> controllers = getControllers(bridgeUuid);
1675
1676 if (controllers != null) {
1677 List<ControllerInfo> controllerInfos = controllers.stream().map(
1678 controller -> new ControllerInfo(
1679 (String) controller.getTargetColumn()
1680 .data())).collect(Collectors.toList());
1681
1682 return OvsdbBridge.builder()
1683 .name(bridgeName)
1684 .datapathId(datapathId)
1685 .controllers(controllerInfos)
1686 .build();
1687 } else {
1688 return OvsdbBridge.builder()
1689 .name(bridgeName)
1690 .datapathId(datapathId)
1691 .build();
1692 }
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001693 }
1694
Frank Wange11a98d2016-10-26 17:04:03 +08001695 private OvsdbQos getOvsdbQos(Row row) {
1696 DatabaseSchema dbSchema = getDatabaseSchema(DATABASENAME);
1697 Qos qos = (Qos) TableGenerator.getTable(dbSchema, row, OvsdbTable.QOS);
1698 if (qos == null) {
1699 return null;
1700 }
1701
1702 String type = (String) qos.getTypeColumn().data();
1703 Map<String, String> otherConfigs;
1704 Map<String, String> externalIds;
1705 Map<Long, String> queues;
1706
1707 otherConfigs = ((OvsdbMap) qos.getOtherConfigColumn().data()).map();
1708 externalIds = ((OvsdbMap) qos.getExternalIdsColumn().data()).map();
1709 queues = ((OvsdbMap) qos.getQueuesColumn().data()).map();
1710 return OvsdbQos.builder().qosType(type).
1711 queues(queues).otherConfigs(otherConfigs).
1712 externalIds(externalIds).build();
1713 }
1714
1715 private OvsdbQueue getOvsdbQueue(Row row) {
1716 DatabaseSchema dbSchema = getDatabaseSchema(DATABASENAME);
1717 Queue queue = (Queue) TableGenerator.getTable(dbSchema, row, OvsdbTable.QUEUE);
1718 if (queue == null) {
1719 return null;
1720 }
1721
1722 OvsdbSet dscpOvsdbSet = ((OvsdbSet) queue.getDscpColumn().data());
1723 @SuppressWarnings("unchecked")
1724 Set<String> dscpSet = dscpOvsdbSet.set();
1725 Long dscp = null;
1726 if (dscpSet != null && !dscpSet.isEmpty()) {
1727 dscp = Long.valueOf((String) dscpSet.toArray()[0]);
1728 }
1729
1730 Map<String, String> otherConfigs;
1731 Map<String, String> externalIds;
1732
1733 otherConfigs = ((OvsdbMap) queue.getOtherConfigColumn().data()).map();
1734 externalIds = ((OvsdbMap) queue.getExternalIdsColumn().data()).map();
1735 return OvsdbQueue.builder().dscp(dscp).
1736 otherConfigs(otherConfigs).externalIds(externalIds).build();
1737 }
1738
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001739 private long getOfPort(Interface intf) {
1740 OvsdbSet ofPortSet = (OvsdbSet) intf.getOpenFlowPortColumn().data();
1741 @SuppressWarnings("unchecked")
1742 Set<Integer> ofPorts = ofPortSet.set();
Jon Hallcbd1b392017-01-18 20:15:44 -08001743 if (ofPorts == null || ofPorts.isEmpty()) {
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001744 log.debug("The ofport is null in {}", intf.getName());
1745 return -1;
1746 }
1747 // return (long) ofPorts.toArray()[0];
1748 Iterator<Integer> it = ofPorts.iterator();
1749 return Long.parseLong(it.next().toString());
1750 }
CNluciusa66c3972015-09-06 20:31:29 +08001751
1752 @Override
1753 public Set<OvsdbPort> getLocalPorts(Iterable<String> ifaceids) {
Hyunsun Moon1251e192016-06-07 16:57:05 -07001754 Set<OvsdbPort> ovsdbPorts = new HashSet<>();
1755 OvsdbTableStore tableStore = getTableStore(DATABASENAME);
CNluciusa66c3972015-09-06 20:31:29 +08001756 if (tableStore == null) {
1757 return null;
1758 }
Hyunsun Moon1251e192016-06-07 16:57:05 -07001759 OvsdbRowStore rowStore = tableStore.getRows(INTERFACE);
CNluciusa66c3972015-09-06 20:31:29 +08001760 if (rowStore == null) {
1761 return null;
1762 }
1763 ConcurrentMap<String, Row> rows = rowStore.getRowStore();
1764 for (String uuid : rows.keySet()) {
Hyunsun Moon1251e192016-06-07 16:57:05 -07001765 Row row = getRow(DATABASENAME, INTERFACE, uuid);
1766 DatabaseSchema dbSchema = getDatabaseSchema(DATABASENAME);
CNluciusa66c3972015-09-06 20:31:29 +08001767 Interface intf = (Interface) TableGenerator
1768 .getTable(dbSchema, row, OvsdbTable.INTERFACE);
1769 if (intf == null || getIfaceid(intf) == null) {
1770 continue;
1771 }
1772 String portName = intf.getName();
Hyunsun Moon1251e192016-06-07 16:57:05 -07001773 if (portName == null) {
1774 continue;
1775 }
CNluciusa66c3972015-09-06 20:31:29 +08001776 Set<String> ifaceidSet = Sets.newHashSet(ifaceids);
Hyunsun Moon1251e192016-06-07 16:57:05 -07001777 if (portName.startsWith(TYPEVXLAN) || !ifaceidSet.contains(getIfaceid(intf))) {
CNluciusa66c3972015-09-06 20:31:29 +08001778 continue;
1779 }
1780 long ofPort = getOfPort(intf);
Hyunsun Moon1251e192016-06-07 16:57:05 -07001781 if (ofPort < 0) {
CNluciusa66c3972015-09-06 20:31:29 +08001782 continue;
1783 }
Hyunsun Moon1251e192016-06-07 16:57:05 -07001784 ovsdbPorts.add(new OvsdbPort(new OvsdbPortNumber(ofPort),
1785 new OvsdbPortName(portName)));
CNluciusa66c3972015-09-06 20:31:29 +08001786 }
1787 return ovsdbPorts;
1788 }
1789
1790 private String getIfaceid(Interface intf) {
1791 OvsdbMap ovsdbMap = (OvsdbMap) intf.getExternalIdsColumn().data();
1792 @SuppressWarnings("unchecked")
1793 Map<String, String> externalIds = ovsdbMap.map();
1794 if (externalIds.isEmpty()) {
1795 log.warn("The external_ids is null");
1796 return null;
1797 }
Hyunsun Moon1251e192016-06-07 16:57:05 -07001798 String ifaceid = externalIds.get(EXTERNAL_ID_INTERFACE_ID);
CNluciusa66c3972015-09-06 20:31:29 +08001799 if (ifaceid == null) {
1800 log.warn("The ifaceid is null");
1801 return null;
1802 }
1803 return ifaceid;
1804 }
Hyunsun Moon5fb20a52015-09-25 17:02:33 -07001805
1806 @Override
1807 public void disconnect() {
1808 channel.disconnect();
1809 this.agent.removeConnectedNode(nodeId);
1810 }
Saritha1583a6f2017-06-16 14:42:58 +05301811
1812 @Override
1813 public List<OvsdbPortName> getPorts(List<String> portNames, DeviceId deviceId) {
1814 Uuid bridgeUuid = getBridgeUuid(deviceId);
1815 if (bridgeUuid == null) {
1816 log.error("Can't find the bridge for the deviceId {}", deviceId);
1817 return Collections.emptyList();
1818 }
1819 DatabaseSchema dbSchema = schema.get(DATABASENAME);
1820 Row bridgeRow = getRow(DATABASENAME, BRIDGE, bridgeUuid.value());
1821 Bridge bridge = (Bridge) TableGenerator.getTable(dbSchema, bridgeRow, OvsdbTable.BRIDGE);
1822 if (bridge == null) {
1823 return Collections.emptyList();
1824 }
1825 OvsdbSet setPorts = (OvsdbSet) bridge.getPortsColumn().data();
1826 Set<Uuid> portSet = setPorts.set();
1827 if (portSet.isEmpty()) {
1828 return Collections.emptyList();
1829 }
1830
1831 Map<Uuid, Port> portMap = portSet.stream().collect(Collectors.toMap(
1832 java.util.function.Function.identity(), port -> (Port) TableGenerator
1833 .getTable(dbSchema, getRow(DATABASENAME,
1834 PORT, port.value()), OvsdbTable.PORT)));
1835
1836 List<OvsdbPortName> portList = portMap.entrySet().stream().filter(port -> Objects.nonNull(port.getValue())
1837 && portNames.contains(port.getValue().getName())
1838 && Objects.nonNull(getInterfacebyPort(port.getKey().value(), port.getValue().getName())))
1839 .map(port -> new OvsdbPortName(port.getValue().getName())).collect(Collectors.toList());
1840
1841 return Collections.unmodifiableList(portList);
1842 }
1843
1844 @Override
1845 public boolean getPortError(List<OvsdbPortName> portNames, DeviceId bridgeId) {
1846 Uuid bridgeUuid = getBridgeUuid(bridgeId);
1847
1848 List<Interface> interfaceList = portNames.stream().collect(Collectors
1849 .toMap(java.util.function.Function.identity(),
1850 port -> (Interface) getInterfacebyPort(getPortUuid(port.value(),
1851 bridgeUuid.value()), port.value())))
1852 .entrySet().stream().filter(intf -> Objects.nonNull(intf.getValue())
1853 && ((OvsdbSet) intf.getValue().getOpenFlowPortColumn().data()).set()
1854 .stream().findAny().orElse(OFPORT_ERROR_COMPARISON).equals(OFPORT_ERROR))
1855 .map(intf -> intf.getValue()).collect(Collectors.toList());
1856
1857 interfaceList.forEach(intf -> new Consumer<Interface>() {
1858 @Override
1859 public void accept(Interface intf) {
1860 try {
1861 Set<String> setErrors = ((OvsdbSet) intf.getErrorColumn().data()).set();
1862 log.info("Port has errors. ofport value - {}, Interface - {} has error - {} ",
1863 intf.getOpenFlowPortColumn().data(), intf.getName(), setErrors.stream()
1864 .findFirst().get());
1865 } catch (ColumnSchemaNotFoundException | VersionMismatchException e) {
1866 log.debug("Port has errors. ofport value - {}, Interface - {} has error - {} ",
1867 intf.getOpenFlowPortColumn().data(), intf.getName(), e);
1868 }
1869 }
1870 }.accept(intf));
1871
1872 return !interfaceList.isEmpty();
1873 }
1874
1875 private Interface getInterfacebyPort(String portUuid, String portName) {
1876 DatabaseSchema dbSchema = schema.get(DATABASENAME);
1877
1878 Row portRow = getRow(DATABASENAME, PORT, portUuid);
1879 Port port = (Port) TableGenerator.getTable(dbSchema, portRow,
1880 OvsdbTable.PORT);
1881 if (port == null) {
1882 return null;
1883 }
1884
1885 OvsdbSet setInterfaces = (OvsdbSet) port.getInterfacesColumn().data();
1886 Set<Uuid> interfaces = setInterfaces.set();
1887
1888 return interfaces.stream().map(intf -> (Interface) TableGenerator
1889 .getTable(dbSchema, getRow(DATABASENAME,
1890 INTERFACE, intf.value()), OvsdbTable.INTERFACE))
1891 .filter(intf -> Objects.nonNull(intf) && portName.equalsIgnoreCase(intf.getName()))
1892 .findFirst().orElse(null);
1893 }
Sho SHIMIZUe4efe452015-08-26 15:06:55 -07001894}