Committed by
Gerrit Code Review
Link config enhancements:
o Links can be injected using configs o fix for AllowedEntity check on links o config for link durability o Link operator methods for creating Link descriptions Change-Id: I8a1fabc688a2e7eeb579feced451a6c1ba7e3232
Showing
4 changed files
with
132 additions
and
23 deletions
| ... | @@ -17,6 +17,7 @@ package org.onosproject.net.config.basics; | ... | @@ -17,6 +17,7 @@ package org.onosproject.net.config.basics; |
| 17 | 17 | ||
| 18 | import org.onosproject.net.Link; | 18 | import org.onosproject.net.Link; |
| 19 | import org.onosproject.net.LinkKey; | 19 | import org.onosproject.net.LinkKey; |
| 20 | +import com.fasterxml.jackson.databind.JsonNode; | ||
| 20 | 21 | ||
| 21 | import java.time.Duration; | 22 | import java.time.Duration; |
| 22 | 23 | ||
| ... | @@ -28,6 +29,7 @@ public class BasicLinkConfig extends AllowedEntityConfig<LinkKey> { | ... | @@ -28,6 +29,7 @@ public class BasicLinkConfig extends AllowedEntityConfig<LinkKey> { |
| 28 | public static final String TYPE = "type"; | 29 | public static final String TYPE = "type"; |
| 29 | public static final String LATENCY = "latency"; | 30 | public static final String LATENCY = "latency"; |
| 30 | public static final String BANDWIDTH = "bandwidth"; | 31 | public static final String BANDWIDTH = "bandwidth"; |
| 32 | + public static final String IS_DURABLE = "durable"; | ||
| 31 | 33 | ||
| 32 | /** | 34 | /** |
| 33 | * Returns the link type. | 35 | * Returns the link type. |
| ... | @@ -87,4 +89,26 @@ public class BasicLinkConfig extends AllowedEntityConfig<LinkKey> { | ... | @@ -87,4 +89,26 @@ public class BasicLinkConfig extends AllowedEntityConfig<LinkKey> { |
| 87 | return (BasicLinkConfig) setOrClear(BANDWIDTH, bandwidth); | 89 | return (BasicLinkConfig) setOrClear(BANDWIDTH, bandwidth); |
| 88 | } | 90 | } |
| 89 | 91 | ||
| 92 | + /** | ||
| 93 | + * Returns if link is durable in the network model or not. | ||
| 94 | + * | ||
| 95 | + * @return true for durable, false otherwise | ||
| 96 | + */ | ||
| 97 | + public Boolean isDurable() { | ||
| 98 | + JsonNode res = object.path(IS_DURABLE); | ||
| 99 | + if (res.isMissingNode()) { | ||
| 100 | + return null; | ||
| 101 | + } | ||
| 102 | + return res.asBoolean(); | ||
| 103 | + } | ||
| 104 | + | ||
| 105 | + /** | ||
| 106 | + * Sets durability for this link. | ||
| 107 | + * | ||
| 108 | + * @param isDurable true for durable, false otherwise | ||
| 109 | + * @return this BasicLinkConfig | ||
| 110 | + */ | ||
| 111 | + public BasicLinkConfig isDurable(Boolean isDurable) { | ||
| 112 | + return (BasicLinkConfig) setOrClear(IS_DURABLE, isDurable); | ||
| 113 | + } | ||
| 90 | } | 114 | } | ... | ... |
| ... | @@ -16,12 +16,14 @@ | ... | @@ -16,12 +16,14 @@ |
| 16 | package org.onosproject.net.link.impl; | 16 | package org.onosproject.net.link.impl; |
| 17 | 17 | ||
| 18 | import static org.slf4j.LoggerFactory.getLogger; | 18 | import static org.slf4j.LoggerFactory.getLogger; |
| 19 | +import static com.google.common.base.Preconditions.checkNotNull; | ||
| 19 | 20 | ||
| 20 | import java.time.Duration; | 21 | import java.time.Duration; |
| 21 | 22 | ||
| 22 | import org.onosproject.net.AnnotationKeys; | 23 | import org.onosproject.net.AnnotationKeys; |
| 23 | import org.onosproject.net.config.ConfigOperator; | 24 | import org.onosproject.net.config.ConfigOperator; |
| 24 | import org.onosproject.net.config.basics.BasicLinkConfig; | 25 | import org.onosproject.net.config.basics.BasicLinkConfig; |
| 26 | +import org.onosproject.net.ConnectPoint; | ||
| 25 | import org.onosproject.net.DefaultAnnotations; | 27 | import org.onosproject.net.DefaultAnnotations; |
| 26 | import org.onosproject.net.Link; | 28 | import org.onosproject.net.Link; |
| 27 | import org.onosproject.net.SparseAnnotations; | 29 | import org.onosproject.net.SparseAnnotations; |
| ... | @@ -81,6 +83,46 @@ public final class BasicLinkOperator implements ConfigOperator { | ... | @@ -81,6 +83,46 @@ public final class BasicLinkOperator implements ConfigOperator { |
| 81 | if (cfg.bandwidth() != DEF_BANDWIDTH) { | 83 | if (cfg.bandwidth() != DEF_BANDWIDTH) { |
| 82 | b.set(AnnotationKeys.BANDWIDTH, String.valueOf(cfg.bandwidth())); | 84 | b.set(AnnotationKeys.BANDWIDTH, String.valueOf(cfg.bandwidth())); |
| 83 | } | 85 | } |
| 86 | + if (cfg.isDurable() != null) { | ||
| 87 | + b.set(AnnotationKeys.DURABLE, String.valueOf(cfg.isDurable())); | ||
| 88 | + } | ||
| 84 | return DefaultAnnotations.union(an, b.build()); | 89 | return DefaultAnnotations.union(an, b.build()); |
| 85 | } | 90 | } |
| 91 | + | ||
| 92 | + /** | ||
| 93 | + * Generates a link description from a link description entity. The endpoints | ||
| 94 | + * must be specified to indicate directionality. | ||
| 95 | + * | ||
| 96 | + * @param src the source ConnectPoint | ||
| 97 | + * @param dst the destination ConnectPoint | ||
| 98 | + * @param link the link config entity | ||
| 99 | + * @return a linkDescription based on the config | ||
| 100 | + */ | ||
| 101 | + public static LinkDescription descriptionOf( | ||
| 102 | + ConnectPoint src, ConnectPoint dst, Link link) { | ||
| 103 | + checkNotNull(src, "Must supply a source endpoint"); | ||
| 104 | + checkNotNull(dst, "Must supply a destination endpoint"); | ||
| 105 | + checkNotNull(link, "Must supply a link"); | ||
| 106 | + return new DefaultLinkDescription( | ||
| 107 | + src, dst, link.type(), (SparseAnnotations) link.annotations()); | ||
| 108 | + } | ||
| 109 | + | ||
| 110 | + /** | ||
| 111 | + * Generates a link description from a link config entity. This is for | ||
| 112 | + * links that cannot be discovered and has to be injected. The endpoints | ||
| 113 | + * must be specified to indicate directionality. | ||
| 114 | + * | ||
| 115 | + * @param src the source ConnectPoint | ||
| 116 | + * @param dst the destination ConnectPoint | ||
| 117 | + * @param link the link config entity | ||
| 118 | + * @return a linkDescription based on the config | ||
| 119 | + */ | ||
| 120 | + public static LinkDescription descriptionOf( | ||
| 121 | + ConnectPoint src, ConnectPoint dst, BasicLinkConfig link) { | ||
| 122 | + checkNotNull(src, "Must supply a source endpoint"); | ||
| 123 | + checkNotNull(dst, "Must supply a destination endpoint"); | ||
| 124 | + checkNotNull(link, "Must supply a link config"); | ||
| 125 | + return new DefaultLinkDescription( | ||
| 126 | + src, dst, link.type(), combine(link, DefaultAnnotations.EMPTY)); | ||
| 127 | + } | ||
| 86 | } | 128 | } | ... | ... |
| ... | @@ -18,6 +18,7 @@ package org.onosproject.net.link.impl; | ... | @@ -18,6 +18,7 @@ package org.onosproject.net.link.impl; |
| 18 | import com.google.common.base.Predicate; | 18 | import com.google.common.base.Predicate; |
| 19 | import com.google.common.collect.FluentIterable; | 19 | import com.google.common.collect.FluentIterable; |
| 20 | import com.google.common.collect.Sets; | 20 | import com.google.common.collect.Sets; |
| 21 | + | ||
| 21 | import org.apache.felix.scr.annotations.Activate; | 22 | import org.apache.felix.scr.annotations.Activate; |
| 22 | import org.apache.felix.scr.annotations.Component; | 23 | import org.apache.felix.scr.annotations.Component; |
| 23 | import org.apache.felix.scr.annotations.Deactivate; | 24 | import org.apache.felix.scr.annotations.Deactivate; |
| ... | @@ -25,6 +26,7 @@ import org.apache.felix.scr.annotations.Reference; | ... | @@ -25,6 +26,7 @@ import org.apache.felix.scr.annotations.Reference; |
| 25 | import org.apache.felix.scr.annotations.ReferenceCardinality; | 26 | import org.apache.felix.scr.annotations.ReferenceCardinality; |
| 26 | import org.apache.felix.scr.annotations.Service; | 27 | import org.apache.felix.scr.annotations.Service; |
| 27 | import org.onosproject.net.provider.AbstractListenerProviderRegistry; | 28 | import org.onosproject.net.provider.AbstractListenerProviderRegistry; |
| 29 | +import org.onosproject.net.provider.ProviderId; | ||
| 28 | import org.onosproject.net.config.NetworkConfigEvent; | 30 | import org.onosproject.net.config.NetworkConfigEvent; |
| 29 | import org.onosproject.net.config.NetworkConfigListener; | 31 | import org.onosproject.net.config.NetworkConfigListener; |
| 30 | import org.onosproject.net.config.NetworkConfigService; | 32 | import org.onosproject.net.config.NetworkConfigService; |
| ... | @@ -54,7 +56,6 @@ import org.slf4j.Logger; | ... | @@ -54,7 +56,6 @@ import org.slf4j.Logger; |
| 54 | import java.util.Set; | 56 | import java.util.Set; |
| 55 | 57 | ||
| 56 | import static com.google.common.base.Preconditions.checkNotNull; | 58 | import static com.google.common.base.Preconditions.checkNotNull; |
| 57 | -import static com.google.common.base.Preconditions.checkState; | ||
| 58 | import static org.onosproject.net.LinkKey.linkKey; | 59 | import static org.onosproject.net.LinkKey.linkKey; |
| 59 | import static org.onosproject.security.AppGuard.checkPermission; | 60 | import static org.onosproject.security.AppGuard.checkPermission; |
| 60 | import static org.slf4j.LoggerFactory.getLogger; | 61 | import static org.slf4j.LoggerFactory.getLogger; |
| ... | @@ -207,6 +208,10 @@ public class LinkManager | ... | @@ -207,6 +208,10 @@ public class LinkManager |
| 207 | post(store.removeLink(src, dst)); | 208 | post(store.removeLink(src, dst)); |
| 208 | } | 209 | } |
| 209 | 210 | ||
| 211 | + private boolean isAllowed(BasicLinkConfig cfg) { | ||
| 212 | + return (cfg == null || cfg.isAllowed()); | ||
| 213 | + } | ||
| 214 | + | ||
| 210 | // Auxiliary interceptor for device remove events to prune links that | 215 | // Auxiliary interceptor for device remove events to prune links that |
| 211 | // are associated with the removed device or its port. | 216 | // are associated with the removed device or its port. |
| 212 | private class InternalDeviceListener implements DeviceListener { | 217 | private class InternalDeviceListener implements DeviceListener { |
| ... | @@ -240,11 +245,12 @@ public class LinkManager | ... | @@ -240,11 +245,12 @@ public class LinkManager |
| 240 | checkNotNull(linkDescription, LINK_DESC_NULL); | 245 | checkNotNull(linkDescription, LINK_DESC_NULL); |
| 241 | checkValidity(); | 246 | checkValidity(); |
| 242 | linkDescription = validateLink(linkDescription); | 247 | linkDescription = validateLink(linkDescription); |
| 243 | - LinkEvent event = store.createOrUpdateLink(provider().id(), | 248 | + if (linkDescription != null) { |
| 244 | - linkDescription); | 249 | + LinkEvent event = store.createOrUpdateLink(provider().id(), linkDescription); |
| 245 | - if (event != null) { | 250 | + if (event != null) { |
| 246 | - log.info("Link {} detected", linkDescription); | 251 | + log.info("Link {} detected", linkDescription); |
| 247 | - post(event); | 252 | + post(event); |
| 253 | + } | ||
| 248 | } | 254 | } |
| 249 | } | 255 | } |
| 250 | 256 | ||
| ... | @@ -258,11 +264,12 @@ public class LinkManager | ... | @@ -258,11 +264,12 @@ public class LinkManager |
| 258 | BasicLinkConfig cfgTwo = networkConfigService.getConfig(linkKey(linkDescription.dst(), | 264 | BasicLinkConfig cfgTwo = networkConfigService.getConfig(linkKey(linkDescription.dst(), |
| 259 | linkDescription.src()), | 265 | linkDescription.src()), |
| 260 | BasicLinkConfig.class); | 266 | BasicLinkConfig.class); |
| 261 | - | 267 | + if (isAllowed(cfg) && isAllowed(cfgTwo)) { |
| 262 | - checkState(cfg == null || cfg.isAllowed(), "Link " + linkDescription.toString() + " is not allowed"); | 268 | + return BasicLinkOperator.combine(cfg, linkDescription); |
| 263 | - checkState(cfgTwo == null || cfgTwo.isAllowed(), "Link " + linkDescription.toString() + " is not allowed"); | 269 | + } else { |
| 264 | - | 270 | + log.trace("Link " + linkDescription.toString() + " is not allowed"); |
| 265 | - return BasicLinkOperator.combine(cfg, linkDescription); | 271 | + return null; |
| 272 | + } | ||
| 266 | } | 273 | } |
| 267 | 274 | ||
| 268 | @Override | 275 | @Override |
| ... | @@ -324,20 +331,41 @@ public class LinkManager | ... | @@ -324,20 +331,41 @@ public class LinkManager |
| 324 | // listens for NetworkConfigEvents of type BasicLinkConfig and removes | 331 | // listens for NetworkConfigEvents of type BasicLinkConfig and removes |
| 325 | // links that the config does not allow | 332 | // links that the config does not allow |
| 326 | private class InternalNetworkConfigListener implements NetworkConfigListener { | 333 | private class InternalNetworkConfigListener implements NetworkConfigListener { |
| 334 | + | ||
| 335 | + @Override | ||
| 336 | + public boolean isRelevant(NetworkConfigEvent event) { | ||
| 337 | + return event.configClass().equals(BasicLinkConfig.class) | ||
| 338 | + && (event.type() == NetworkConfigEvent.Type.CONFIG_ADDED | ||
| 339 | + || event.type() == NetworkConfigEvent.Type.CONFIG_UPDATED); | ||
| 340 | + } | ||
| 341 | + | ||
| 327 | @Override | 342 | @Override |
| 328 | public void event(NetworkConfigEvent event) { | 343 | public void event(NetworkConfigEvent event) { |
| 329 | - if ((event.type() == NetworkConfigEvent.Type.CONFIG_ADDED || | 344 | + LinkKey lk = (LinkKey) event.subject(); |
| 330 | - event.type() == NetworkConfigEvent.Type.CONFIG_UPDATED) && | 345 | + BasicLinkConfig cfg = networkConfigService.getConfig(lk, BasicLinkConfig.class); |
| 331 | - event.configClass().equals(BasicLinkConfig.class)) { | 346 | + |
| 332 | - log.info("Detected Link network config event {}", event.type()); | 347 | + if (!isAllowed(cfg)) { |
| 333 | - LinkKey lk = (LinkKey) event.subject(); | 348 | + log.info("Kicking out links between {} and {}", lk.src(), lk.dst()); |
| 334 | - BasicLinkConfig cfg = networkConfigService.getConfig(lk, BasicLinkConfig.class); | 349 | + removeLink(lk.src(), lk.dst()); |
| 335 | - if (cfg != null && !cfg.isAllowed()) { | 350 | + removeLink(lk.dst(), lk.src()); |
| 336 | - log.info("Kicking out links between {} and {}", lk.src(), lk.dst()); | 351 | + return; |
| 337 | - removeLink(lk.src(), lk.dst()); | ||
| 338 | - removeLink(lk.dst(), lk.src()); | ||
| 339 | - } | ||
| 340 | } | 352 | } |
| 353 | + Link link = getLink(lk.src(), lk.dst()); | ||
| 354 | + LinkDescription fldesc; | ||
| 355 | + LinkDescription rldesc; | ||
| 356 | + if (link == null) { | ||
| 357 | + fldesc = BasicLinkOperator.descriptionOf(lk.src(), lk.dst(), cfg); | ||
| 358 | + rldesc = BasicLinkOperator.descriptionOf(lk.dst(), lk.src(), cfg); | ||
| 359 | + } else { | ||
| 360 | + fldesc = BasicLinkOperator.combine(cfg, | ||
| 361 | + BasicLinkOperator.descriptionOf(lk.src(), lk.dst(), link)); | ||
| 362 | + rldesc = BasicLinkOperator.combine(cfg, | ||
| 363 | + BasicLinkOperator.descriptionOf(lk.dst(), lk.src(), link)); | ||
| 364 | + } | ||
| 365 | + // XXX think of sane way to fetch the LinkProvider | ||
| 366 | + store.createOrUpdateLink(ProviderId.NONE, fldesc); | ||
| 367 | + store.createOrUpdateLink(ProviderId.NONE, rldesc); | ||
| 341 | } | 368 | } |
| 369 | + | ||
| 342 | } | 370 | } |
| 343 | } | 371 | } | ... | ... |
| ... | @@ -211,7 +211,10 @@ public class ECLinkStore | ... | @@ -211,7 +211,10 @@ public class ECLinkStore |
| 211 | // otherwise signal the actual master. | 211 | // otherwise signal the actual master. |
| 212 | if (clusterService.getLocalNode().id().equals(dstNodeId)) { | 212 | if (clusterService.getLocalNode().id().equals(dstNodeId)) { |
| 213 | LinkKey linkKey = linkKey(linkDescription.src(), linkDescription.dst()); | 213 | LinkKey linkKey = linkKey(linkDescription.src(), linkDescription.dst()); |
| 214 | - Provided<LinkKey> internalLinkKey = new Provided<>(linkKey, providerId); | 214 | + Provided<LinkKey> internalLinkKey = getProvided(linkKey, providerId); |
| 215 | + if (internalLinkKey == null) { | ||
| 216 | + return null; | ||
| 217 | + } | ||
| 215 | linkDescriptions.compute(internalLinkKey, (k, v) -> createOrUpdateLinkInternal(v , linkDescription)); | 218 | linkDescriptions.compute(internalLinkKey, (k, v) -> createOrUpdateLinkInternal(v , linkDescription)); |
| 216 | return refreshLinkCache(linkKey); | 219 | return refreshLinkCache(linkKey); |
| 217 | } else { | 220 | } else { |
| ... | @@ -226,6 +229,18 @@ public class ECLinkStore | ... | @@ -226,6 +229,18 @@ public class ECLinkStore |
| 226 | } | 229 | } |
| 227 | } | 230 | } |
| 228 | 231 | ||
| 232 | + private Provided<LinkKey> getProvided(LinkKey linkKey, ProviderId provId) { | ||
| 233 | + ProviderId bpid = getBaseProviderId(linkKey); | ||
| 234 | + if (provId == null) { | ||
| 235 | + // The LinkService didn't know who this LinkKey belongs to. | ||
| 236 | + // A fix is to either modify the getProvider() in LinkService classes | ||
| 237 | + // or expose the contents of linkDescriptions to the LinkService. | ||
| 238 | + return (bpid == null) ? null : new Provided<>(linkKey, bpid); | ||
| 239 | + } else { | ||
| 240 | + return new Provided<>(linkKey, provId); | ||
| 241 | + } | ||
| 242 | + } | ||
| 243 | + | ||
| 229 | private LinkDescription createOrUpdateLinkInternal(LinkDescription current, LinkDescription updated) { | 244 | private LinkDescription createOrUpdateLinkInternal(LinkDescription current, LinkDescription updated) { |
| 230 | if (current != null) { | 245 | if (current != null) { |
| 231 | // we only allow transition from INDIRECT -> DIRECT | 246 | // we only allow transition from INDIRECT -> DIRECT | ... | ... |
-
Please register or login to post a comment