Hyunsun Moon
Committed by Gerrit Code Review

CORD-151 add initial skeleton for cord-vtn application

Change-Id: I57bf17445f1e571b51bca2fe7c2631e65cd43145
...@@ -36,6 +36,19 @@ ...@@ -36,6 +36,19 @@
36 </properties> 36 </properties>
37 37
38 <dependencies> 38 <dependencies>
39 + <dependency>
40 + <groupId>org.osgi</groupId>
41 + <artifactId>org.osgi.compendium</artifactId>
42 + </dependency>
43 + <dependency>
44 + <groupId>org.onosproject</groupId>
45 + <artifactId>onos-api</artifactId>
46 + </dependency>
47 + <dependency>
48 + <groupId>org.onosproject</groupId>
49 + <artifactId>onos-core-serializers</artifactId>
50 + <version>${project.version}</version>
51 + </dependency>
39 </dependencies> 52 </dependencies>
40 53
41 </project> 54 </project>
......
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 +/**
19 + * Entity capable of handling a subject connected and disconnected situation.
20 + */
21 +public interface ConnectionHandler<T> {
22 +
23 + /**
24 + * Processes the connected subject.
25 + *
26 + * @param subject subject
27 + */
28 + void connected(T subject);
29 +
30 + /**
31 + * Processes the disconnected subject.
32 + *
33 + * @param subject subject.
34 + */
35 + void disconnected(T subject);
36 +}
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.apache.felix.scr.annotations.Activate;
19 +import org.apache.felix.scr.annotations.Component;
20 +import org.apache.felix.scr.annotations.Deactivate;
21 +import org.apache.felix.scr.annotations.Reference;
22 +import org.apache.felix.scr.annotations.ReferenceCardinality;
23 +import org.apache.felix.scr.annotations.Service;
24 +import org.onlab.packet.IpAddress;
25 +import org.onlab.packet.TpPort;
26 +import org.onlab.util.KryoNamespace;
27 +import org.onosproject.cluster.ClusterService;
28 +import org.onosproject.cluster.LeadershipEvent;
29 +import org.onosproject.cluster.LeadershipEventListener;
30 +import org.onosproject.cluster.LeadershipService;
31 +import org.onosproject.cluster.NodeId;
32 +import org.onosproject.core.ApplicationId;
33 +import org.onosproject.core.CoreService;
34 +import org.onosproject.mastership.MastershipService;
35 +import org.onosproject.net.Device;
36 +import org.onosproject.net.DeviceId;
37 +import org.onosproject.net.Host;
38 +import org.onosproject.net.config.ConfigFactory;
39 +import org.onosproject.net.config.NetworkConfigRegistry;
40 +import org.onosproject.net.config.NetworkConfigService;
41 +import org.onosproject.net.config.basics.SubjectFactories;
42 +import org.onosproject.net.device.DeviceEvent;
43 +import org.onosproject.net.device.DeviceListener;
44 +import org.onosproject.net.device.DeviceService;
45 +import org.onosproject.net.host.HostEvent;
46 +import org.onosproject.net.host.HostListener;
47 +import org.onosproject.net.host.HostService;
48 +import org.onosproject.store.serializers.KryoNamespaces;
49 +import org.onosproject.store.service.EventuallyConsistentMap;
50 +import org.onosproject.store.service.LogicalClockService;
51 +import org.onosproject.store.service.StorageService;
52 +import org.slf4j.Logger;
53 +
54 +import java.util.List;
55 +import java.util.concurrent.ExecutorService;
56 +import java.util.concurrent.Executors;
57 +import java.util.stream.Collectors;
58 +
59 +import static org.onlab.util.Tools.groupedThreads;
60 +import static org.onosproject.cordvtn.OvsdbNode.State.INIT;
61 +import static org.slf4j.LoggerFactory.getLogger;
62 +
63 +/**
64 + * CORD VTN Application that provisions overlay virtual tenant networks.
65 + */
66 +@Component(immediate = true)
67 +@Service
68 +public class CordVtn implements CordVtnService {
69 +
70 + protected final Logger log = getLogger(getClass());
71 +
72 + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
73 + protected CoreService coreService;
74 +
75 + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
76 + protected StorageService storageService;
77 +
78 + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
79 + protected LogicalClockService clockService;
80 +
81 + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
82 + protected ClusterService clusterService;
83 +
84 + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
85 + protected LeadershipService leadershipService;
86 +
87 + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
88 + protected NetworkConfigService configService;
89 +
90 + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
91 + protected NetworkConfigRegistry configRegistry;
92 +
93 + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
94 + protected DeviceService deviceService;
95 +
96 + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
97 + protected HostService hostService;
98 +
99 + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
100 + protected MastershipService mastershipService;
101 +
102 + private static final int DEFAULT_NUM_THREADS = 1;
103 + private static final KryoNamespace.Builder NODE_SERIALIZER = KryoNamespace.newBuilder()
104 + .register(KryoNamespaces.API)
105 + .register(OvsdbNode.class);
106 +
107 + private final ExecutorService eventExecutor = Executors.newFixedThreadPool(
108 + DEFAULT_NUM_THREADS, groupedThreads("onos/cordvtn", "event-handler"));
109 +
110 + private final LeadershipEventListener leadershipListener = new InternalLeadershipListener();
111 + private final DeviceListener deviceListener = new InternalDeviceListener();
112 + private final HostListener hostListener = new InternalHostListener();
113 + private final NodeHandler nodeHandler = new NodeHandler();
114 + private final BridgeHandler bridgeHandler = new BridgeHandler();
115 + private final VirtualMachineHandler vmHandler = new VirtualMachineHandler();
116 +
117 + private final ConfigFactory configFactory =
118 + new ConfigFactory(SubjectFactories.APP_SUBJECT_FACTORY, CordVtnConfig.class, "cordvtn") {
119 + @Override
120 + public CordVtnConfig createConfig() {
121 + return new CordVtnConfig();
122 + }
123 + };
124 +
125 + private ApplicationId appId;
126 + private NodeId local;
127 + private EventuallyConsistentMap<DeviceId, OvsdbNode> nodeStore;
128 + private NodeConnectionManager nodeConnectionManager;
129 +
130 + @Activate
131 + protected void activate() {
132 + appId = coreService.registerApplication("org.onosproject.cordvtn");
133 +
134 + local = clusterService.getLocalNode().id();
135 + nodeStore = storageService.<DeviceId, OvsdbNode>eventuallyConsistentMapBuilder()
136 + .withName("cordvtn-nodestore")
137 + .withSerializer(NODE_SERIALIZER)
138 + .withTimestampProvider((k, v) -> clockService.getTimestamp())
139 + .build();
140 + configRegistry.registerConfigFactory(configFactory);
141 +
142 + deviceService.addListener(deviceListener);
143 + hostService.addListener(hostListener);
144 + leadershipService.addListener(leadershipListener);
145 + leadershipService.runForLeadership(appId.name());
146 + nodeConnectionManager = new NodeConnectionManager(appId, local, nodeStore,
147 + mastershipService, leadershipService);
148 + nodeConnectionManager.start();
149 + log.info("Started");
150 + }
151 +
152 + @Deactivate
153 + protected void deactivate() {
154 + nodeConnectionManager.stop();
155 + leadershipService.removeListener(leadershipListener);
156 + leadershipService.withdraw(appId.name());
157 + deviceService.removeListener(deviceListener);
158 + hostService.removeListener(hostListener);
159 + eventExecutor.shutdown();
160 + nodeStore.destroy();
161 + configRegistry.unregisterConfigFactory(configFactory);
162 + log.info("Stopped");
163 + }
164 +
165 + @Override
166 + public void addNode(String hostname, IpAddress ip, TpPort port) {
167 + DefaultOvsdbNode node = new DefaultOvsdbNode(hostname, ip, port, DeviceId.NONE, INIT);
168 +
169 + if (nodeStore.containsKey(node.deviceId())) {
170 + log.warn("Node {} with ovsdb-server {}:{} already exists", hostname, ip, port);
171 + return;
172 + }
173 + nodeStore.put(node.deviceId(), node);
174 + log.info("New node {} with ovsdb-server {}:{} has been added", hostname, ip, port);
175 + }
176 +
177 + @Override
178 + public void deleteNode(IpAddress ip, TpPort port) {
179 + DeviceId deviceId = DeviceId.deviceId("ovsdb:" + ip + ":" + port);
180 + OvsdbNode node = nodeStore.get(deviceId);
181 +
182 + if (node == null) {
183 + log.warn("Node with ovsdb-server on {}:{} does not exist", ip, port);
184 + return;
185 + }
186 + nodeConnectionManager.disconnectNode(node);
187 + nodeStore.remove(node.deviceId());
188 + }
189 +
190 + @Override
191 + public int getNodeCount() {
192 + return nodeStore.size();
193 + }
194 +
195 + @Override
196 + public List<OvsdbNode> getNodes() {
197 + return nodeStore.values()
198 + .stream()
199 + .collect(Collectors.toList());
200 + }
201 +
202 + private void initialSetup() {
203 + // Read ovsdb nodes from network config
204 + CordVtnConfig config = configService.getConfig(appId, CordVtnConfig.class);
205 + if (config == null) {
206 + log.warn("No configuration found");
207 + return;
208 + }
209 + config.ovsdbNodes().forEach(
210 + node -> addNode(node.hostname(), node.ip(), node.port()));
211 + }
212 +
213 + private synchronized void processLeadershipChange(NodeId leader) {
214 + // Only the leader performs the initial setup
215 + if (leader == null || !leader.equals(local)) {
216 + return;
217 + }
218 + initialSetup();
219 + }
220 +
221 + private class InternalLeadershipListener implements LeadershipEventListener {
222 +
223 + @Override
224 + public void event(LeadershipEvent event) {
225 + if (event.subject().topic().equals(appId.name())) {
226 + processLeadershipChange(event.subject().leader());
227 + }
228 + }
229 + }
230 +
231 + private class InternalDeviceListener implements DeviceListener {
232 +
233 + @Override
234 + public void event(DeviceEvent event) {
235 + Device device = event.subject();
236 + ConnectionHandler handler =
237 + (device.type() == Device.Type.CONTROLLER ? nodeHandler : bridgeHandler);
238 +
239 + switch (event.type()) {
240 + case DEVICE_ADDED:
241 + eventExecutor.submit(() -> handler.connected(device));
242 + break;
243 + case DEVICE_AVAILABILITY_CHANGED:
244 + eventExecutor.submit(() -> handler.disconnected(device));
245 + break;
246 + default:
247 + break;
248 + }
249 + }
250 + }
251 +
252 + private class InternalHostListener implements HostListener {
253 +
254 + @Override
255 + public void event(HostEvent event) {
256 + Host vm = event.subject();
257 +
258 + switch (event.type()) {
259 + case HOST_ADDED:
260 + eventExecutor.submit(() -> vmHandler.connected(vm));
261 + break;
262 + case HOST_REMOVED:
263 + eventExecutor.submit(() -> vmHandler.disconnected(vm));
264 + break;
265 + default:
266 + break;
267 + }
268 + }
269 + }
270 +
271 + private class NodeHandler implements ConnectionHandler<Device> {
272 +
273 + @Override
274 + public void connected(Device device) {
275 + // create bridge and set bridgeId
276 + // set node state connected
277 + }
278 +
279 + @Override
280 + public void disconnected(Device device) {
281 + // set node state disconnected if the node exists
282 + // which means that the node is not deleted explicitly
283 + }
284 + }
285 +
286 + private class BridgeHandler implements ConnectionHandler<Device> {
287 +
288 + @Override
289 + public void connected(Device device) {
290 + // create vxlan port
291 + }
292 +
293 + @Override
294 + public void disconnected(Device device) {
295 +
296 + }
297 + }
298 +
299 + private class VirtualMachineHandler implements ConnectionHandler<Host> {
300 +
301 + @Override
302 + public void connected(Host host) {
303 + // install flow rules for this vm
304 + }
305 +
306 + @Override
307 + public void disconnected(Host host) {
308 + // uninstall flow rules associated with this vm
309 + }
310 + }
311 +}
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.fasterxml.jackson.databind.JsonNode;
19 +import com.google.common.collect.Sets;
20 +import org.onlab.packet.IpAddress;
21 +import org.onlab.packet.TpPort;
22 +import org.onosproject.core.ApplicationId;
23 +import org.onosproject.net.config.Config;
24 +
25 +import java.util.Set;
26 +
27 +import static com.google.common.base.Preconditions.checkNotNull;
28 +
29 +/**
30 + * Configuration object for CORD VTN service.
31 + */
32 +public class CordVtnConfig extends Config<ApplicationId> {
33 +
34 + public static final String OVSDB_NODES = "ovsdbNodes";
35 + public static final String HOSTNAME = "hostname";
36 + public static final String IP = "ip";
37 + public static final String PORT = "port";
38 +
39 + /**
40 + * Returns the set of ovsdb nodes read from network config.
41 + *
42 + * @return set of OvsdbNodeConfig or null
43 + */
44 + public Set<OvsdbNodeConfig> ovsdbNodes() {
45 + Set<OvsdbNodeConfig> ovsdbNodes = Sets.newHashSet();
46 +
47 + JsonNode nodes = object.get(OVSDB_NODES);
48 + if (nodes == null) {
49 + return null;
50 + }
51 + nodes.forEach(jsonNode -> ovsdbNodes.add(new OvsdbNodeConfig(
52 + jsonNode.path(HOSTNAME).asText(),
53 + IpAddress.valueOf(jsonNode.path(IP).asText()),
54 + TpPort.tpPort(jsonNode.path(PORT).asInt()))));
55 +
56 + return ovsdbNodes;
57 + }
58 +
59 + /**
60 + * Configuration for an OVSDB node.
61 + */
62 + public static class OvsdbNodeConfig {
63 +
64 + private final String hostname;
65 + private final IpAddress ip;
66 + private final TpPort port;
67 +
68 + public OvsdbNodeConfig(String hostname, IpAddress ip, TpPort port) {
69 + this.hostname = checkNotNull(hostname);
70 + this.ip = checkNotNull(ip);
71 + this.port = checkNotNull(port);
72 + }
73 +
74 + /**
75 + * Returns hostname of the node.
76 + *
77 + * @return hostname
78 + */
79 + public String hostname() {
80 + return this.hostname;
81 + }
82 +
83 + /**
84 + * Returns ip address to access ovsdb-server of the node.
85 + *
86 + * @return ip address
87 + */
88 + public IpAddress ip() {
89 + return this.ip;
90 + }
91 +
92 + /**
93 + * Returns port number to access ovsdb-server of the node.
94 + *
95 + * @return port number
96 + */
97 + public TpPort port() {
98 + return this.port;
99 + }
100 + }
101 +}
...@@ -15,6 +15,9 @@ ...@@ -15,6 +15,9 @@
15 */ 15 */
16 package org.onosproject.cordvtn; 16 package org.onosproject.cordvtn;
17 17
18 +import org.onlab.packet.IpAddress;
19 +import org.onlab.packet.TpPort;
20 +
18 import java.util.List; 21 import java.util.List;
19 22
20 /** 23 /**
...@@ -22,19 +25,21 @@ import java.util.List; ...@@ -22,19 +25,21 @@ import java.util.List;
22 */ 25 */
23 public interface CordVtnService { 26 public interface CordVtnService {
24 /** 27 /**
25 - * Adds new nodes to the service and processes initial setup. 28 + * Adds a new node to the service.
26 * 29 *
27 - * @param ovsdbNodes list of nodes 30 + * @param hostname hostname of the node
31 + * @param ip ip address to access the ovsdb server running on the node
32 + * @param port port number to access the ovsdb server running on the node
28 */ 33 */
29 - void addNodes(List<OvsdbNode> ovsdbNodes); 34 + void addNode(String hostname, IpAddress ip, TpPort port);
30 35
31 /** 36 /**
32 - * Deletes the nodes from the service and cleans up unnecessary configurations 37 + * Deletes the node from the service.
33 - * associated with the deleted nodes.
34 * 38 *
35 - * @param ovsdbNodes list of nodes 39 + * @param ip ip address to access the ovsdb server running on the node
40 + * @param port port number to access the ovsdb server running on the node
36 */ 41 */
37 - void deleteNodes(List<OvsdbNode> ovsdbNodes); 42 + void deleteNode(IpAddress ip, TpPort port);
38 43
39 /** 44 /**
40 * Returns the number of the nodes known to the service. 45 * Returns the number of the nodes known to the service.
......
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.Objects;
23 +
24 +/**
25 + * OvsdbNode implementation.
26 + */
27 +public class DefaultOvsdbNode implements OvsdbNode {
28 +
29 + private final String hostname;
30 + private final IpAddress ip;
31 + private final TpPort port;
32 + private final DeviceId deviceId;
33 + private final DeviceId bridgeId;
34 + private final State state;
35 +
36 + public DefaultOvsdbNode(String hostname, IpAddress ip, TpPort port,
37 + DeviceId bridgeId, State state) {
38 + this.hostname = hostname;
39 + this.ip = ip;
40 + this.port = port;
41 + this.deviceId = DeviceId.deviceId(
42 + "ovsdb:" + ip.toString() + ":" + port.toString());
43 + this.bridgeId = bridgeId;
44 + this.state = state;
45 + }
46 +
47 + @Override
48 + public IpAddress ip() {
49 + return this.ip;
50 + }
51 +
52 + @Override
53 + public TpPort port() {
54 + return this.port;
55 + }
56 +
57 + @Override
58 + public String hostname() {
59 + return this.hostname;
60 + }
61 +
62 + @Override
63 + public State state() {
64 + return this.state;
65 + }
66 +
67 + @Override
68 + public DeviceId deviceId() {
69 + return this.deviceId;
70 + }
71 +
72 + @Override
73 + public DeviceId bridgeId() {
74 + return this.bridgeId;
75 + }
76 +
77 + @Override
78 + public boolean equals(Object o) {
79 + if (this == o) {
80 + return true;
81 + }
82 +
83 + if (o instanceof DefaultOvsdbNode) {
84 + DefaultOvsdbNode that = (DefaultOvsdbNode) o;
85 + // We compare the ip and port only.
86 + if (this.ip.equals(that.ip) && this.port.equals(that.port)) {
87 + return true;
88 + }
89 + }
90 + return false;
91 + }
92 +
93 + @Override
94 + public int hashCode() {
95 + return Objects.hash(ip, port);
96 + }
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 org.onosproject.cluster.LeadershipService;
19 +import org.onosproject.cluster.NodeId;
20 +import org.onosproject.core.ApplicationId;
21 +import org.onosproject.mastership.MastershipService;
22 +import org.onosproject.net.DeviceId;
23 +import org.onosproject.store.service.EventuallyConsistentMap;
24 +import org.slf4j.Logger;
25 +
26 +import java.util.concurrent.Executors;
27 +import java.util.concurrent.ScheduledExecutorService;
28 +import java.util.concurrent.TimeUnit;
29 +
30 +import static org.onlab.util.Tools.groupedThreads;
31 +import static org.slf4j.LoggerFactory.getLogger;
32 +
33 +/**
34 + * Node connection manager.
35 + */
36 +public class NodeConnectionManager {
37 + protected final Logger log = getLogger(getClass());
38 +
39 + private final ApplicationId appId;
40 + private final NodeId localId;
41 + private final EventuallyConsistentMap<DeviceId, OvsdbNode> nodeStore;
42 + private final MastershipService mastershipService;
43 + private final LeadershipService leadershipService;
44 +
45 + private static final int DELAY_SEC = 5;
46 + private ScheduledExecutorService connectionExecutor;
47 +
48 + /**
49 + * Creates a new NodeConnectionManager.
50 + *
51 + * @param localId local id
52 + * @param nodeStore node store
53 + * @param mastershipService mastership service
54 + */
55 + public NodeConnectionManager(ApplicationId appId, NodeId localId,
56 + EventuallyConsistentMap<DeviceId, OvsdbNode> nodeStore,
57 + MastershipService mastershipService,
58 + LeadershipService leadershipService) {
59 + this.appId = appId;
60 + this.localId = localId;
61 + this.nodeStore = nodeStore;
62 + this.mastershipService = mastershipService;
63 + this.leadershipService = leadershipService;
64 + }
65 +
66 + /**
67 + * Starts the node connection manager.
68 + */
69 + public void start() {
70 + connectionExecutor = Executors.newSingleThreadScheduledExecutor(
71 + groupedThreads("onos/cordvtn", "connection-executor"));
72 + connectionExecutor.scheduleWithFixedDelay(() -> nodeStore.values()
73 + .stream()
74 + .filter(node -> localId.equals(getMaster(node)))
75 + .forEach(node -> connectNode(node)), 0, DELAY_SEC, TimeUnit.SECONDS);
76 + }
77 +
78 + /**
79 + * Stops the node connection manager.
80 + */
81 + public void stop() {
82 + connectionExecutor.shutdown();
83 + }
84 +
85 + /**
86 + * Adds a new node to the system.
87 + *
88 + * @param ovsdbNode ovsdb node
89 + */
90 + public void connectNode(OvsdbNode ovsdbNode) {
91 + switch (ovsdbNode.state()) {
92 + case INIT:
93 + case DISCONNECTED:
94 + // TODO: set the node to passive mode
95 + case READY:
96 + // TODO: initiate connection
97 + break;
98 + case CONNECTED:
99 + break;
100 + default:
101 + }
102 + }
103 +
104 + /**
105 + * Deletes the ovsdb node.
106 + *
107 + * @param ovsdbNode ovsdb node
108 + */
109 + public void disconnectNode(OvsdbNode ovsdbNode) {
110 + switch (ovsdbNode.state()) {
111 + case CONNECTED:
112 + // TODO: disconnect
113 + break;
114 + case INIT:
115 + case READY:
116 + case DISCONNECTED:
117 + break;
118 + default:
119 + }
120 + }
121 +
122 + private NodeId getMaster(OvsdbNode ovsdbNode) {
123 + // Return the master of the bridge(switch) if it exist or
124 + // return the current leader
125 + if (ovsdbNode.bridgeId() == DeviceId.NONE) {
126 + return leadershipService.getLeader(this.appId.name());
127 + } else {
128 + return mastershipService.getMasterFor(ovsdbNode.bridgeId());
129 + }
130 + }
131 +
132 + private void setPassiveMode(OvsdbNode ovsdbNode) {
133 + // TODO: need ovsdb client implementation first
134 + // TODO: set the remove ovsdb server passive mode
135 + // TODO: set the node state READY if it succeed
136 + }
137 +
138 + private void connect(OvsdbNode ovsdbNode) {
139 + // TODO: need ovsdb client implementation first
140 + }
141 +
142 + private void disconnect(OvsdbNode ovsdbNode) {
143 + // TODO: need ovsdb client implementation first
144 + }
145 +}
...@@ -18,8 +18,6 @@ package org.onosproject.cordvtn; ...@@ -18,8 +18,6 @@ package org.onosproject.cordvtn;
18 import org.onlab.packet.IpAddress; 18 import org.onlab.packet.IpAddress;
19 import org.onlab.packet.TpPort; 19 import org.onlab.packet.TpPort;
20 import org.onosproject.net.DeviceId; 20 import org.onosproject.net.DeviceId;
21 -import org.onosproject.net.behaviour.BridgeConfig;
22 -import org.onosproject.net.behaviour.TunnelConfig;
23 21
24 /** 22 /**
25 * Representation of a node with ovsdb server. 23 * Representation of a node with ovsdb server.
...@@ -29,7 +27,7 @@ public interface OvsdbNode { ...@@ -29,7 +27,7 @@ public interface OvsdbNode {
29 * State of the ovsdb node. 27 * State of the ovsdb node.
30 */ 28 */
31 enum State { 29 enum State {
32 - READY, CONNECTED, DISCONNECTED 30 + INIT, READY, CONNECTED, DISCONNECTED
33 } 31 }
34 32
35 /** 33 /**
...@@ -47,44 +45,30 @@ public interface OvsdbNode { ...@@ -47,44 +45,30 @@ public interface OvsdbNode {
47 TpPort port(); 45 TpPort port();
48 46
49 /** 47 /**
50 - * Returns the state of the node. 48 + * Returns the hostname of the node.
51 * 49 *
52 - * @return state of the node 50 + * @return hostname
53 */ 51 */
54 - State getState(); 52 + String hostname();
55 53
56 /** 54 /**
57 - * Sets the state of the node. 55 + * Returns the state of the node.
58 * 56 *
59 - * @param state state of the node 57 + * @return state of the node
60 */ 58 */
61 - void setState(State state); 59 + State state();
62 60
63 /** 61 /**
64 * Returns the device ID of the node. 62 * Returns the device ID of the node.
65 * 63 *
66 * @return device id 64 * @return device id
67 */ 65 */
68 - DeviceId getDeviceId(); 66 + DeviceId deviceId();
69 67
70 /** 68 /**
71 - * Sets the device id of the node. 69 + * Returns the device ID of the bridge associated with this node.
72 * 70 *
73 - * @param deviceId device identifier 71 + * @return device id
74 - */
75 - void setDeviceId(DeviceId deviceId);
76 -
77 - /**
78 - * Returns the bridge configuration handler of the node.
79 - *
80 - * @return bridge config behavior instance
81 - */
82 - BridgeConfig getBridgeConfig();
83 -
84 - /**
85 - * Returns the tunnel configuration handler of the node.
86 - *
87 - * @return tunnel config behavior instance
88 */ 72 */
89 - TunnelConfig getTunnelConfig(); 73 + DeviceId bridgeId();
90 } 74 }
......