You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tamaya.apache.org by an...@apache.org on 2015/12/20 11:54:11 UTC
[2/2] incubator-tamaya git commit: Adapted comments to changes in
events module.
Adapted comments to changes in events module.
Project: http://git-wip-us.apache.org/repos/asf/incubator-tamaya/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-tamaya/commit/cb08b1e4
Tree: http://git-wip-us.apache.org/repos/asf/incubator-tamaya/tree/cb08b1e4
Diff: http://git-wip-us.apache.org/repos/asf/incubator-tamaya/diff/cb08b1e4
Branch: refs/heads/master
Commit: cb08b1e4338059dca5072c5a1715f5534a10590a
Parents: ef44f42
Author: anatole <an...@apache.org>
Authored: Sun Dec 20 11:54:04 2015 +0100
Committer: anatole <an...@apache.org>
Committed: Sun Dec 20 11:54:04 2015 +0100
----------------------------------------------------------------------
src/site/asciidoc/extensions/mod_events.adoc | 233 +++++++++++++---------
1 file changed, 134 insertions(+), 99 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/cb08b1e4/src/site/asciidoc/extensions/mod_events.adoc
----------------------------------------------------------------------
diff --git a/src/site/asciidoc/extensions/mod_events.adoc b/src/site/asciidoc/extensions/mod_events.adoc
index 237b47c..ffed04a 100644
--- a/src/site/asciidoc/extensions/mod_events.adoc
+++ b/src/site/asciidoc/extensions/mod_events.adoc
@@ -75,30 +75,24 @@ for event handling and observation:
[source,java]
.ConfigEvent
--------------------------------------------
-public final class ConfigEvent {
-
- public ConfigEvent() {
- }
-
- public static void addListener(ConfigEventListener<?> l);
- public static void removeListener(ConfigEventListener<?> l);
- public static void fireEvent(Object event);
- public static <T> void fireEvent(T event, Class<T> eventType);
+public final interface ConfigEvent<T> {
+ Class<T> getResourceType();
+ T getResource();
+ String getVersion();
+ long getTimestamp();
}
// @FunctionalInterface
-public interface ConfigEventListener<T> {
- /**
- * Called if an event occurred.
- * @param event the event, not null.
- */
- void onConfigEvent(T event);
+public interface ConfigEventListener {
+
+ void onConfigEvent(ConfigEvent<?> event);
}
--------------------------------------------
-This mechanism can now be used to propagate configuration changes to all interested stakeholders. The next sections
+This mechanism can now be used to propagate configuration changes to all interested stakeholders. Hereby the payloed
+can be basically arbitrary as long as it implements the +ConfigEvent+ interface. The next sections
give more details on the the provided event implementations and abstractions that are used to implement such
features.
@@ -123,24 +117,34 @@ public enum ChangeType {
}
-------------------------------------------------------
-This enum type is used within the +ConfigurationChange+ class:
+This enum type is used within the +ConfigurationChange+ class, which implements the event sent for a changed
++Configuration+:
[source,java]
-------------------------------------------------------
-public final class ConfigurationChange implements Serializable{
+public final class ConfigurationChange implements ConfigEvent<Configuration>, Serializable{
public static ConfigurationChange emptyChangeSet(Configuration configuration);
- public Configuration getConfiguration();
-
+ @Override
+ public Configuration getResource();
+ @Override
+ public Class<Configuration> getResourceType();
+ @Override
public String getVersion();
+ @Override
+ public long getTimestamp();
+ @Override
public long getTimestamp();
- public Collection<PropertyChangeEvent> getEvents();
+ // Event specific methods
+
+ public Collection<PropertyChangeEvent> getChanges();
public int getRemovedSize();
public int getAddedSize();
public int getUpdatedSize();
+ public boolean isKeyAffected(String key);
public boolean isRemoved(String key);
public boolean isAdded(String key);
public boolean isUpdated(String key);
@@ -184,9 +188,11 @@ public final class MyConfigChangeListener implements ConfigChangeListener<Config
private Configuration config = ConfigurationProvider.getConfiguration();
- public void onConfigEvent(ConfigurationChange event){
- if(event.getConfiguration()==config){
- // do something
+ public void onConfigEvent(ConfigEvent<?> event){
+ if(event.getResourceTspe()==Configuration.class){
+ if(event.getConfiguration()==config){
+ // do something
+ }
}
}
@@ -195,16 +201,18 @@ public final class MyConfigChangeListener implements ConfigChangeListener<Config
You can *register* your implementation in 2 ways:
-. Manually by calling +ConfigEvent.addListener(new MyConfigChangeListener())+
+. Manually by calling +ConfigEventManager.addListener(new MyConfigChangeListener())+
. Automatically by registering your listener using the +ServiceLoader+ under
- +META-INF/services/org.apache.tamaya.ConfigEventListener+
+ +META-INF/services/org.apache.tamaya.events.ConfigEventListener+
+
=== Modelling PropertySource Changes
Beside that a whole configuration changes, also +PropertySource+ instance can change, e.g. by a configuration file
-edited on the fly. This is similarly to +ConfigurationChange+ reflected by the classes +PropertySourceChange,
+edited on the fly. This is similarly to a +ConfigurationChange+ reflected by the classes +PropertySourceChange,
PropertySourceChangeBuilder+.
+
=== Modelling Configuration Context Changes
The +ConfigurationContext+ models the container that manages all subcomponents that are used to define and
@@ -213,14 +221,21 @@ file folder, the +ConfigurationContext+ may change, so a corresponding +Configur
defined:
[source,java]
-.Implementing a ConfigChangeListener
-------------------------------------------------------
-public final class ConfigurationContextChange implements Serializable{
+public final class ConfigurationContextChange implements ConfigEvent<ConfigurationContext>, Serializable{
public static ConfigurationContextChange emptyChangeSet();
+ @Override
+ public ConfigurationContext getResource();
+ @Override
+ public Class<ConfigurationContext> getResourceType();
+ @Override
public String getVersion();
+ @Override
public long getTimestamp();
+
+ // specific methods
public Collection<PropertySourceChange> getPropertySourceChanges();
public Collection<PropertySourceChange> getPropertySourceUpdates();
public Collection<PropertySource> getRemovedPropertySources();
@@ -234,40 +249,53 @@ public final class ConfigurationContextChange implements Serializable{
Similar to the +ConfigurationChange+ class you also must use a +ConfigurationContextChangeBuilder+ to create instances
of +ConfigurationContextChange+.
-=== Modelling of an observing PropertySourceProvider.
+=== The ConfigEventManager Singleton
-In Tamaya configuration data is provided by instances of +PropertySource+, which in case of a configuration directory
-may be provided by an implementation of +PropertySourceProvider+. The events module provides a base provider
-implementation that
+Main entry point of the events module is the +ConfigEventManager+ singleton class, which provides static accessor
+methods to the extension's functionality:
-* observes all changes in a +Path+
-* tries to reevaluate corresponding resources based on the +ConfigurationFormats+ supported.
-* it creates an instance of +ConfigurationContextChange+ reflecting the changed +ConfigurationContext+ and triggers
- this event by calling +ConfigEvent.fireEvent(contextChange);+.
+[source,java]
+-------------------------------------------------------
+public final class ConfigEventManager {
-Additionally this module registers an instance of +ConfigEventListener<ConfigurationContextChange+>+, which listenes to
-these events. If such an event is triggered the listener tries to apply the changes by
+ private ConfigEventManager() {}
-. accessing the current +Configuration+ and its +ConfigurationContext+
-. checking if the event is affecting the current +ConfigurationContext+.
-. in the case the current context is affected, based on the current +ConfigurationContext+ a new context is created,
- whereas
- .. all +PropertySources+ provided by this provider implementation type are removed.
- .. the new +PropertySources+ loaded are added.
-. Finally the listener tries to apply the new +ConfigurationContext+ by calling the corresponding API methods of the
- +ConfigurationProvider+:
+ public static void addListener(ConfigEventListener l);
+ public static <T extends ConfigEvent> void addListener(ConfigEventListener l, Class<T> eventType);
+ public static void removeListener(ConfigEventListener l);
+ public static <T extends ConfigEvent> void removeListener(ConfigEventListener l, Class<T> eventType);
+ public static <T extends ConfigEvent>
+ Collection<? extends ConfigEventListener> getListeners();
+ public static <T extends ConfigEvent>
+ Collection<? extends ConfigEventListener> getListeners(Class<T> type);
+
+ public static <T> void fireEvent(ConfigEvent<?> event);
+ public static <T> void fireEventAsynch(ConfigEvent<?> event);
+
+ public static void enableChangeMonitoring(boolean enable);
+ public static boolean isChangeMonitoring();
+ public long getChangeMonitoringPeriod();
+ public void setChangeMonitoringPeriod(long millis);
-[source,java]
---------------------------------------------------
-try {
- ConfigurationProvider.setConfigurationContext(newContext);
-} catch (Exception e) {
- LOG.log(Level.INFO, "Failed to update the current ConfigurationContext due to config model changes", e);
}
---------------------------------------------------
+-------------------------------------------------------
-So if the current +ConfigurationProvider+ supports reloading of the current +ConfigurationContext+ this will apply the
-changes to the current +Configuration+. Otherwise the change is logged, but no further actions are taken.
+Looking at the methods listed above you see that there is more functionality worth to be mentioned:
+
+* +ConfigCHangeListeners+ can be registered either _globally_ or for a certain _event type_ only.
+* +ConfigEvents+ can be published within the same thread, or asynchronously.
+
+
+==== Monitoring of configuration changes
+
+The +ConfigEventManager+ also supports active monitoring of the current configuration to trigger corresponding change
+events to listeners registered. This feature is activated by default, but can be deactivated optionally. Nevertheless
+this feature is quite handy, since regularly polling your local +Configuration+ for any kind of changes is much
+more simpler than implementing change management on the +PropertySource+ level. With this feature you can easily
+implement also remote property source, which can deliver different configuration based on any changes done remotedly
+on another node in your system. If such a change happened Tamaya identifies it and triggers corresponding
++ConfigurationChange" events automatically. Similarly changes in a configuration tree, can actively identified and
+broadcasted to the targeting nodes automatically.
=== Freezing Configurations and PropertySources
@@ -296,62 +324,69 @@ Configuration frozenConfig = FrozenConfiguration.of(ConfigurationProvider.getCon
PropertySource frozenSource = FrozenPropertySource.of(ConfigurationProvider.getConfiguration());
--------------------------------------------------
-=== Observing and publishing configuration changes
-The event module allows to register and publish listeners for acting on configuration changes, e.g. of paramters with a
-private section name. The main entry point for this feature is the +ConfigurationObserver+ singleton:
+=== Modelling of an observing PropertySourceProvider.
-[source,java]
-.ConfigurationObserver
---------------------------------------------------
-public class ConfigurationObserver {
+In Tamaya configuration data is provided by instances of +PropertySource+, which in case of a configuration directory
+may be provided by an implementation of +PropertySourceProvider+, which produces one +PropertySource+ (at least) per
+file detected. The events module provides a base provider implementation that
+
+* observes all changes in a +Path+
+* tries to reevaluate corresponding resources based on the +ConfigurationFormats+ supported.
+* it creates an instance of +ConfigurationContextChange+ reflecting the changed +ConfigurationContext+ and triggers
+ this event by calling +ConfigEventManager.fireEvent(contextChange);+.
- private ConfigurationObserver() {}
+Additionally this module registers an instance of +ConfigEventListener<ConfigurationContextChange+>+, which listenes to
+these events. If such an event is triggered the listener tries to apply the changes by
+
+. accessing the current +Configuration+ and its +ConfigurationContext+
+. checking if the event is affecting the current +ConfigurationContext+.
+. in the case the current context is affected, based on the current +ConfigurationContext+ a new context is created,
+ whereas
+ .. all +PropertySources+ provided by this provider implementation type are removed.
+ .. the new +PropertySources+ loaded are added.
+. Finally the listener tries to apply the new +ConfigurationContext+ by calling the corresponding API methods of the
+ +ConfigurationProvider+:
- public static <T> void addObservedKeys(Collection<String> keys);
- public static <T> void addObservedKeys(String... keys);
- public static <T> void removeObservedKeys(Collection<String> keys);
- public static <T> void removeObservedKeys(String... keys);
- public static Set<String> getObservedKeys();
+[source,java]
+--------------------------------------------------
+try {
+ ConfigurationProvider.setConfigurationContext(newContext);
+} catch (Exception e) {
+ LOG.log(Level.INFO, "Failed to update the current ConfigurationContext due to config model changes", e);
+}
--------------------------------------------------
-This singleton allows to register keys on which listeners may listen to. Hereby, when changes have been identified
-that are observed, a +ConfigurationChange+ event is published on the event bus.
+So if the current +ConfigurationProvider+ supports reloading of the current +ConfigurationContext+ this will apply the
+changes to the current +Configuration+. Otherwise the change is logged, but no further actions are taken.
=== SPIs
-This component also defines an additional SPI, which allows to implement/adapt the mechanism how events are forwarded/
-received and how +ConfigEventListeners+ are managed. This enables to use external eventing systems, such as CDI,
-instead of the simple SE, fully synchronized implementation provided by default.
+This component also defines an additional SPI, which allows to adapt the implementation of the main +ConfigEventManager+
+singleton. This enables, for example, using external eventing systems, such as CDI, instead of the default provided
+simple SE based implementation. As normal, implementation mus be registered using the current +ServiceContext+
+active, by default using the Java +ServiceLoader+ mechanism.
[source,java]
.SPI: ConfigEventSpi
--------------------------------------------------
-public interface ConfigEventSpi {
- /**
- * Add a listener for observing events. References of this
- * component to the listeners must be managed as weak references.
- *
- * @param l the listener not null.
- */
- <T> void addListener(ConfigEventListener<T> l);
-
-
- /**
- * Removes a listener for observing events.
- *
- * @param l the listener not null.
- */
- <T> void removeListener(ConfigEventListener<T> l);
-
- /**
- * Publishes an event to all interested listeners.
- *
- * @param event the event, not null.
- * @param eventType the event type.
- */
- <T> void fireEvent(T event, Class<T> eventType);
-
+public interface ConfigEventManagerSpi {
+
+ <T> void addListener(ConfigEventListener l);
+ <T extends ConfigEvent> void addListener(ConfigEventListener l, Class<T> eventType);
+ void removeListener(ConfigEventListener l);
+ <T extends ConfigEvent> void removeListener(ConfigEventListener l, Class<T> eventType);
+ Collection<? extends ConfigEventListener> getListeners();
+ Collection<? extends ConfigEventListener> getListeners(Class<? extends ConfigEvent> eventType);
+
+ void fireEvent(ConfigEvent<?> event);
+ void fireEventAsynch(ConfigEvent<?> event);
+
+ long getChangeMonitoringPeriod();
+ void setChangeMonitoringPeriod(long millis);
+ boolean isChangeMonitorActive();
+ void enableChangeMonitor(boolean enable);
}
--------------------------------------------------
+