Committed by
Gerrit Code Review
Passing current and previous config value in NetworkConfigEvent
Change-Id: I4ed16f17b5fc991594d1b83b6c0ffca7aa2130fa
Showing
3 changed files
with
122 additions
and
21 deletions
| ... | @@ -32,6 +32,7 @@ import java.util.Set; | ... | @@ -32,6 +32,7 @@ import java.util.Set; |
| 32 | import java.util.function.Function; | 32 | import java.util.function.Function; |
| 33 | 33 | ||
| 34 | import static com.google.common.base.Preconditions.checkNotNull; | 34 | import static com.google.common.base.Preconditions.checkNotNull; |
| 35 | +import static com.google.common.base.Preconditions.checkState; | ||
| 35 | 36 | ||
| 36 | /** | 37 | /** |
| 37 | * Base abstraction of a configuration facade for a specific subject. Derived | 38 | * Base abstraction of a configuration facade for a specific subject. Derived |
| ... | @@ -77,17 +78,17 @@ public abstract class Config<S> { | ... | @@ -77,17 +78,17 @@ public abstract class Config<S> { |
| 77 | * @param key configuration key | 78 | * @param key configuration key |
| 78 | * @param node JSON node where configuration data is stored | 79 | * @param node JSON node where configuration data is stored |
| 79 | * @param mapper JSON object mapper | 80 | * @param mapper JSON object mapper |
| 80 | - * @param delegate delegate context | 81 | + * @param delegate delegate context, or null for detached configs. |
| 81 | */ | 82 | */ |
| 82 | - public void init(S subject, String key, JsonNode node, ObjectMapper mapper, | 83 | + public final void init(S subject, String key, JsonNode node, ObjectMapper mapper, |
| 83 | ConfigApplyDelegate delegate) { | 84 | ConfigApplyDelegate delegate) { |
| 84 | - this.subject = checkNotNull(subject); | 85 | + this.subject = checkNotNull(subject, "Subject cannot be null"); |
| 85 | this.key = key; | 86 | this.key = key; |
| 86 | - this.node = checkNotNull(node); | 87 | + this.node = checkNotNull(node, "Node cannot be null"); |
| 87 | this.object = node instanceof ObjectNode ? (ObjectNode) node : null; | 88 | this.object = node instanceof ObjectNode ? (ObjectNode) node : null; |
| 88 | this.array = node instanceof ArrayNode ? (ArrayNode) node : null; | 89 | this.array = node instanceof ArrayNode ? (ArrayNode) node : null; |
| 89 | - this.mapper = checkNotNull(mapper); | 90 | + this.mapper = checkNotNull(mapper, "Mapper cannot be null"); |
| 90 | - this.delegate = checkNotNull(delegate); | 91 | + this.delegate = delegate; |
| 91 | } | 92 | } |
| 92 | 93 | ||
| 93 | /** | 94 | /** |
| ... | @@ -144,12 +145,14 @@ public abstract class Config<S> { | ... | @@ -144,12 +145,14 @@ public abstract class Config<S> { |
| 144 | 145 | ||
| 145 | /** | 146 | /** |
| 146 | * Applies any configuration changes made via this configuration. | 147 | * Applies any configuration changes made via this configuration. |
| 148 | + * | ||
| 149 | + * Not effective for detached configs. | ||
| 147 | */ | 150 | */ |
| 148 | public void apply() { | 151 | public void apply() { |
| 152 | + checkState(delegate != null, "Cannot apply detached config"); | ||
| 149 | delegate.onApply(this); | 153 | delegate.onApply(this); |
| 150 | } | 154 | } |
| 151 | 155 | ||
| 152 | - | ||
| 153 | // Miscellaneous helpers for interacting with JSON | 156 | // Miscellaneous helpers for interacting with JSON |
| 154 | 157 | ||
| 155 | /** | 158 | /** | ... | ... |
| ... | @@ -15,14 +15,21 @@ | ... | @@ -15,14 +15,21 @@ |
| 15 | */ | 15 | */ |
| 16 | package org.onosproject.net.config; | 16 | package org.onosproject.net.config; |
| 17 | 17 | ||
| 18 | +import org.joda.time.LocalDateTime; | ||
| 18 | import org.onosproject.event.AbstractEvent; | 19 | import org.onosproject.event.AbstractEvent; |
| 19 | 20 | ||
| 21 | +import java.util.Optional; | ||
| 22 | + | ||
| 23 | +import static com.google.common.base.MoreObjects.toStringHelper; | ||
| 24 | + | ||
| 20 | /** | 25 | /** |
| 21 | * Describes network configuration event. | 26 | * Describes network configuration event. |
| 22 | */ | 27 | */ |
| 23 | public class NetworkConfigEvent extends AbstractEvent<NetworkConfigEvent.Type, Object> { | 28 | public class NetworkConfigEvent extends AbstractEvent<NetworkConfigEvent.Type, Object> { |
| 24 | 29 | ||
| 25 | private final Class configClass; | 30 | private final Class configClass; |
| 31 | + private final Config config; | ||
| 32 | + private final Config prevConfig; | ||
| 26 | 33 | ||
| 27 | /** | 34 | /** |
| 28 | * Type of network configuration events. | 35 | * Type of network configuration events. |
| ... | @@ -65,6 +72,8 @@ public class NetworkConfigEvent extends AbstractEvent<NetworkConfigEvent.Type, O | ... | @@ -65,6 +72,8 @@ public class NetworkConfigEvent extends AbstractEvent<NetworkConfigEvent.Type, O |
| 65 | public NetworkConfigEvent(Type type, Object subject, Class configClass) { | 72 | public NetworkConfigEvent(Type type, Object subject, Class configClass) { |
| 66 | super(type, subject); | 73 | super(type, subject); |
| 67 | this.configClass = configClass; | 74 | this.configClass = configClass; |
| 75 | + this.config = null; | ||
| 76 | + this.prevConfig = null; | ||
| 68 | } | 77 | } |
| 69 | 78 | ||
| 70 | /** | 79 | /** |
| ... | @@ -78,6 +87,26 @@ public class NetworkConfigEvent extends AbstractEvent<NetworkConfigEvent.Type, O | ... | @@ -78,6 +87,26 @@ public class NetworkConfigEvent extends AbstractEvent<NetworkConfigEvent.Type, O |
| 78 | public NetworkConfigEvent(Type type, Object subject, Class configClass, long time) { | 87 | public NetworkConfigEvent(Type type, Object subject, Class configClass, long time) { |
| 79 | super(type, subject, time); | 88 | super(type, subject, time); |
| 80 | this.configClass = configClass; | 89 | this.configClass = configClass; |
| 90 | + this.config = null; | ||
| 91 | + this.prevConfig = null; | ||
| 92 | + } | ||
| 93 | + | ||
| 94 | + /** | ||
| 95 | + * Creates an event of a given type and for the specified subject, | ||
| 96 | + * previous config and time. | ||
| 97 | + * | ||
| 98 | + * @param type device event type | ||
| 99 | + * @param subject event subject | ||
| 100 | + * @param configClass configuration class | ||
| 101 | + * @param config current config | ||
| 102 | + * @param prevConfig previous config | ||
| 103 | + */ | ||
| 104 | + public NetworkConfigEvent(Type type, Object subject, Config config, | ||
| 105 | + Config prevConfig, Class configClass) { | ||
| 106 | + super(type, subject); | ||
| 107 | + this.configClass = configClass; | ||
| 108 | + this.config = config; | ||
| 109 | + this.prevConfig = prevConfig; | ||
| 81 | } | 110 | } |
| 82 | 111 | ||
| 83 | /** | 112 | /** |
| ... | @@ -89,4 +118,34 @@ public class NetworkConfigEvent extends AbstractEvent<NetworkConfigEvent.Type, O | ... | @@ -89,4 +118,34 @@ public class NetworkConfigEvent extends AbstractEvent<NetworkConfigEvent.Type, O |
| 89 | return configClass; | 118 | return configClass; |
| 90 | } | 119 | } |
| 91 | 120 | ||
| 121 | + /** | ||
| 122 | + * Returns current config. | ||
| 123 | + * | ||
| 124 | + * @return current config; value presents only when the type is | ||
| 125 | + * CONFIG_ADDED or CONFIG_UPDATED | ||
| 126 | + */ | ||
| 127 | + public Optional<Config> config() { | ||
| 128 | + return (config != null) ? Optional.of(config) : Optional.empty(); | ||
| 129 | + } | ||
| 130 | + | ||
| 131 | + /** | ||
| 132 | + * Returns previous config. | ||
| 133 | + * | ||
| 134 | + * @return previous config; value presents only when the type is | ||
| 135 | + * CONFIG_UPDATED or CONFIG_REMOVED | ||
| 136 | + */ | ||
| 137 | + public Optional<Config> prevConfig() { | ||
| 138 | + return (prevConfig != null) ? Optional.of(prevConfig) : Optional.empty(); | ||
| 139 | + } | ||
| 140 | + | ||
| 141 | + @Override | ||
| 142 | + public String toString() { | ||
| 143 | + return toStringHelper(this) | ||
| 144 | + .add("time", new LocalDateTime(time())) | ||
| 145 | + .add("type", type()) | ||
| 146 | + .add("config", config()) | ||
| 147 | + .add("prevConfig", prevConfig()) | ||
| 148 | + .add("configClass", configClass()) | ||
| 149 | + .toString(); | ||
| 150 | + } | ||
| 92 | } | 151 | } | ... | ... |
| ... | @@ -267,6 +267,33 @@ public class DistributedNetworkConfigStore | ... | @@ -267,6 +267,33 @@ public class DistributedNetworkConfigStore |
| 267 | return null; | 267 | return null; |
| 268 | } | 268 | } |
| 269 | 269 | ||
| 270 | + /** | ||
| 271 | + * Produces a detached config from the specified subject, config class and | ||
| 272 | + * raw JSON. | ||
| 273 | + * | ||
| 274 | + * A detached config can no longer be applied. This should be used only for | ||
| 275 | + * passing the config object in the NetworkConfigEvent. | ||
| 276 | + * | ||
| 277 | + * @param subject config subject | ||
| 278 | + * @param configClass config class | ||
| 279 | + * @param json raw JSON data | ||
| 280 | + * @return config object or null of no factory found or if the specified | ||
| 281 | + * JSON is null | ||
| 282 | + */ | ||
| 283 | + @SuppressWarnings("unchecked") | ||
| 284 | + private Config createDetachedConfig(Object subject, | ||
| 285 | + Class configClass, JsonNode json) { | ||
| 286 | + if (json != null) { | ||
| 287 | + ConfigFactory factory = factoriesByConfig.get(configClass.getName()); | ||
| 288 | + if (factory != null) { | ||
| 289 | + Config config = factory.createConfig(); | ||
| 290 | + config.init(subject, factory.configKey(), json, mapper, null); | ||
| 291 | + return config; | ||
| 292 | + } | ||
| 293 | + } | ||
| 294 | + return null; | ||
| 295 | + } | ||
| 296 | + | ||
| 270 | 297 | ||
| 271 | // Auxiliary delegate to receive notifications about changes applied to | 298 | // Auxiliary delegate to receive notifications about changes applied to |
| 272 | // the network configuration - by the apps. | 299 | // the network configuration - by the apps. |
| ... | @@ -336,23 +363,35 @@ public class DistributedNetworkConfigStore | ... | @@ -336,23 +363,35 @@ public class DistributedNetworkConfigStore |
| 336 | return; | 363 | return; |
| 337 | } | 364 | } |
| 338 | 365 | ||
| 339 | - NetworkConfigEvent.Type type; | ||
| 340 | - switch (event.type()) { | ||
| 341 | - case INSERT: | ||
| 342 | - type = CONFIG_ADDED; | ||
| 343 | - break; | ||
| 344 | - case UPDATE: | ||
| 345 | - type = CONFIG_UPDATED; | ||
| 346 | - break; | ||
| 347 | - case REMOVE: | ||
| 348 | - default: | ||
| 349 | - type = CONFIG_REMOVED; | ||
| 350 | - break; | ||
| 351 | - } | ||
| 352 | ConfigFactory factory = factoriesByConfig.get(event.key().configClass); | 366 | ConfigFactory factory = factoriesByConfig.get(event.key().configClass); |
| 353 | if (factory != null) { | 367 | if (factory != null) { |
| 368 | + Object subject = event.key().subject; | ||
| 369 | + Class configClass = factory.configClass(); | ||
| 370 | + Versioned<JsonNode> newValue = event.newValue(); | ||
| 371 | + Versioned<JsonNode> oldValue = event.oldValue(); | ||
| 372 | + | ||
| 373 | + Config config = (newValue != null) ? | ||
| 374 | + createDetachedConfig(subject, configClass, newValue.value()) : | ||
| 375 | + null; | ||
| 376 | + Config prevConfig = (oldValue != null) ? | ||
| 377 | + createDetachedConfig(subject, configClass, oldValue.value()) : | ||
| 378 | + null; | ||
| 379 | + | ||
| 380 | + NetworkConfigEvent.Type type; | ||
| 381 | + switch (event.type()) { | ||
| 382 | + case INSERT: | ||
| 383 | + type = CONFIG_ADDED; | ||
| 384 | + break; | ||
| 385 | + case UPDATE: | ||
| 386 | + type = CONFIG_UPDATED; | ||
| 387 | + break; | ||
| 388 | + case REMOVE: | ||
| 389 | + default: | ||
| 390 | + type = CONFIG_REMOVED; | ||
| 391 | + break; | ||
| 392 | + } | ||
| 354 | notifyDelegate(new NetworkConfigEvent(type, event.key().subject, | 393 | notifyDelegate(new NetworkConfigEvent(type, event.key().subject, |
| 355 | - factory.configClass())); | 394 | + config, prevConfig, factory.configClass())); |
| 356 | } | 395 | } |
| 357 | } | 396 | } |
| 358 | } | 397 | } | ... | ... |
-
Please register or login to post a comment