Hyunsun Moon
Committed by Jonathan Hart

Support existing VMs running on the newly added node

- Added openstack node state event
- Made openstack switching to listen to the node state events and
  add existing VMs running in the complete state node

Change-Id: I7b7186c3b889376a4bc0385313433604dcd93d70
...@@ -56,6 +56,10 @@ import org.onosproject.openstackinterface.OpenstackPort; ...@@ -56,6 +56,10 @@ import org.onosproject.openstackinterface.OpenstackPort;
56 import org.onosproject.openstackinterface.OpenstackSubnet; 56 import org.onosproject.openstackinterface.OpenstackSubnet;
57 import org.onosproject.openstacknetworking.OpenstackPortInfo; 57 import org.onosproject.openstacknetworking.OpenstackPortInfo;
58 import org.onosproject.openstacknetworking.OpenstackSwitchingService; 58 import org.onosproject.openstacknetworking.OpenstackSwitchingService;
59 +import org.onosproject.openstacknode.OpenstackNode;
60 +import org.onosproject.openstacknode.OpenstackNodeEvent;
61 +import org.onosproject.openstacknode.OpenstackNodeListener;
62 +import org.onosproject.openstacknode.OpenstackNodeService;
59 import org.slf4j.Logger; 63 import org.slf4j.Logger;
60 import org.slf4j.LoggerFactory; 64 import org.slf4j.LoggerFactory;
61 65
...@@ -103,11 +107,15 @@ public final class OpenstackSwitchingManager extends AbstractProvider ...@@ -103,11 +107,15 @@ public final class OpenstackSwitchingManager extends AbstractProvider
103 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) 107 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
104 protected OpenstackInterfaceService openstackService; 108 protected OpenstackInterfaceService openstackService;
105 109
110 + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
111 + protected OpenstackNodeService openstackNodeService;
112 +
106 private final ExecutorService deviceEventExecutor = 113 private final ExecutorService deviceEventExecutor =
107 Executors.newSingleThreadExecutor(groupedThreads("onos/openstackswitching", "device-event")); 114 Executors.newSingleThreadExecutor(groupedThreads("onos/openstackswitching", "device-event"));
108 private final ExecutorService configEventExecutor = 115 private final ExecutorService configEventExecutor =
109 Executors.newSingleThreadExecutor(groupedThreads("onos/openstackswitching", "config-event")); 116 Executors.newSingleThreadExecutor(groupedThreads("onos/openstackswitching", "config-event"));
110 private final InternalDeviceListener internalDeviceListener = new InternalDeviceListener(); 117 private final InternalDeviceListener internalDeviceListener = new InternalDeviceListener();
118 + private final InternalOpenstackNodeListener internalNodeListener = new InternalOpenstackNodeListener();
111 119
112 private HostProviderService hostProvider; 120 private HostProviderService hostProvider;
113 121
...@@ -122,6 +130,7 @@ public final class OpenstackSwitchingManager extends AbstractProvider ...@@ -122,6 +130,7 @@ public final class OpenstackSwitchingManager extends AbstractProvider
122 protected void activate() { 130 protected void activate() {
123 coreService.registerApplication(APP_ID); 131 coreService.registerApplication(APP_ID);
124 deviceService.addListener(internalDeviceListener); 132 deviceService.addListener(internalDeviceListener);
133 + openstackNodeService.addListener(internalNodeListener);
125 hostProvider = hostProviderRegistry.register(this); 134 hostProvider = hostProviderRegistry.register(this);
126 135
127 log.info("Started"); 136 log.info("Started");
...@@ -131,6 +140,7 @@ public final class OpenstackSwitchingManager extends AbstractProvider ...@@ -131,6 +140,7 @@ public final class OpenstackSwitchingManager extends AbstractProvider
131 protected void deactivate() { 140 protected void deactivate() {
132 hostProviderRegistry.unregister(this); 141 hostProviderRegistry.unregister(this);
133 deviceService.removeListener(internalDeviceListener); 142 deviceService.removeListener(internalDeviceListener);
143 + openstackNodeService.removeListener(internalNodeListener);
134 144
135 deviceEventExecutor.shutdown(); 145 deviceEventExecutor.shutdown();
136 configEventExecutor.shutdown(); 146 configEventExecutor.shutdown();
...@@ -179,6 +189,7 @@ public final class OpenstackSwitchingManager extends AbstractProvider ...@@ -179,6 +189,7 @@ public final class OpenstackSwitchingManager extends AbstractProvider
179 } 189 }
180 190
181 private void processPortAdded(Port port) { 191 private void processPortAdded(Port port) {
192 + // TODO check the node state is COMPLETE
182 OpenstackPort osPort = openstackService.port(port); 193 OpenstackPort osPort = openstackService.port(port);
183 if (osPort == null) { 194 if (osPort == null) {
184 log.warn("Failed to get OpenStack port for {}", port); 195 log.warn("Failed to get OpenStack port for {}", port);
...@@ -221,6 +232,10 @@ public final class OpenstackSwitchingManager extends AbstractProvider ...@@ -221,6 +232,10 @@ public final class OpenstackSwitchingManager extends AbstractProvider
221 232
222 private void processPortRemoved(Port port) { 233 private void processPortRemoved(Port port) {
223 ConnectPoint connectPoint = new ConnectPoint(port.element().id(), port.number()); 234 ConnectPoint connectPoint = new ConnectPoint(port.element().id(), port.number());
235 + removeHosts(connectPoint);
236 + }
237 +
238 + private void removeHosts(ConnectPoint connectPoint) {
224 hostService.getConnectedHosts(connectPoint).stream() 239 hostService.getConnectedHosts(connectPoint).stream()
225 .forEach(host -> { 240 .forEach(host -> {
226 dhcpService.removeStaticMapping(host.mac()); 241 dhcpService.removeStaticMapping(host.mac());
...@@ -300,4 +315,45 @@ public final class OpenstackSwitchingManager extends AbstractProvider ...@@ -300,4 +315,45 @@ public final class OpenstackSwitchingManager extends AbstractProvider
300 } 315 }
301 } 316 }
302 } 317 }
318 +
319 + private class InternalOpenstackNodeListener implements OpenstackNodeListener {
320 +
321 + @Override
322 + public void event(OpenstackNodeEvent event) {
323 + OpenstackNode node = event.node();
324 + // TODO check leadership of the node and make only the leader process
325 +
326 + switch (event.type()) {
327 + case COMPLETE:
328 + log.info("COMPLETE node {} detected", node.hostname());
329 +
330 + // adds existing VMs running on the complete state node
331 + deviceService.getPorts(node.intBridge()).stream()
332 + .filter(port -> port.annotations().value(PORT_NAME)
333 + .startsWith(PORTNAME_PREFIX_VM) &&
334 + port.isEnabled())
335 + .forEach(port -> {
336 + deviceEventExecutor.execute(() -> processPortAdded(port));
337 + log.info("VM is detected on {}", port);
338 + });
339 +
340 + // removes stale VMs
341 + hostService.getHosts().forEach(host -> {
342 + if (deviceService.getPort(host.location().deviceId(),
343 + host.location().port()) == null) {
344 + deviceEventExecutor.execute(() -> removeHosts(host.location()));
345 + log.info("Removed stale VM {}", host.location());
346 + }
347 + });
348 + break;
349 + case INCOMPLETE:
350 + log.warn("{} is changed to INCOMPLETE state", node);
351 + break;
352 + case INIT:
353 + case DEVICE_CREATED:
354 + default:
355 + break;
356 + }
357 + }
358 + }
303 } 359 }
......
...@@ -19,6 +19,7 @@ import com.google.common.base.MoreObjects; ...@@ -19,6 +19,7 @@ import com.google.common.base.MoreObjects;
19 import com.google.common.base.Strings; 19 import com.google.common.base.Strings;
20 import org.onlab.packet.IpAddress; 20 import org.onlab.packet.IpAddress;
21 import org.onosproject.net.DeviceId; 21 import org.onosproject.net.DeviceId;
22 +import org.onosproject.openstacknode.OpenstackNodeEvent.NodeState;
22 import org.onosproject.openstacknode.OpenstackNodeService.NodeType; 23 import org.onosproject.openstacknode.OpenstackNodeService.NodeType;
23 24
24 import java.util.Comparator; 25 import java.util.Comparator;
...@@ -27,6 +28,7 @@ import java.util.Optional; ...@@ -27,6 +28,7 @@ import java.util.Optional;
27 28
28 import static com.google.common.base.Preconditions.checkArgument; 29 import static com.google.common.base.Preconditions.checkArgument;
29 import static com.google.common.base.Preconditions.checkNotNull; 30 import static com.google.common.base.Preconditions.checkNotNull;
31 +import static org.onosproject.openstacknode.OpenstackNodeEvent.NodeState.INIT;
30 32
31 /** 33 /**
32 * Representation of a compute/gateway node for OpenstackSwitching/Routing service. 34 * Representation of a compute/gateway node for OpenstackSwitching/Routing service.
...@@ -39,7 +41,7 @@ public final class OpenstackNode { ...@@ -39,7 +41,7 @@ public final class OpenstackNode {
39 private final IpAddress dataIp; 41 private final IpAddress dataIp;
40 private final DeviceId integrationBridge; 42 private final DeviceId integrationBridge;
41 private final Optional<DeviceId> routerBridge; 43 private final Optional<DeviceId> routerBridge;
42 - private final OpenstackNodeState state; 44 + private final NodeState state;
43 45
44 public static final Comparator<OpenstackNode> OPENSTACK_NODE_COMPARATOR = 46 public static final Comparator<OpenstackNode> OPENSTACK_NODE_COMPARATOR =
45 (node1, node2) -> node1.hostname().compareTo(node2.hostname()); 47 (node1, node2) -> node1.hostname().compareTo(node2.hostname());
...@@ -50,7 +52,7 @@ public final class OpenstackNode { ...@@ -50,7 +52,7 @@ public final class OpenstackNode {
50 IpAddress dataIp, 52 IpAddress dataIp,
51 DeviceId integrationBridge, 53 DeviceId integrationBridge,
52 Optional<DeviceId> routerBridge, 54 Optional<DeviceId> routerBridge,
53 - OpenstackNodeState state) { 55 + NodeState state) {
54 this.hostname = hostname; 56 this.hostname = hostname;
55 this.type = type; 57 this.type = type;
56 this.managementIp = managementIp; 58 this.managementIp = managementIp;
...@@ -67,7 +69,7 @@ public final class OpenstackNode { ...@@ -67,7 +69,7 @@ public final class OpenstackNode {
67 * @param state openstack node init state 69 * @param state openstack node init state
68 * @return openstack node 70 * @return openstack node
69 */ 71 */
70 - public static OpenstackNode getUpdatedNode(OpenstackNode node, OpenstackNodeState state) { 72 + public static OpenstackNode getUpdatedNode(OpenstackNode node, NodeState state) {
71 return new OpenstackNode(node.hostname, 73 return new OpenstackNode(node.hostname,
72 node.type, 74 node.type,
73 node.managementIp, 75 node.managementIp,
...@@ -137,7 +139,7 @@ public final class OpenstackNode { ...@@ -137,7 +139,7 @@ public final class OpenstackNode {
137 * 139 *
138 * @return init state 140 * @return init state
139 */ 141 */
140 - public OpenstackNodeState state() { 142 + public NodeState state() {
141 return state; 143 return state;
142 } 144 }
143 145
...@@ -212,7 +214,7 @@ public final class OpenstackNode { ...@@ -212,7 +214,7 @@ public final class OpenstackNode {
212 private IpAddress dataIp; 214 private IpAddress dataIp;
213 private DeviceId integrationBridge; 215 private DeviceId integrationBridge;
214 private Optional<DeviceId> routerBridge = Optional.empty(); 216 private Optional<DeviceId> routerBridge = Optional.empty();
215 - private OpenstackNodeState state = OpenstackNodeState.noState(); 217 + private NodeState state = INIT;
216 218
217 private Builder() { 219 private Builder() {
218 } 220 }
...@@ -305,7 +307,7 @@ public final class OpenstackNode { ...@@ -305,7 +307,7 @@ public final class OpenstackNode {
305 * @param state node init state 307 * @param state node init state
306 * @return openstack node builder 308 * @return openstack node builder
307 */ 309 */
308 - public Builder state(OpenstackNodeState state) { 310 + public Builder state(NodeState state) {
309 this.state = state; 311 this.state = state;
310 return this; 312 return this;
311 } 313 }
......
1 +/*
2 + * Copyright 2016-present 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.openstacknode;
17 +
18 +import org.joda.time.LocalDateTime;
19 +import org.onosproject.event.AbstractEvent;
20 +
21 +import static com.google.common.base.MoreObjects.toStringHelper;
22 +
23 +/**
24 + * Describes OpenStack node init state event.
25 + */
26 +public class OpenstackNodeEvent extends AbstractEvent<OpenstackNodeEvent.NodeState, Object> {
27 +
28 + public enum NodeState {
29 + /**
30 + * Indicates the node is newly added.
31 + */
32 + INIT {
33 + @Override
34 + public void process(OpenstackNodeService nodeService, OpenstackNode node) {
35 + nodeService.processInitState(node);
36 + }
37 + },
38 + /**
39 + * Indicates bridge devices are added according to the node state.
40 + */
41 + DEVICE_CREATED {
42 + @Override
43 + public void process(OpenstackNodeService nodeService, OpenstackNode node) {
44 + nodeService.processDeviceCreatedState(node);
45 + }
46 + },
47 + /**
48 + * Indicates all node initialization is done.
49 + */
50 + COMPLETE {
51 + @Override
52 + public void process(OpenstackNodeService nodeService, OpenstackNode node) {
53 + nodeService.processCompleteState(node);
54 + }
55 + },
56 + /**
57 + * Indicates node initialization is not done but unable to proceed to
58 + * the next step for some reason.
59 + */
60 + INCOMPLETE {
61 + @Override
62 + public void process(OpenstackNodeService nodeService, OpenstackNode node) {
63 + nodeService.processIncompleteState(node);
64 + }
65 + };
66 +
67 + public abstract void process(OpenstackNodeService nodeService, OpenstackNode node);
68 + }
69 +
70 + public OpenstackNodeEvent(NodeState state, Object subject) {
71 + super(state, subject);
72 + }
73 +
74 + public OpenstackNode node() {
75 + return (OpenstackNode) subject();
76 + }
77 +
78 + @Override
79 + public String toString() {
80 + return toStringHelper(this)
81 + .add("time", new LocalDateTime(time()))
82 + .add("state", type())
83 + .add("node", subject())
84 + .toString();
85 + }
86 +}
...@@ -15,16 +15,10 @@ ...@@ -15,16 +15,10 @@
15 */ 15 */
16 package org.onosproject.openstacknode; 16 package org.onosproject.openstacknode;
17 17
18 +import org.onosproject.event.EventListener;
19 +
18 /** 20 /**
19 - * Entity that defines possible init state of the OpenStack node. 21 + * Listener for OpenStack node events.
20 */ 22 */
21 -public interface OpenstackNodeState {
22 - /**
23 - * Returns null for no state.
24 - *
25 - * @return null
26 - */
27 - static OpenstackNodeState noState() {
28 - return null;
29 - }
30 -}
...\ No newline at end of file ...\ No newline at end of file
23 +public interface OpenstackNodeListener extends EventListener<OpenstackNodeEvent> {
24 +}
......
...@@ -34,6 +34,7 @@ import org.onosproject.cluster.LeadershipService; ...@@ -34,6 +34,7 @@ import org.onosproject.cluster.LeadershipService;
34 import org.onosproject.cluster.NodeId; 34 import org.onosproject.cluster.NodeId;
35 import org.onosproject.core.ApplicationId; 35 import org.onosproject.core.ApplicationId;
36 import org.onosproject.core.CoreService; 36 import org.onosproject.core.CoreService;
37 +import org.onosproject.event.ListenerRegistry;
37 import org.onosproject.net.Device; 38 import org.onosproject.net.Device;
38 import org.onosproject.net.DeviceId; 39 import org.onosproject.net.DeviceId;
39 import org.onosproject.net.Port; 40 import org.onosproject.net.Port;
...@@ -57,6 +58,7 @@ import org.onosproject.net.config.basics.SubjectFactories; ...@@ -57,6 +58,7 @@ import org.onosproject.net.config.basics.SubjectFactories;
57 import org.onosproject.net.device.DeviceEvent; 58 import org.onosproject.net.device.DeviceEvent;
58 import org.onosproject.net.device.DeviceListener; 59 import org.onosproject.net.device.DeviceListener;
59 import org.onosproject.net.device.DeviceService; 60 import org.onosproject.net.device.DeviceService;
61 +import org.onosproject.openstacknode.OpenstackNodeEvent.NodeState;
60 import org.onosproject.ovsdb.controller.OvsdbClientService; 62 import org.onosproject.ovsdb.controller.OvsdbClientService;
61 import org.onosproject.ovsdb.controller.OvsdbController; 63 import org.onosproject.ovsdb.controller.OvsdbController;
62 import org.onosproject.ovsdb.controller.OvsdbNodeId; 64 import org.onosproject.ovsdb.controller.OvsdbNodeId;
...@@ -76,6 +78,7 @@ import static org.onosproject.net.AnnotationKeys.PORT_NAME; ...@@ -76,6 +78,7 @@ import static org.onosproject.net.AnnotationKeys.PORT_NAME;
76 import static org.onosproject.net.Device.Type.SWITCH; 78 import static org.onosproject.net.Device.Type.SWITCH;
77 import static org.onosproject.net.behaviour.TunnelDescription.Type.VXLAN; 79 import static org.onosproject.net.behaviour.TunnelDescription.Type.VXLAN;
78 import static org.onosproject.openstacknode.Constants.*; 80 import static org.onosproject.openstacknode.Constants.*;
81 +import static org.onosproject.openstacknode.OpenstackNodeEvent.NodeState.*;
79 import static org.slf4j.LoggerFactory.getLogger; 82 import static org.slf4j.LoggerFactory.getLogger;
80 83
81 import java.util.Dictionary; 84 import java.util.Dictionary;
...@@ -92,8 +95,9 @@ import java.util.stream.Collectors; ...@@ -92,8 +95,9 @@ import java.util.stream.Collectors;
92 */ 95 */
93 @Component(immediate = true) 96 @Component(immediate = true)
94 @Service 97 @Service
95 -public final class OpenstackNodeManager implements OpenstackNodeService { 98 +public final class OpenstackNodeManager extends ListenerRegistry<OpenstackNodeEvent, OpenstackNodeListener>
96 - protected final Logger log = getLogger(getClass()); 99 + implements OpenstackNodeService {
100 + private final Logger log = getLogger(getClass());
97 101
98 private static final KryoNamespace.Builder NODE_SERIALIZER = KryoNamespace.newBuilder() 102 private static final KryoNamespace.Builder NODE_SERIALIZER = KryoNamespace.newBuilder()
99 .register(KryoNamespaces.API) 103 .register(KryoNamespaces.API)
...@@ -160,59 +164,6 @@ public final class OpenstackNodeManager implements OpenstackNodeService { ...@@ -160,59 +164,6 @@ public final class OpenstackNodeManager implements OpenstackNodeService {
160 private ApplicationId appId; 164 private ApplicationId appId;
161 private NodeId localNodeId; 165 private NodeId localNodeId;
162 166
163 - private enum NodeState implements OpenstackNodeState {
164 -
165 - INIT {
166 - @Override
167 - public void process(OpenstackNodeManager nodeManager, OpenstackNode node) {
168 - // make sure there is OVSDB connection
169 - if (!nodeManager.isOvsdbConnected(node)) {
170 - nodeManager.connectOvsdb(node);
171 - return;
172 - }
173 - nodeManager.createBridge(node,
174 - INTEGRATION_BRIDGE,
175 - node.intBridge().toString().substring(DPID_BEGIN));
176 -
177 - // creates additional router bridge if the node type is GATEWAY
178 - if (node.type().equals(NodeType.GATEWAY)) {
179 - nodeManager.createBridge(node,
180 - ROUTER_BRIDGE,
181 - node.routerBridge().get().toString().substring(DPID_BEGIN));
182 - }
183 - }
184 - },
185 - BRIDGE_CREATED {
186 - @Override
187 - public void process(OpenstackNodeManager nodeManager, OpenstackNode node) {
188 - // make sure there is OVSDB connection
189 - if (!nodeManager.isOvsdbConnected(node)) {
190 - nodeManager.connectOvsdb(node);
191 - return;
192 - }
193 - nodeManager.createTunnelInterface(node);
194 - // creates additional patch ports connecting integration bridge and
195 - // router bridge if the node type is GATEWAY
196 - if (node.type().equals(NodeType.GATEWAY)) {
197 - nodeManager.createPatchInterface(node);
198 - }
199 - }
200 - },
201 - COMPLETE {
202 - @Override
203 - public void process(OpenstackNodeManager nodeManager, OpenstackNode node) {
204 - nodeManager.postInit(node);
205 - }
206 - },
207 - INCOMPLETE {
208 - @Override
209 - public void process(OpenstackNodeManager nodeManager, OpenstackNode node) {
210 - }
211 - };
212 -
213 - public abstract void process(OpenstackNodeManager nodeManager, OpenstackNode node);
214 - }
215 -
216 @Activate 167 @Activate
217 protected void activate() { 168 protected void activate() {
218 appId = coreService.getAppId(APP_ID); 169 appId = coreService.getAppId(APP_ID);
...@@ -275,6 +226,57 @@ public final class OpenstackNodeManager implements OpenstackNodeService { ...@@ -275,6 +226,57 @@ public final class OpenstackNodeManager implements OpenstackNodeService {
275 controller.getOvsdbClient(ovsdb).disconnect(); 226 controller.getOvsdbClient(ovsdb).disconnect();
276 } 227 }
277 nodeStore.remove(node.hostname()); 228 nodeStore.remove(node.hostname());
229 + process(new OpenstackNodeEvent(INCOMPLETE, node));
230 + }
231 +
232 + @Override
233 + public void processInitState(OpenstackNode node) {
234 + // make sure there is OVSDB connection
235 + if (!isOvsdbConnected(node)) {
236 + connectOvsdb(node);
237 + return;
238 + }
239 +
240 + process(new OpenstackNodeEvent(INIT, node));
241 + createBridge(node, INTEGRATION_BRIDGE,
242 + node.intBridge().toString().substring(DPID_BEGIN));
243 +
244 + // creates additional router bridge if the node type is GATEWAY
245 + if (node.type().equals(NodeType.GATEWAY)) {
246 + createBridge(node, ROUTER_BRIDGE,
247 + node.routerBridge().get().toString().substring(DPID_BEGIN));
248 + }
249 + }
250 +
251 + @Override
252 + public void processDeviceCreatedState(OpenstackNode node) {
253 + // make sure there is OVSDB connection
254 + if (!isOvsdbConnected(node)) {
255 + connectOvsdb(node);
256 + return;
257 + }
258 + process(new OpenstackNodeEvent(DEVICE_CREATED, node));
259 + createTunnelInterface(node);
260 + // creates additional patch ports connecting integration bridge and
261 + // router bridge if the node type is GATEWAY
262 + if (node.type().equals(NodeType.GATEWAY)) {
263 + createPatchInterface(node);
264 + }
265 + }
266 +
267 + @Override
268 + public void processCompleteState(OpenstackNode node) {
269 + if (isOvsdbConnected(node)) {
270 + OvsdbNodeId ovsdb = new OvsdbNodeId(node.managementIp(), ovsdbPort);
271 + controller.getOvsdbClient(ovsdb).disconnect();
272 + }
273 + process(new OpenstackNodeEvent(COMPLETE, node));
274 + log.info("Finished init {}", node.hostname());
275 + }
276 +
277 + @Override
278 + public void processIncompleteState(OpenstackNode node) {
279 + process(new OpenstackNodeEvent(INCOMPLETE, node));
278 } 280 }
279 281
280 @Override 282 @Override
...@@ -285,22 +287,11 @@ public final class OpenstackNodeManager implements OpenstackNodeService { ...@@ -285,22 +287,11 @@ public final class OpenstackNodeManager implements OpenstackNodeService {
285 @Override 287 @Override
286 public Set<OpenstackNode> completeNodes() { 288 public Set<OpenstackNode> completeNodes() {
287 return nodeStore.values().stream().map(Versioned::value) 289 return nodeStore.values().stream().map(Versioned::value)
288 - .filter(node -> node.state().equals(NodeState.COMPLETE)) 290 + .filter(node -> node.state().equals(COMPLETE))
289 .collect(Collectors.toSet()); 291 .collect(Collectors.toSet());
290 } 292 }
291 293
292 @Override 294 @Override
293 - public boolean isComplete(String hostname) {
294 - Versioned<OpenstackNode> versionedNode = nodeStore.get(hostname);
295 - if (versionedNode == null) {
296 - log.warn("Node {} does not exist", hostname);
297 - return false;
298 - }
299 - OpenstackNodeState state = versionedNode.value().state();
300 - return state != null && state.equals(NodeState.COMPLETE);
301 - }
302 -
303 - @Override
304 public Optional<IpAddress> dataIp(DeviceId deviceId) { 295 public Optional<IpAddress> dataIp(DeviceId deviceId) {
305 OpenstackNode node = nodeByDeviceId(deviceId); 296 OpenstackNode node = nodeByDeviceId(deviceId);
306 if (node == null) { 297 if (node == null) {
...@@ -337,21 +328,11 @@ public final class OpenstackNodeManager implements OpenstackNodeService { ...@@ -337,21 +328,11 @@ public final class OpenstackNodeManager implements OpenstackNodeService {
337 } 328 }
338 329
339 private void initNode(OpenstackNode node) { 330 private void initNode(OpenstackNode node) {
340 - NodeState state = (NodeState) node.state(); 331 + NodeState state = node.state();
341 state.process(this, node); 332 state.process(this, node);
342 log.debug("Processing node: {} state: {}", node.hostname(), state); 333 log.debug("Processing node: {} state: {}", node.hostname(), state);
343 } 334 }
344 335
345 - private void postInit(OpenstackNode node) {
346 - if (isOvsdbConnected(node)) {
347 - OvsdbNodeId ovsdb = new OvsdbNodeId(node.managementIp(), ovsdbPort);
348 - controller.getOvsdbClient(ovsdb).disconnect();
349 - }
350 -
351 - // TODO add gateway node to scalable gateway pool
352 - log.info("Finished init {}", node.hostname());
353 - }
354 -
355 private void setNodeState(OpenstackNode node, NodeState newState) { 336 private void setNodeState(OpenstackNode node, NodeState newState) {
356 log.debug("Changed {} state: {}", node.hostname(), newState); 337 log.debug("Changed {} state: {}", node.hostname(), newState);
357 nodeStore.put(node.hostname(), OpenstackNode.getUpdatedNode(node, newState)); 338 nodeStore.put(node.hostname(), OpenstackNode.getUpdatedNode(node, newState));
...@@ -359,23 +340,23 @@ public final class OpenstackNodeManager implements OpenstackNodeService { ...@@ -359,23 +340,23 @@ public final class OpenstackNodeManager implements OpenstackNodeService {
359 340
360 private NodeState nodeState(OpenstackNode node) { 341 private NodeState nodeState(OpenstackNode node) {
361 if (!deviceService.isAvailable(node.intBridge())) { 342 if (!deviceService.isAvailable(node.intBridge())) {
362 - return NodeState.INIT; 343 + return INIT;
363 } 344 }
364 if (node.type().equals(NodeType.GATEWAY) && 345 if (node.type().equals(NodeType.GATEWAY) &&
365 !deviceService.isAvailable(node.routerBridge().get())) { 346 !deviceService.isAvailable(node.routerBridge().get())) {
366 - return NodeState.INIT; 347 + return INIT;
367 } 348 }
368 349
369 if (!isIfaceCreated(node.intBridge(), DEFAULT_TUNNEL)) { 350 if (!isIfaceCreated(node.intBridge(), DEFAULT_TUNNEL)) {
370 - return NodeState.BRIDGE_CREATED; 351 + return DEVICE_CREATED;
371 } 352 }
372 if (node.type().equals(NodeType.GATEWAY) && ( 353 if (node.type().equals(NodeType.GATEWAY) && (
373 !isIfaceCreated(node.routerBridge().get(), PATCH_ROUT_BRIDGE) || 354 !isIfaceCreated(node.routerBridge().get(), PATCH_ROUT_BRIDGE) ||
374 !isIfaceCreated(node.intBridge(), PATCH_INTG_BRIDGE))) { 355 !isIfaceCreated(node.intBridge(), PATCH_INTG_BRIDGE))) {
375 - return NodeState.BRIDGE_CREATED; 356 + return DEVICE_CREATED;
376 } 357 }
377 358
378 - return NodeState.COMPLETE; 359 + return COMPLETE;
379 } 360 }
380 361
381 private boolean isIfaceCreated(DeviceId deviceId, String ifaceName) { 362 private boolean isIfaceCreated(DeviceId deviceId, String ifaceName) {
...@@ -683,4 +664,3 @@ public final class OpenstackNodeManager implements OpenstackNodeService { ...@@ -683,4 +664,3 @@ public final class OpenstackNodeManager implements OpenstackNodeService {
683 } 664 }
684 } 665 }
685 } 666 }
686 -
......
...@@ -16,6 +16,7 @@ ...@@ -16,6 +16,7 @@
16 package org.onosproject.openstacknode; 16 package org.onosproject.openstacknode;
17 17
18 import org.onlab.packet.IpAddress; 18 import org.onlab.packet.IpAddress;
19 +import org.onosproject.event.ListenerService;
19 import org.onosproject.net.DeviceId; 20 import org.onosproject.net.DeviceId;
20 import org.onosproject.net.PortNumber; 21 import org.onosproject.net.PortNumber;
21 22
...@@ -26,7 +27,8 @@ import java.util.Set; ...@@ -26,7 +27,8 @@ import java.util.Set;
26 /** 27 /**
27 * Handles the bootstrap request for compute/gateway node. 28 * Handles the bootstrap request for compute/gateway node.
28 */ 29 */
29 -public interface OpenstackNodeService { 30 +public interface OpenstackNodeService
31 + extends ListenerService<OpenstackNodeEvent, OpenstackNodeListener> {
30 32
31 enum NodeType { 33 enum NodeType {
32 /** 34 /**
...@@ -44,6 +46,34 @@ public interface OpenstackNodeService { ...@@ -44,6 +46,34 @@ public interface OpenstackNodeService {
44 void addOrUpdateNode(OpenstackNode node); 46 void addOrUpdateNode(OpenstackNode node);
45 47
46 /** 48 /**
49 + * Bootstraps node with INIT state.
50 + *
51 + * @param node openstack node
52 + */
53 + void processInitState(OpenstackNode node);
54 +
55 + /**
56 + * Bootstraps node with DEVICE_CREATED state.
57 + *
58 + * @param node openstack node
59 + */
60 + void processDeviceCreatedState(OpenstackNode node);
61 +
62 + /**
63 + * Bootstraps node with COMPLETE state.
64 + *
65 + * @param node openstack node
66 + */
67 + void processCompleteState(OpenstackNode node);
68 +
69 + /**
70 + * Bootstraps node with INCOMPLETE state.
71 + *
72 + * @param node openstack node
73 + */
74 + void processIncompleteState(OpenstackNode node);
75 +
76 + /**
47 * Deletes a node from the service. 77 * Deletes a node from the service.
48 * 78 *
49 * @param node openstack node 79 * @param node openstack node
...@@ -65,14 +95,6 @@ public interface OpenstackNodeService { ...@@ -65,14 +95,6 @@ public interface OpenstackNodeService {
65 Set<OpenstackNode> completeNodes(); 95 Set<OpenstackNode> completeNodes();
66 96
67 /** 97 /**
68 - * Returns node initialization state is complete or not.
69 - *
70 - * @param hostname hostname of the node
71 - * @return true if initial node setup is completed, otherwise false
72 - */
73 - boolean isComplete(String hostname);
74 -
75 - /**
76 * Returns data network IP address of a given integration bridge device. 98 * Returns data network IP address of a given integration bridge device.
77 * 99 *
78 * @param intBridgeId integration bridge device id 100 * @param intBridgeId integration bridge device id
......
...@@ -34,9 +34,6 @@ import java.util.List; ...@@ -34,9 +34,6 @@ import java.util.List;
34 description = "Lists all nodes registered in OpenStack node service") 34 description = "Lists all nodes registered in OpenStack node service")
35 public class OpenstackNodeListCommand extends AbstractShellCommand { 35 public class OpenstackNodeListCommand extends AbstractShellCommand {
36 36
37 - private static final String COMPLETE = "COMPLETE";
38 - private static final String INCOMPLETE = "INCOMPLETE";
39 -
40 @Override 37 @Override
41 protected void execute() { 38 protected void execute() {
42 OpenstackNodeService nodeService = AbstractShellCommand.get(OpenstackNodeService.class); 39 OpenstackNodeService nodeService = AbstractShellCommand.get(OpenstackNodeService.class);
...@@ -44,7 +41,7 @@ public class OpenstackNodeListCommand extends AbstractShellCommand { ...@@ -44,7 +41,7 @@ public class OpenstackNodeListCommand extends AbstractShellCommand {
44 Collections.sort(nodes, OpenstackNode.OPENSTACK_NODE_COMPARATOR); 41 Collections.sort(nodes, OpenstackNode.OPENSTACK_NODE_COMPARATOR);
45 42
46 if (outputJson()) { 43 if (outputJson()) {
47 - print("%s", json(nodeService, nodes)); 44 + print("%s", json(nodes));
48 } else { 45 } else {
49 for (OpenstackNode node : nodes) { 46 for (OpenstackNode node : nodes) {
50 print("hostname=%s, type=%s, managementIp=%s, dataIp=%s, intBridge=%s, routerBridge=%s init=%s", 47 print("hostname=%s, type=%s, managementIp=%s, dataIp=%s, intBridge=%s, routerBridge=%s init=%s",
...@@ -54,13 +51,13 @@ public class OpenstackNodeListCommand extends AbstractShellCommand { ...@@ -54,13 +51,13 @@ public class OpenstackNodeListCommand extends AbstractShellCommand {
54 node.dataIp(), 51 node.dataIp(),
55 node.intBridge(), 52 node.intBridge(),
56 node.routerBridge(), 53 node.routerBridge(),
57 - getState(nodeService, node)); 54 + node.state());
58 } 55 }
59 print("Total %s nodes", nodeService.nodes().size()); 56 print("Total %s nodes", nodeService.nodes().size());
60 } 57 }
61 } 58 }
62 59
63 - private JsonNode json(OpenstackNodeService nodeService, List<OpenstackNode> nodes) { 60 + private JsonNode json(List<OpenstackNode> nodes) {
64 ObjectMapper mapper = new ObjectMapper(); 61 ObjectMapper mapper = new ObjectMapper();
65 ArrayNode result = mapper.createArrayNode(); 62 ArrayNode result = mapper.createArrayNode();
66 for (OpenstackNode node : nodes) { 63 for (OpenstackNode node : nodes) {
...@@ -71,12 +68,8 @@ public class OpenstackNodeListCommand extends AbstractShellCommand { ...@@ -71,12 +68,8 @@ public class OpenstackNodeListCommand extends AbstractShellCommand {
71 .put("dataIp", node.dataIp().toString()) 68 .put("dataIp", node.dataIp().toString())
72 .put("intBridge", node.intBridge().toString()) 69 .put("intBridge", node.intBridge().toString())
73 .put("routerBridge", node.routerBridge().toString()) 70 .put("routerBridge", node.routerBridge().toString())
74 - .put("state", getState(nodeService, node))); 71 + .put("state", node.state().name()));
75 } 72 }
76 return result; 73 return result;
77 } 74 }
78 -
79 - private String getState(OpenstackNodeService nodeService, OpenstackNode node) {
80 - return nodeService.isComplete(node.hostname()) ? COMPLETE : INCOMPLETE;
81 - }
82 } 75 }
...\ No newline at end of file ...\ No newline at end of file
......