Hyunsun Moon
Committed by Gerrit Code Review

CORD-151 add initial skeleton for cord-vtn application

Change-Id: I57bf17445f1e571b51bca2fe7c2631e65cd43145
......@@ -36,6 +36,19 @@
</properties>
<dependencies>
<dependency>
<groupId>org.osgi</groupId>
<artifactId>org.osgi.compendium</artifactId>
</dependency>
<dependency>
<groupId>org.onosproject</groupId>
<artifactId>onos-api</artifactId>
</dependency>
<dependency>
<groupId>org.onosproject</groupId>
<artifactId>onos-core-serializers</artifactId>
<version>${project.version}</version>
</dependency>
</dependencies>
</project>
......
/*
* 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;
/**
* Entity capable of handling a subject connected and disconnected situation.
*/
public interface ConnectionHandler<T> {
/**
* Processes the connected subject.
*
* @param subject subject
*/
void connected(T subject);
/**
* Processes the disconnected subject.
*
* @param subject subject.
*/
void disconnected(T subject);
}
This diff is collapsed. Click to expand it.
/*
* 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.fasterxml.jackson.databind.JsonNode;
import com.google.common.collect.Sets;
import org.onlab.packet.IpAddress;
import org.onlab.packet.TpPort;
import org.onosproject.core.ApplicationId;
import org.onosproject.net.config.Config;
import java.util.Set;
import static com.google.common.base.Preconditions.checkNotNull;
/**
* Configuration object for CORD VTN service.
*/
public class CordVtnConfig extends Config<ApplicationId> {
public static final String OVSDB_NODES = "ovsdbNodes";
public static final String HOSTNAME = "hostname";
public static final String IP = "ip";
public static final String PORT = "port";
/**
* Returns the set of ovsdb nodes read from network config.
*
* @return set of OvsdbNodeConfig or null
*/
public Set<OvsdbNodeConfig> ovsdbNodes() {
Set<OvsdbNodeConfig> ovsdbNodes = Sets.newHashSet();
JsonNode nodes = object.get(OVSDB_NODES);
if (nodes == null) {
return null;
}
nodes.forEach(jsonNode -> ovsdbNodes.add(new OvsdbNodeConfig(
jsonNode.path(HOSTNAME).asText(),
IpAddress.valueOf(jsonNode.path(IP).asText()),
TpPort.tpPort(jsonNode.path(PORT).asInt()))));
return ovsdbNodes;
}
/**
* Configuration for an OVSDB node.
*/
public static class OvsdbNodeConfig {
private final String hostname;
private final IpAddress ip;
private final TpPort port;
public OvsdbNodeConfig(String hostname, IpAddress ip, TpPort port) {
this.hostname = checkNotNull(hostname);
this.ip = checkNotNull(ip);
this.port = checkNotNull(port);
}
/**
* Returns hostname of the node.
*
* @return hostname
*/
public String hostname() {
return this.hostname;
}
/**
* Returns ip address to access ovsdb-server of the node.
*
* @return ip address
*/
public IpAddress ip() {
return this.ip;
}
/**
* Returns port number to access ovsdb-server of the node.
*
* @return port number
*/
public TpPort port() {
return this.port;
}
}
}
......@@ -15,6 +15,9 @@
*/
package org.onosproject.cordvtn;
import org.onlab.packet.IpAddress;
import org.onlab.packet.TpPort;
import java.util.List;
/**
......@@ -22,19 +25,21 @@ import java.util.List;
*/
public interface CordVtnService {
/**
* Adds new nodes to the service and processes initial setup.
* Adds a new node to the service.
*
* @param ovsdbNodes list of nodes
* @param hostname hostname of the node
* @param ip ip address to access the ovsdb server running on the node
* @param port port number to access the ovsdb server running on the node
*/
void addNodes(List<OvsdbNode> ovsdbNodes);
void addNode(String hostname, IpAddress ip, TpPort port);
/**
* Deletes the nodes from the service and cleans up unnecessary configurations
* associated with the deleted nodes.
* Deletes the node from the service.
*
* @param ovsdbNodes list of nodes
* @param ip ip address to access the ovsdb server running on the node
* @param port port number to access the ovsdb server running on the node
*/
void deleteNodes(List<OvsdbNode> ovsdbNodes);
void deleteNode(IpAddress ip, TpPort port);
/**
* Returns the number of the nodes known to the service.
......
/*
* 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.Objects;
/**
* OvsdbNode implementation.
*/
public class DefaultOvsdbNode implements OvsdbNode {
private final String hostname;
private final IpAddress ip;
private final TpPort port;
private final DeviceId deviceId;
private final DeviceId bridgeId;
private final State state;
public DefaultOvsdbNode(String hostname, IpAddress ip, TpPort port,
DeviceId bridgeId, State state) {
this.hostname = hostname;
this.ip = ip;
this.port = port;
this.deviceId = DeviceId.deviceId(
"ovsdb:" + ip.toString() + ":" + port.toString());
this.bridgeId = bridgeId;
this.state = state;
}
@Override
public IpAddress ip() {
return this.ip;
}
@Override
public TpPort port() {
return this.port;
}
@Override
public String hostname() {
return this.hostname;
}
@Override
public State state() {
return this.state;
}
@Override
public DeviceId deviceId() {
return this.deviceId;
}
@Override
public DeviceId bridgeId() {
return this.bridgeId;
}
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o instanceof DefaultOvsdbNode) {
DefaultOvsdbNode that = (DefaultOvsdbNode) o;
// We compare the ip and port only.
if (this.ip.equals(that.ip) && this.port.equals(that.port)) {
return true;
}
}
return false;
}
@Override
public int hashCode() {
return Objects.hash(ip, port);
}
}
/*
* 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.onosproject.cluster.LeadershipService;
import org.onosproject.cluster.NodeId;
import org.onosproject.core.ApplicationId;
import org.onosproject.mastership.MastershipService;
import org.onosproject.net.DeviceId;
import org.onosproject.store.service.EventuallyConsistentMap;
import org.slf4j.Logger;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import static org.onlab.util.Tools.groupedThreads;
import static org.slf4j.LoggerFactory.getLogger;
/**
* Node connection manager.
*/
public class NodeConnectionManager {
protected final Logger log = getLogger(getClass());
private final ApplicationId appId;
private final NodeId localId;
private final EventuallyConsistentMap<DeviceId, OvsdbNode> nodeStore;
private final MastershipService mastershipService;
private final LeadershipService leadershipService;
private static final int DELAY_SEC = 5;
private ScheduledExecutorService connectionExecutor;
/**
* Creates a new NodeConnectionManager.
*
* @param localId local id
* @param nodeStore node store
* @param mastershipService mastership service
*/
public NodeConnectionManager(ApplicationId appId, NodeId localId,
EventuallyConsistentMap<DeviceId, OvsdbNode> nodeStore,
MastershipService mastershipService,
LeadershipService leadershipService) {
this.appId = appId;
this.localId = localId;
this.nodeStore = nodeStore;
this.mastershipService = mastershipService;
this.leadershipService = leadershipService;
}
/**
* Starts the node connection manager.
*/
public void start() {
connectionExecutor = Executors.newSingleThreadScheduledExecutor(
groupedThreads("onos/cordvtn", "connection-executor"));
connectionExecutor.scheduleWithFixedDelay(() -> nodeStore.values()
.stream()
.filter(node -> localId.equals(getMaster(node)))
.forEach(node -> connectNode(node)), 0, DELAY_SEC, TimeUnit.SECONDS);
}
/**
* Stops the node connection manager.
*/
public void stop() {
connectionExecutor.shutdown();
}
/**
* Adds a new node to the system.
*
* @param ovsdbNode ovsdb node
*/
public void connectNode(OvsdbNode ovsdbNode) {
switch (ovsdbNode.state()) {
case INIT:
case DISCONNECTED:
// TODO: set the node to passive mode
case READY:
// TODO: initiate connection
break;
case CONNECTED:
break;
default:
}
}
/**
* Deletes the ovsdb node.
*
* @param ovsdbNode ovsdb node
*/
public void disconnectNode(OvsdbNode ovsdbNode) {
switch (ovsdbNode.state()) {
case CONNECTED:
// TODO: disconnect
break;
case INIT:
case READY:
case DISCONNECTED:
break;
default:
}
}
private NodeId getMaster(OvsdbNode ovsdbNode) {
// Return the master of the bridge(switch) if it exist or
// return the current leader
if (ovsdbNode.bridgeId() == DeviceId.NONE) {
return leadershipService.getLeader(this.appId.name());
} else {
return mastershipService.getMasterFor(ovsdbNode.bridgeId());
}
}
private void setPassiveMode(OvsdbNode ovsdbNode) {
// TODO: need ovsdb client implementation first
// TODO: set the remove ovsdb server passive mode
// TODO: set the node state READY if it succeed
}
private void connect(OvsdbNode ovsdbNode) {
// TODO: need ovsdb client implementation first
}
private void disconnect(OvsdbNode ovsdbNode) {
// TODO: need ovsdb client implementation first
}
}
......@@ -18,8 +18,6 @@ package org.onosproject.cordvtn;
import org.onlab.packet.IpAddress;
import org.onlab.packet.TpPort;
import org.onosproject.net.DeviceId;
import org.onosproject.net.behaviour.BridgeConfig;
import org.onosproject.net.behaviour.TunnelConfig;
/**
* Representation of a node with ovsdb server.
......@@ -29,7 +27,7 @@ public interface OvsdbNode {
* State of the ovsdb node.
*/
enum State {
READY, CONNECTED, DISCONNECTED
INIT, READY, CONNECTED, DISCONNECTED
}
/**
......@@ -47,44 +45,30 @@ public interface OvsdbNode {
TpPort port();
/**
* Returns the state of the node.
* Returns the hostname of the node.
*
* @return state of the node
* @return hostname
*/
State getState();
String hostname();
/**
* Sets the state of the node.
* Returns the state of the node.
*
* @param state state of the node
* @return state of the node
*/
void setState(State state);
State state();
/**
* Returns the device ID of the node.
*
* @return device id
*/
DeviceId getDeviceId();
DeviceId deviceId();
/**
* Sets the device id of the node.
* Returns the device ID of the bridge associated with this node.
*
* @param deviceId device identifier
*/
void setDeviceId(DeviceId deviceId);
/**
* Returns the bridge configuration handler of the node.
*
* @return bridge config behavior instance
*/
BridgeConfig getBridgeConfig();
/**
* Returns the tunnel configuration handler of the node.
*
* @return tunnel config behavior instance
* @return device id
*/
TunnelConfig getTunnelConfig();
DeviceId bridgeId();
}
......