Committed by
Gerrit Code Review
Some improvements on cordvtn
- Removed unnecessary CordVtnNodeConfig class - Don't allow local and host management IP range overlapping - Check node init state saved in the store instead of really check when a VM is detected or vanished since it's too slow Change-Id: I076780bdc3946b2000176cb05805003ba7c8724d
Showing
7 changed files
with
130 additions
and
240 deletions
... | @@ -70,9 +70,11 @@ import org.slf4j.Logger; | ... | @@ -70,9 +70,11 @@ import org.slf4j.Logger; |
70 | 70 | ||
71 | import java.util.List; | 71 | import java.util.List; |
72 | import java.util.Map; | 72 | import java.util.Map; |
73 | +import java.util.Objects; | ||
73 | import java.util.Set; | 74 | import java.util.Set; |
74 | import java.util.concurrent.ExecutorService; | 75 | import java.util.concurrent.ExecutorService; |
75 | import java.util.stream.Collectors; | 76 | import java.util.stream.Collectors; |
77 | +import java.util.stream.StreamSupport; | ||
76 | 78 | ||
77 | import static com.google.common.base.Preconditions.checkNotNull; | 79 | import static com.google.common.base.Preconditions.checkNotNull; |
78 | import static java.util.concurrent.Executors.newSingleThreadScheduledExecutor; | 80 | import static java.util.concurrent.Executors.newSingleThreadScheduledExecutor; |
... | @@ -266,7 +268,7 @@ public class CordVtn extends AbstractProvider implements CordVtnService, HostPro | ... | @@ -266,7 +268,7 @@ public class CordVtn extends AbstractProvider implements CordVtnService, HostPro |
266 | } | 268 | } |
267 | } | 269 | } |
268 | 270 | ||
269 | - Set<IpAddress> ip = Sets.newHashSet(vPort.fixedIps().values()); | 271 | + Set<IpAddress> fixedIp = Sets.newHashSet(vPort.fixedIps().values()); |
270 | DefaultAnnotations.Builder annotations = DefaultAnnotations.builder() | 272 | DefaultAnnotations.Builder annotations = DefaultAnnotations.builder() |
271 | .set(SERVICE_ID, vPort.networkId()) | 273 | .set(SERVICE_ID, vPort.networkId()) |
272 | .set(OPENSTACK_VM_ID, vPort.deviceId()) | 274 | .set(OPENSTACK_VM_ID, vPort.deviceId()) |
... | @@ -283,7 +285,7 @@ public class CordVtn extends AbstractProvider implements CordVtnService, HostPro | ... | @@ -283,7 +285,7 @@ public class CordVtn extends AbstractProvider implements CordVtnService, HostPro |
283 | mac, | 285 | mac, |
284 | VlanId.NONE, | 286 | VlanId.NONE, |
285 | new HostLocation(connectPoint, System.currentTimeMillis()), | 287 | new HostLocation(connectPoint, System.currentTimeMillis()), |
286 | - ip, | 288 | + fixedIp, |
287 | annotations.build()); | 289 | annotations.build()); |
288 | 290 | ||
289 | hostProvider.hostDetected(hostId, hostDesc, false); | 291 | hostProvider.hostDetected(hostId, hostDesc, false); |
... | @@ -357,6 +359,30 @@ public class CordVtn extends AbstractProvider implements CordVtnService, HostPro | ... | @@ -357,6 +359,30 @@ public class CordVtn extends AbstractProvider implements CordVtnService, HostPro |
357 | } | 359 | } |
358 | 360 | ||
359 | /** | 361 | /** |
362 | + * Returns public ip addresses of vSGs running inside a give vSG host. | ||
363 | + * | ||
364 | + * @param vSgHost vSG host | ||
365 | + * @return map of ip and mac address, or empty map | ||
366 | + */ | ||
367 | + private Map<IpAddress, MacAddress> getSubscriberGateways(Host vSgHost) { | ||
368 | + String vPortId = vSgHost.annotations().value(OPENSTACK_PORT_ID); | ||
369 | + String serviceVlan = vSgHost.annotations().value(S_TAG); | ||
370 | + | ||
371 | + OpenstackPort vPort = openstackService.port(vPortId); | ||
372 | + if (vPort == null) { | ||
373 | + log.warn("Failed to get OpenStack port {} for VM {}", vPortId, vSgHost.id()); | ||
374 | + return Maps.newHashMap(); | ||
375 | + } | ||
376 | + | ||
377 | + if (!serviceVlan.equals(getServiceVlan(vPort))) { | ||
378 | + log.error("Host({}) s-tag does not match with vPort s-tag", vSgHost.id()); | ||
379 | + return Maps.newHashMap(); | ||
380 | + } | ||
381 | + | ||
382 | + return vPort.allowedAddressPairs(); | ||
383 | + } | ||
384 | + | ||
385 | + /** | ||
360 | * Returns CordService by service ID. | 386 | * Returns CordService by service ID. |
361 | * | 387 | * |
362 | * @param serviceId service id | 388 | * @param serviceId service id |
... | @@ -453,6 +479,16 @@ public class CordVtn extends AbstractProvider implements CordVtnService, HostPro | ... | @@ -453,6 +479,16 @@ public class CordVtn extends AbstractProvider implements CordVtnService, HostPro |
453 | } | 479 | } |
454 | 480 | ||
455 | /** | 481 | /** |
482 | + * Returns service ID of this host. | ||
483 | + * | ||
484 | + * @param host host | ||
485 | + * @return service id, or null if not found | ||
486 | + */ | ||
487 | + private String getServiceId(Host host) { | ||
488 | + return host.annotations().value(SERVICE_ID); | ||
489 | + } | ||
490 | + | ||
491 | + /** | ||
456 | * Returns hosts associated with a given OpenStack network. | 492 | * Returns hosts associated with a given OpenStack network. |
457 | * | 493 | * |
458 | * @param vNet openstack network | 494 | * @param vNet openstack network |
... | @@ -461,40 +497,10 @@ public class CordVtn extends AbstractProvider implements CordVtnService, HostPro | ... | @@ -461,40 +497,10 @@ public class CordVtn extends AbstractProvider implements CordVtnService, HostPro |
461 | private Set<Host> getHostsWithOpenstackNetwork(OpenstackNetwork vNet) { | 497 | private Set<Host> getHostsWithOpenstackNetwork(OpenstackNetwork vNet) { |
462 | checkNotNull(vNet); | 498 | checkNotNull(vNet); |
463 | 499 | ||
464 | - Set<Host> hosts = openstackService.ports(vNet.id()).stream() | 500 | + String vNetId = vNet.id(); |
465 | - .filter(port -> port.deviceOwner().contains("compute")) | 501 | + return StreamSupport.stream(hostService.getHosts().spliterator(), false) |
466 | - .map(port -> hostService.getHostsByMac(port.macAddress()) | 502 | + .filter(host -> Objects.equals(vNetId, getServiceId(host))) |
467 | - .stream() | ||
468 | - .findFirst() | ||
469 | - .orElse(null)) | ||
470 | .collect(Collectors.toSet()); | 503 | .collect(Collectors.toSet()); |
471 | - | ||
472 | - hosts.remove(null); | ||
473 | - return hosts; | ||
474 | - } | ||
475 | - | ||
476 | - /** | ||
477 | - * Returns public ip addresses of vSGs running inside a give vSG host. | ||
478 | - * | ||
479 | - * @param vSgHost vSG host | ||
480 | - * @return map of ip and mac address, or empty map | ||
481 | - */ | ||
482 | - private Map<IpAddress, MacAddress> getSubscriberGateways(Host vSgHost) { | ||
483 | - String vPortId = vSgHost.annotations().value(OPENSTACK_PORT_ID); | ||
484 | - String serviceVlan = vSgHost.annotations().value(S_TAG); | ||
485 | - | ||
486 | - OpenstackPort vPort = openstackService.port(vPortId); | ||
487 | - if (vPort == null) { | ||
488 | - log.warn("Failed to get OpenStack port {} for VM {}", vPortId, vSgHost.id()); | ||
489 | - return Maps.newHashMap(); | ||
490 | - } | ||
491 | - | ||
492 | - if (!serviceVlan.equals(getServiceVlan(vPort))) { | ||
493 | - log.error("Host({}) s-tag does not match with vPort s-tag", vSgHost.id()); | ||
494 | - return Maps.newHashMap(); | ||
495 | - } | ||
496 | - | ||
497 | - return vPort.allowedAddressPairs(); | ||
498 | } | 504 | } |
499 | 505 | ||
500 | /** | 506 | /** | ... | ... |
... | @@ -18,6 +18,7 @@ package org.onosproject.cordvtn; | ... | @@ -18,6 +18,7 @@ package org.onosproject.cordvtn; |
18 | import com.fasterxml.jackson.databind.JsonNode; | 18 | import com.fasterxml.jackson.databind.JsonNode; |
19 | import com.google.common.collect.Maps; | 19 | import com.google.common.collect.Maps; |
20 | import com.google.common.collect.Sets; | 20 | import com.google.common.collect.Sets; |
21 | +import org.onlab.packet.Ip4Address; | ||
21 | import org.onlab.packet.IpAddress; | 22 | import org.onlab.packet.IpAddress; |
22 | import org.onlab.packet.MacAddress; | 23 | import org.onlab.packet.MacAddress; |
23 | import org.onlab.packet.TpPort; | 24 | import org.onlab.packet.TpPort; |
... | @@ -29,7 +30,6 @@ import org.slf4j.Logger; | ... | @@ -29,7 +30,6 @@ import org.slf4j.Logger; |
29 | import java.util.Map; | 30 | import java.util.Map; |
30 | import java.util.Set; | 31 | import java.util.Set; |
31 | 32 | ||
32 | -import static com.google.common.base.Preconditions.checkNotNull; | ||
33 | import static org.slf4j.LoggerFactory.getLogger; | 33 | import static org.slf4j.LoggerFactory.getLogger; |
34 | 34 | ||
35 | /** | 35 | /** |
... | @@ -45,11 +45,12 @@ public class CordVtnConfig extends Config<ApplicationId> { | ... | @@ -45,11 +45,12 @@ public class CordVtnConfig extends Config<ApplicationId> { |
45 | public static final String GATEWAY_MAC = "gatewayMac"; | 45 | public static final String GATEWAY_MAC = "gatewayMac"; |
46 | public static final String LOCAL_MANAGEMENT_IP = "localManagementIp"; | 46 | public static final String LOCAL_MANAGEMENT_IP = "localManagementIp"; |
47 | public static final String OVSDB_PORT = "ovsdbPort"; | 47 | public static final String OVSDB_PORT = "ovsdbPort"; |
48 | + | ||
48 | public static final String SSH_PORT = "sshPort"; | 49 | public static final String SSH_PORT = "sshPort"; |
49 | public static final String SSH_USER = "sshUser"; | 50 | public static final String SSH_USER = "sshUser"; |
50 | public static final String SSH_KEY_FILE = "sshKeyFile"; | 51 | public static final String SSH_KEY_FILE = "sshKeyFile"; |
51 | - public static final String CORDVTN_NODES = "nodes"; | ||
52 | 52 | ||
53 | + public static final String CORDVTN_NODES = "nodes"; | ||
53 | public static final String HOSTNAME = "hostname"; | 54 | public static final String HOSTNAME = "hostname"; |
54 | public static final String HOST_MANAGEMENT_IP = "hostManagementIp"; | 55 | public static final String HOST_MANAGEMENT_IP = "hostManagementIp"; |
55 | public static final String DATA_PLANE_IP = "dataPlaneIp"; | 56 | public static final String DATA_PLANE_IP = "dataPlaneIp"; |
... | @@ -61,31 +62,70 @@ public class CordVtnConfig extends Config<ApplicationId> { | ... | @@ -61,31 +62,70 @@ public class CordVtnConfig extends Config<ApplicationId> { |
61 | * | 62 | * |
62 | * @return set of CordVtnNodeConfig or null | 63 | * @return set of CordVtnNodeConfig or null |
63 | */ | 64 | */ |
64 | - public Set<CordVtnNodeConfig> cordVtnNodes() { | 65 | + public Set<CordVtnNode> cordVtnNodes() { |
65 | - Set<CordVtnNodeConfig> nodes = Sets.newHashSet(); | ||
66 | 66 | ||
67 | + Set<CordVtnNode> nodes = Sets.newHashSet(); | ||
67 | JsonNode jsonNodes = object.get(CORDVTN_NODES); | 68 | JsonNode jsonNodes = object.get(CORDVTN_NODES); |
68 | if (jsonNodes == null) { | 69 | if (jsonNodes == null) { |
70 | + log.debug("No CORD VTN nodes found"); | ||
69 | return null; | 71 | return null; |
70 | } | 72 | } |
71 | 73 | ||
72 | - jsonNodes.forEach(jsonNode -> { | 74 | + for (JsonNode jsonNode : jsonNodes) { |
73 | try { | 75 | try { |
74 | - nodes.add(new CordVtnNodeConfig( | 76 | + NetworkAddress hostMgmt = NetworkAddress.valueOf(getConfig(jsonNode, HOST_MANAGEMENT_IP)); |
75 | - jsonNode.path(HOSTNAME).asText(), | 77 | + NetworkAddress localMgmt = NetworkAddress.valueOf(getConfig(object, LOCAL_MANAGEMENT_IP)); |
76 | - NetworkAddress.valueOf(jsonNode.path(HOST_MANAGEMENT_IP).asText()), | 78 | + if (hostMgmt.prefix().contains(localMgmt.prefix()) || |
77 | - NetworkAddress.valueOf(jsonNode.path(DATA_PLANE_IP).asText()), | 79 | + localMgmt.prefix().contains(hostMgmt.prefix())) { |
78 | - jsonNode.path(DATA_PLANE_INTF).asText(), | 80 | + log.error("hostMamt and localMgmt cannot be overlapped, skip this node"); |
79 | - DeviceId.deviceId(jsonNode.path(BRIDGE_ID).asText()))); | 81 | + continue; |
82 | + } | ||
83 | + | ||
84 | + Ip4Address hostMgmtIp = hostMgmt.ip().getIp4Address(); | ||
85 | + SshAccessInfo sshInfo = new SshAccessInfo( | ||
86 | + hostMgmtIp, | ||
87 | + TpPort.tpPort(Integer.parseInt(getConfig(object, SSH_PORT))), | ||
88 | + getConfig(object, SSH_USER), getConfig(object, SSH_KEY_FILE)); | ||
89 | + | ||
90 | + String hostname = getConfig(jsonNode, HOSTNAME); | ||
91 | + CordVtnNode newNode = new CordVtnNode( | ||
92 | + hostname, hostMgmt, localMgmt, | ||
93 | + NetworkAddress.valueOf(getConfig(jsonNode, DATA_PLANE_IP)), | ||
94 | + TpPort.tpPort(Integer.parseInt(getConfig(object, OVSDB_PORT))), | ||
95 | + sshInfo, | ||
96 | + DeviceId.deviceId(getConfig(jsonNode, BRIDGE_ID)), | ||
97 | + getConfig(jsonNode, DATA_PLANE_INTF)); | ||
98 | + | ||
99 | + log.info("Successfully read {} from the config", hostname); | ||
100 | + nodes.add(newNode); | ||
80 | } catch (IllegalArgumentException | NullPointerException e) { | 101 | } catch (IllegalArgumentException | NullPointerException e) { |
81 | - log.error("Failed to read {}", e.toString()); | 102 | + log.error("{}", e.toString()); |
103 | + } | ||
82 | } | 104 | } |
83 | - }); | ||
84 | 105 | ||
85 | return nodes; | 106 | return nodes; |
86 | } | 107 | } |
87 | 108 | ||
88 | /** | 109 | /** |
110 | + * Returns value of a given path. If the path is missing, show log and return | ||
111 | + * null. | ||
112 | + * | ||
113 | + * @param path path | ||
114 | + * @return value or null | ||
115 | + */ | ||
116 | + private String getConfig(JsonNode jsonNode, String path) { | ||
117 | + jsonNode = jsonNode.path(path); | ||
118 | + | ||
119 | + if (jsonNode.isMissingNode()) { | ||
120 | + log.error("{} is not configured", path); | ||
121 | + return null; | ||
122 | + } else { | ||
123 | + log.debug("{} : {}", path, jsonNode.asText()); | ||
124 | + return jsonNode.asText(); | ||
125 | + } | ||
126 | + } | ||
127 | + | ||
128 | + /** | ||
89 | * Returns private network gateway MAC address. | 129 | * Returns private network gateway MAC address. |
90 | * | 130 | * |
91 | * @return mac address, or null | 131 | * @return mac address, or null |
... | @@ -112,7 +152,7 @@ public class CordVtnConfig extends Config<ApplicationId> { | ... | @@ -112,7 +152,7 @@ public class CordVtnConfig extends Config<ApplicationId> { |
112 | public Map<IpAddress, MacAddress> publicGateways() { | 152 | public Map<IpAddress, MacAddress> publicGateways() { |
113 | JsonNode jsonNodes = object.get(PUBLIC_GATEWAYS); | 153 | JsonNode jsonNodes = object.get(PUBLIC_GATEWAYS); |
114 | if (jsonNodes == null) { | 154 | if (jsonNodes == null) { |
115 | - return null; | 155 | + return Maps.newHashMap(); |
116 | } | 156 | } |
117 | 157 | ||
118 | Map<IpAddress, MacAddress> publicGateways = Maps.newHashMap(); | 158 | Map<IpAddress, MacAddress> publicGateways = Maps.newHashMap(); |
... | @@ -128,155 +168,5 @@ public class CordVtnConfig extends Config<ApplicationId> { | ... | @@ -128,155 +168,5 @@ public class CordVtnConfig extends Config<ApplicationId> { |
128 | 168 | ||
129 | return publicGateways; | 169 | return publicGateways; |
130 | } | 170 | } |
131 | - | ||
132 | - /** | ||
133 | - * Returns local management network address. | ||
134 | - * | ||
135 | - * @return network address | ||
136 | - */ | ||
137 | - public NetworkAddress localMgmtIp() { | ||
138 | - JsonNode jsonNode = object.get(LOCAL_MANAGEMENT_IP); | ||
139 | - if (jsonNode == null) { | ||
140 | - return null; | ||
141 | - } | ||
142 | - | ||
143 | - try { | ||
144 | - return NetworkAddress.valueOf(jsonNode.asText()); | ||
145 | - } catch (IllegalArgumentException e) { | ||
146 | - log.error("Wrong address format {}", jsonNode.asText()); | ||
147 | - return null; | ||
148 | - } | ||
149 | - } | ||
150 | - | ||
151 | - /** | ||
152 | - * Returns the port number used for OVSDB connection. | ||
153 | - * | ||
154 | - * @return port number, or null | ||
155 | - */ | ||
156 | - public TpPort ovsdbPort() { | ||
157 | - JsonNode jsonNode = object.get(OVSDB_PORT); | ||
158 | - if (jsonNode == null) { | ||
159 | - return null; | ||
160 | - } | ||
161 | - | ||
162 | - try { | ||
163 | - return TpPort.tpPort(jsonNode.asInt()); | ||
164 | - } catch (IllegalArgumentException e) { | ||
165 | - log.error("Wrong TCP port format {}", jsonNode.asText()); | ||
166 | - return null; | ||
167 | - } | ||
168 | - } | ||
169 | - | ||
170 | - /** | ||
171 | - * Returns the port number used for SSH connection. | ||
172 | - * | ||
173 | - * @return port number, or null | ||
174 | - */ | ||
175 | - public TpPort sshPort() { | ||
176 | - JsonNode jsonNode = object.get(SSH_PORT); | ||
177 | - if (jsonNode == null) { | ||
178 | - return null; | ||
179 | - } | ||
180 | - | ||
181 | - try { | ||
182 | - return TpPort.tpPort(jsonNode.asInt()); | ||
183 | - } catch (IllegalArgumentException e) { | ||
184 | - log.error("Wrong TCP port format {}", jsonNode.asText()); | ||
185 | - return null; | ||
186 | - } | ||
187 | - } | ||
188 | - | ||
189 | - /** | ||
190 | - * Returns the user name for SSH connection. | ||
191 | - * | ||
192 | - * @return user name, or null | ||
193 | - */ | ||
194 | - public String sshUser() { | ||
195 | - JsonNode jsonNode = object.get(SSH_USER); | ||
196 | - if (jsonNode == null) { | ||
197 | - return null; | ||
198 | - } | ||
199 | - | ||
200 | - return jsonNode.asText(); | ||
201 | - } | ||
202 | - | ||
203 | - /** | ||
204 | - * Returns the private key file for SSH connection. | ||
205 | - * | ||
206 | - * @return file path, or null | ||
207 | - */ | ||
208 | - public String sshKeyFile() { | ||
209 | - JsonNode jsonNode = object.get(SSH_KEY_FILE); | ||
210 | - if (jsonNode == null) { | ||
211 | - return null; | ||
212 | - } | ||
213 | - | ||
214 | - return jsonNode.asText(); | ||
215 | - } | ||
216 | - | ||
217 | - /** | ||
218 | - * Configuration for CordVtn node. | ||
219 | - */ | ||
220 | - public static class CordVtnNodeConfig { | ||
221 | - | ||
222 | - private final String hostname; | ||
223 | - private final NetworkAddress hostMgmtIp; | ||
224 | - private final NetworkAddress dpIp; | ||
225 | - private final String dpIntf; | ||
226 | - private final DeviceId bridgeId; | ||
227 | - | ||
228 | - public CordVtnNodeConfig(String hostname, NetworkAddress hostMgmtIp, NetworkAddress dpIp, | ||
229 | - String dpIntf, DeviceId bridgeId) { | ||
230 | - this.hostname = checkNotNull(hostname); | ||
231 | - this.hostMgmtIp = checkNotNull(hostMgmtIp); | ||
232 | - this.dpIp = checkNotNull(dpIp); | ||
233 | - this.dpIntf = checkNotNull(dpIntf); | ||
234 | - this.bridgeId = checkNotNull(bridgeId); | ||
235 | - } | ||
236 | - | ||
237 | - /** | ||
238 | - * Returns hostname of the node. | ||
239 | - * | ||
240 | - * @return hostname | ||
241 | - */ | ||
242 | - public String hostname() { | ||
243 | - return this.hostname; | ||
244 | - } | ||
245 | - | ||
246 | - /** | ||
247 | - * Returns the host management network address of the node. | ||
248 | - * | ||
249 | - * @return management network address | ||
250 | - */ | ||
251 | - public NetworkAddress hostMgmtIp() { | ||
252 | - return this.hostMgmtIp; | ||
253 | - } | ||
254 | - | ||
255 | - /** | ||
256 | - * Returns the data plane network address. | ||
257 | - * | ||
258 | - * @return network address | ||
259 | - */ | ||
260 | - public NetworkAddress dpIp() { | ||
261 | - return this.dpIp; | ||
262 | - } | ||
263 | - | ||
264 | - /** | ||
265 | - * Returns the data plane interface name. | ||
266 | - * | ||
267 | - * @return interface name | ||
268 | - */ | ||
269 | - public String dpIntf() { | ||
270 | - return this.dpIntf; | ||
271 | - } | ||
272 | - | ||
273 | - /** | ||
274 | - * Returns integration bridge id of the node. | ||
275 | - * | ||
276 | - * @return device id | ||
277 | - */ | ||
278 | - public DeviceId bridgeId() { | ||
279 | - return this.bridgeId; | ||
280 | - } | ||
281 | - } | ||
282 | } | 171 | } |
172 | + | ... | ... |
... | @@ -24,7 +24,6 @@ import org.apache.felix.scr.annotations.Reference; | ... | @@ -24,7 +24,6 @@ import org.apache.felix.scr.annotations.Reference; |
24 | import org.apache.felix.scr.annotations.ReferenceCardinality; | 24 | import org.apache.felix.scr.annotations.ReferenceCardinality; |
25 | import org.apache.felix.scr.annotations.Service; | 25 | import org.apache.felix.scr.annotations.Service; |
26 | import org.onlab.packet.IpAddress; | 26 | import org.onlab.packet.IpAddress; |
27 | -import org.onlab.packet.TpPort; | ||
28 | import org.onlab.util.ItemNotFoundException; | 27 | import org.onlab.util.ItemNotFoundException; |
29 | import org.onlab.util.KryoNamespace; | 28 | import org.onlab.util.KryoNamespace; |
30 | import org.onosproject.cluster.ClusterService; | 29 | import org.onosproject.cluster.ClusterService; |
... | @@ -64,6 +63,7 @@ import org.onosproject.store.serializers.KryoNamespaces; | ... | @@ -64,6 +63,7 @@ import org.onosproject.store.serializers.KryoNamespaces; |
64 | import org.onosproject.store.service.ConsistentMap; | 63 | import org.onosproject.store.service.ConsistentMap; |
65 | import org.onosproject.store.service.Serializer; | 64 | import org.onosproject.store.service.Serializer; |
66 | import org.onosproject.store.service.StorageService; | 65 | import org.onosproject.store.service.StorageService; |
66 | +import org.onosproject.store.service.Versioned; | ||
67 | import org.slf4j.Logger; | 67 | import org.slf4j.Logger; |
68 | 68 | ||
69 | import java.util.ArrayList; | 69 | import java.util.ArrayList; |
... | @@ -300,6 +300,22 @@ public class CordVtnNodeManager { | ... | @@ -300,6 +300,22 @@ public class CordVtnNodeManager { |
300 | } | 300 | } |
301 | 301 | ||
302 | /** | 302 | /** |
303 | + * Returns if current node state saved in nodeStore is COMPLETE or not. | ||
304 | + * | ||
305 | + * @param node cordvtn node | ||
306 | + * @return true if it's complete state, otherwise false | ||
307 | + */ | ||
308 | + private boolean isNodeStateComplete(CordVtnNode node) { | ||
309 | + checkNotNull(node); | ||
310 | + | ||
311 | + // the state saved in nodeStore can be wrong if IP address settings are changed | ||
312 | + // after the node init has been completed since there's no way to detect it | ||
313 | + // getNodeState and checkNodeInitState always return correct answer but can be slow | ||
314 | + Versioned<NodeState> state = nodeStore.get(node); | ||
315 | + return state != null && state.value().equals(NodeState.COMPLETE); | ||
316 | + } | ||
317 | + | ||
318 | + /** | ||
303 | * Returns detailed node initialization state. | 319 | * Returns detailed node initialization state. |
304 | * | 320 | * |
305 | * @param node cordvtn node | 321 | * @param node cordvtn node |
... | @@ -771,7 +787,7 @@ public class CordVtnNodeManager { | ... | @@ -771,7 +787,7 @@ public class CordVtnNodeManager { |
771 | log.debug("Port {} is added to {}", portName, node.hostname()); | 787 | log.debug("Port {} is added to {}", portName, node.hostname()); |
772 | 788 | ||
773 | if (portName.startsWith(VPORT_PREFIX)) { | 789 | if (portName.startsWith(VPORT_PREFIX)) { |
774 | - if (isNodeInitComplete(node)) { | 790 | + if (isNodeStateComplete(node)) { |
775 | cordVtnService.addServiceVm(node, getConnectPoint(port)); | 791 | cordVtnService.addServiceVm(node, getConnectPoint(port)); |
776 | } else { | 792 | } else { |
777 | log.debug("VM is detected on incomplete node, ignore it.", portName); | 793 | log.debug("VM is detected on incomplete node, ignore it.", portName); |
... | @@ -799,7 +815,7 @@ public class CordVtnNodeManager { | ... | @@ -799,7 +815,7 @@ public class CordVtnNodeManager { |
799 | log.debug("Port {} is removed from {}", portName, node.hostname()); | 815 | log.debug("Port {} is removed from {}", portName, node.hostname()); |
800 | 816 | ||
801 | if (portName.startsWith(VPORT_PREFIX)) { | 817 | if (portName.startsWith(VPORT_PREFIX)) { |
802 | - if (isNodeInitComplete(node)) { | 818 | + if (isNodeStateComplete(node)) { |
803 | cordVtnService.removeServiceVm(getConnectPoint(port)); | 819 | cordVtnService.removeServiceVm(getConnectPoint(port)); |
804 | } else { | 820 | } else { |
805 | log.debug("VM is vanished from incomplete node, ignore it.", portName); | 821 | log.debug("VM is vanished from incomplete node, ignore it.", portName); |
... | @@ -847,36 +863,12 @@ public class CordVtnNodeManager { | ... | @@ -847,36 +863,12 @@ public class CordVtnNodeManager { |
847 | */ | 863 | */ |
848 | private void readConfiguration() { | 864 | private void readConfiguration() { |
849 | CordVtnConfig config = configRegistry.getConfig(appId, CordVtnConfig.class); | 865 | CordVtnConfig config = configRegistry.getConfig(appId, CordVtnConfig.class); |
850 | - | ||
851 | if (config == null) { | 866 | if (config == null) { |
852 | log.debug("No configuration found"); | 867 | log.debug("No configuration found"); |
853 | return; | 868 | return; |
854 | } | 869 | } |
855 | 870 | ||
856 | - NetworkAddress localMgmtIp = config.localMgmtIp(); | 871 | + config.cordVtnNodes().forEach(this::addNode); |
857 | - TpPort ovsdbPort = config.ovsdbPort(); | ||
858 | - TpPort sshPort = config.sshPort(); | ||
859 | - String sshUser = config.sshUser(); | ||
860 | - String sshKeyFile = config.sshKeyFile(); | ||
861 | - | ||
862 | - config.cordVtnNodes().forEach(node -> { | ||
863 | - log.debug("Read node {}", node.hostname()); | ||
864 | - CordVtnNode cordVtnNode = new CordVtnNode( | ||
865 | - node.hostname(), | ||
866 | - node.hostMgmtIp(), | ||
867 | - localMgmtIp, | ||
868 | - node.dpIp(), | ||
869 | - ovsdbPort, | ||
870 | - new SshAccessInfo(node.hostMgmtIp().ip().getIp4Address(), | ||
871 | - sshPort, | ||
872 | - sshUser, | ||
873 | - sshKeyFile), | ||
874 | - node.bridgeId(), | ||
875 | - node.dpIntf()); | ||
876 | - | ||
877 | - addNode(cordVtnNode); | ||
878 | - }); | ||
879 | - | ||
880 | // TODO remove nodes if needed | 872 | // TODO remove nodes if needed |
881 | } | 873 | } |
882 | 874 | ... | ... |
... | @@ -21,6 +21,8 @@ import org.onlab.packet.TpPort; | ... | @@ -21,6 +21,8 @@ import org.onlab.packet.TpPort; |
21 | 21 | ||
22 | import java.util.Objects; | 22 | import java.util.Objects; |
23 | 23 | ||
24 | +import static com.google.common.base.Preconditions.checkNotNull; | ||
25 | + | ||
24 | /** | 26 | /** |
25 | * Representation of SSH access information. | 27 | * Representation of SSH access information. |
26 | */ | 28 | */ |
... | @@ -40,10 +42,10 @@ public final class SshAccessInfo { | ... | @@ -40,10 +42,10 @@ public final class SshAccessInfo { |
40 | * @param privateKey path of ssh private key | 42 | * @param privateKey path of ssh private key |
41 | */ | 43 | */ |
42 | public SshAccessInfo(Ip4Address remoteIp, TpPort port, String user, String privateKey) { | 44 | public SshAccessInfo(Ip4Address remoteIp, TpPort port, String user, String privateKey) { |
43 | - this.remoteIp = remoteIp; | 45 | + this.remoteIp = checkNotNull(remoteIp); |
44 | - this.port = port; | 46 | + this.port = checkNotNull(port); |
45 | - this.user = user; | 47 | + this.user = checkNotNull(user); |
46 | - this.privateKey = privateKey; | 48 | + this.privateKey = checkNotNull(privateKey); |
47 | } | 49 | } |
48 | 50 | ||
49 | /** | 51 | /** | ... | ... |
... | @@ -43,7 +43,7 @@ public class NeutronMl2NetworksWebResource extends AbstractWebResource { | ... | @@ -43,7 +43,7 @@ public class NeutronMl2NetworksWebResource extends AbstractWebResource { |
43 | @Consumes(MediaType.APPLICATION_JSON) | 43 | @Consumes(MediaType.APPLICATION_JSON) |
44 | @Produces(MediaType.APPLICATION_JSON) | 44 | @Produces(MediaType.APPLICATION_JSON) |
45 | public Response createNetwork(InputStream input) { | 45 | public Response createNetwork(InputStream input) { |
46 | - log.debug(String.format(NETWORKS_MESSAGE, "create")); | 46 | + log.trace(String.format(NETWORKS_MESSAGE, "create")); |
47 | return Response.status(Response.Status.OK).build(); | 47 | return Response.status(Response.Status.OK).build(); |
48 | } | 48 | } |
49 | 49 | ||
... | @@ -52,7 +52,7 @@ public class NeutronMl2NetworksWebResource extends AbstractWebResource { | ... | @@ -52,7 +52,7 @@ public class NeutronMl2NetworksWebResource extends AbstractWebResource { |
52 | @Consumes(MediaType.APPLICATION_JSON) | 52 | @Consumes(MediaType.APPLICATION_JSON) |
53 | @Produces(MediaType.APPLICATION_JSON) | 53 | @Produces(MediaType.APPLICATION_JSON) |
54 | public Response updateNetwork(@PathParam("id") String id, InputStream input) { | 54 | public Response updateNetwork(@PathParam("id") String id, InputStream input) { |
55 | - log.debug(String.format(NETWORKS_MESSAGE, "update")); | 55 | + log.trace(String.format(NETWORKS_MESSAGE, "update")); |
56 | return Response.status(Response.Status.OK).build(); | 56 | return Response.status(Response.Status.OK).build(); |
57 | } | 57 | } |
58 | 58 | ||
... | @@ -60,7 +60,7 @@ public class NeutronMl2NetworksWebResource extends AbstractWebResource { | ... | @@ -60,7 +60,7 @@ public class NeutronMl2NetworksWebResource extends AbstractWebResource { |
60 | @Path("{id}") | 60 | @Path("{id}") |
61 | @Produces(MediaType.APPLICATION_JSON) | 61 | @Produces(MediaType.APPLICATION_JSON) |
62 | public Response deleteNetwork(@PathParam("id") String id) { | 62 | public Response deleteNetwork(@PathParam("id") String id) { |
63 | - log.debug(String.format(NETWORKS_MESSAGE, "delete")); | 63 | + log.trace(String.format(NETWORKS_MESSAGE, "delete")); |
64 | return Response.status(Response.Status.OK).build(); | 64 | return Response.status(Response.Status.OK).build(); |
65 | } | 65 | } |
66 | } | 66 | } | ... | ... |
... | @@ -63,7 +63,7 @@ public class NeutronMl2PortsWebResource extends AbstractWebResource { | ... | @@ -63,7 +63,7 @@ public class NeutronMl2PortsWebResource extends AbstractWebResource { |
63 | @Consumes(MediaType.APPLICATION_JSON) | 63 | @Consumes(MediaType.APPLICATION_JSON) |
64 | @Produces(MediaType.APPLICATION_JSON) | 64 | @Produces(MediaType.APPLICATION_JSON) |
65 | public Response createPorts(InputStream input) { | 65 | public Response createPorts(InputStream input) { |
66 | - log.debug(String.format(PORTS_MESSAGE, "create")); | 66 | + log.trace(String.format(PORTS_MESSAGE, "create")); |
67 | return Response.status(Response.Status.OK).build(); | 67 | return Response.status(Response.Status.OK).build(); |
68 | } | 68 | } |
69 | 69 | ||
... | @@ -110,7 +110,7 @@ public class NeutronMl2PortsWebResource extends AbstractWebResource { | ... | @@ -110,7 +110,7 @@ public class NeutronMl2PortsWebResource extends AbstractWebResource { |
110 | @DELETE | 110 | @DELETE |
111 | @Produces(MediaType.APPLICATION_JSON) | 111 | @Produces(MediaType.APPLICATION_JSON) |
112 | public Response deletePorts(@PathParam("id") String id) { | 112 | public Response deletePorts(@PathParam("id") String id) { |
113 | - log.debug(String.format(PORTS_MESSAGE, "delete")); | 113 | + log.trace(String.format(PORTS_MESSAGE, "delete")); |
114 | return Response.status(Response.Status.OK).build(); | 114 | return Response.status(Response.Status.OK).build(); |
115 | } | 115 | } |
116 | } | 116 | } | ... | ... |
... | @@ -43,7 +43,7 @@ public class NeutronMl2SubnetsWebResource extends AbstractWebResource { | ... | @@ -43,7 +43,7 @@ public class NeutronMl2SubnetsWebResource extends AbstractWebResource { |
43 | @Consumes(MediaType.APPLICATION_JSON) | 43 | @Consumes(MediaType.APPLICATION_JSON) |
44 | @Produces(MediaType.APPLICATION_JSON) | 44 | @Produces(MediaType.APPLICATION_JSON) |
45 | public Response createSubnet(InputStream input) { | 45 | public Response createSubnet(InputStream input) { |
46 | - log.debug(String.format(SUBNETS_MESSAGE, "create")); | 46 | + log.trace(String.format(SUBNETS_MESSAGE, "create")); |
47 | return Response.status(Response.Status.OK).build(); | 47 | return Response.status(Response.Status.OK).build(); |
48 | } | 48 | } |
49 | 49 | ||
... | @@ -53,7 +53,7 @@ public class NeutronMl2SubnetsWebResource extends AbstractWebResource { | ... | @@ -53,7 +53,7 @@ public class NeutronMl2SubnetsWebResource extends AbstractWebResource { |
53 | @Produces(MediaType.APPLICATION_JSON) | 53 | @Produces(MediaType.APPLICATION_JSON) |
54 | @Consumes(MediaType.APPLICATION_JSON) | 54 | @Consumes(MediaType.APPLICATION_JSON) |
55 | public Response updateSubnet(@PathParam("id") String id, InputStream input) { | 55 | public Response updateSubnet(@PathParam("id") String id, InputStream input) { |
56 | - log.debug(String.format(SUBNETS_MESSAGE, "update")); | 56 | + log.trace(String.format(SUBNETS_MESSAGE, "update")); |
57 | return Response.status(Response.Status.OK).build(); | 57 | return Response.status(Response.Status.OK).build(); |
58 | 58 | ||
59 | } | 59 | } |
... | @@ -62,7 +62,7 @@ public class NeutronMl2SubnetsWebResource extends AbstractWebResource { | ... | @@ -62,7 +62,7 @@ public class NeutronMl2SubnetsWebResource extends AbstractWebResource { |
62 | @Path("{id}") | 62 | @Path("{id}") |
63 | @Produces(MediaType.APPLICATION_JSON) | 63 | @Produces(MediaType.APPLICATION_JSON) |
64 | public Response deleteSubnet(@PathParam("id") String id) { | 64 | public Response deleteSubnet(@PathParam("id") String id) { |
65 | - log.debug(String.format(SUBNETS_MESSAGE, "delete")); | 65 | + log.trace(String.format(SUBNETS_MESSAGE, "delete")); |
66 | return Response.status(Response.Status.OK).build(); | 66 | return Response.status(Response.Status.OK).build(); |
67 | } | 67 | } |
68 | } | 68 | } | ... | ... |
-
Please register or login to post a comment