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 2016/02/18 00:43:15 UTC

[7/8] incubator-tamaya git commit: Redesigned component slightly.

Redesigned component slightly.


Project: http://git-wip-us.apache.org/repos/asf/incubator-tamaya/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-tamaya/commit/a231ff05
Tree: http://git-wip-us.apache.org/repos/asf/incubator-tamaya/tree/a231ff05
Diff: http://git-wip-us.apache.org/repos/asf/incubator-tamaya/diff/a231ff05

Branch: refs/heads/master
Commit: a231ff05dfe5a5589f76fd7374d2cf492d26f4fb
Parents: 1547d4a
Author: anatole <an...@apache.org>
Authored: Thu Feb 18 00:41:01 2016 +0100
Committer: anatole <an...@apache.org>
Committed: Thu Feb 18 00:41:01 2016 +0100

----------------------------------------------------------------------
 .../mutableconfig/MutableConfiguration.java     |  76 ++++-----
 .../MutableConfigurationQuery.java              | 163 ++++++++++++-------
 .../DefaultConfigurationBackendSpi.java         |  14 +-
 .../spi/AbstractMutableConfiguration.java       |  91 ++---------
 .../MutableConfigurationBackendProviderSpi.java |   7 +-
 .../spi/MutableConfigurationBackendSpi.java     |   4 +-
 .../MutableConfigurationQueryTest.java          |  16 +-
 .../PropertiesFileConfigBackendTest.java        |  31 ++--
 .../asciidoc/extensions/mod_mutable_config.adoc |  74 +++++----
 9 files changed, 230 insertions(+), 246 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/a231ff05/modules/mutable-config/src/main/java/org/apache/tamaya/mutableconfig/MutableConfiguration.java
----------------------------------------------------------------------
diff --git a/modules/mutable-config/src/main/java/org/apache/tamaya/mutableconfig/MutableConfiguration.java b/modules/mutable-config/src/main/java/org/apache/tamaya/mutableconfig/MutableConfiguration.java
index fed3151..468c3cd 100644
--- a/modules/mutable-config/src/main/java/org/apache/tamaya/mutableconfig/MutableConfiguration.java
+++ b/modules/mutable-config/src/main/java/org/apache/tamaya/mutableconfig/MutableConfiguration.java
@@ -18,6 +18,8 @@
  */
 package org.apache.tamaya.mutableconfig;
 
+import org.apache.tamaya.Configuration;
+
 import java.net.URI;
 import java.util.Collection;
 import java.util.Map;
@@ -28,21 +30,16 @@ import java.util.Map;
  * Hereby not all configuration entries are necessarily mutable, since some entries may be read from non
  * mutable areas of configuration. Of course, it is always possible to add a mutable shadow layer on top of all
  * configuration to enable whatever changes applied. The exact management and storage persistence algorithm should be
- * transparent.<br>
- * As a consequence clients should first check, using the corresponding methods, if entries are to edited or removed
+ * transparent.
+ *
+ * As a consequence clients should first check, using the corresponding methods, if entries are to edited or
+ * removedProperties
  * actually are eligible for change/creation or removal.
  */
-public interface MutableConfiguration {
-
-    /**
-     * Get the unique id of this change request (UUID).
-     *
-     * @return the unique id of this change request (UUID).
-     */
-    String getRequestID();
+public interface MutableConfiguration extends Configuration {
 
     /**
-     * Identifies the configuration backends that participate in this request instance and which are
+     * Identifies the configuration backends that are targeted by this instance and which are
      * also responsible for writing back the changes applied.
      *
      * @return the backend URI, never null.
@@ -60,7 +57,7 @@ public interface MutableConfiguration {
 
     /**
      * Checks if a configuration key is removable. This also implies that it is writable, but there might be writable
-     * keys that cannot be removed.
+     * keys that cannot be removedProperties.
      *
      * @param keyExpression the keyExpression the key to be cheched for write access (including creation), not null.
      *                      Here this could also
@@ -70,7 +67,7 @@ public interface MutableConfiguration {
     boolean isRemovable(String keyExpression);
 
     /**
-     * Checks if any keys of the given type already exist in the backend. <b>NOTE:</b> there may be backends that
+     * Checks if any keys of the given type already exist in the write backend. <b>NOTE:</b> there may be backends that
      * are not able to support lookups with regular expressions. In most such cases you should pass the keys to
      * lookup explicitly.
      *
@@ -78,7 +75,7 @@ public interface MutableConfiguration {
      *                      also be a regular expression, such "as a.b.c.*".
      * @return true, if there is any key found matching the expression.
      */
-    boolean exists(String keyExpression);
+    boolean isExisting(String keyExpression);
 
     /**
      * Sets a property.
@@ -93,28 +90,32 @@ public interface MutableConfiguration {
     /**
      * Puts all given configuration entries. This method should check that all given properties are
      * basically removable, as defined by #isWritable. If any of the passed keys is not writable during this initial
-     * check, the operation should not perform any configuration changes and throw a {@link org.apache.tamaya.ConfigException}. If errors
-     * occur afterwards, when the properties are effectively written back to the backends, the errors should be
-     * collected and returned as part of the ConfigException payload. Nevertheless the operation should in that case
-     * remove all entries as far as possible and abort the writing operation.
+     * check, the operation should not perform any configuration changes and throw a
+     * {@link org.apache.tamaya.ConfigException}. If errors occur afterwards, when the properties are effectively
+     * written back to the backends, the errors should be collected and returned as part of the ConfigException
+     * payload. Nevertheless the operation should in that case remove all entries as far as possible and abort the
+     * writing operation.
      *
      * @param properties the properties tobe written, not null.
      * @return the config change request
-     * @throws org.apache.tamaya.ConfigException if any of the given properties could not be written, or the request is read-only.
+     * @throws org.apache.tamaya.ConfigException if any of the given properties could not be written, or the request
+     * is read-only.
      */
     MutableConfiguration putAll(Map<String, String> properties);
 
     /**
      * Removes all given configuration entries. This method should check that all given properties are
      * basically removable, as defined by #isRemovable. If any of the passed keys is not removable during this initial
-     * check, the operation should not perform any configuration changes and throw a {@link org.apache.tamaya.ConfigException}. If errors
+     * check, the operation should not perform any configuration changes and throw a
+     * {@link org.apache.tamaya.ConfigException}. If errors
      * occur afterwards, when the properties are effectively written back to the backends, the errors should be
      * collected and returned as part of the ConfigException payload. Nevertheless the operation should in that case
      * remove all entries as far as possible and abort the writing operation.
      *
-     * @param keys the property's keys to be removed, not null.
+     * @param keys the property's keys to be removedProperties, not null.
      * @return the config change request
-     * @throws org.apache.tamaya.ConfigException if any of the given keys could not be removed, or the request is read-only.
+     * @throws org.apache.tamaya.ConfigException if any of the given keys could not be removedProperties, or the
+     * request is read-only.
      */
     MutableConfiguration remove(Collection<String> keys);
 
@@ -126,39 +127,26 @@ public interface MutableConfiguration {
      * collected and returned as part of the ConfigException payload. Nevertheless the operation should in that case
      * remove all entries as far as possible and abort the writing operation.
      *
-     * @param keys the property's keys to be removed, not null.
+     * @param keys the property's keys to be removedProperties, not null.
      * @return the config change request
-     * @throws org.apache.tamaya.ConfigException if any of the given keys could not be removed, or the request is read-only.
+     * @throws org.apache.tamaya.ConfigException if any of the given keys could not be removedProperties, or the request is read-only.
      */
     MutableConfiguration remove(String... keys);
 
     /**
      * Commits the request. After a commit the change is not editable anymore. All changes applied will be written to
      * the corresponding configuration backend.
-     * " @throws ConfigException if the request already has been committed or cancelled, or the commit fails.
-     */
-    void commit();
-
-    /**
-     * Cancel the given request, leaving everything unchanged. Cancelled requests are read-only and can not be used
-     * for preparing/submitting any configuration changes.
      *
-     * @throws org.apache.tamaya.ConfigException if the request already has been committed or cancelled.
+     * NOTE that changes applied must not necessarily be visible in the current {@link Configuration} instance,
+     * since visibility of changes also depends on the ordinals set on the {@link org.apache.tamaya.spi.PropertySource}s
+     * configured.
+     * @throws org.apache.tamaya.ConfigException if the request already has been committed or cancelled, or the commit fails.
      */
-    void cancel();
+    void commit();
 
     /**
-     * Operation to check, if the current request is closed (either commited or cancelled). Closed requests are
-     * read-only and can not be used for preparing/submitting any configuration changes.
-     *
-     * @return true, if this instance is closed.
+     * Rollback any changes leaving everything unchanged. This will rollback all changes applied since the last commit.
      */
-    boolean isClosed();
+    void rollback();
 
-    /**
-     * Method to set the request id to be used.
-     * @param requestId the id to  be used, not null
-     * @throws IllegalStateException if the request is already closed.
-     */
-    void setRequestId(String requestId);
 }

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/a231ff05/modules/mutable-config/src/main/java/org/apache/tamaya/mutableconfig/MutableConfigurationQuery.java
----------------------------------------------------------------------
diff --git a/modules/mutable-config/src/main/java/org/apache/tamaya/mutableconfig/MutableConfigurationQuery.java b/modules/mutable-config/src/main/java/org/apache/tamaya/mutableconfig/MutableConfigurationQuery.java
index 7aaf2bf..31d6697 100644
--- a/modules/mutable-config/src/main/java/org/apache/tamaya/mutableconfig/MutableConfigurationQuery.java
+++ b/modules/mutable-config/src/main/java/org/apache/tamaya/mutableconfig/MutableConfigurationQuery.java
@@ -19,7 +19,13 @@
 package org.apache.tamaya.mutableconfig;
 
 import org.apache.tamaya.ConfigException;
-import org.apache.tamaya.mutableconfig.spi.ConfigChangeManagerSpi;
+import org.apache.tamaya.ConfigOperator;
+import org.apache.tamaya.ConfigQuery;
+import org.apache.tamaya.Configuration;
+import org.apache.tamaya.TypeLiteral;
+import org.apache.tamaya.mutableconfig.spi.AbstractMutableConfiguration;
+import org.apache.tamaya.mutableconfig.spi.MutableConfigurationBackendSpi;
+import org.apache.tamaya.mutableconfig.spi.MutableConfigurationBackendProviderSpi;
 import org.apache.tamaya.spi.ServiceContextManager;
 
 import java.net.URI;
@@ -31,16 +37,27 @@ import java.util.Collections;
 import java.util.List;
 import java.util.Map;
 import java.util.Objects;
-import java.util.UUID;
 
 
 /**
  * Accessor for creating {@link MutableConfiguration} instances to change and commit configuration.
  */
-public final class MutableConfigurationQuery {
+public final class MutableConfigurationQuery implements ConfigQuery<MutableConfiguration> {
+
+    /**
+     * URIs used by this query instance to identify the backends to use for write operations.
+     */
+    private List<MutableConfigurationBackendSpi> targets = new ArrayList<>();
 
     /** Singleton constructor. */
-    private MutableConfigurationQuery(){}
+    private MutableConfigurationQuery(List<MutableConfigurationBackendSpi> targets){
+        this.targets.addAll(targets);
+    }
+
+    @Override
+    public MutableConfiguration query(Configuration config) {
+        return new DefaultMutableConfiguration(config, targets);
+    }
 
     /**
      * Creates a new change request for the given configurationSource
@@ -52,13 +69,13 @@ public final class MutableConfigurationQuery {
      * @return a new ChangeRequest
      * @throws org.apache.tamaya.ConfigException if the given configurationSource cannot be edited.
      */
-    public static MutableConfiguration createChangeRequest(String... configurationTargets){
+    public static MutableConfigurationQuery of(String... configurationTargets){
         try {
             URI[] uris = new URI[configurationTargets.length];
             for (int i = 0; i < configurationTargets.length; i++) {
                 uris[i] = new URI(configurationTargets[i]);
             }
-            return createChangeRequest(uris);
+            return of(uris);
         } catch(URISyntaxException e){
             throw new ConfigException("Invalid URIs enocuntered in " + Arrays.toString(configurationTargets));
         }
@@ -74,15 +91,15 @@ public final class MutableConfigurationQuery {
      * @return a new ChangeRequest
      * @throws org.apache.tamaya.ConfigException if the given configurationSource cannot be edited.
      */
-    public static MutableConfiguration createChangeRequest(URI... configurationTargets){
+    public static MutableConfigurationQuery of(URI... configurationTargets){
         if(Objects.requireNonNull(configurationTargets).length==0){
             throw new IllegalArgumentException("At least one target URI is required.");
         }
-        List<MutableConfiguration> targets = new ArrayList<>();
-        for(ConfigChangeManagerSpi spi:ServiceContextManager.getServiceContext()
-                .getServices(ConfigChangeManagerSpi.class)){
+        List<MutableConfigurationBackendSpi> targets = new ArrayList<>();
+        for(MutableConfigurationBackendProviderSpi spi:ServiceContextManager.getServiceContext()
+                .getServices(MutableConfigurationBackendProviderSpi.class)){
             for(URI target:configurationTargets) {
-                MutableConfiguration req = spi.createChangeRequest(target);
+                MutableConfigurationBackendSpi req = spi.getBackend(target);
                 if (req != null) {
                     targets.add(req);
                 }
@@ -92,43 +109,36 @@ public final class MutableConfigurationQuery {
             throw new ConfigException("Not an editable configuration target for: " +
                     Arrays.toString(configurationTargets));
         }
-        if(targets.size()==1){
-            return targets.get(0);
-        }
-        return new CompoundConfigChangeRequest(targets);
+        return new MutableConfigurationQuery(targets);
     }
 
 
     /**
      * Compound request that contains internally multiple change requests. Changes are committed to all members.
      */
-    private static final class CompoundConfigChangeRequest implements MutableConfiguration {
+    private static final class DefaultMutableConfiguration extends AbstractMutableConfiguration
+            implements MutableConfiguration {
 
-        private final List<MutableConfiguration> targets;
-        private final List<URI> backendURIs = new ArrayList<>();
-        private String requestId = UUID.randomUUID().toString();
+        private final List<MutableConfigurationBackendSpi> targets;
+        private final Configuration config;
 
-        CompoundConfigChangeRequest(List<MutableConfiguration> targets){
-            this.targets = targets;
-            for(MutableConfiguration req:targets){
-                req.setRequestId(requestId);
-                backendURIs.addAll(req.getBackendURIs());
-            }
-        }
-
-        @Override
-        public String getRequestID() {
-            return requestId;
+        DefaultMutableConfiguration(Configuration config, List<MutableConfigurationBackendSpi> targets){
+            this.targets = Objects.requireNonNull(targets);
+            this.config = Objects.requireNonNull(config);
         }
 
         @Override
         public List<URI> getBackendURIs() {
-            return Collections.unmodifiableList(backendURIs);
+            List<URI> result = new ArrayList<>(getBackendURIs().size());
+            for(MutableConfigurationBackendSpi backend: targets){
+                result.add(backend.getBackendURI());
+            }
+            return Collections.unmodifiableList(result);
         }
 
         @Override
         public boolean isWritable(String keyExpression) {
-            for(MutableConfiguration req:targets){
+            for(MutableConfigurationBackendSpi req:targets){
                 if(req.isWritable(keyExpression)){
                     return true;
                 }
@@ -138,7 +148,7 @@ public final class MutableConfigurationQuery {
 
         @Override
         public boolean isRemovable(String keyExpression) {
-            for(MutableConfiguration req:targets){
+            for(MutableConfigurationBackendSpi req:targets){
                 if(req.isRemovable(keyExpression)){
                     return true;
                 }
@@ -147,9 +157,9 @@ public final class MutableConfigurationQuery {
         }
 
         @Override
-        public boolean exists(String keyExpression) {
-            for(MutableConfiguration req:targets){
-                if(req.exists(keyExpression)){
+        public boolean isExisting(String keyExpression) {
+            for(MutableConfigurationBackendSpi req:targets){
+                if(req.isExisting(keyExpression)){
                     return true;
                 }
             }
@@ -158,80 +168,111 @@ public final class MutableConfigurationQuery {
 
         @Override
         public MutableConfiguration put(String key, String value) {
-            for(MutableConfiguration req:targets){
+            for(MutableConfigurationBackendSpi req:targets){
                 if(req.isWritable(key)){
                     req.put(key, value);
                 }
             }
-            return this;
+            return super.put(key, value);
         }
 
         @Override
         public MutableConfiguration putAll(Map<String, String> properties) {
-            for(MutableConfiguration req:targets){
+            for(MutableConfigurationBackendSpi req:targets){
                 for(Map.Entry<String,String> en:properties.entrySet()) {
                     if (req.isWritable(en.getKey())) {
                         req.put(en.getKey(), en.getValue());
                     }
                 }
             }
-            return this;
+            return super.putAll(properties);
         }
 
         @Override
         public MutableConfiguration remove(String... keys) {
-            for(MutableConfiguration req:targets){
+            for(MutableConfigurationBackendSpi req:targets){
                 for(String key:keys){
                     if (req.isRemovable(key)) {
                         req.remove(key);
                     }
                 }
             }
-            return this;
+            return super.remove(keys);
         }
 
         @Override
         public MutableConfiguration remove(Collection<String> keys) {
-            for(MutableConfiguration req:targets){
+            for(MutableConfigurationBackendSpi req:targets){
                 for(String key:keys){
                     if (req.isRemovable(key)) {
                         req.remove(key);
                     }
                 }
             }
-            return this;
+            return super.remove(keys);
         }
 
         @Override
-        public void commit() {
-            for(MutableConfiguration req:targets){
+        protected void commitInternal() {
+            for(MutableConfigurationBackendSpi req:targets){
                 req.commit();
             }
         }
 
         @Override
-        public void rollback() {
-            for(MutableConfiguration req:targets){
-                req.rollback();
-            }
+        public String get(String key) {
+            return config.get(key);
         }
 
         @Override
-        public boolean isClosed() {
-            for(MutableConfiguration req:targets){
-                if(req.isClosed()){
-                    return true;
-                }
-            }
-            return false;
+        public String getOrDefault(String key, String defaultValue) {
+            return config.getOrDefault(key, defaultValue);
+        }
+
+        @Override
+        public <T> T getOrDefault(String key, Class<T> type, T defaultValue) {
+            return config.getOrDefault(key, type, defaultValue);
+        }
+
+        @Override
+        public <T> T get(String key, Class<T> type) {
+            return config.get(key, type);
+        }
+
+        @Override
+        public <T> T get(String key, TypeLiteral<T> type) {
+            return config.get(key, type);
+        }
+
+        @Override
+        public <T> T getOrDefault(String key, TypeLiteral<T> type, T defaultValue) {
+            return config.getOrDefault(key, type, defaultValue);
         }
 
         @Override
-        public void setRequestId(String requestId) {
-            if(isClosed()){
-                throw new IllegalStateException("Cannot set requestId, already closed.");
+        public Map<String, String> getProperties() {
+            return config.getProperties();
+        }
+
+        @Override
+        public Configuration with(ConfigOperator operator) {
+            return operator.operate(this);
+        }
+
+        @Override
+        public <T> T query(ConfigQuery<T> query) {
+            if(query instanceof MutableConfigurationQuery){
+                throw new ConfigException("Cannot query a mutable configuration, already is one!");
             }
-            this.requestId = Objects.requireNonNull(requestId);
+            return query.query(this);
+        }
+
+        @Override
+        public String toString() {
+            return "DefaultMutableConfiguration{" +
+                    "config=" + config +
+                    ", targets=" + targets +
+                    '}';
         }
     }
 

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/a231ff05/modules/mutable-config/src/main/java/org/apache/tamaya/mutableconfig/internal/DefaultConfigurationBackendSpi.java
----------------------------------------------------------------------
diff --git a/modules/mutable-config/src/main/java/org/apache/tamaya/mutableconfig/internal/DefaultConfigurationBackendSpi.java b/modules/mutable-config/src/main/java/org/apache/tamaya/mutableconfig/internal/DefaultConfigurationBackendSpi.java
index e5def2e..cfdfe29 100644
--- a/modules/mutable-config/src/main/java/org/apache/tamaya/mutableconfig/internal/DefaultConfigurationBackendSpi.java
+++ b/modules/mutable-config/src/main/java/org/apache/tamaya/mutableconfig/internal/DefaultConfigurationBackendSpi.java
@@ -18,8 +18,8 @@
  */
 package org.apache.tamaya.mutableconfig.internal;
 
-import org.apache.tamaya.mutableconfig.MutableConfiguration;
-import org.apache.tamaya.mutableconfig.spi.ConfigurationBackendSpi;
+import org.apache.tamaya.mutableconfig.spi.MutableConfigurationBackendSpi;
+import org.apache.tamaya.mutableconfig.spi.MutableConfigurationBackendProviderSpi;
 
 import java.io.File;
 import java.net.URI;
@@ -30,18 +30,18 @@ import java.util.logging.Logger;
  * Mutable Config Request factory that tries to convert given URIs to file references, if successful, it returns
  * ConfigChangeRequests fir .properties and .xml files.
  */
-public class DefaultConfigurationBackendSpi implements ConfigurationBackendSpi {
+public class DefaultConfigurationBackendSpi implements MutableConfigurationBackendProviderSpi {
 
-    private static final Logger LOG = Logger.getLogger(XmlPropertiesFileConfigChangeRequest.class.getName());
+    private static final Logger LOG = Logger.getLogger(DefaultConfigurationBackendSpi.class.getName());
 
     @Override
-    public MutableConfiguration getBackend(URI uri) {
+    public MutableConfigurationBackendSpi getBackend(URI uri) {
         try{
             File f = new File(uri);
             if(f.getName().endsWith(".properties")){
-                return new PropertiesFileConfigChangeRequest(f);
+                return new PropertiesFileConfigBackendSpi(f);
             }else if(f.getName().endsWith(".xml")){
-                return new XmlPropertiesFileConfigChangeRequest(f);
+                return new XmlPropertiesFileConfigBackendSpi(f);
             }
         } catch(Exception e){
             LOG.log(Level.FINEST, "URI not convertible to file, ignoring " + uri, e);

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/a231ff05/modules/mutable-config/src/main/java/org/apache/tamaya/mutableconfig/spi/AbstractMutableConfiguration.java
----------------------------------------------------------------------
diff --git a/modules/mutable-config/src/main/java/org/apache/tamaya/mutableconfig/spi/AbstractMutableConfiguration.java b/modules/mutable-config/src/main/java/org/apache/tamaya/mutableconfig/spi/AbstractMutableConfiguration.java
index 2dd9a20..d1afaf6 100644
--- a/modules/mutable-config/src/main/java/org/apache/tamaya/mutableconfig/spi/AbstractMutableConfiguration.java
+++ b/modules/mutable-config/src/main/java/org/apache/tamaya/mutableconfig/spi/AbstractMutableConfiguration.java
@@ -18,72 +18,35 @@
  */
 package org.apache.tamaya.mutableconfig.spi;
 
-import org.apache.tamaya.ConfigException;
 import org.apache.tamaya.mutableconfig.MutableConfiguration;
 
-import java.net.URI;
-import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Collections;
 import java.util.HashMap;
 import java.util.HashSet;
-import java.util.List;
 import java.util.Map;
-import java.util.Objects;
 import java.util.Set;
-import java.util.UUID;
 
 /**
  * Base class for implementing a ConfigChangeRequest.
  */
 public abstract class AbstractMutableConfiguration implements MutableConfiguration {
 
-    private final List<URI> uris = new ArrayList<>();
-    private String requestID = UUID.randomUUID().toString();
     /**
      * The Properties.
      */
-    protected final Map<String,String> properties = new HashMap<>();
+    protected final Map<String,String> addedProperties = new HashMap<>();
     /**
      * The Removed.
      */
-    protected final Set<String> removed = new HashSet<>();
-    private boolean closed = false;
+    protected final Set<String> removedProperties = new HashSet<>();
 
-    protected Set<String> getRemoved() {
-        return removed;
+    protected Set<String> getRemovedProperties() {
+        return removedProperties;
     }
 
-    protected Map<String,String> getProperties() {
-        return properties;
-    }
-
-    /**
-     * Instantiates a new Abstract config change request.
-     *
-     * @param uris the uris
-     */
-    protected AbstractMutableConfiguration(URI... uris){
-        for(URI uri:uris){
-            this.uris.add(Objects.requireNonNull(uri));
-        }
-        if(this.uris.isEmpty()){
-            throw new IllegalArgumentException("At least one URI should be provided.");
-        }
-    }
-
-    /**
-     * Get the unique id of this change request (UUID).
-     * @return the unique id of this change request (UUID).
-     */
-    @Override
-    public String getRequestID(){
-        return requestID;
-    }
-
-    @Override
-    public final Collection<URI> getBackendURIs() {
-        return Collections.unmodifiableCollection(uris);
+    protected Map<String,String> getAddedProperties() {
+        return addedProperties;
     }
 
     @Override
@@ -97,47 +60,37 @@ public abstract class AbstractMutableConfiguration implements MutableConfigurati
     }
 
     @Override
-    public abstract boolean exists(String keyExpression);
-
-    @Override
-    public void setRequestId(String requestId) {
-        checkClosed();
-        this.requestID = Objects.requireNonNull(requestId);
-    }
+    public abstract boolean isExisting(String keyExpression);
 
     @Override
     public MutableConfiguration put(String key, String value) {
-        checkClosed();
-        this.properties.put(key, value);
+        this.addedProperties.put(key, value);
         return this;
     }
 
     @Override
     public MutableConfiguration putAll(Map<String, String> properties) {
-        checkClosed();
-        this.properties.putAll(properties);
+        this.addedProperties.putAll(properties);
         return this;
     }
 
     @Override
     public MutableConfiguration remove(String... keys) {
-        checkClosed();
-        Collections.addAll(this.removed, keys);
+        Collections.addAll(this.removedProperties, keys);
         return this;
     }
 
     @Override
     public MutableConfiguration remove(Collection<String> keys) {
-        checkClosed();
-        this.removed.addAll(keys);
+        this.removedProperties.addAll(keys);
         return this;
     }
 
     @Override
     public final void commit() {
-        checkClosed();
         commitInternal();
-        closed = true;
+        this.removedProperties.clear();
+        this.addedProperties.clear();
     }
 
     /**
@@ -147,21 +100,7 @@ public abstract class AbstractMutableConfiguration implements MutableConfigurati
 
     @Override
     public final void rollback() {
-        checkClosed();
-        closed = true;
-    }
-
-    @Override
-    public final boolean isClosed() {
-        return closed;
-    }
-
-    /**
-     * Check closed.
-     */
-    protected void checkClosed(){
-        if(closed){
-            throw new ConfigException("Change request already closed.");
-        }
+        this.removedProperties.clear();
+        this.addedProperties.clear();
     }
 }

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/a231ff05/modules/mutable-config/src/main/java/org/apache/tamaya/mutableconfig/spi/MutableConfigurationBackendProviderSpi.java
----------------------------------------------------------------------
diff --git a/modules/mutable-config/src/main/java/org/apache/tamaya/mutableconfig/spi/MutableConfigurationBackendProviderSpi.java b/modules/mutable-config/src/main/java/org/apache/tamaya/mutableconfig/spi/MutableConfigurationBackendProviderSpi.java
index 98d4eb7..5e8300b 100644
--- a/modules/mutable-config/src/main/java/org/apache/tamaya/mutableconfig/spi/MutableConfigurationBackendProviderSpi.java
+++ b/modules/mutable-config/src/main/java/org/apache/tamaya/mutableconfig/spi/MutableConfigurationBackendProviderSpi.java
@@ -18,13 +18,10 @@
  */
 package org.apache.tamaya.mutableconfig.spi;
 
-import org.apache.tamaya.mutableconfig.MutableConfiguration;
-import org.apache.tamaya.mutableconfig.MutableConfigurationQuery;
-
 import java.net.URI;
 
 /**
- * Provider SPI used by {@link MutableConfigurationQuery}. Providers may override
+ * Provider SPI used by {@link org.apache.tamaya.mutableconfig.MutableConfigurationQuery}. Providers may override
  * other providers registering with a higher {@link javax.annotation.Priority} value annotated.
  */
 public interface MutableConfigurationBackendProviderSpi {
@@ -35,6 +32,6 @@ public interface MutableConfigurationBackendProviderSpi {
     * @param backendURI the backend uri
     * @return the requested backend, or null if the given backend URI is not supported by the given SPI.
     */
-   MutableConfigurationBackend getBackend(URI backendURI);
+   MutableConfigurationBackendSpi getBackend(URI backendURI);
 
 }

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/a231ff05/modules/mutable-config/src/main/java/org/apache/tamaya/mutableconfig/spi/MutableConfigurationBackendSpi.java
----------------------------------------------------------------------
diff --git a/modules/mutable-config/src/main/java/org/apache/tamaya/mutableconfig/spi/MutableConfigurationBackendSpi.java b/modules/mutable-config/src/main/java/org/apache/tamaya/mutableconfig/spi/MutableConfigurationBackendSpi.java
index a1825d7..0c05807 100644
--- a/modules/mutable-config/src/main/java/org/apache/tamaya/mutableconfig/spi/MutableConfigurationBackendSpi.java
+++ b/modules/mutable-config/src/main/java/org/apache/tamaya/mutableconfig/spi/MutableConfigurationBackendSpi.java
@@ -18,8 +18,6 @@
  */
 package org.apache.tamaya.mutableconfig.spi;
 
-import org.apache.tamaya.Configuration;
-
 import java.net.URI;
 import java.util.Collection;
 import java.util.Map;
@@ -128,7 +126,7 @@ public interface MutableConfigurationBackendSpi {
      * Commits the request. After a commit the change is not editable anymore. All changes applied will be written to
      * the corresponding configuration backend.
      *
-     * NOTE that changes applied must not necessarily be visible in the current {@link Configuration} instance,
+     * NOTE that changes applied must not necessarily be visible in the current {@link org.apache.tamaya.Configuration} instance,
      * since visibility of changes also depends on the ordinals set on the {@link org.apache.tamaya.spi.PropertySource}s
      * configured.
      * @throws org.apache.tamaya.ConfigException if the request already has been committed or cancelled, or the commit fails.

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/a231ff05/modules/mutable-config/src/test/java/org/apache/tamaya/mutableconfig/MutableConfigurationQueryTest.java
----------------------------------------------------------------------
diff --git a/modules/mutable-config/src/test/java/org/apache/tamaya/mutableconfig/MutableConfigurationQueryTest.java b/modules/mutable-config/src/test/java/org/apache/tamaya/mutableconfig/MutableConfigurationQueryTest.java
index b235149..6ab394d 100644
--- a/modules/mutable-config/src/test/java/org/apache/tamaya/mutableconfig/MutableConfigurationQueryTest.java
+++ b/modules/mutable-config/src/test/java/org/apache/tamaya/mutableconfig/MutableConfigurationQueryTest.java
@@ -19,6 +19,7 @@
 package org.apache.tamaya.mutableconfig;
 
 import org.apache.tamaya.ConfigException;
+import org.apache.tamaya.ConfigurationProvider;
 import org.junit.Test;
 
 import java.io.File;
@@ -39,10 +40,12 @@ public class MutableConfigurationQueryTest {
     @Test
     public void testCreateChangeRequest() throws Exception {
         File f = File.createTempFile("ConfigChangeRequest",".properties");
-        MutableConfiguration req = MutableConfigurationQuery.createChangeRequest(f.toURI());
+        MutableConfiguration req = ConfigurationProvider.getConfiguration().query(
+                MutableConfigurationQuery.of(f.toURI()));
         assertNotNull(req);
         f = File.createTempFile("ConfigChangeRequest",".xml");
-        req = MutableConfigurationQuery.createChangeRequest(f.toURI());
+        req = ConfigurationProvider.getConfiguration().query(
+                MutableConfigurationQuery.of(f.toURI()));
         assertNotNull(req);
     }
 
@@ -53,7 +56,8 @@ public class MutableConfigurationQueryTest {
      */
     @Test(expected=ConfigException.class)
     public void testInvalidCreateChangeRequest() throws Exception {
-        MutableConfiguration req = MutableConfigurationQuery.createChangeRequest(new URI("foo:bar"));
+        MutableConfiguration req = ConfigurationProvider.getConfiguration().query(
+                MutableConfigurationQuery.of(new URI("foo:bar")));
     }
 
     /**
@@ -63,7 +67,8 @@ public class MutableConfigurationQueryTest {
      */
     @Test(expected=NullPointerException.class)
     public void testNullCreateChangeRequest1() throws Exception {
-        MutableConfiguration req = MutableConfigurationQuery.createChangeRequest((URI[])null);
+        MutableConfiguration req = ConfigurationProvider.getConfiguration().query(
+                MutableConfigurationQuery.of((URI[])null));
     }
 
     /**
@@ -73,6 +78,7 @@ public class MutableConfigurationQueryTest {
      */
     @Test(expected=NullPointerException.class)
     public void testNullCreateChangeRequest2() throws Exception {
-        MutableConfiguration req = MutableConfigurationQuery.createChangeRequest((String[])null);
+        MutableConfiguration req = ConfigurationProvider.getConfiguration().query(
+                MutableConfigurationQuery.of((String[])null));
     }
 }
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/a231ff05/modules/mutable-config/src/test/java/org/apache/tamaya/mutableconfig/internal/PropertiesFileConfigBackendTest.java
----------------------------------------------------------------------
diff --git a/modules/mutable-config/src/test/java/org/apache/tamaya/mutableconfig/internal/PropertiesFileConfigBackendTest.java b/modules/mutable-config/src/test/java/org/apache/tamaya/mutableconfig/internal/PropertiesFileConfigBackendTest.java
index c2e220e..a4fe1f2 100644
--- a/modules/mutable-config/src/test/java/org/apache/tamaya/mutableconfig/internal/PropertiesFileConfigBackendTest.java
+++ b/modules/mutable-config/src/test/java/org/apache/tamaya/mutableconfig/internal/PropertiesFileConfigBackendTest.java
@@ -18,6 +18,7 @@
  */
 package org.apache.tamaya.mutableconfig.internal;
 
+import org.apache.tamaya.ConfigurationProvider;
 import org.apache.tamaya.mutableconfig.MutableConfigurationQuery;
 import org.apache.tamaya.mutableconfig.MutableConfiguration;
 import org.junit.Test;
@@ -31,7 +32,7 @@ import java.util.Properties;
 import static org.junit.Assert.*;
 
 /**
- * Tests for {@link PropertiesFileConfigBackend}.
+ * Tests for {@link PropertiesFileConfigBackendSpi}.
  */
 public class PropertiesFileConfigBackendTest {
     /**
@@ -43,14 +44,13 @@ public class PropertiesFileConfigBackendTest {
     public void testReadWriteProperties_WithCancel() throws IOException {
         File f = File.createTempFile("testReadWriteProperties_WithCancel",".properties");
         f.delete();
-        MutableConfiguration req = MutableConfigurationQuery.createChangeRequest(f.toURI());
-        assertTrue(req instanceof PropertiesFileConfigBackend);
+        MutableConfiguration req = ConfigurationProvider.getConfiguration().query(
+                MutableConfigurationQuery.of(f.toURI()));
         req.put("key1", "value1");
         Map<String,String> cm = new HashMap<>();
         cm.put("key2", "value2");
         cm.put("key3", "value3");
         req.rollback();;
-        assertTrue(req.isClosed());
         assertFalse(f.exists());
     }
 
@@ -63,17 +63,17 @@ public class PropertiesFileConfigBackendTest {
     public void testReadWriteProperties_WithCommit() throws IOException {
         File f = File.createTempFile("testReadWriteProperties_WithCommit",".properties");
         f.delete();
-        MutableConfiguration req = MutableConfigurationQuery.createChangeRequest(f.toURI());
-        assertTrue(req instanceof PropertiesFileConfigBackend);
+        MutableConfiguration req = ConfigurationProvider.getConfiguration().query(
+                MutableConfigurationQuery.of(f.toURI()));
         req.put("key1", "value1");
         Map<String,String> cm = new HashMap<>();
         cm.put("key2", "value2");
         cm.put("key3", "value3");
         req.putAll(cm);
         req.commit();;
-        assertTrue(req.isClosed());
         assertTrue(f.exists());
-        MutableConfiguration req2 = MutableConfigurationQuery.createChangeRequest(f.toURI());
+        MutableConfiguration req2 = ConfigurationProvider.getConfiguration().query(
+                MutableConfigurationQuery.of(f.toURI()));
         assertTrue(req != req2);
         req2.remove("foo");
         req2.remove("key3");
@@ -97,17 +97,17 @@ public class PropertiesFileConfigBackendTest {
     public void testReadWriteXmlProperties_WithCommit() throws IOException {
         File f = File.createTempFile("testReadWriteProperties_WithCommit",".xml");
         f.delete();
-        MutableConfiguration req = MutableConfigurationQuery.createChangeRequest(f.toURI());
-        assertTrue(req instanceof XmlPropertiesFileConfigChangeRequest);
+        MutableConfiguration req = ConfigurationProvider.getConfiguration().query(
+                MutableConfigurationQuery.of(f.toURI()));
         req.put("key1", "value1");
         Map<String,String> cm = new HashMap<>();
         cm.put("key2", "value2");
         cm.put("key3", "value3");
         req.putAll(cm);
         req.commit();;
-        assertTrue(req.isClosed());
         assertTrue(f.exists());
-        MutableConfiguration req2 = MutableConfigurationQuery.createChangeRequest(f.toURI());
+        MutableConfiguration req2 = ConfigurationProvider.getConfiguration().query(
+                MutableConfigurationQuery.of(f.toURI()));
         assertTrue(req != req2);
         req2.remove("foo");
         req2.remove("key3");
@@ -128,17 +128,18 @@ public class PropertiesFileConfigBackendTest {
         f1.delete();
         File f2 = File.createTempFile("testReadWrite_Compound",".properties");
         f2.delete();
-        MutableConfiguration req = MutableConfigurationQuery.createChangeRequest(f1.toURI(),f2.toURI());
+        MutableConfiguration req = ConfigurationProvider.getConfiguration().query(
+                MutableConfigurationQuery.of(f1.toURI(), f2.toURI()));
         req.put("key1", "value1");
         Map<String,String> cm = new HashMap<>();
         cm.put("key2", "value2");
         cm.put("key3", "value3");
         req.putAll(cm);
         req.commit();;
-        assertTrue(req.isClosed());
         assertTrue(f1.exists());
         assertTrue(f2.exists());
-        MutableConfiguration req2 = MutableConfigurationQuery.createChangeRequest(f1.toURI(),f2.toURI());
+        MutableConfiguration req2 = ConfigurationProvider.getConfiguration().query(
+                MutableConfigurationQuery.of(f1.toURI(), f2.toURI()));
         assertTrue(req != req2);
         req2.remove("foo");
         req2.remove("key3");

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/a231ff05/src/site/asciidoc/extensions/mod_mutable_config.adoc
----------------------------------------------------------------------
diff --git a/src/site/asciidoc/extensions/mod_mutable_config.adoc b/src/site/asciidoc/extensions/mod_mutable_config.adoc
index b9a0668..4fca404 100644
--- a/src/site/asciidoc/extensions/mod_mutable_config.adoc
+++ b/src/site/asciidoc/extensions/mod_mutable_config.adoc
@@ -15,7 +15,7 @@
 // specific language governing permissions and limitations
 // under the License.
 
-= Apache Tamaya -- Extension: Events
+= Apache Tamaya -- Extension: Mutable Configuration
 
 :name: Tamaya
 :rootpackage: org.apache.tamaya.mutableconfig
@@ -47,9 +47,8 @@ toc::[]
 == Tamaya Mutable Configuration (Extension Module)
 === Overview
 
-Tamaya Configuration by default is read-only, which covers must of the use cases. Make it writable through out
-creates also a bunch of new issues, especially with distributed configuration services and eventual consistency.
-Therefore mutability of configuration is modelled in Tamaya as a separate concern. This module defines the API
+Tamaya Configuration by default is read-only, which covers must of the use cases. But there are many legit use cases
+where configuration should be written back to some backend systems or the local file system. This module defines the API
 to be used, whereas multiple mutable backends can register their mechanism to write configuration properties.
 
 === Compatibility
@@ -71,29 +70,26 @@ To benefit from configuration mutability support you only must add the correspon
 
 === Core Architecture
 
-The core of the module is the +ConfigChangeManager+ singleton, which creates a +ConfigChangeReuqest+ class for
-one or multiple +configurationTargets+ passed. The supported target +URIs+ hereby are determined (and must be
-documented) by the registered backend spis. If not sure you can call +getSupportedURIInfo()+ to see, which kind of URI's
-supported.
+The core of the module is the +MutableConfigQuery+ singleton, which is a +ConfigQuery+ that creates a new
++Mutableonfiguration+ based on a +Configuration+ and a set of target backend +URIs+. If not sure you can call
++getSupportedURIInfo()+ to see, which kind of URI's are  currently supported.
 As an example writing configuration entries to an +etcd+ server can be done as follows:
 
 [source,java]
-.Writing configuration to etcd
+.Accessing a mutable configuration backed by etcd
 --------------------------------------------
-ConfigChangeRequest request = ConfigChangeManager.createChangeRequest(
-    new URI("etc:http://127.0.0.1:4441"),
-    new URI("file:/home/etcd/backup-config.properties"));
-ChangeSummary summary = request
-                .set("newKey", "newValue").set("anotherKey", "updatedValue")
-                .remove("valueNotValid")
-                .commit();
+MutableConfiguration config = ConfigChangeManager.getConfiguration().query(
+    MutableConfigurationQuery.of("etc:http://127.0.0.1:4441", "file:/home/etcd/backup-config.properties");
+config.set("newKey", "newValue").set("anotherKey", "updatedValue")
+      .remove("valueNotValid")
+      .commit();
 --------------------------------------------
 
 The effective effect of your changes to the overall configuration changes cannot be easily predicted, since it depends
 on several aspects:
 
 . is the corresponding configuration resource configured as part of the current system's configuration?
-. what is the +PropertySource's+ ordinal? Is it overriding or overriden by other sources?
+. what is the +PropertySource's+ ordinal? Is it overriding or overridden by other sources?
 . is the change directly visible to the configuration system? E.g. injected values are normally not updated,
   whereas injecting a +DynamicValue<T>+ instance allows to detect and react single value changes. Also the
   +PropertySources+ implementation must be able to detect any configuration changes and adapt its values returned
@@ -101,21 +97,22 @@ on several aspects:
 . Is configuration cached, or written/collected directly on access?
 . can the changes applied be committed at all?
 
-So it is part of your application configuration design to clearly define, which confoguration may be read-only, which
-may be mutable, how overridings should work and to which backends finally any changes should be written back. To
-support such fine granular scenarios the +ConfigChangeRequest+ interface also has methods to determine if a key
-is writable at all for a given configuration target:
+So it is part of your application configuration design to clearly define, which configuration may be read-only, which
+may be mutable, how overriding should work and to which backends finally any changes should be written back. To
+support such fine granular scenarios a +MutableConfiguration+ also offers methods to determine if a key
+is writable at all or can be removed or updated:
 
 [source,java]
 .Checking for mutability
 --------------------------------------------
-ConfigChangeRequest request = ConfigChangeManager.createChangeRequest(new URI("file://$USER_HOME/.myapp/mapp.properties"));
-if(request,isWritable("mycluster.shared.appKey")){
-    request.set("newKey", "newValue")
+MutableConfiguration config = ConfigChangeManager.getConfiguration().query(
+    MutableConfigurationQuery.of("etc:http://127.0.0.1:4441", "file:/home/etcd/backup-config.properties");
+if(config,isWritable("mycluster.shared.appKey")){
+    config.set("newKey", "newValue")
     .remove("valueNotValid")
      .commit();
 }else{
-    request.cancel();
+    config.rollbacks();
 }
 --------------------------------------------
 
@@ -126,22 +123,39 @@ several ways, e.g. by:
 
 * using the _tamaya-events_ extension, which can be used to observe the system's configuration and
   publishing events when things have been changed.
-* The SPI implementing the +ConfigChangeManagerSpi+ may inform/update any affected +PropertySource,
+* The SPI implementing the +MutableConfigurationBackendSpi+ may inform/update any affected +PropertySource,
   PropertySourceProvider+ instances about the changes applied.
 
+=== Supported Backends modules
+
+Multiple backends are supported. E.g. the _etcd_ and _consul_ integration modules of Tamaya also registers
+corresponding SPI implementations/backends. By default the following backends are available:
+
+* +.properties+ resources, e.g. files or resources located on a web server, following the +java.util.Properties+
+  format.
+* +.xml+ resources, e.g. files or resources located on a web server, following the +java.util.Properties+ XML format.
+
 
 === SPIs
 
-The module defines only one single SPI, that must be implemented to implement the fabric method
-+createChangeRequest(URI)+ of the +ConfigChangeManager+ singleton:
+The module defines only one single SPI +MutableConfigurationBackendProviderSpi+, that must be implemented. It
+defines a fabric method +MutableConfigurationBackendSpi getBackend(URI)+ used by the +MutableConfigurationQuery+
+accessor:
 
 [source,java]
 .SPI: ConfigEventSpi
 --------------------------------------------------
-public interface ConfigChangeManagerSpi {
-    ConfigChangeRequest createChangeRequest(URI backendURI);
+public interface MutableConfigurationBackendProviderSpi {
+    MutableConfigurationBackendSpi getBackend(URI backendURI);
 }
 --------------------------------------------------
 
 Implementations are registered with the current +ServiceContext+, be default as with
  +java.util.ServiceLoader+.
+
+
+As convenience the following base classes are provided:
+
+* +org.apache.tamaya.mutableconfig.spi.AbstractMutableConfiguration+ simplifying implementation of +MutableConfiguration+.
+* +org.apache.tamaya.mutableconfig.spi.AbstractMutableConfigurationBackendSpi+ simplifying the implemenation of
+  +MutableConfigurationBackendSpi+.
\ No newline at end of file