Hyunsun Moon
Committed by Gerrit Code Review

CORD-333 Minimized OVSDB provider dependency

With this patch, cordvtn doesn't need to care for OVSDB connection state
anymore. It will make a connection to OVSDB server like befor but just
for node init and disconnect the OVSDB right after init is done.
- Changed OvsdbNode to CordVtnNode
- Removed OVSDB connect/disconnect and added initNode instead
- Changed ovsdb* commands to cordvtn-node* command, and removed
  connect/disconnect command and added init instead
- Fixed to remove OVSDB device from the system after node init or before
  making a connection to work around OVSDB device re-connect issue

Change-Id: If69369a06526947122494b2f7e816e37aa931f2c
...@@ -15,7 +15,6 @@ ...@@ -15,7 +15,6 @@
15 */ 15 */
16 package org.onosproject.cordvtn; 16 package org.onosproject.cordvtn;
17 17
18 -import com.google.common.collect.Collections2;
19 import com.google.common.collect.Sets; 18 import com.google.common.collect.Sets;
20 import org.apache.felix.scr.annotations.Activate; 19 import org.apache.felix.scr.annotations.Activate;
21 import org.apache.felix.scr.annotations.Component; 20 import org.apache.felix.scr.annotations.Component;
...@@ -32,6 +31,7 @@ import org.onosproject.net.DefaultAnnotations; ...@@ -32,6 +31,7 @@ import org.onosproject.net.DefaultAnnotations;
32 import org.onosproject.net.Device; 31 import org.onosproject.net.Device;
33 import org.onosproject.net.DeviceId; 32 import org.onosproject.net.DeviceId;
34 import org.onosproject.net.Host; 33 import org.onosproject.net.Host;
34 +import org.onosproject.net.Port;
35 import org.onosproject.net.behaviour.BridgeConfig; 35 import org.onosproject.net.behaviour.BridgeConfig;
36 import org.onosproject.net.behaviour.BridgeName; 36 import org.onosproject.net.behaviour.BridgeName;
37 import org.onosproject.net.behaviour.ControllerInfo; 37 import org.onosproject.net.behaviour.ControllerInfo;
...@@ -39,6 +39,7 @@ import org.onosproject.net.behaviour.DefaultTunnelDescription; ...@@ -39,6 +39,7 @@ import org.onosproject.net.behaviour.DefaultTunnelDescription;
39 import org.onosproject.net.behaviour.TunnelConfig; 39 import org.onosproject.net.behaviour.TunnelConfig;
40 import org.onosproject.net.behaviour.TunnelDescription; 40 import org.onosproject.net.behaviour.TunnelDescription;
41 import org.onosproject.net.behaviour.TunnelName; 41 import org.onosproject.net.behaviour.TunnelName;
42 +import org.onosproject.net.device.DeviceAdminService;
42 import org.onosproject.net.device.DeviceEvent; 43 import org.onosproject.net.device.DeviceEvent;
43 import org.onosproject.net.device.DeviceListener; 44 import org.onosproject.net.device.DeviceListener;
44 import org.onosproject.net.device.DeviceService; 45 import org.onosproject.net.device.DeviceService;
...@@ -54,7 +55,6 @@ import org.onosproject.store.serializers.KryoNamespaces; ...@@ -54,7 +55,6 @@ import org.onosproject.store.serializers.KryoNamespaces;
54 import org.onosproject.store.service.ConsistentMap; 55 import org.onosproject.store.service.ConsistentMap;
55 import org.onosproject.store.service.Serializer; 56 import org.onosproject.store.service.Serializer;
56 import org.onosproject.store.service.StorageService; 57 import org.onosproject.store.service.StorageService;
57 -import org.onosproject.store.service.Versioned;
58 import org.slf4j.Logger; 58 import org.slf4j.Logger;
59 59
60 import java.util.ArrayList; 60 import java.util.ArrayList;
...@@ -84,7 +84,8 @@ public class CordVtn implements CordVtnService { ...@@ -84,7 +84,8 @@ public class CordVtn implements CordVtnService {
84 private static final int NUM_THREADS = 1; 84 private static final int NUM_THREADS = 1;
85 private static final KryoNamespace.Builder NODE_SERIALIZER = KryoNamespace.newBuilder() 85 private static final KryoNamespace.Builder NODE_SERIALIZER = KryoNamespace.newBuilder()
86 .register(KryoNamespaces.API) 86 .register(KryoNamespaces.API)
87 - .register(DefaultOvsdbNode.class); 87 + .register(CordVtnNode.class)
88 + .register(NodeState.class);
88 private static final String DEFAULT_BRIDGE_NAME = "br-int"; 89 private static final String DEFAULT_BRIDGE_NAME = "br-int";
89 private static final String DEFAULT_TUNNEL = "vxlan"; 90 private static final String DEFAULT_TUNNEL = "vxlan";
90 private static final Map<String, String> DEFAULT_TUNNEL_OPTIONS = new HashMap<String, String>() { 91 private static final Map<String, String> DEFAULT_TUNNEL_OPTIONS = new HashMap<String, String>() {
...@@ -112,6 +113,9 @@ public class CordVtn implements CordVtnService { ...@@ -112,6 +113,9 @@ public class CordVtn implements CordVtnService {
112 protected DriverService driverService; 113 protected DriverService driverService;
113 114
114 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) 115 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
116 + protected DeviceAdminService adminService;
117 +
118 + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
115 protected OvsdbController controller; 119 protected OvsdbController controller;
116 120
117 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) 121 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
...@@ -127,12 +131,55 @@ public class CordVtn implements CordVtnService { ...@@ -127,12 +131,55 @@ public class CordVtn implements CordVtnService {
127 private final BridgeHandler bridgeHandler = new BridgeHandler(); 131 private final BridgeHandler bridgeHandler = new BridgeHandler();
128 private final VmHandler vmHandler = new VmHandler(); 132 private final VmHandler vmHandler = new VmHandler();
129 133
130 - private ConsistentMap<DeviceId, OvsdbNode> nodeStore; 134 + private ConsistentMap<CordVtnNode, NodeState> nodeStore;
135 +
136 + private enum NodeState {
137 +
138 + INIT {
139 + @Override
140 + public void process(CordVtn cordVtn, CordVtnNode node) {
141 + cordVtn.connect(node);
142 + }
143 + },
144 + OVSDB_CONNECTED {
145 + @Override
146 + public void process(CordVtn cordVtn, CordVtnNode node) {
147 + if (!cordVtn.getOvsdbConnectionState(node)) {
148 + cordVtn.connect(node);
149 + } else {
150 + cordVtn.createIntegrationBridge(node);
151 + }
152 + }
153 + },
154 + BRIDGE_CREATED {
155 + @Override
156 + public void process(CordVtn cordVtn, CordVtnNode node) {
157 + if (!cordVtn.getOvsdbConnectionState(node)) {
158 + cordVtn.connect(node);
159 + } else {
160 + cordVtn.createTunnelInterface(node);
161 + }
162 + }
163 + },
164 + COMPLETE {
165 + @Override
166 + public void process(CordVtn cordVtn, CordVtnNode node) {
167 + cordVtn.postInit(node);
168 + }
169 + },
170 + INCOMPLETE {
171 + @Override
172 + public void process(CordVtn cordVtn, CordVtnNode node) {
173 + }
174 + };
175 +
176 + public abstract void process(CordVtn cordVtn, CordVtnNode node);
177 + }
131 178
132 @Activate 179 @Activate
133 protected void activate() { 180 protected void activate() {
134 ApplicationId appId = coreService.registerApplication("org.onosproject.cordvtn"); 181 ApplicationId appId = coreService.registerApplication("org.onosproject.cordvtn");
135 - nodeStore = storageService.<DeviceId, OvsdbNode>consistentMapBuilder() 182 + nodeStore = storageService.<CordVtnNode, NodeState>consistentMapBuilder()
136 .withSerializer(Serializer.using(NODE_SERIALIZER.build())) 183 .withSerializer(Serializer.using(NODE_SERIALIZER.build()))
137 .withName("cordvtn-nodestore") 184 .withName("cordvtn-nodestore")
138 .withApplicationId(appId) 185 .withApplicationId(appId)
...@@ -156,145 +203,272 @@ public class CordVtn implements CordVtnService { ...@@ -156,145 +203,272 @@ public class CordVtn implements CordVtnService {
156 } 203 }
157 204
158 @Override 205 @Override
159 - public void addNode(OvsdbNode ovsdb) { 206 + public void addNode(CordVtnNode node) {
160 - checkNotNull(ovsdb); 207 + checkNotNull(node);
208 +
209 + nodeStore.putIfAbsent(node, checkNodeState(node));
210 + initNode(node);
211 + }
161 212
162 - nodeStore.putIfAbsent(ovsdb.deviceId(), ovsdb); 213 + @Override
214 + public void deleteNode(CordVtnNode node) {
215 + checkNotNull(node);
163 216
164 - if (isNodeConnected(ovsdb)) { 217 + if (getOvsdbConnectionState(node)) {
165 - init(ovsdb); 218 + disconnect(node);
166 - } else {
167 - connect(ovsdb);
168 } 219 }
220 +
221 + nodeStore.remove(node);
169 } 222 }
170 223
171 @Override 224 @Override
172 - public void deleteNode(OvsdbNode ovsdb) { 225 + public int getNodeCount() {
173 - checkNotNull(ovsdb); 226 + return nodeStore.size();
227 + }
174 228
175 - if (deviceService.getDevice(ovsdb.deviceId()) != null) { 229 + @Override
176 - if (deviceService.isAvailable(ovsdb.deviceId())) { 230 + public List<CordVtnNode> getNodes() {
177 - log.warn("Cannot delete connected node {}", ovsdb.host()); 231 + List<CordVtnNode> nodes = new ArrayList<>();
178 - return; 232 + nodes.addAll(nodeStore.keySet());
179 - } 233 + return nodes;
180 - }
181 - nodeStore.remove(ovsdb.deviceId());
182 } 234 }
183 235
184 @Override 236 @Override
185 - public void connect(OvsdbNode ovsdb) { 237 + public void initNode(CordVtnNode node) {
186 - checkNotNull(ovsdb); 238 + checkNotNull(node);
187 239
188 - if (!nodeStore.containsKey(ovsdb.deviceId())) { 240 + if (!nodeStore.containsKey(node)) {
189 - log.warn("Node {} does not exist", ovsdb.host()); 241 + log.warn("Node {} does not exist, add node first", node.hostname());
190 return; 242 return;
191 } 243 }
192 244
193 - if (!isNodeConnected(ovsdb)) { 245 + NodeState state = getNodeState(node);
194 - controller.connect(ovsdb.ip(), ovsdb.port()); 246 + if (state == null) {
247 + return;
248 + } else if (state.equals(NodeState.INCOMPLETE)) {
249 + state = checkNodeState(node);
195 } 250 }
251 +
252 + state.process(this, node);
196 } 253 }
197 254
198 @Override 255 @Override
199 - public void disconnect(OvsdbNode ovsdb) { 256 + public boolean getNodeInitState(CordVtnNode node) {
200 - checkNotNull(ovsdb); 257 + checkNotNull(node);
201 258
202 - if (!nodeStore.containsKey(ovsdb.deviceId())) { 259 + NodeState state = getNodeState(node);
203 - log.warn("Node {} does not exist", ovsdb.host()); 260 + return state != null && state.equals(NodeState.COMPLETE);
204 - return; 261 + }
262 +
263 + /**
264 + * Returns state of a given cordvtn node.
265 + *
266 + * @param node cordvtn node
267 + * @return node state, or null if no such node exists
268 + */
269 + private NodeState getNodeState(CordVtnNode node) {
270 + checkNotNull(node);
271 +
272 + try {
273 + return nodeStore.get(node).value();
274 + } catch (NullPointerException e) {
275 + log.error("Failed to get state of {}", node.hostname());
276 + return null;
205 } 277 }
278 + }
206 279
207 - if (isNodeConnected(ovsdb)) { 280 + /**
208 - OvsdbClientService ovsdbClient = getOvsdbClient(ovsdb); 281 + * Sets a new state for a given cordvtn node.
209 - ovsdbClient.disconnect(); 282 + *
283 + * @param node cordvtn node
284 + * @param newState new node state
285 + */
286 + private void setNodeState(CordVtnNode node, NodeState newState) {
287 + checkNotNull(node);
288 +
289 + log.info("Changed {} state: {}", node.hostname(), newState.toString());
290 +
291 + nodeStore.put(node, newState);
292 + newState.process(this, node);
293 + }
294 +
295 + /**
296 + * Checks current state of a given cordvtn node and returns it.
297 + *
298 + * @param node cordvtn node
299 + * @return node state
300 + */
301 + private NodeState checkNodeState(CordVtnNode node) {
302 + checkNotNull(node);
303 +
304 + if (checkIntegrationBridge(node) && checkTunnelInterface(node)) {
305 + return NodeState.COMPLETE;
306 + } else if (checkIntegrationBridge(node)) {
307 + return NodeState.BRIDGE_CREATED;
308 + } else if (getOvsdbConnectionState(node)) {
309 + return NodeState.OVSDB_CONNECTED;
310 + } else {
311 + return NodeState.INIT;
210 } 312 }
211 } 313 }
212 314
213 - private void init(OvsdbNode ovsdb) { 315 + /**
214 - checkNotNull(ovsdb); 316 + * Performs tasks after node initialization.
317 + *
318 + * @param node cordvtn node
319 + */
320 + private void postInit(CordVtnNode node) {
321 + disconnect(node);
322 + }
323 +
324 + /**
325 + * Returns connection state of OVSDB server for a given node.
326 + *
327 + * @param node cordvtn node
328 + * @return true if it is connected, false otherwise
329 + */
330 + private boolean getOvsdbConnectionState(CordVtnNode node) {
331 + checkNotNull(node);
332 +
333 + OvsdbClientService ovsdbClient = getOvsdbClient(node);
334 + return deviceService.isAvailable(node.ovsdbId()) &&
335 + ovsdbClient != null && ovsdbClient.isConnected();
336 + }
337 +
338 + /**
339 + * Connects to OVSDB server for a given node.
340 + *
341 + * @param node cordvtn node
342 + */
343 + private void connect(CordVtnNode node) {
344 + checkNotNull(node);
215 345
216 - if (!nodeStore.containsKey(ovsdb.deviceId())) { 346 + if (!nodeStore.containsKey(node)) {
217 - log.warn("Node {} does not exist", ovsdb.host()); 347 + log.warn("Node {} does not exist", node.hostname());
218 return; 348 return;
219 } 349 }
220 350
221 - if (!isNodeConnected(ovsdb)) { 351 + if (!getOvsdbConnectionState(node)) {
222 - log.warn("Node {} is not connected", ovsdb.host()); 352 + // FIXME remove existing OVSDB device to work around OVSDB device re-connect issue
353 + if (deviceService.getDevice(node.ovsdbId()) != null) {
354 + adminService.removeDevice(node.ovsdbId());
355 + }
356 + controller.connect(node.ovsdbIp(), node.ovsdbPort());
357 + }
358 + }
359 +
360 + /**
361 + * Disconnects OVSDB server for a given node.
362 + *
363 + * @param node cordvtn node
364 + */
365 + private void disconnect(CordVtnNode node) {
366 + checkNotNull(node);
367 +
368 + if (!nodeStore.containsKey(node)) {
369 + log.warn("Node {} does not exist", node.hostname());
223 return; 370 return;
224 } 371 }
225 372
226 - if (deviceService.getDevice(ovsdb.intBrId()) == null || 373 + if (getOvsdbConnectionState(node)) {
227 - !deviceService.isAvailable(ovsdb.intBrId())) { 374 + OvsdbClientService ovsdbClient = getOvsdbClient(node);
228 - createIntegrationBridge(ovsdb); 375 + ovsdbClient.disconnect();
229 - } else if (!checkVxlanInterface(ovsdb)) {
230 - createVxlanInterface(ovsdb);
231 } 376 }
232 - }
233 377
234 - @Override 378 + // FIXME remove existing OVSDB device to work around OVSDB device re-connect issue
235 - public int getNodeCount() { 379 + if (deviceService.getDevice(node.ovsdbId()) != null) {
236 - return nodeStore.size(); 380 + adminService.removeDevice(node.ovsdbId());
381 + }
237 } 382 }
238 383
239 - @Override 384 + /**
240 - public OvsdbNode getNode(DeviceId deviceId) { 385 + * Returns cordvtn node associated with a given OVSDB device.
241 - Versioned<OvsdbNode> ovsdb = nodeStore.get(deviceId); 386 + *
242 - if (ovsdb != null) { 387 + * @param ovsdbId OVSDB device id
243 - return ovsdb.value(); 388 + * @return cordvtn node, null if it fails to find the node
244 - } else { 389 + */
390 + private CordVtnNode getNodeByOvsdbId(DeviceId ovsdbId) {
391 + try {
392 + return getNodes().stream()
393 + .filter(node -> node.ovsdbId().equals(ovsdbId))
394 + .findFirst().get();
395 + } catch (NoSuchElementException e) {
396 + log.debug("Couldn't find node information for {}", ovsdbId);
245 return null; 397 return null;
246 } 398 }
247 } 399 }
248 400
249 - @Override 401 + /**
250 - public List<OvsdbNode> getNodes() { 402 + * Returns cordvtn node associated with a given integration bridge.
251 - List<OvsdbNode> ovsdbs = new ArrayList<>(); 403 + *
252 - ovsdbs.addAll(Collections2.transform(nodeStore.values(), Versioned::value)); 404 + * @param bridgeId device id of integration bridge
253 - return ovsdbs; 405 + * @return cordvtn node, null if it fails to find the node
254 - } 406 + */
255 - 407 + private CordVtnNode getNodeByBridgeId(DeviceId bridgeId) {
256 - @Override 408 + try {
257 - public boolean isNodeConnected(OvsdbNode ovsdb) { 409 + return getNodes().stream()
258 - checkNotNull(ovsdb); 410 + .filter(node -> node.intBrId().equals(bridgeId))
259 - 411 + .findFirst().get();
260 - OvsdbClientService ovsdbClient = getOvsdbClient(ovsdb); 412 + } catch (NoSuchElementException e) {
261 - if (ovsdbClient == null) { 413 + log.debug("Couldn't find node information for {}", bridgeId);
262 - return false; 414 + return null;
263 - } else {
264 - return ovsdbClient.isConnected();
265 } 415 }
266 } 416 }
267 417
268 - private OvsdbClientService getOvsdbClient(OvsdbNode ovsdb) { 418 + /**
269 - checkNotNull(ovsdb); 419 + * Returns OVSDB client for a given node.
420 + *
421 + * @param node cordvtn node
422 + * @return OVSDB client, or null if it fails to get OVSDB client
423 + */
424 + private OvsdbClientService getOvsdbClient(CordVtnNode node) {
425 + checkNotNull(node);
270 426
271 OvsdbClientService ovsdbClient = controller.getOvsdbClient( 427 OvsdbClientService ovsdbClient = controller.getOvsdbClient(
272 - new OvsdbNodeId(ovsdb.ip(), ovsdb.port().toInt())); 428 + new OvsdbNodeId(node.ovsdbIp(), node.ovsdbPort().toInt()));
273 if (ovsdbClient == null) { 429 if (ovsdbClient == null) {
274 - log.debug("Couldn't find ovsdb client for {}", ovsdb.host()); 430 + log.debug("Couldn't find OVSDB client for {}", node.hostname());
275 } 431 }
276 return ovsdbClient; 432 return ovsdbClient;
277 } 433 }
278 434
279 - private void createIntegrationBridge(OvsdbNode ovsdb) { 435 + /**
436 + * Creates an integration bridge for a given node.
437 + *
438 + * @param node cordvtn node
439 + */
440 + private void createIntegrationBridge(CordVtnNode node) {
441 + if (checkIntegrationBridge(node)) {
442 + return;
443 + }
444 +
280 List<ControllerInfo> controllers = new ArrayList<>(); 445 List<ControllerInfo> controllers = new ArrayList<>();
281 Sets.newHashSet(clusterService.getNodes()) 446 Sets.newHashSet(clusterService.getNodes())
282 .forEach(controller -> { 447 .forEach(controller -> {
283 ControllerInfo ctrlInfo = new ControllerInfo(controller.ip(), OFPORT, "tcp"); 448 ControllerInfo ctrlInfo = new ControllerInfo(controller.ip(), OFPORT, "tcp");
284 controllers.add(ctrlInfo); 449 controllers.add(ctrlInfo);
285 }); 450 });
286 - String dpid = ovsdb.intBrId().toString().substring(DPID_BEGIN); 451 + String dpid = node.intBrId().toString().substring(DPID_BEGIN);
287 452
288 try { 453 try {
289 - DriverHandler handler = driverService.createHandler(ovsdb.deviceId()); 454 + DriverHandler handler = driverService.createHandler(node.ovsdbId());
290 BridgeConfig bridgeConfig = handler.behaviour(BridgeConfig.class); 455 BridgeConfig bridgeConfig = handler.behaviour(BridgeConfig.class);
291 bridgeConfig.addBridge(BridgeName.bridgeName(DEFAULT_BRIDGE_NAME), dpid, controllers); 456 bridgeConfig.addBridge(BridgeName.bridgeName(DEFAULT_BRIDGE_NAME), dpid, controllers);
292 } catch (ItemNotFoundException e) { 457 } catch (ItemNotFoundException e) {
293 - log.warn("Failed to create integration bridge on {}", ovsdb.deviceId()); 458 + log.warn("Failed to create integration bridge on {}", node.ovsdbId());
294 } 459 }
295 } 460 }
296 461
297 - private void createVxlanInterface(OvsdbNode ovsdb) { 462 + /**
463 + * Creates tunnel interface to the integration bridge for a given node.
464 + *
465 + * @param node cordvtn node
466 + */
467 + private void createTunnelInterface(CordVtnNode node) {
468 + if (checkTunnelInterface(node)) {
469 + return;
470 + }
471 +
298 DefaultAnnotations.Builder optionBuilder = DefaultAnnotations.builder(); 472 DefaultAnnotations.Builder optionBuilder = DefaultAnnotations.builder();
299 for (String key : DEFAULT_TUNNEL_OPTIONS.keySet()) { 473 for (String key : DEFAULT_TUNNEL_OPTIONS.keySet()) {
300 optionBuilder.set(key, DEFAULT_TUNNEL_OPTIONS.get(key)); 474 optionBuilder.set(key, DEFAULT_TUNNEL_OPTIONS.get(key));
...@@ -304,38 +478,63 @@ public class CordVtn implements CordVtnService { ...@@ -304,38 +478,63 @@ public class CordVtn implements CordVtnService {
304 TunnelName.tunnelName(DEFAULT_TUNNEL), 478 TunnelName.tunnelName(DEFAULT_TUNNEL),
305 optionBuilder.build()); 479 optionBuilder.build());
306 try { 480 try {
307 - DriverHandler handler = driverService.createHandler(ovsdb.deviceId()); 481 + DriverHandler handler = driverService.createHandler(node.ovsdbId());
308 TunnelConfig tunnelConfig = handler.behaviour(TunnelConfig.class); 482 TunnelConfig tunnelConfig = handler.behaviour(TunnelConfig.class);
309 tunnelConfig.createTunnelInterface(BridgeName.bridgeName(DEFAULT_BRIDGE_NAME), description); 483 tunnelConfig.createTunnelInterface(BridgeName.bridgeName(DEFAULT_BRIDGE_NAME), description);
310 } catch (ItemNotFoundException e) { 484 } catch (ItemNotFoundException e) {
311 - log.warn("Failed to create VXLAN interface on {}", ovsdb.deviceId()); 485 + log.warn("Failed to create tunnel interface on {}", node.ovsdbId());
312 } 486 }
313 } 487 }
314 488
315 - private boolean checkVxlanInterface(OvsdbNode ovsdb) { 489 + /**
490 + * Checks if integration bridge exists and available.
491 + *
492 + * @param node cordvtn node
493 + * @return true if the bridge is available, false otherwise
494 + */
495 + private boolean checkIntegrationBridge(CordVtnNode node) {
496 + return (deviceService.getDevice(node.intBrId()) != null
497 + && deviceService.isAvailable(node.intBrId()));
498 + }
499 +
500 + /**
501 + * Checks if tunnel interface exists.
502 + *
503 + * @param node cordvtn node
504 + * @return true if the interface exists, false otherwise
505 + */
506 + private boolean checkTunnelInterface(CordVtnNode node) {
316 try { 507 try {
317 - DriverHandler handler = driverService.createHandler(ovsdb.deviceId()); 508 + deviceService.getPorts(node.intBrId())
318 - BridgeConfig bridgeConfig = handler.behaviour(BridgeConfig.class); 509 + .stream()
319 - bridgeConfig.getPorts().stream() 510 + .filter(p -> p.annotations().value("portName").contains(DEFAULT_TUNNEL)
320 - .filter(p -> p.annotations().value("portName").equals(DEFAULT_TUNNEL)) 511 + && p.isEnabled())
321 .findAny().get(); 512 .findAny().get();
322 - } catch (ItemNotFoundException | NoSuchElementException e) { 513 + return true;
514 + } catch (NoSuchElementException e) {
323 return false; 515 return false;
324 } 516 }
325 - return true;
326 } 517 }
327 518
328 private class InternalDeviceListener implements DeviceListener { 519 private class InternalDeviceListener implements DeviceListener {
329 520
330 @Override 521 @Override
331 public void event(DeviceEvent event) { 522 public void event(DeviceEvent event) {
523 +
332 Device device = event.subject(); 524 Device device = event.subject();
333 - ConnectionHandler handler = (device.type() == SWITCH ? bridgeHandler : ovsdbHandler); 525 + ConnectionHandler<Device> handler =
526 + (device.type().equals(SWITCH) ? bridgeHandler : ovsdbHandler);
334 527
335 switch (event.type()) { 528 switch (event.type()) {
336 - case DEVICE_ADDED: 529 + case PORT_ADDED:
337 - eventExecutor.submit(() -> handler.connected(device)); 530 + eventExecutor.submit(() -> bridgeHandler.portAdded(event.port()));
531 + break;
532 + case PORT_UPDATED:
533 + if (!event.port().isEnabled()) {
534 + eventExecutor.submit(() -> bridgeHandler.portRemoved(event.port()));
535 + }
338 break; 536 break;
537 + case DEVICE_ADDED:
339 case DEVICE_AVAILABILITY_CHANGED: 538 case DEVICE_AVAILABILITY_CHANGED:
340 if (deviceService.isAvailable(device.id())) { 539 if (deviceService.isAvailable(device.id())) {
341 eventExecutor.submit(() -> handler.connected(device)); 540 eventExecutor.submit(() -> handler.connected(device));
...@@ -372,17 +571,15 @@ public class CordVtn implements CordVtnService { ...@@ -372,17 +571,15 @@ public class CordVtn implements CordVtnService {
372 571
373 @Override 572 @Override
374 public void connected(Device device) { 573 public void connected(Device device) {
375 - log.info("Ovsdb {} is connected", device.id()); 574 + CordVtnNode node = getNodeByOvsdbId(device.id());
376 - 575 + if (node != null) {
377 - OvsdbNode ovsdb = getNode(device.id()); 576 + setNodeState(node, checkNodeState(node));
378 - if (ovsdb != null) {
379 - init(ovsdb);
380 } 577 }
381 } 578 }
382 579
383 @Override 580 @Override
384 public void disconnected(Device device) { 581 public void disconnected(Device device) {
385 - log.warn("Ovsdb {} is disconnected", device.id()); 582 + log.info("OVSDB {} is disconnected", device.id());
386 } 583 }
387 } 584 }
388 585
...@@ -390,26 +587,56 @@ public class CordVtn implements CordVtnService { ...@@ -390,26 +587,56 @@ public class CordVtn implements CordVtnService {
390 587
391 @Override 588 @Override
392 public void connected(Device device) { 589 public void connected(Device device) {
393 - log.info("Integration Bridge {} is detected", device.id()); 590 + CordVtnNode node = getNodeByBridgeId(device.id());
394 - 591 + if (node != null) {
395 - OvsdbNode ovsdb; 592 + setNodeState(node, checkNodeState(node));
396 - try { 593 + }
397 - ovsdb = getNodes().stream() 594 + }
398 - .filter(node -> node.intBrId().equals(device.id())) 595 +
399 - .findFirst().get(); 596 + @Override
400 - } catch (NoSuchElementException e) { 597 + public void disconnected(Device device) {
401 - log.warn("Couldn't find OVSDB associated with {}", device.id()); 598 + CordVtnNode node = getNodeByBridgeId(device.id());
599 + if (node != null) {
600 + log.info("Integration Bridge is disconnected from {}", node.hostname());
601 + setNodeState(node, NodeState.INCOMPLETE);
602 + }
603 + }
604 +
605 + /**
606 + * Handles port added situation.
607 + * If the added port is tunnel port, proceed remaining node initialization.
608 + * Otherwise, do nothing.
609 + *
610 + * @param port port
611 + */
612 + public void portAdded(Port port) {
613 + if (!port.annotations().value("portName").contains(DEFAULT_TUNNEL)) {
402 return; 614 return;
403 } 615 }
404 616
405 - if (!checkVxlanInterface(ovsdb)) { 617 + CordVtnNode node = getNodeByBridgeId((DeviceId) port.element().id());
406 - createVxlanInterface(ovsdb); 618 + if (node != null) {
619 + setNodeState(node, checkNodeState(node));
407 } 620 }
408 } 621 }
409 622
410 - @Override 623 + /**
411 - public void disconnected(Device device) { 624 + * Handles port removed situation.
412 - log.info("Integration Bridge {} is vanished", device.id()); 625 + * If the removed port is tunnel port, proceed remaining node initialization.
626 + * Others, do nothing.
627 + *
628 + * @param port port
629 + */
630 + public void portRemoved(Port port) {
631 + if (!port.annotations().value("portName").contains(DEFAULT_TUNNEL)) {
632 + return;
633 + }
634 +
635 + CordVtnNode node = getNodeByBridgeId((DeviceId) port.element().id());
636 + if (node != null) {
637 + log.info("Tunnel interface is removed from {}", node.hostname());
638 + setNodeState(node, NodeState.INCOMPLETE);
639 + }
413 } 640 }
414 } 641 }
415 642
......
...@@ -32,77 +32,82 @@ import static com.google.common.base.Preconditions.checkNotNull; ...@@ -32,77 +32,82 @@ import static com.google.common.base.Preconditions.checkNotNull;
32 */ 32 */
33 public class CordVtnConfig extends Config<ApplicationId> { 33 public class CordVtnConfig extends Config<ApplicationId> {
34 34
35 - public static final String OVSDB_NODES = "ovsdbNodes"; 35 + public static final String CORDVTN_NODES = "nodes";
36 - public static final String HOST = "host"; 36 + public static final String HOSTNAME = "hostname";
37 - public static final String IP = "ip"; 37 + public static final String OVSDB_IP = "ovsdbIp";
38 - public static final String PORT = "port"; 38 + public static final String OVSDB_PORT = "ovsdbPort";
39 public static final String BRIDGE_ID = "bridgeId"; 39 public static final String BRIDGE_ID = "bridgeId";
40 40
41 /** 41 /**
42 - * Returns the set of ovsdb nodes read from network config. 42 + * Returns the set of nodes read from network config.
43 * 43 *
44 - * @return set of OvsdbNodeConfig or null 44 + * @return set of CordVtnNodeConfig or null
45 */ 45 */
46 - public Set<OvsdbNodeConfig> ovsdbNodes() { 46 + public Set<CordVtnNodeConfig> cordVtnNodes() {
47 - Set<OvsdbNodeConfig> ovsdbNodes = Sets.newHashSet(); 47 + Set<CordVtnNodeConfig> nodes = Sets.newHashSet();
48 48
49 - JsonNode nodes = object.get(OVSDB_NODES); 49 + JsonNode jsonNodes = object.get(CORDVTN_NODES);
50 - if (nodes == null) { 50 + if (jsonNodes == null) {
51 return null; 51 return null;
52 } 52 }
53 - nodes.forEach(jsonNode -> ovsdbNodes.add(new OvsdbNodeConfig( 53 + jsonNodes.forEach(jsonNode -> nodes.add(new CordVtnNodeConfig(
54 - jsonNode.path(HOST).asText(), 54 + jsonNode.path(HOSTNAME).asText(),
55 - IpAddress.valueOf(jsonNode.path(IP).asText()), 55 + IpAddress.valueOf(jsonNode.path(OVSDB_IP).asText()),
56 - TpPort.tpPort(jsonNode.path(PORT).asInt()), 56 + TpPort.tpPort(jsonNode.path(OVSDB_PORT).asInt()),
57 DeviceId.deviceId(jsonNode.path(BRIDGE_ID).asText())))); 57 DeviceId.deviceId(jsonNode.path(BRIDGE_ID).asText()))));
58 58
59 - return ovsdbNodes; 59 + return nodes;
60 } 60 }
61 61
62 /** 62 /**
63 - * Configuration for an ovsdb node. 63 + * Configuration for CordVtn node.
64 */ 64 */
65 - public static class OvsdbNodeConfig { 65 + public static class CordVtnNodeConfig {
66 66
67 - private final String host; 67 + private final String hostname;
68 - private final IpAddress ip; 68 + private final IpAddress ovsdbIp;
69 - private final TpPort port; 69 + private final TpPort ovsdbPort;
70 private final DeviceId bridgeId; 70 private final DeviceId bridgeId;
71 71
72 - public OvsdbNodeConfig(String host, IpAddress ip, TpPort port, DeviceId bridgeId) { 72 + public CordVtnNodeConfig(String hostname, IpAddress ovsdbIp, TpPort ovsdbPort, DeviceId bridgeId) {
73 - this.host = checkNotNull(host); 73 + this.hostname = checkNotNull(hostname);
74 - this.ip = checkNotNull(ip); 74 + this.ovsdbIp = checkNotNull(ovsdbIp);
75 - this.port = checkNotNull(port); 75 + this.ovsdbPort = checkNotNull(ovsdbPort);
76 this.bridgeId = checkNotNull(bridgeId); 76 this.bridgeId = checkNotNull(bridgeId);
77 } 77 }
78 78
79 /** 79 /**
80 - * Returns host information of the node. 80 + * Returns hostname of the node.
81 * 81 *
82 - * @return host 82 + * @return hostname
83 */ 83 */
84 - public String host() { 84 + public String hostname() {
85 - return this.host; 85 + return this.hostname;
86 } 86 }
87 87
88 /** 88 /**
89 - * Returns ip address to access ovsdb-server of the node. 89 + * Returns OVSDB ip address of the node.
90 * 90 *
91 - * @return ip address 91 + * @return OVSDB server IP address
92 */ 92 */
93 - public IpAddress ip() { 93 + public IpAddress ovsdbIp() {
94 - return this.ip; 94 + return this.ovsdbIp;
95 } 95 }
96 96
97 /** 97 /**
98 - * Returns port number to access ovsdb-server of the node. 98 + * Returns OVSDB port number of the node.
99 * 99 *
100 * @return port number 100 * @return port number
101 */ 101 */
102 - public TpPort port() { 102 + public TpPort ovsdbPort() {
103 - return this.port; 103 + return this.ovsdbPort;
104 } 104 }
105 105
106 + /**
107 + * Returns integration bridge id of the node.
108 + *
109 + * @return device id
110 + */
106 public DeviceId bridgeId() { 111 public DeviceId bridgeId() {
107 return this.bridgeId; 112 return this.bridgeId;
108 } 113 }
......
...@@ -88,10 +88,10 @@ public class CordVtnConfigManager { ...@@ -88,10 +88,10 @@ public class CordVtnConfigManager {
88 return; 88 return;
89 } 89 }
90 90
91 - config.ovsdbNodes().forEach(node -> { 91 + config.cordVtnNodes().forEach(node -> {
92 - DefaultOvsdbNode ovsdb = new DefaultOvsdbNode( 92 + CordVtnNode cordVtnNode = new CordVtnNode(
93 - node.host(), node.ip(), node.port(), node.bridgeId()); 93 + node.hostname(), node.ovsdbIp(), node.ovsdbPort(), node.bridgeId());
94 - cordVtnService.addNode(ovsdb); 94 + cordVtnService.addNode(cordVtnNode);
95 }); 95 });
96 } 96 }
97 97
......
1 +/*
2 + * Copyright 2014-2015 Open Networking Laboratory
3 + *
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 + */
16 +package org.onosproject.cordvtn;
17 +
18 +import com.google.common.base.MoreObjects;
19 +import org.onlab.packet.IpAddress;
20 +import org.onlab.packet.TpPort;
21 +import org.onosproject.net.DeviceId;
22 +
23 +import java.util.Comparator;
24 +import java.util.Objects;
25 +
26 +import static com.google.common.base.Preconditions.checkNotNull;
27 +
28 +/**
29 + * Representation of a compute infrastructure node for CORD VTN service.
30 + */
31 +public final class CordVtnNode {
32 +
33 + private final String hostname;
34 + private final IpAddress ovsdbIp;
35 + private final TpPort ovsdbPort;
36 + private final DeviceId bridgeId;
37 +
38 + public static final Comparator<CordVtnNode> CORDVTN_NODE_COMPARATOR =
39 + (node1, node2) -> node1.hostname().compareTo(node2.hostname());
40 +
41 + /**
42 + * Creates a new node.
43 + *
44 + * @param hostname hostname
45 + * @param ovsdbIp OVSDB server IP address
46 + * @param ovsdbPort OVSDB server port number
47 + * @param bridgeId integration bridge identifier
48 + */
49 + public CordVtnNode(String hostname, IpAddress ovsdbIp, TpPort ovsdbPort, DeviceId bridgeId) {
50 + this.hostname = checkNotNull(hostname);
51 + this.ovsdbIp = checkNotNull(ovsdbIp);
52 + this.ovsdbPort = checkNotNull(ovsdbPort);
53 + this.bridgeId = checkNotNull(bridgeId);
54 + }
55 +
56 + /**
57 + * Returns the OVSDB server IP address.
58 + *
59 + * @return ip address
60 + */
61 + public IpAddress ovsdbIp() {
62 + return this.ovsdbIp;
63 + }
64 +
65 + /**
66 + * Returns the OVSDB server port number.
67 + *
68 + * @return port number
69 + */
70 + public TpPort ovsdbPort() {
71 + return this.ovsdbPort;
72 + }
73 +
74 + /**
75 + * Returns the hostname.
76 + *
77 + * @return hostname
78 + */
79 + public String hostname() {
80 + return this.hostname;
81 + }
82 +
83 + /**
84 + * Returns the identifier of the integration bridge.
85 + *
86 + * @return device id
87 + */
88 + public DeviceId intBrId() {
89 + return this.bridgeId;
90 + }
91 +
92 + /**
93 + * Returns the identifier of the OVSDB device.
94 + *
95 + * @return device id
96 + */
97 + public DeviceId ovsdbId() {
98 + return DeviceId.deviceId("ovsdb:" + this.ovsdbIp.toString());
99 + }
100 +
101 + @Override
102 + public boolean equals(Object obj) {
103 + if (this == obj) {
104 + return true;
105 + }
106 +
107 + if (obj instanceof CordVtnNode) {
108 + CordVtnNode that = (CordVtnNode) obj;
109 + if (Objects.equals(hostname, that.hostname) &&
110 + Objects.equals(ovsdbIp, that.ovsdbIp) &&
111 + Objects.equals(ovsdbPort, that.ovsdbPort) &&
112 + Objects.equals(bridgeId, that.bridgeId)) {
113 + return true;
114 + }
115 + }
116 + return false;
117 + }
118 +
119 + @Override
120 + public int hashCode() {
121 + return Objects.hash(hostname, ovsdbIp, ovsdbPort);
122 + }
123 +
124 + @Override
125 + public String toString() {
126 + return MoreObjects.toStringHelper(getClass())
127 + .add("host", hostname)
128 + .add("ip", ovsdbIp)
129 + .add("port", ovsdbPort)
130 + .add("bridgeId", bridgeId)
131 + .toString();
132 + }
133 +}
...@@ -15,8 +15,6 @@ ...@@ -15,8 +15,6 @@
15 */ 15 */
16 package org.onosproject.cordvtn; 16 package org.onosproject.cordvtn;
17 17
18 -import org.onosproject.net.DeviceId;
19 -
20 import java.util.List; 18 import java.util.List;
21 19
22 /** 20 /**
...@@ -28,30 +26,23 @@ public interface CordVtnService { ...@@ -28,30 +26,23 @@ public interface CordVtnService {
28 /** 26 /**
29 * Adds a new node to the service. 27 * Adds a new node to the service.
30 * 28 *
31 - * @param ovsdb ovsdb node 29 + * @param node cordvtn node
32 */ 30 */
33 - void addNode(OvsdbNode ovsdb); 31 + void addNode(CordVtnNode node);
34 32
35 /** 33 /**
36 * Deletes a node from the service. 34 * Deletes a node from the service.
37 * 35 *
38 - * @param ovsdb ovsdb node 36 + * @param node cordvtn node
39 - */
40 - void deleteNode(OvsdbNode ovsdb);
41 -
42 - /**
43 - * Connect to a node.
44 - *
45 - * @param ovsdb ovsdb node
46 */ 37 */
47 - void connect(OvsdbNode ovsdb); 38 + void deleteNode(CordVtnNode node);
48 39
49 /** 40 /**
50 - * Disconnect a node. 41 + * Initiates node to serve virtual tenant network.
51 * 42 *
52 - * @param ovsdb ovsdb node 43 + * @param node cordvtn node
53 */ 44 */
54 - void disconnect(OvsdbNode ovsdb); 45 + void initNode(CordVtnNode node);
55 46
56 /** 47 /**
57 * Returns the number of the nodes known to the service. 48 * Returns the number of the nodes known to the service.
...@@ -61,25 +52,17 @@ public interface CordVtnService { ...@@ -61,25 +52,17 @@ public interface CordVtnService {
61 int getNodeCount(); 52 int getNodeCount();
62 53
63 /** 54 /**
64 - * Returns OvsdbNode with given device id. 55 + * Returns node initialization state.
65 - *
66 - * @param deviceId device id
67 - * @return ovsdb node
68 - */
69 - OvsdbNode getNode(DeviceId deviceId);
70 -
71 - /**
72 - * Returns connection state of the node.
73 * 56 *
74 - * @param ovsdb ovsdb node 57 + * @param node cordvtn node
75 - * @return true if the node is connected, false otherwise 58 + * @return true if initial node setup is completed, otherwise false
76 */ 59 */
77 - boolean isNodeConnected(OvsdbNode ovsdb); 60 + boolean getNodeInitState(CordVtnNode node);
78 61
79 /** 62 /**
80 * Returns all nodes known to the service. 63 * Returns all nodes known to the service.
81 * 64 *
82 * @return list of nodes 65 * @return list of nodes
83 */ 66 */
84 - List<OvsdbNode> getNodes(); 67 + List<CordVtnNode> getNodes();
85 } 68 }
......
1 -/*
2 - * Copyright 2014-2015 Open Networking Laboratory
3 - *
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 - */
16 -package org.onosproject.cordvtn;
17 -
18 -import com.google.common.base.MoreObjects;
19 -import org.onlab.packet.IpAddress;
20 -import org.onlab.packet.TpPort;
21 -import org.onosproject.net.DeviceId;
22 -
23 -import java.util.Objects;
24 -
25 -/**
26 - * OvsdbNode implementation.
27 - */
28 -public class DefaultOvsdbNode implements OvsdbNode {
29 -
30 - private final String host;
31 - private final IpAddress ip;
32 - private final TpPort port;
33 - private final DeviceId brId;
34 -
35 - public DefaultOvsdbNode(String host, IpAddress ip, TpPort port, DeviceId brId) {
36 - this.host = host;
37 - this.ip = ip;
38 - this.port = port;
39 - this.brId = brId;
40 - }
41 -
42 - @Override
43 - public IpAddress ip() {
44 - return this.ip;
45 - }
46 -
47 - @Override
48 - public TpPort port() {
49 - return this.port;
50 - }
51 -
52 - @Override
53 - public String host() {
54 - return this.host;
55 - }
56 -
57 - @Override
58 - public DeviceId intBrId() {
59 - return this.brId;
60 - }
61 -
62 - @Override
63 - public DeviceId deviceId() {
64 - return DeviceId.deviceId("ovsdb:" + this.ip.toString());
65 - }
66 -
67 - @Override
68 - public boolean equals(Object o) {
69 - if (this == o) {
70 - return true;
71 - }
72 -
73 - if (o instanceof DefaultOvsdbNode) {
74 - DefaultOvsdbNode that = (DefaultOvsdbNode) o;
75 - if (this.host.equals(that.host) &&
76 - this.ip.equals(that.ip) &&
77 - this.port.equals(that.port) &&
78 - this.brId.equals(that.brId)) {
79 - return true;
80 - }
81 - }
82 - return false;
83 - }
84 -
85 - @Override
86 - public int hashCode() {
87 - return Objects.hash(host, ip, port);
88 - }
89 -
90 - @Override
91 - public String toString() {
92 - return MoreObjects.toStringHelper(getClass())
93 - .add("host", host)
94 - .add("ip", ip)
95 - .add("port", port)
96 - .add("bridgeId", brId)
97 - .toString();
98 - }
99 -}
1 -/*
2 - * Copyright 2014-2015 Open Networking Laboratory
3 - *
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 - */
16 -package org.onosproject.cordvtn;
17 -
18 -import org.onlab.packet.IpAddress;
19 -import org.onlab.packet.TpPort;
20 -import org.onosproject.net.DeviceId;
21 -
22 -import java.util.Comparator;
23 -
24 -/**
25 - * Representation of a node with ovsdb server.
26 - */
27 -public interface OvsdbNode {
28 -
29 - Comparator<OvsdbNode> OVSDB_NODE_COMPARATOR = new Comparator<OvsdbNode>() {
30 - @Override
31 - public int compare(OvsdbNode ovsdb1, OvsdbNode ovsdb2) {
32 - return ovsdb1.host().compareTo(ovsdb2.host());
33 - }
34 - };
35 -
36 - /**
37 - * Returns the IP address of the ovsdb server.
38 - *
39 - * @return ip address
40 - */
41 - IpAddress ip();
42 -
43 - /**
44 - * Returns the port number of the ovsdb server.
45 - *
46 - * @return port number
47 - */
48 - TpPort port();
49 -
50 - /**
51 - * Returns the host information of the ovsdb server.
52 - * It could be hostname or ip address.
53 - *
54 - * @return host
55 - */
56 - String host();
57 -
58 - /**
59 - * Returns the device id of the ovsdb server.
60 - *
61 - * @return device id
62 - */
63 - DeviceId deviceId();
64 -
65 - /**
66 - * Returns the device id of the integration bridge associated with the node.
67 - *
68 - * @return device id
69 - */
70 - DeviceId intBrId();
71 -}
...@@ -22,27 +22,26 @@ import org.onlab.packet.IpAddress; ...@@ -22,27 +22,26 @@ import org.onlab.packet.IpAddress;
22 import org.onlab.packet.TpPort; 22 import org.onlab.packet.TpPort;
23 import org.onosproject.cli.AbstractShellCommand; 23 import org.onosproject.cli.AbstractShellCommand;
24 import org.onosproject.cordvtn.CordVtnService; 24 import org.onosproject.cordvtn.CordVtnService;
25 -import org.onosproject.cordvtn.DefaultOvsdbNode; 25 +import org.onosproject.cordvtn.CordVtnNode;
26 -import org.onosproject.cordvtn.OvsdbNode;
27 import org.onosproject.net.DeviceId; 26 import org.onosproject.net.DeviceId;
28 27
29 import static com.google.common.base.Preconditions.checkArgument; 28 import static com.google.common.base.Preconditions.checkArgument;
30 29
31 /** 30 /**
32 - * Adds a new OVSDB nodes. 31 + * Adds a new node to the service.
33 */ 32 */
34 -@Command(scope = "onos", name = "ovsdb-add", 33 +@Command(scope = "onos", name = "cordvtn-node-add",
35 - description = "Adds a new OVSDB node to cordvtn") 34 + description = "Adds a new node to CORD VTN service")
36 -public class OvsdbNodeAddCommand extends AbstractShellCommand { 35 +public class CordVtnNodeAddCommand extends AbstractShellCommand {
37 36
38 - @Argument(index = 0, name = "host", description = "Hostname or IP", 37 + @Argument(index = 0, name = "hostname", description = "Hostname",
39 required = true, multiValued = false) 38 required = true, multiValued = false)
40 - private String host = null; 39 + private String hostname = null;
41 40
42 - @Argument(index = 1, name = "address", 41 + @Argument(index = 1, name = "ovsdb",
43 description = "OVSDB server listening address (ip:port)", 42 description = "OVSDB server listening address (ip:port)",
44 required = true, multiValued = false) 43 required = true, multiValued = false)
45 - private String address = null; 44 + private String ovsdb = null;
46 45
47 @Argument(index = 2, name = "bridgeId", 46 @Argument(index = 2, name = "bridgeId",
48 description = "Device ID of integration bridge", 47 description = "Device ID of integration bridge",
...@@ -51,15 +50,15 @@ public class OvsdbNodeAddCommand extends AbstractShellCommand { ...@@ -51,15 +50,15 @@ public class OvsdbNodeAddCommand extends AbstractShellCommand {
51 50
52 @Override 51 @Override
53 protected void execute() { 52 protected void execute() {
54 - checkArgument(address.contains(":"), "address should be ip:port format"); 53 + checkArgument(ovsdb.contains(":"), "OVSDB address should be ip:port format");
55 checkArgument(bridgeId.startsWith("of:"), "bridgeId should be of:dpid format"); 54 checkArgument(bridgeId.startsWith("of:"), "bridgeId should be of:dpid format");
56 55
57 CordVtnService service = AbstractShellCommand.get(CordVtnService.class); 56 CordVtnService service = AbstractShellCommand.get(CordVtnService.class);
58 - String[] ipPort = address.split(":"); 57 + String[] ipPort = ovsdb.split(":");
59 - OvsdbNode ovsdb = new DefaultOvsdbNode(host, 58 + CordVtnNode node = new CordVtnNode(hostname,
60 - IpAddress.valueOf(ipPort[0]), 59 + IpAddress.valueOf(ipPort[0]),
61 - TpPort.tpPort(Integer.parseInt(ipPort[1])), 60 + TpPort.tpPort(Integer.parseInt(ipPort[1])),
62 - DeviceId.deviceId(bridgeId)); 61 + DeviceId.deviceId(bridgeId));
63 - service.addNode(ovsdb); 62 + service.addNode(node);
64 } 63 }
65 } 64 }
......
...@@ -20,38 +20,38 @@ import org.apache.karaf.shell.commands.Argument; ...@@ -20,38 +20,38 @@ import org.apache.karaf.shell.commands.Argument;
20 import org.apache.karaf.shell.commands.Command; 20 import org.apache.karaf.shell.commands.Command;
21 import org.onosproject.cli.AbstractShellCommand; 21 import org.onosproject.cli.AbstractShellCommand;
22 import org.onosproject.cordvtn.CordVtnService; 22 import org.onosproject.cordvtn.CordVtnService;
23 -import org.onosproject.cordvtn.OvsdbNode; 23 +import org.onosproject.cordvtn.CordVtnNode;
24 24
25 import java.util.NoSuchElementException; 25 import java.util.NoSuchElementException;
26 26
27 /** 27 /**
28 - * Deletes OVSDB nodes from cordvtn. 28 + * Deletes nodes from the service.
29 */ 29 */
30 -@Command(scope = "onos", name = "ovsdb-delete", 30 +@Command(scope = "onos", name = "cordvtn-node-delete",
31 - description = "Deletes OVSDB nodes from cordvtn") 31 + description = "Deletes nodes from CORD VTN service")
32 -public class OvsdbNodeDeleteCommand extends AbstractShellCommand { 32 +public class CordVtnNodeDeleteCommand extends AbstractShellCommand {
33 33
34 - @Argument(index = 0, name = "hosts", description = "Hostname(s) or IP(s)", 34 + @Argument(index = 0, name = "hostnames", description = "Hostname(s)",
35 required = true, multiValued = true) 35 required = true, multiValued = true)
36 - private String[] hosts = null; 36 + private String[] hostnames = null;
37 37
38 @Override 38 @Override
39 protected void execute() { 39 protected void execute() {
40 CordVtnService service = AbstractShellCommand.get(CordVtnService.class); 40 CordVtnService service = AbstractShellCommand.get(CordVtnService.class);
41 41
42 - for (String host : hosts) { 42 + for (String hostname : hostnames) {
43 - OvsdbNode ovsdb; 43 + CordVtnNode node;
44 try { 44 try {
45 - ovsdb = service.getNodes().stream() 45 + node = service.getNodes()
46 - .filter(node -> node.host().equals(host)) 46 + .stream()
47 + .filter(n -> n.hostname().equals(hostname))
47 .findFirst().get(); 48 .findFirst().get();
48 -
49 } catch (NoSuchElementException e) { 49 } catch (NoSuchElementException e) {
50 - print("Unable to find %s", host); 50 + print("Unable to find %s", hostname);
51 continue; 51 continue;
52 } 52 }
53 53
54 - service.deleteNode(ovsdb); 54 + service.deleteNode(node);
55 } 55 }
56 } 56 }
57 } 57 }
......
...@@ -20,41 +20,38 @@ import org.apache.karaf.shell.commands.Argument; ...@@ -20,41 +20,38 @@ import org.apache.karaf.shell.commands.Argument;
20 import org.apache.karaf.shell.commands.Command; 20 import org.apache.karaf.shell.commands.Command;
21 import org.onosproject.cli.AbstractShellCommand; 21 import org.onosproject.cli.AbstractShellCommand;
22 import org.onosproject.cordvtn.CordVtnService; 22 import org.onosproject.cordvtn.CordVtnService;
23 -import org.onosproject.cordvtn.OvsdbNode; 23 +import org.onosproject.cordvtn.CordVtnNode;
24 24
25 import java.util.NoSuchElementException; 25 import java.util.NoSuchElementException;
26 26
27 /** 27 /**
28 - * Connects to OVSDBs. 28 + * Initializes nodes for CordVtn service.
29 */ 29 */
30 -@Command(scope = "onos", name = "ovsdb-connect", 30 +@Command(scope = "onos", name = "cordvtn-node-init",
31 - description = "Connects to OVSDBs") 31 + description = "Initializes nodes for CORD VTN service")
32 -public class OvsdbNodeConnectCommand extends AbstractShellCommand { 32 +public class CordVtnNodeInitCommand extends AbstractShellCommand {
33 33
34 - @Argument(index = 0, name = "hosts", description = "Hostname(s) or IP(s)", 34 + @Argument(index = 0, name = "hostnames", description = "Hostname(s)",
35 required = true, multiValued = true) 35 required = true, multiValued = true)
36 - private String[] hosts = null; 36 + private String[] hostnames = null;
37 37
38 @Override 38 @Override
39 protected void execute() { 39 protected void execute() {
40 CordVtnService service = AbstractShellCommand.get(CordVtnService.class); 40 CordVtnService service = AbstractShellCommand.get(CordVtnService.class);
41 41
42 - for (String host : hosts) { 42 + for (String hostname : hostnames) {
43 - OvsdbNode ovsdb; 43 + CordVtnNode node;
44 try { 44 try {
45 - ovsdb = service.getNodes().stream() 45 + node = service.getNodes()
46 - .filter(node -> node.host().equals(host)) 46 + .stream()
47 + .filter(n -> n.hostname().equals(hostname))
47 .findFirst().get(); 48 .findFirst().get();
48 } catch (NoSuchElementException e) { 49 } catch (NoSuchElementException e) {
49 - print("Unable to find %s", host); 50 + print("Unable to find %s", hostname);
50 continue; 51 continue;
51 } 52 }
52 53
53 - if (service.isNodeConnected(ovsdb)) { 54 + service.initNode(node);
54 - print("OVSDB %s is already in connected state, do nothing", host);
55 - } else {
56 - service.connect(ovsdb);
57 - }
58 } 55 }
59 } 56 }
60 } 57 }
......
...@@ -22,53 +22,53 @@ import com.fasterxml.jackson.databind.node.ArrayNode; ...@@ -22,53 +22,53 @@ import com.fasterxml.jackson.databind.node.ArrayNode;
22 import org.apache.karaf.shell.commands.Command; 22 import org.apache.karaf.shell.commands.Command;
23 import org.onosproject.cli.AbstractShellCommand; 23 import org.onosproject.cli.AbstractShellCommand;
24 import org.onosproject.cordvtn.CordVtnService; 24 import org.onosproject.cordvtn.CordVtnService;
25 -import org.onosproject.cordvtn.OvsdbNode; 25 +import org.onosproject.cordvtn.CordVtnNode;
26 26
27 import java.util.Collections; 27 import java.util.Collections;
28 import java.util.List; 28 import java.util.List;
29 29
30 /** 30 /**
31 - * Lists all OVSDB nodes. 31 + * Lists all nodes registered to the service.
32 */ 32 */
33 -@Command(scope = "onos", name = "ovsdbs", 33 +@Command(scope = "onos", name = "cordvtn-nodes",
34 - description = "Lists all OVSDB nodes registered in cordvtn application") 34 + description = "Lists all nodes registered in CORD VTN service")
35 -public class OvsdbNodeListCommand extends AbstractShellCommand { 35 +public class CordVtnNodeListCommand extends AbstractShellCommand {
36 36
37 @Override 37 @Override
38 protected void execute() { 38 protected void execute() {
39 CordVtnService service = AbstractShellCommand.get(CordVtnService.class); 39 CordVtnService service = AbstractShellCommand.get(CordVtnService.class);
40 - List<OvsdbNode> ovsdbs = service.getNodes(); 40 + List<CordVtnNode> nodes = service.getNodes();
41 - Collections.sort(ovsdbs, OvsdbNode.OVSDB_NODE_COMPARATOR); 41 + Collections.sort(nodes, CordVtnNode.CORDVTN_NODE_COMPARATOR);
42 42
43 if (outputJson()) { 43 if (outputJson()) {
44 - print("%s", json(service, ovsdbs)); 44 + print("%s", json(service, nodes));
45 } else { 45 } else {
46 - for (OvsdbNode ovsdb : ovsdbs) { 46 + for (CordVtnNode node : nodes) {
47 - print("host=%s, address=%s, br-int=%s, state=%s", 47 + print("hostname=%s, ovsdb=%s, br-int=%s, init=%s",
48 - ovsdb.host(), 48 + node.hostname(),
49 - ovsdb.ip().toString() + ":" + ovsdb.port().toString(), 49 + node.ovsdbIp().toString() + ":" + node.ovsdbPort().toString(),
50 - ovsdb.intBrId().toString(), 50 + node.intBrId().toString(),
51 - getState(service, ovsdb)); 51 + getState(service, node));
52 } 52 }
53 print("Total %s nodes", service.getNodeCount()); 53 print("Total %s nodes", service.getNodeCount());
54 } 54 }
55 } 55 }
56 56
57 - private JsonNode json(CordVtnService service, List<OvsdbNode> ovsdbs) { 57 + private JsonNode json(CordVtnService service, List<CordVtnNode> nodes) {
58 ObjectMapper mapper = new ObjectMapper(); 58 ObjectMapper mapper = new ObjectMapper();
59 ArrayNode result = mapper.createArrayNode(); 59 ArrayNode result = mapper.createArrayNode();
60 - for (OvsdbNode ovsdb : ovsdbs) { 60 + for (CordVtnNode node : nodes) {
61 - String ipPort = ovsdb.ip().toString() + ":" + ovsdb.port().toString(); 61 + String ipPort = node.ovsdbIp().toString() + ":" + node.ovsdbPort().toString();
62 result.add(mapper.createObjectNode() 62 result.add(mapper.createObjectNode()
63 - .put("host", ovsdb.host()) 63 + .put("hostname", node.hostname())
64 - .put("address", ipPort) 64 + .put("ovsdb", ipPort)
65 - .put("brInt", ovsdb.intBrId().toString()) 65 + .put("brInt", node.intBrId().toString())
66 - .put("state", getState(service, ovsdb))); 66 + .put("init", getState(service, node)));
67 } 67 }
68 return result; 68 return result;
69 } 69 }
70 70
71 - private String getState(CordVtnService service, OvsdbNode ovsdb) { 71 + private String getState(CordVtnService service, CordVtnNode node) {
72 - return service.isNodeConnected(ovsdb) ? "CONNECTED" : "DISCONNECTED"; 72 + return service.getNodeInitState(node) ? "COMPLETE" : "INCOMPLETE";
73 } 73 }
74 } 74 }
......
1 -/*
2 - * Copyright 2015 Open Networking Laboratory
3 - *
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 - */
16 -
17 -package org.onosproject.cordvtn.cli;
18 -
19 -import org.apache.karaf.shell.commands.Argument;
20 -import org.apache.karaf.shell.commands.Command;
21 -import org.onosproject.cli.AbstractShellCommand;
22 -import org.onosproject.cordvtn.CordVtnService;
23 -import org.onosproject.cordvtn.OvsdbNode;
24 -
25 -import java.util.NoSuchElementException;
26 -
27 -/**
28 - * Disconnects OVSDBs.
29 - */
30 -@Command(scope = "onos", name = "ovsdb-disconnect",
31 - description = "Disconnects OVSDBs")
32 -public class OvsdbNodeDisconnectCommand extends AbstractShellCommand {
33 -
34 - @Argument(index = 0, name = "hosts", description = "Hostname(s) or IP(s)",
35 - required = true, multiValued = true)
36 - private String[] hosts = null;
37 -
38 - @Override
39 - protected void execute() {
40 - CordVtnService service = AbstractShellCommand.get(CordVtnService.class);
41 -
42 - for (String host : hosts) {
43 - OvsdbNode ovsdb;
44 - try {
45 - ovsdb = service.getNodes().stream()
46 - .filter(node -> node.host().equals(host))
47 - .findFirst().get();
48 - } catch (NoSuchElementException e) {
49 - print("Unable to find %s", host);
50 - continue;
51 - }
52 -
53 - if (!service.isNodeConnected(ovsdb)) {
54 - print("OVSDB %s is already in disconnected state, do nothing", host);
55 - } else {
56 - service.disconnect(ovsdb);
57 - }
58 - }
59 - }
60 -}
...@@ -17,19 +17,16 @@ ...@@ -17,19 +17,16 @@
17 17
18 <command-bundle xmlns="http://karaf.apache.org/xmlns/shell/v1.1.0"> 18 <command-bundle xmlns="http://karaf.apache.org/xmlns/shell/v1.1.0">
19 <command> 19 <command>
20 - <action class="org.onosproject.cordvtn.cli.OvsdbNodeListCommand"/> 20 + <action class="org.onosproject.cordvtn.cli.CordVtnNodeListCommand"/>
21 </command> 21 </command>
22 <command> 22 <command>
23 - <action class="org.onosproject.cordvtn.cli.OvsdbNodeAddCommand"/> 23 + <action class="org.onosproject.cordvtn.cli.CordVtnNodeAddCommand"/>
24 </command> 24 </command>
25 <command> 25 <command>
26 - <action class="org.onosproject.cordvtn.cli.OvsdbNodeDeleteCommand"/> 26 + <action class="org.onosproject.cordvtn.cli.CordVtnNodeDeleteCommand"/>
27 </command> 27 </command>
28 <command> 28 <command>
29 - <action class="org.onosproject.cordvtn.cli.OvsdbNodeConnectCommand"/> 29 + <action class="org.onosproject.cordvtn.cli.CordVtnNodeInitCommand"/>
30 - </command>
31 - <command>
32 - <action class="org.onosproject.cordvtn.cli.OvsdbNodeDisconnectCommand"/>
33 </command> 30 </command>
34 </command-bundle> 31 </command-bundle>
35 </blueprint> 32 </blueprint>
......