blob: dde2416da43020464942a199f5f0aaaeb78e7238 [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.impl;
17
andreaed976a42015-10-05 14:38:25 -070018import com.fasterxml.jackson.databind.JsonNode;
debanshur37cf6ba2018-05-08 20:07:30 +053019import com.google.common.base.Strings;
andreaed976a42015-10-05 14:38:25 -070020import com.google.common.collect.ImmutableList;
Sho SHIMIZUe4efe452015-08-26 15:06:55 -070021import org.onlab.packet.IpAddress;
22import org.onlab.packet.MacAddress;
Hyunsun Moon5fb20a52015-09-25 17:02:33 -070023import org.onlab.packet.TpPort;
Jian Lieaf31032018-05-03 15:54:03 +090024import org.onlab.util.Tools;
25import org.onosproject.cfg.ComponentConfigService;
Sho SHIMIZUe4efe452015-08-26 15:06:55 -070026import org.onosproject.ovsdb.controller.DefaultEventSubject;
27import org.onosproject.ovsdb.controller.EventSubject;
28import org.onosproject.ovsdb.controller.OvsdbClientService;
29import org.onosproject.ovsdb.controller.OvsdbConstant;
30import org.onosproject.ovsdb.controller.OvsdbController;
31import org.onosproject.ovsdb.controller.OvsdbDatapathId;
32import org.onosproject.ovsdb.controller.OvsdbEvent;
33import org.onosproject.ovsdb.controller.OvsdbEvent.Type;
34import org.onosproject.ovsdb.controller.OvsdbEventListener;
35import org.onosproject.ovsdb.controller.OvsdbIfaceId;
36import org.onosproject.ovsdb.controller.OvsdbNodeId;
37import org.onosproject.ovsdb.controller.OvsdbNodeListener;
38import org.onosproject.ovsdb.controller.OvsdbPortName;
39import org.onosproject.ovsdb.controller.OvsdbPortNumber;
40import org.onosproject.ovsdb.controller.OvsdbPortType;
41import org.onosproject.ovsdb.controller.driver.OvsdbAgent;
debanshur37cf6ba2018-05-08 20:07:30 +053042import org.onosproject.ovsdb.controller.impl.TlsParams.TlsMode;
Sho SHIMIZUe4efe452015-08-26 15:06:55 -070043import org.onosproject.ovsdb.rfc.jsonrpc.Callback;
44import org.onosproject.ovsdb.rfc.message.TableUpdate;
45import org.onosproject.ovsdb.rfc.message.TableUpdates;
46import org.onosproject.ovsdb.rfc.message.UpdateNotification;
47import org.onosproject.ovsdb.rfc.notation.OvsdbMap;
48import org.onosproject.ovsdb.rfc.notation.OvsdbSet;
49import org.onosproject.ovsdb.rfc.notation.Row;
Jonathan Hart51539b82015-10-29 09:53:04 -070050import org.onosproject.ovsdb.rfc.notation.Uuid;
Sho SHIMIZUe4efe452015-08-26 15:06:55 -070051import org.onosproject.ovsdb.rfc.schema.DatabaseSchema;
52import org.onosproject.ovsdb.rfc.table.Bridge;
53import org.onosproject.ovsdb.rfc.table.Interface;
54import org.onosproject.ovsdb.rfc.table.OvsdbTable;
55import org.onosproject.ovsdb.rfc.table.TableGenerator;
56import org.onosproject.ovsdb.rfc.utils.FromJsonUtil;
57import org.osgi.service.component.ComponentContext;
Ray Milkeyd84f89b2018-08-17 14:54:17 -070058import org.osgi.service.component.annotations.Activate;
59import org.osgi.service.component.annotations.Component;
60import org.osgi.service.component.annotations.Deactivate;
61import org.osgi.service.component.annotations.Modified;
62import org.osgi.service.component.annotations.Reference;
63import org.osgi.service.component.annotations.ReferenceCardinality;
Sho SHIMIZUe4efe452015-08-26 15:06:55 -070064import org.slf4j.Logger;
65import org.slf4j.LoggerFactory;
66
andreaed976a42015-10-05 14:38:25 -070067import java.math.BigInteger;
Jian Lieaf31032018-05-03 15:54:03 +090068import java.util.Dictionary;
andreaed976a42015-10-05 14:38:25 -070069import java.util.HashSet;
70import java.util.Iterator;
71import java.util.List;
72import java.util.Map;
debanshur37cf6ba2018-05-08 20:07:30 +053073import java.util.Objects;
andreaed976a42015-10-05 14:38:25 -070074import java.util.Set;
75import java.util.concurrent.ConcurrentHashMap;
76import java.util.concurrent.CopyOnWriteArraySet;
77import java.util.concurrent.ExecutionException;
jiangruibce80652017-10-17 14:35:42 +080078import java.util.concurrent.TimeUnit;
79import java.util.concurrent.TimeoutException;
jaegonkim1af0ae52017-01-01 10:46:55 +090080import java.util.function.Consumer;
andreaed976a42015-10-05 14:38:25 -070081
82import static com.google.common.base.Preconditions.checkNotNull;
debanshur37cf6ba2018-05-08 20:07:30 +053083import static org.onlab.util.Tools.get;
debanshur37cf6ba2018-05-08 20:07:30 +053084import static org.onosproject.ovsdb.controller.OvsdbConstant.DEFAULT_KS_FILE;
Ray Milkeyd84f89b2018-08-17 14:54:17 -070085import static org.onosproject.ovsdb.controller.OvsdbConstant.DEFAULT_KS_PASSWORD;
debanshur37cf6ba2018-05-08 20:07:30 +053086import static org.onosproject.ovsdb.controller.OvsdbConstant.OVSDB_TLS_FLAG;
Ray Milkeyd84f89b2018-08-17 14:54:17 -070087import static org.onosproject.ovsdb.controller.OvsdbConstant.SERVER_MODE;
debanshur37cf6ba2018-05-08 20:07:30 +053088import static org.onosproject.ovsdb.controller.impl.Controller.MIN_KS_LENGTH;
Sho SHIMIZUe4efe452015-08-26 15:06:55 -070089
90/**
91 * The implementation of OvsdbController.
92 */
Ray Milkeyd84f89b2018-08-17 14:54:17 -070093@Component(immediate = true, service = OvsdbController.class)
Sho SHIMIZUe4efe452015-08-26 15:06:55 -070094public class OvsdbControllerImpl implements OvsdbController {
95
96 public static final Logger log = LoggerFactory
97 .getLogger(OvsdbControllerImpl.class);
jiangruibce80652017-10-17 14:35:42 +080098 private static final long DEFAULT_OVSDB_RPC_TIMEOUT = 3000;
99 private final Controller controller = new Controller();
Sho SHIMIZUe4efe452015-08-26 15:06:55 -0700100 protected ConcurrentHashMap<OvsdbNodeId, OvsdbClientService> ovsdbClients =
kdarapufce5abb2018-05-10 19:37:53 +0530101 new ConcurrentHashMap<>();
Sho SHIMIZUe4efe452015-08-26 15:06:55 -0700102 protected OvsdbAgent agent = new InternalOvsdbNodeAgent();
103 protected InternalMonitorCallBack updateCallback = new InternalMonitorCallBack();
Sho SHIMIZUe4efe452015-08-26 15:06:55 -0700104 protected Set<OvsdbNodeListener> ovsdbNodeListener = new CopyOnWriteArraySet<>();
105 protected Set<OvsdbEventListener> ovsdbEventListener = new CopyOnWriteArraySet<>();
Sho SHIMIZUe4efe452015-08-26 15:06:55 -0700106 protected ConcurrentHashMap<String, OvsdbClientService> requestNotification =
kdarapufce5abb2018-05-10 19:37:53 +0530107 new ConcurrentHashMap<>();
108 protected ConcurrentHashMap<String, String> requestDbName = new ConcurrentHashMap<>();
Sho SHIMIZUe4efe452015-08-26 15:06:55 -0700109
Ray Milkeyd84f89b2018-08-17 14:54:17 -0700110 @Reference(cardinality = ReferenceCardinality.MANDATORY)
Jian Lieaf31032018-05-03 15:54:03 +0900111 protected ComponentConfigService configService;
112
Ray Milkeyd84f89b2018-08-17 14:54:17 -0700113 //@Property(name = "serverMode", boolValue = SERVER_MODE,
114 // label = "Run as server mode, listen on 6640 port")
Jian Lieaf31032018-05-03 15:54:03 +0900115 private boolean serverMode = SERVER_MODE;
116
Ray Milkeyd84f89b2018-08-17 14:54:17 -0700117 //@Property(name = "enableOvsdbTls", boolValue = OVSDB_TLS_FLAG,
118 // label = "TLS mode for OVSDB channel; options are: true false")
debanshur37cf6ba2018-05-08 20:07:30 +0530119 private boolean enableOvsdbTls = OVSDB_TLS_FLAG;
120
Ray Milkeyd84f89b2018-08-17 14:54:17 -0700121 //@Property(name = "keyStoreLocation", value = DEFAULT_KS_FILE,
122 // label = "File path to KeyStore for Ovsdb TLS Connections")
debanshur37cf6ba2018-05-08 20:07:30 +0530123 protected String keyStoreLocation = DEFAULT_KS_FILE;
124
Ray Milkeyd84f89b2018-08-17 14:54:17 -0700125 //@Property(name = "trustStoreLocation", value = DEFAULT_KS_FILE,
126 // label = "File path to TrustStore for Ovsdb TLS Connections")
debanshur37cf6ba2018-05-08 20:07:30 +0530127 protected String trustStoreLocation = DEFAULT_KS_FILE;
128
Ray Milkeyd84f89b2018-08-17 14:54:17 -0700129 //@Property(name = "keyStorePassword", value = DEFAULT_KS_PASSWORD,
130 // label = "KeyStore Password")
debanshur37cf6ba2018-05-08 20:07:30 +0530131 protected String keyStorePassword = DEFAULT_KS_PASSWORD;
132
Ray Milkeyd84f89b2018-08-17 14:54:17 -0700133 //@Property(name = "trustStorePassword", value = DEFAULT_KS_PASSWORD,
134 // label = "TrustStore Password")
debanshur37cf6ba2018-05-08 20:07:30 +0530135 protected String trustStorePassword = DEFAULT_KS_PASSWORD;
136
Sho SHIMIZUe4efe452015-08-26 15:06:55 -0700137 @Activate
138 public void activate(ComponentContext context) {
Jian Lieaf31032018-05-03 15:54:03 +0900139 configService.registerProperties(getClass());
debanshur37cf6ba2018-05-08 20:07:30 +0530140 modified(context);
141 controller.start(agent, updateCallback, serverMode);
Jian Lieaf31032018-05-03 15:54:03 +0900142
Sho SHIMIZUe4efe452015-08-26 15:06:55 -0700143 log.info("Started");
144 }
145
146 @Deactivate
147 public void deactivate() {
148 controller.stop();
Jian Lieaf31032018-05-03 15:54:03 +0900149
150 configService.unregisterProperties(getClass(), false);
151
debanshur37cf6ba2018-05-08 20:07:30 +0530152 log.info("Stopped");
Sho SHIMIZUe4efe452015-08-26 15:06:55 -0700153 }
154
Jian Lieaf31032018-05-03 15:54:03 +0900155 @Modified
156 protected void modified(ComponentContext context) {
debanshur37cf6ba2018-05-08 20:07:30 +0530157 this.setConfigParams(context.getProperties());
158 }
Jian Lieaf31032018-05-03 15:54:03 +0900159
debanshur37cf6ba2018-05-08 20:07:30 +0530160 /**
161 * Sets config params.
162 *
163 * @param properties dictionary
164 */
165 public void setConfigParams(Dictionary<?, ?> properties) {
166 boolean restartRequired = setServerMode(properties);
167 TlsParams tlsParams = getTlsParams(properties);
168 restartRequired |= controller.setTlsParameters(tlsParams);
169 if (restartRequired) {
170 restartController();
171 }
172 }
173
174 /**
175 * Gets the TLS parameters from the properties dict.
176 *
177 * @param properties dictionary
178 * @return TlsParams Modified Tls Params
179 */
180 private TlsParams getTlsParams(Dictionary<?, ?> properties) {
181 TlsMode mode = null;
182
183 boolean flag = Tools.isPropertyEnabled(properties, "enableOvsdbTls");
184 if (Objects.isNull(flag) || !flag) {
185 log.warn("OvsdbTLS Disabled");
186 mode = TlsMode.DISABLED;
187 } else {
188 log.warn("OvsdbTLS Enabled");
189 mode = TlsMode.ENABLED;
190 }
191
192 String ksLocation = null, tsLocation = null, ksPwd = null, tsPwd = null;
193
194 ksLocation = get(properties, "keyStoreLocation");
195 if (Strings.isNullOrEmpty(ksLocation)) {
196 log.warn("trustStoreLocation is not configured");
197 mode = TlsMode.DISABLED;
198 }
199
200 tsLocation = get(properties, "trustStoreLocation");
201 if (Strings.isNullOrEmpty(tsLocation)) {
202 log.warn("trustStoreLocation is not configured");
203 mode = TlsMode.DISABLED;
204 }
205
206 ksPwd = get(properties, "keyStorePassword");
207 if (Strings.isNullOrEmpty(ksPwd) || MIN_KS_LENGTH > ksPwd.length()) {
208 log.warn("keyStorePassword is not configured or Password length too small");
209 mode = TlsMode.DISABLED;
210 }
211
212 tsPwd = get(properties, "trustStorePassword");
213 if (Strings.isNullOrEmpty(tsPwd) || MIN_KS_LENGTH > tsPwd.length()) {
214 log.warn("trustStorePassword is not configured or Password length too small");
215 mode = TlsMode.DISABLED;
216 }
217
218 TlsParams tlsParams = new TlsParams(mode, ksLocation, tsLocation, ksPwd, tsPwd);
219 log.info("OVSDB TLS Params: {}", tlsParams);
220 return tlsParams;
221 }
222
223 private boolean setServerMode(Dictionary<?, ?> properties) {
224 boolean flag = Tools.isPropertyEnabled(properties, "serverMode");
225 if (Objects.isNull(flag) || flag == serverMode) {
226 log.info("Ovsdb server mode is not configured, " +
227 "or modified. Using current value of {}", serverMode);
228 return false;
Jian Lieaf31032018-05-03 15:54:03 +0900229 } else {
230 serverMode = flag;
231 log.info("Configured. OVSDB server mode was {}",
debanshur37cf6ba2018-05-08 20:07:30 +0530232 serverMode ? "enabled" : "disabled");
233 return true;
Jian Lieaf31032018-05-03 15:54:03 +0900234 }
235
Jian Lieaf31032018-05-03 15:54:03 +0900236 }
237
Sho SHIMIZUe4efe452015-08-26 15:06:55 -0700238 @Override
239 public void addNodeListener(OvsdbNodeListener listener) {
240 if (!ovsdbNodeListener.contains(listener)) {
241 this.ovsdbNodeListener.add(listener);
242 }
243 }
244
245 @Override
246 public void removeNodeListener(OvsdbNodeListener listener) {
247 this.ovsdbNodeListener.remove(listener);
248 }
249
250 @Override
251 public void addOvsdbEventListener(OvsdbEventListener listener) {
252 if (!ovsdbEventListener.contains(listener)) {
253 this.ovsdbEventListener.add(listener);
254 }
255 }
256
257 @Override
258 public void removeOvsdbEventListener(OvsdbEventListener listener) {
259 this.ovsdbEventListener.remove(listener);
260 }
261
262 @Override
263 public List<OvsdbNodeId> getNodeIds() {
andreaed976a42015-10-05 14:38:25 -0700264 return ImmutableList.copyOf(ovsdbClients.keySet());
Sho SHIMIZUe4efe452015-08-26 15:06:55 -0700265 }
266
267 @Override
268 public OvsdbClientService getOvsdbClient(OvsdbNodeId nodeId) {
269 return ovsdbClients.get(nodeId);
270 }
271
Hyunsun Moon5fb20a52015-09-25 17:02:33 -0700272 @Override
273 public void connect(IpAddress ip, TpPort port) {
274 controller.connect(ip, port);
275 }
276
jaegonkim1af0ae52017-01-01 10:46:55 +0900277 @Override
278 public void connect(IpAddress ip, TpPort port, Consumer<Exception> failhandler) {
279 controller.connect(ip, port, failhandler);
280 }
281
Jian Lieaf31032018-05-03 15:54:03 +0900282 @Override
283 public void setServerMode(boolean serverMode) {
284 this.serverMode = serverMode;
285 restartController();
286 }
287
Sho SHIMIZUe4efe452015-08-26 15:06:55 -0700288 /**
Sho SHIMIZUe4efe452015-08-26 15:06:55 -0700289 * Processes table updates.
290 *
291 * @param clientService OvsdbClientService instance
andreaed976a42015-10-05 14:38:25 -0700292 * @param updates TableUpdates instance
293 * @param dbName ovsdb database name
Sho SHIMIZUe4efe452015-08-26 15:06:55 -0700294 */
295 private void processTableUpdates(OvsdbClientService clientService,
296 TableUpdates updates, String dbName)
297 throws InterruptedException {
298 checkNotNull(clientService, "OvsdbClientService is not null");
299
300 DatabaseSchema dbSchema = clientService.getDatabaseSchema(dbName);
301
302 for (String tableName : updates.result().keySet()) {
303 TableUpdate update = updates.result().get(tableName);
Jonathan Hart51539b82015-10-29 09:53:04 -0700304 for (Uuid uuid : (Set<Uuid>) update.rows().keySet()) {
Sho SHIMIZUe4efe452015-08-26 15:06:55 -0700305 log.debug("Begin to process table updates uuid: {}, databaseName: {}, tableName: {}",
306 uuid.value(), dbName, tableName);
307
Sho SHIMIZUe4efe452015-08-26 15:06:55 -0700308 Row newRow = update.getNew(uuid);
309 if (newRow != null) {
310 clientService.updateOvsdbStore(dbName, tableName,
311 uuid.value(), newRow);
312
313 if (OvsdbConstant.INTERFACE.equals(tableName)) {
314 dispatchInterfaceEvent(clientService,
CNluciusa66c3972015-09-06 20:31:29 +0800315 newRow,
Sho SHIMIZUe4efe452015-08-26 15:06:55 -0700316 OvsdbEvent.Type.PORT_ADDED,
317 dbSchema);
318 }
319 } else if (update.getOld(uuid) != null) {
CNluciusa66c3972015-09-06 20:31:29 +0800320 if (OvsdbConstant.INTERFACE.equals(tableName)) {
321 Row row = clientService.getRow(OvsdbConstant.DATABASENAME, tableName, uuid.value());
322 dispatchInterfaceEvent(clientService,
323 row,
andreaed976a42015-10-05 14:38:25 -0700324 OvsdbEvent.Type.PORT_REMOVED,
325 dbSchema);
Sho SHIMIZUe4efe452015-08-26 15:06:55 -0700326 }
CNluciusa66c3972015-09-06 20:31:29 +0800327 clientService.removeRow(dbName, tableName, uuid.value());
Sho SHIMIZUe4efe452015-08-26 15:06:55 -0700328 }
329 }
330 }
331 }
332
333 /**
334 * Dispatches event to the north.
335 *
336 * @param clientService OvsdbClientService instance
tanbangchenge8d04392017-11-18 18:12:47 +0800337 * @param row a new row
andreaed976a42015-10-05 14:38:25 -0700338 * @param eventType type of event
339 * @param dbSchema ovsdb database schema
Sho SHIMIZUe4efe452015-08-26 15:06:55 -0700340 */
341 private void dispatchInterfaceEvent(OvsdbClientService clientService,
CNluciusa66c3972015-09-06 20:31:29 +0800342 Row row,
Sho SHIMIZUe4efe452015-08-26 15:06:55 -0700343 Type eventType,
344 DatabaseSchema dbSchema) {
345
346 long dpid = getDataPathid(clientService, dbSchema);
347 Interface intf = (Interface) TableGenerator
CNluciusa66c3972015-09-06 20:31:29 +0800348 .getTable(dbSchema, row, OvsdbTable.INTERFACE);
Sho SHIMIZUe4efe452015-08-26 15:06:55 -0700349 if (intf == null) {
350 return;
351 }
352
353 String portType = (String) intf.getTypeColumn().data();
354 long localPort = getOfPort(intf);
355 if (localPort < 0) {
356 return;
357 }
358 String[] macAndIfaceId = getMacAndIfaceid(intf);
359 if (macAndIfaceId == null) {
360 return;
361 }
362
363 EventSubject eventSubject = new DefaultEventSubject(MacAddress.valueOf(
andreaed976a42015-10-05 14:38:25 -0700364 macAndIfaceId[0]),
kdarapufce5abb2018-05-10 19:37:53 +0530365 new HashSet<>(),
Sho SHIMIZUe4efe452015-08-26 15:06:55 -0700366 new OvsdbPortName(intf
andreaed976a42015-10-05 14:38:25 -0700367 .getName()),
Sho SHIMIZUe4efe452015-08-26 15:06:55 -0700368 new OvsdbPortNumber(localPort),
369 new OvsdbDatapathId(Long
andreaed976a42015-10-05 14:38:25 -0700370 .toString(dpid)),
Sho SHIMIZUe4efe452015-08-26 15:06:55 -0700371 new OvsdbPortType(portType),
372 new OvsdbIfaceId(macAndIfaceId[1]));
373 for (OvsdbEventListener listener : ovsdbEventListener) {
kdarapufce5abb2018-05-10 19:37:53 +0530374 listener.handle(new OvsdbEvent<>(eventType,
375 eventSubject));
Sho SHIMIZUe4efe452015-08-26 15:06:55 -0700376 }
377 }
378
379 /**
380 * Gets mac and iface from the table Interface.
381 *
382 * @param intf Interface instance
383 * @return attachedMac, ifaceid
384 */
385 private String[] getMacAndIfaceid(Interface intf) {
386 OvsdbMap ovsdbMap = (OvsdbMap) intf.getExternalIdsColumn().data();
387 @SuppressWarnings("unchecked")
388 Map<String, String> externalIds = ovsdbMap.map();
389 if (externalIds == null) {
390 log.warn("The external_ids is null");
391 return null;
392 }
393
394 String attachedMac = externalIds.get(OvsdbConstant.EXTERNAL_ID_VM_MAC);
395 if (attachedMac == null) {
andreaed976a42015-10-05 14:38:25 -0700396 log.debug("The attachedMac is null"); //FIXME why always null?
Sho SHIMIZUe4efe452015-08-26 15:06:55 -0700397 return null;
398 }
399 String ifaceid = externalIds
400 .get(OvsdbConstant.EXTERNAL_ID_INTERFACE_ID);
401 if (ifaceid == null) {
402 log.warn("The ifaceid is null");
403 return null;
404 }
andreaed976a42015-10-05 14:38:25 -0700405 return new String[]{attachedMac, ifaceid};
Sho SHIMIZUe4efe452015-08-26 15:06:55 -0700406 }
407
408 /**
409 * Gets ofPorts number from table Interface.
410 *
411 * @param intf Interface instance
412 * @return ofport the ofport number
413 */
414 private long getOfPort(Interface intf) {
415 OvsdbSet ofPortSet = (OvsdbSet) intf.getOpenFlowPortColumn().data();
416 @SuppressWarnings("unchecked")
417 Set<Integer> ofPorts = ofPortSet.set();
Jon Hallb1f4e0f2017-02-22 13:36:16 -0800418 if (ofPorts == null || ofPorts.isEmpty()) {
Sho SHIMIZUe4efe452015-08-26 15:06:55 -0700419 log.debug("The ofport is null in {}", intf.getName());
420 return -1;
421 }
422 Iterator<Integer> it = ofPorts.iterator();
423 return Long.parseLong(it.next().toString());
424 }
425
426 /**
427 * Gets datapathid from table bridge.
428 *
429 * @param clientService OvsdbClientService instance
andreaed976a42015-10-05 14:38:25 -0700430 * @param dbSchema ovsdb database schema
Sho SHIMIZUe4efe452015-08-26 15:06:55 -0700431 * @return datapathid the bridge datapathid
432 */
433 private long getDataPathid(OvsdbClientService clientService,
434 DatabaseSchema dbSchema) {
435 String bridgeUuid = clientService
436 .getBridgeUuid(OvsdbConstant.INTEGRATION_BRIDGE);
437 if (bridgeUuid == null) {
438 log.debug("Unable to spot bridge uuid for {} in {}",
439 OvsdbConstant.INTEGRATION_BRIDGE, clientService);
440 return 0;
441 }
442
443 Row bridgeRow = clientService.getRow(OvsdbConstant.DATABASENAME,
444 "Bridge", bridgeUuid);
445 Bridge bridge = (Bridge) TableGenerator.getTable(dbSchema, bridgeRow,
446 OvsdbTable.BRIDGE);
447 OvsdbSet dpidSet = (OvsdbSet) bridge.getDatapathIdColumn().data();
448 @SuppressWarnings("unchecked")
449 Set<String> dpids = dpidSet.set();
Jon Hallcbd1b392017-01-18 20:15:44 -0800450 if (dpids == null || dpids.isEmpty()) {
Sho SHIMIZUe4efe452015-08-26 15:06:55 -0700451 return 0;
452 }
453 return stringToLong((String) dpids.toArray()[0]);
454 }
455
456 private long stringToLong(String values) {
457 long value = (new BigInteger(values.replaceAll(":", ""), 16))
458 .longValue();
459 return value;
460 }
461
Jian Lieaf31032018-05-03 15:54:03 +0900462 private void restartController() {
463 controller.stop();
464 controller.start(agent, updateCallback, serverMode);
465 }
466
Sho SHIMIZUe4efe452015-08-26 15:06:55 -0700467 /**
jiangruibce80652017-10-17 14:35:42 +0800468 * Implementation of an Ovsdb Agent which is responsible for keeping track
469 * of connected node and the state in which they are.
470 */
471 private class InternalOvsdbNodeAgent implements OvsdbAgent {
472 @Override
473 public void addConnectedNode(OvsdbNodeId nodeId,
474 OvsdbClientService ovsdbClient) {
475
476 if (ovsdbClients.get(nodeId) != null) {
477 ovsdbClient.disconnect();
478 return;
479 } else {
480
481 try {
482 List<String> dbNames = ovsdbClient.listDbs().get(DEFAULT_OVSDB_RPC_TIMEOUT, TimeUnit.MILLISECONDS);
483 for (String dbName : dbNames) {
484 DatabaseSchema dbSchema;
485 dbSchema = ovsdbClient.getOvsdbSchema(dbName)
486 .get(DEFAULT_OVSDB_RPC_TIMEOUT, TimeUnit.MILLISECONDS);
487
488 log.debug("Begin to monitor tables");
489 String id = java.util.UUID.randomUUID().toString();
490 TableUpdates updates = ovsdbClient
491 .monitorTables(dbName, id).get(DEFAULT_OVSDB_RPC_TIMEOUT, TimeUnit.MILLISECONDS);
492
493 requestDbName.put(id, dbName);
494 requestNotification.put(id, ovsdbClient);
495
496 if (updates != null) {
497 processTableUpdates(ovsdbClient, updates,
498 dbSchema.name());
499 }
500 }
501 } catch (InterruptedException e) {
502 log.warn("Interrupted while waiting to get message from ovsdb");
503 Thread.currentThread().interrupt();
504 return;
505 } catch (ExecutionException e) {
506 log.error("Exception thrown while to get message from ovsdb");
507 ovsdbClient.disconnect();
508 return;
509 } catch (TimeoutException e) {
510 log.error("TimeoutException thrown while to get message from ovsdb");
511 ovsdbClient.disconnect();
512 return;
513 }
514 ovsdbClients.put(nodeId, ovsdbClient);
515
516 log.debug("Add node to north");
517 for (OvsdbNodeListener l : ovsdbNodeListener) {
518 l.nodeAdded(nodeId);
519 }
520 return;
521 }
522 }
523
524 @Override
525 public void removeConnectedNode(OvsdbNodeId nodeId) {
tanbangchenge8d04392017-11-18 18:12:47 +0800526 requestNotification.forEach((k, v) -> {
527 if (v.nodeId().equals(nodeId)) {
528 requestNotification.remove(k);
529 requestDbName.remove(k);
530
531 ovsdbClients.remove(nodeId);
532 log.debug("Node connection is removed");
533 for (OvsdbNodeListener l : ovsdbNodeListener) {
534 l.nodeRemoved(nodeId);
535 }
536 }
537 });
jiangruibce80652017-10-17 14:35:42 +0800538 }
539 }
540
541 /**
Sho SHIMIZUe4efe452015-08-26 15:06:55 -0700542 * Implementation of an Callback which is responsible for receiving request
543 * infomation from ovsdb.
544 */
545 private class InternalMonitorCallBack implements Callback {
546 @Override
547 public void update(UpdateNotification updateNotification) {
548 Object key = updateNotification.jsonValue();
549 OvsdbClientService ovsdbClient = requestNotification.get(key);
550
551 String dbName = requestDbName.get(key);
552 JsonNode updatesJson = updateNotification.tbUpdatesJsonNode();
553 DatabaseSchema dbSchema = ovsdbClient.getDatabaseSchema(dbName);
554 TableUpdates updates = FromJsonUtil
555 .jsonNodeToTableUpdates(updatesJson, dbSchema);
556 try {
557 processTableUpdates(ovsdbClient, updates, dbName);
558 } catch (InterruptedException e) {
559 log.warn("Interrupted while processing table updates");
560 Thread.currentThread().interrupt();
561 }
562 }
563
564 @Override
565 public void locked(List<String> ids) {
566 // TODO Auto-generated method stub
567 }
568
569 @Override
570 public void stolen(List<String> ids) {
571 // TODO Auto-generated method stub
572 }
573
574 }
575
576}