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
......@@ -32,77 +32,82 @@ import static com.google.common.base.Preconditions.checkNotNull;
*/
public class CordVtnConfig extends Config<ApplicationId> {
public static final String OVSDB_NODES = "ovsdbNodes";
public static final String HOST = "host";
public static final String IP = "ip";
public static final String PORT = "port";
public static final String CORDVTN_NODES = "nodes";
public static final String HOSTNAME = "hostname";
public static final String OVSDB_IP = "ovsdbIp";
public static final String OVSDB_PORT = "ovsdbPort";
public static final String BRIDGE_ID = "bridgeId";
/**
* Returns the set of ovsdb nodes read from network config.
* Returns the set of nodes read from network config.
*
* @return set of OvsdbNodeConfig or null
* @return set of CordVtnNodeConfig or null
*/
public Set<OvsdbNodeConfig> ovsdbNodes() {
Set<OvsdbNodeConfig> ovsdbNodes = Sets.newHashSet();
public Set<CordVtnNodeConfig> cordVtnNodes() {
Set<CordVtnNodeConfig> nodes = Sets.newHashSet();
JsonNode nodes = object.get(OVSDB_NODES);
if (nodes == null) {
JsonNode jsonNodes = object.get(CORDVTN_NODES);
if (jsonNodes == null) {
return null;
}
nodes.forEach(jsonNode -> ovsdbNodes.add(new OvsdbNodeConfig(
jsonNode.path(HOST).asText(),
IpAddress.valueOf(jsonNode.path(IP).asText()),
TpPort.tpPort(jsonNode.path(PORT).asInt()),
jsonNodes.forEach(jsonNode -> nodes.add(new CordVtnNodeConfig(
jsonNode.path(HOSTNAME).asText(),
IpAddress.valueOf(jsonNode.path(OVSDB_IP).asText()),
TpPort.tpPort(jsonNode.path(OVSDB_PORT).asInt()),
DeviceId.deviceId(jsonNode.path(BRIDGE_ID).asText()))));
return ovsdbNodes;
return nodes;
}
/**
* Configuration for an ovsdb node.
* Configuration for CordVtn node.
*/
public static class OvsdbNodeConfig {
public static class CordVtnNodeConfig {
private final String host;
private final IpAddress ip;
private final TpPort port;
private final String hostname;
private final IpAddress ovsdbIp;
private final TpPort ovsdbPort;
private final DeviceId bridgeId;
public OvsdbNodeConfig(String host, IpAddress ip, TpPort port, DeviceId bridgeId) {
this.host = checkNotNull(host);
this.ip = checkNotNull(ip);
this.port = checkNotNull(port);
public CordVtnNodeConfig(String hostname, IpAddress ovsdbIp, TpPort ovsdbPort, DeviceId bridgeId) {
this.hostname = checkNotNull(hostname);
this.ovsdbIp = checkNotNull(ovsdbIp);
this.ovsdbPort = checkNotNull(ovsdbPort);
this.bridgeId = checkNotNull(bridgeId);
}
/**
* Returns host information of the node.
* Returns hostname of the node.
*
* @return host
* @return hostname
*/
public String host() {
return this.host;
public String hostname() {
return this.hostname;
}
/**
* Returns ip address to access ovsdb-server of the node.
* Returns OVSDB ip address of the node.
*
* @return ip address
* @return OVSDB server IP address
*/
public IpAddress ip() {
return this.ip;
public IpAddress ovsdbIp() {
return this.ovsdbIp;
}
/**
* Returns port number to access ovsdb-server of the node.
* Returns OVSDB port number of the node.
*
* @return port number
*/
public TpPort port() {
return this.port;
public TpPort ovsdbPort() {
return this.ovsdbPort;
}
/**
* Returns integration bridge id of the node.
*
* @return device id
*/
public DeviceId bridgeId() {
return this.bridgeId;
}
......
......@@ -88,10 +88,10 @@ public class CordVtnConfigManager {
return;
}
config.ovsdbNodes().forEach(node -> {
DefaultOvsdbNode ovsdb = new DefaultOvsdbNode(
node.host(), node.ip(), node.port(), node.bridgeId());
cordVtnService.addNode(ovsdb);
config.cordVtnNodes().forEach(node -> {
CordVtnNode cordVtnNode = new CordVtnNode(
node.hostname(), node.ovsdbIp(), node.ovsdbPort(), node.bridgeId());
cordVtnService.addNode(cordVtnNode);
});
}
......
/*
* Copyright 2014-2015 Open Networking Laboratory
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.onosproject.cordvtn;
import com.google.common.base.MoreObjects;
import org.onlab.packet.IpAddress;
import org.onlab.packet.TpPort;
import org.onosproject.net.DeviceId;
import java.util.Comparator;
import java.util.Objects;
import static com.google.common.base.Preconditions.checkNotNull;
/**
* Representation of a compute infrastructure node for CORD VTN service.
*/
public final class CordVtnNode {
private final String hostname;
private final IpAddress ovsdbIp;
private final TpPort ovsdbPort;
private final DeviceId bridgeId;
public static final Comparator<CordVtnNode> CORDVTN_NODE_COMPARATOR =
(node1, node2) -> node1.hostname().compareTo(node2.hostname());
/**
* Creates a new node.
*
* @param hostname hostname
* @param ovsdbIp OVSDB server IP address
* @param ovsdbPort OVSDB server port number
* @param bridgeId integration bridge identifier
*/
public CordVtnNode(String hostname, IpAddress ovsdbIp, TpPort ovsdbPort, DeviceId bridgeId) {
this.hostname = checkNotNull(hostname);
this.ovsdbIp = checkNotNull(ovsdbIp);
this.ovsdbPort = checkNotNull(ovsdbPort);
this.bridgeId = checkNotNull(bridgeId);
}
/**
* Returns the OVSDB server IP address.
*
* @return ip address
*/
public IpAddress ovsdbIp() {
return this.ovsdbIp;
}
/**
* Returns the OVSDB server port number.
*
* @return port number
*/
public TpPort ovsdbPort() {
return this.ovsdbPort;
}
/**
* Returns the hostname.
*
* @return hostname
*/
public String hostname() {
return this.hostname;
}
/**
* Returns the identifier of the integration bridge.
*
* @return device id
*/
public DeviceId intBrId() {
return this.bridgeId;
}
/**
* Returns the identifier of the OVSDB device.
*
* @return device id
*/
public DeviceId ovsdbId() {
return DeviceId.deviceId("ovsdb:" + this.ovsdbIp.toString());
}
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj instanceof CordVtnNode) {
CordVtnNode that = (CordVtnNode) obj;
if (Objects.equals(hostname, that.hostname) &&
Objects.equals(ovsdbIp, that.ovsdbIp) &&
Objects.equals(ovsdbPort, that.ovsdbPort) &&
Objects.equals(bridgeId, that.bridgeId)) {
return true;
}
}
return false;
}
@Override
public int hashCode() {
return Objects.hash(hostname, ovsdbIp, ovsdbPort);
}
@Override
public String toString() {
return MoreObjects.toStringHelper(getClass())
.add("host", hostname)
.add("ip", ovsdbIp)
.add("port", ovsdbPort)
.add("bridgeId", bridgeId)
.toString();
}
}
......@@ -15,8 +15,6 @@
*/
package org.onosproject.cordvtn;
import org.onosproject.net.DeviceId;
import java.util.List;
/**
......@@ -28,30 +26,23 @@ public interface CordVtnService {
/**
* Adds a new node to the service.
*
* @param ovsdb ovsdb node
* @param node cordvtn node
*/
void addNode(OvsdbNode ovsdb);
void addNode(CordVtnNode node);
/**
* Deletes a node from the service.
*
* @param ovsdb ovsdb node
*/
void deleteNode(OvsdbNode ovsdb);
/**
* Connect to a node.
*
* @param ovsdb ovsdb node
* @param node cordvtn node
*/
void connect(OvsdbNode ovsdb);
void deleteNode(CordVtnNode node);
/**
* Disconnect a node.
* Initiates node to serve virtual tenant network.
*
* @param ovsdb ovsdb node
* @param node cordvtn node
*/
void disconnect(OvsdbNode ovsdb);
void initNode(CordVtnNode node);
/**
* Returns the number of the nodes known to the service.
......@@ -61,25 +52,17 @@ public interface CordVtnService {
int getNodeCount();
/**
* Returns OvsdbNode with given device id.
*
* @param deviceId device id
* @return ovsdb node
*/
OvsdbNode getNode(DeviceId deviceId);
/**
* Returns connection state of the node.
* Returns node initialization state.
*
* @param ovsdb ovsdb node
* @return true if the node is connected, false otherwise
* @param node cordvtn node
* @return true if initial node setup is completed, otherwise false
*/
boolean isNodeConnected(OvsdbNode ovsdb);
boolean getNodeInitState(CordVtnNode node);
/**
* Returns all nodes known to the service.
*
* @return list of nodes
*/
List<OvsdbNode> getNodes();
List<CordVtnNode> getNodes();
}
......
/*
* Copyright 2014-2015 Open Networking Laboratory
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.onosproject.cordvtn;
import com.google.common.base.MoreObjects;
import org.onlab.packet.IpAddress;
import org.onlab.packet.TpPort;
import org.onosproject.net.DeviceId;
import java.util.Objects;
/**
* OvsdbNode implementation.
*/
public class DefaultOvsdbNode implements OvsdbNode {
private final String host;
private final IpAddress ip;
private final TpPort port;
private final DeviceId brId;
public DefaultOvsdbNode(String host, IpAddress ip, TpPort port, DeviceId brId) {
this.host = host;
this.ip = ip;
this.port = port;
this.brId = brId;
}
@Override
public IpAddress ip() {
return this.ip;
}
@Override
public TpPort port() {
return this.port;
}
@Override
public String host() {
return this.host;
}
@Override
public DeviceId intBrId() {
return this.brId;
}
@Override
public DeviceId deviceId() {
return DeviceId.deviceId("ovsdb:" + this.ip.toString());
}
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o instanceof DefaultOvsdbNode) {
DefaultOvsdbNode that = (DefaultOvsdbNode) o;
if (this.host.equals(that.host) &&
this.ip.equals(that.ip) &&
this.port.equals(that.port) &&
this.brId.equals(that.brId)) {
return true;
}
}
return false;
}
@Override
public int hashCode() {
return Objects.hash(host, ip, port);
}
@Override
public String toString() {
return MoreObjects.toStringHelper(getClass())
.add("host", host)
.add("ip", ip)
.add("port", port)
.add("bridgeId", brId)
.toString();
}
}
/*
* Copyright 2014-2015 Open Networking Laboratory
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.onosproject.cordvtn;
import org.onlab.packet.IpAddress;
import org.onlab.packet.TpPort;
import org.onosproject.net.DeviceId;
import java.util.Comparator;
/**
* Representation of a node with ovsdb server.
*/
public interface OvsdbNode {
Comparator<OvsdbNode> OVSDB_NODE_COMPARATOR = new Comparator<OvsdbNode>() {
@Override
public int compare(OvsdbNode ovsdb1, OvsdbNode ovsdb2) {
return ovsdb1.host().compareTo(ovsdb2.host());
}
};
/**
* Returns the IP address of the ovsdb server.
*
* @return ip address
*/
IpAddress ip();
/**
* Returns the port number of the ovsdb server.
*
* @return port number
*/
TpPort port();
/**
* Returns the host information of the ovsdb server.
* It could be hostname or ip address.
*
* @return host
*/
String host();
/**
* Returns the device id of the ovsdb server.
*
* @return device id
*/
DeviceId deviceId();
/**
* Returns the device id of the integration bridge associated with the node.
*
* @return device id
*/
DeviceId intBrId();
}
......@@ -22,27 +22,26 @@ import org.onlab.packet.IpAddress;
import org.onlab.packet.TpPort;
import org.onosproject.cli.AbstractShellCommand;
import org.onosproject.cordvtn.CordVtnService;
import org.onosproject.cordvtn.DefaultOvsdbNode;
import org.onosproject.cordvtn.OvsdbNode;
import org.onosproject.cordvtn.CordVtnNode;
import org.onosproject.net.DeviceId;
import static com.google.common.base.Preconditions.checkArgument;
/**
* Adds a new OVSDB nodes.
* Adds a new node to the service.
*/
@Command(scope = "onos", name = "ovsdb-add",
description = "Adds a new OVSDB node to cordvtn")
public class OvsdbNodeAddCommand extends AbstractShellCommand {
@Command(scope = "onos", name = "cordvtn-node-add",
description = "Adds a new node to CORD VTN service")
public class CordVtnNodeAddCommand extends AbstractShellCommand {
@Argument(index = 0, name = "host", description = "Hostname or IP",
@Argument(index = 0, name = "hostname", description = "Hostname",
required = true, multiValued = false)
private String host = null;
private String hostname = null;
@Argument(index = 1, name = "address",
@Argument(index = 1, name = "ovsdb",
description = "OVSDB server listening address (ip:port)",
required = true, multiValued = false)
private String address = null;
private String ovsdb = null;
@Argument(index = 2, name = "bridgeId",
description = "Device ID of integration bridge",
......@@ -51,15 +50,15 @@ public class OvsdbNodeAddCommand extends AbstractShellCommand {
@Override
protected void execute() {
checkArgument(address.contains(":"), "address should be ip:port format");
checkArgument(ovsdb.contains(":"), "OVSDB address should be ip:port format");
checkArgument(bridgeId.startsWith("of:"), "bridgeId should be of:dpid format");
CordVtnService service = AbstractShellCommand.get(CordVtnService.class);
String[] ipPort = address.split(":");
OvsdbNode ovsdb = new DefaultOvsdbNode(host,
String[] ipPort = ovsdb.split(":");
CordVtnNode node = new CordVtnNode(hostname,
IpAddress.valueOf(ipPort[0]),
TpPort.tpPort(Integer.parseInt(ipPort[1])),
DeviceId.deviceId(bridgeId));
service.addNode(ovsdb);
service.addNode(node);
}
}
......
......@@ -20,38 +20,38 @@ import org.apache.karaf.shell.commands.Argument;
import org.apache.karaf.shell.commands.Command;
import org.onosproject.cli.AbstractShellCommand;
import org.onosproject.cordvtn.CordVtnService;
import org.onosproject.cordvtn.OvsdbNode;
import org.onosproject.cordvtn.CordVtnNode;
import java.util.NoSuchElementException;
/**
* Deletes OVSDB nodes from cordvtn.
* Deletes nodes from the service.
*/
@Command(scope = "onos", name = "ovsdb-delete",
description = "Deletes OVSDB nodes from cordvtn")
public class OvsdbNodeDeleteCommand extends AbstractShellCommand {
@Command(scope = "onos", name = "cordvtn-node-delete",
description = "Deletes nodes from CORD VTN service")
public class CordVtnNodeDeleteCommand extends AbstractShellCommand {
@Argument(index = 0, name = "hosts", description = "Hostname(s) or IP(s)",
@Argument(index = 0, name = "hostnames", description = "Hostname(s)",
required = true, multiValued = true)
private String[] hosts = null;
private String[] hostnames = null;
@Override
protected void execute() {
CordVtnService service = AbstractShellCommand.get(CordVtnService.class);
for (String host : hosts) {
OvsdbNode ovsdb;
for (String hostname : hostnames) {
CordVtnNode node;
try {
ovsdb = service.getNodes().stream()
.filter(node -> node.host().equals(host))
node = service.getNodes()
.stream()
.filter(n -> n.hostname().equals(hostname))
.findFirst().get();
} catch (NoSuchElementException e) {
print("Unable to find %s", host);
print("Unable to find %s", hostname);
continue;
}
service.deleteNode(ovsdb);
service.deleteNode(node);
}
}
}
......
......@@ -20,41 +20,38 @@ import org.apache.karaf.shell.commands.Argument;
import org.apache.karaf.shell.commands.Command;
import org.onosproject.cli.AbstractShellCommand;
import org.onosproject.cordvtn.CordVtnService;
import org.onosproject.cordvtn.OvsdbNode;
import org.onosproject.cordvtn.CordVtnNode;
import java.util.NoSuchElementException;
/**
* Connects to OVSDBs.
* Initializes nodes for CordVtn service.
*/
@Command(scope = "onos", name = "ovsdb-connect",
description = "Connects to OVSDBs")
public class OvsdbNodeConnectCommand extends AbstractShellCommand {
@Command(scope = "onos", name = "cordvtn-node-init",
description = "Initializes nodes for CORD VTN service")
public class CordVtnNodeInitCommand extends AbstractShellCommand {
@Argument(index = 0, name = "hosts", description = "Hostname(s) or IP(s)",
@Argument(index = 0, name = "hostnames", description = "Hostname(s)",
required = true, multiValued = true)
private String[] hosts = null;
private String[] hostnames = null;
@Override
protected void execute() {
CordVtnService service = AbstractShellCommand.get(CordVtnService.class);
for (String host : hosts) {
OvsdbNode ovsdb;
for (String hostname : hostnames) {
CordVtnNode node;
try {
ovsdb = service.getNodes().stream()
.filter(node -> node.host().equals(host))
node = service.getNodes()
.stream()
.filter(n -> n.hostname().equals(hostname))
.findFirst().get();
} catch (NoSuchElementException e) {
print("Unable to find %s", host);
print("Unable to find %s", hostname);
continue;
}
if (service.isNodeConnected(ovsdb)) {
print("OVSDB %s is already in connected state, do nothing", host);
} else {
service.connect(ovsdb);
}
service.initNode(node);
}
}
}
......
......@@ -22,53 +22,53 @@ import com.fasterxml.jackson.databind.node.ArrayNode;
import org.apache.karaf.shell.commands.Command;
import org.onosproject.cli.AbstractShellCommand;
import org.onosproject.cordvtn.CordVtnService;
import org.onosproject.cordvtn.OvsdbNode;
import org.onosproject.cordvtn.CordVtnNode;
import java.util.Collections;
import java.util.List;
/**
* Lists all OVSDB nodes.
* Lists all nodes registered to the service.
*/
@Command(scope = "onos", name = "ovsdbs",
description = "Lists all OVSDB nodes registered in cordvtn application")
public class OvsdbNodeListCommand extends AbstractShellCommand {
@Command(scope = "onos", name = "cordvtn-nodes",
description = "Lists all nodes registered in CORD VTN service")
public class CordVtnNodeListCommand extends AbstractShellCommand {
@Override
protected void execute() {
CordVtnService service = AbstractShellCommand.get(CordVtnService.class);
List<OvsdbNode> ovsdbs = service.getNodes();
Collections.sort(ovsdbs, OvsdbNode.OVSDB_NODE_COMPARATOR);
List<CordVtnNode> nodes = service.getNodes();
Collections.sort(nodes, CordVtnNode.CORDVTN_NODE_COMPARATOR);
if (outputJson()) {
print("%s", json(service, ovsdbs));
print("%s", json(service, nodes));
} else {
for (OvsdbNode ovsdb : ovsdbs) {
print("host=%s, address=%s, br-int=%s, state=%s",
ovsdb.host(),
ovsdb.ip().toString() + ":" + ovsdb.port().toString(),
ovsdb.intBrId().toString(),
getState(service, ovsdb));
for (CordVtnNode node : nodes) {
print("hostname=%s, ovsdb=%s, br-int=%s, init=%s",
node.hostname(),
node.ovsdbIp().toString() + ":" + node.ovsdbPort().toString(),
node.intBrId().toString(),
getState(service, node));
}
print("Total %s nodes", service.getNodeCount());
}
}
private JsonNode json(CordVtnService service, List<OvsdbNode> ovsdbs) {
private JsonNode json(CordVtnService service, List<CordVtnNode> nodes) {
ObjectMapper mapper = new ObjectMapper();
ArrayNode result = mapper.createArrayNode();
for (OvsdbNode ovsdb : ovsdbs) {
String ipPort = ovsdb.ip().toString() + ":" + ovsdb.port().toString();
for (CordVtnNode node : nodes) {
String ipPort = node.ovsdbIp().toString() + ":" + node.ovsdbPort().toString();
result.add(mapper.createObjectNode()
.put("host", ovsdb.host())
.put("address", ipPort)
.put("brInt", ovsdb.intBrId().toString())
.put("state", getState(service, ovsdb)));
.put("hostname", node.hostname())
.put("ovsdb", ipPort)
.put("brInt", node.intBrId().toString())
.put("init", getState(service, node)));
}
return result;
}
private String getState(CordVtnService service, OvsdbNode ovsdb) {
return service.isNodeConnected(ovsdb) ? "CONNECTED" : "DISCONNECTED";
private String getState(CordVtnService service, CordVtnNode node) {
return service.getNodeInitState(node) ? "COMPLETE" : "INCOMPLETE";
}
}
......
/*
* Copyright 2015 Open Networking Laboratory
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.onosproject.cordvtn.cli;
import org.apache.karaf.shell.commands.Argument;
import org.apache.karaf.shell.commands.Command;
import org.onosproject.cli.AbstractShellCommand;
import org.onosproject.cordvtn.CordVtnService;
import org.onosproject.cordvtn.OvsdbNode;
import java.util.NoSuchElementException;
/**
* Disconnects OVSDBs.
*/
@Command(scope = "onos", name = "ovsdb-disconnect",
description = "Disconnects OVSDBs")
public class OvsdbNodeDisconnectCommand extends AbstractShellCommand {
@Argument(index = 0, name = "hosts", description = "Hostname(s) or IP(s)",
required = true, multiValued = true)
private String[] hosts = null;
@Override
protected void execute() {
CordVtnService service = AbstractShellCommand.get(CordVtnService.class);
for (String host : hosts) {
OvsdbNode ovsdb;
try {
ovsdb = service.getNodes().stream()
.filter(node -> node.host().equals(host))
.findFirst().get();
} catch (NoSuchElementException e) {
print("Unable to find %s", host);
continue;
}
if (!service.isNodeConnected(ovsdb)) {
print("OVSDB %s is already in disconnected state, do nothing", host);
} else {
service.disconnect(ovsdb);
}
}
}
}
......@@ -17,19 +17,16 @@
<command-bundle xmlns="http://karaf.apache.org/xmlns/shell/v1.1.0">
<command>
<action class="org.onosproject.cordvtn.cli.OvsdbNodeListCommand"/>
<action class="org.onosproject.cordvtn.cli.CordVtnNodeListCommand"/>
</command>
<command>
<action class="org.onosproject.cordvtn.cli.OvsdbNodeAddCommand"/>
<action class="org.onosproject.cordvtn.cli.CordVtnNodeAddCommand"/>
</command>
<command>
<action class="org.onosproject.cordvtn.cli.OvsdbNodeDeleteCommand"/>
<action class="org.onosproject.cordvtn.cli.CordVtnNodeDeleteCommand"/>
</command>
<command>
<action class="org.onosproject.cordvtn.cli.OvsdbNodeConnectCommand"/>
</command>
<command>
<action class="org.onosproject.cordvtn.cli.OvsdbNodeDisconnectCommand"/>
<action class="org.onosproject.cordvtn.cli.CordVtnNodeInitCommand"/>
</command>
</command-bundle>
</blueprint>
......