deltaspike-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From strub...@apache.org
Subject git commit: DELTASPIKE-382 add ConfigFilter mechanism
Date Sun, 23 Jun 2013 15:00:32 GMT
Updated Branches:
  refs/heads/master eb526e50a -> 9c301fc28


DELTASPIKE-382 add ConfigFilter mechanism

This allows to filter DeltaSpike configuration values,
e.g. for applying decryption of secure configuration values
on the fly.


Project: http://git-wip-us.apache.org/repos/asf/deltaspike/repo
Commit: http://git-wip-us.apache.org/repos/asf/deltaspike/commit/9c301fc2
Tree: http://git-wip-us.apache.org/repos/asf/deltaspike/tree/9c301fc2
Diff: http://git-wip-us.apache.org/repos/asf/deltaspike/diff/9c301fc2

Branch: refs/heads/master
Commit: 9c301fc289a15a84552950737df03f9d0487150f
Parents: eb526e5
Author: Mark Struberg <struberg@apache.org>
Authored: Sun Jun 23 16:58:51 2013 +0200
Committer: Mark Struberg <struberg@apache.org>
Committed: Sun Jun 23 16:58:51 2013 +0200

----------------------------------------------------------------------
 .../core/api/config/ConfigResolver.java         | 75 ++++++++++++++++++--
 .../core/spi/config/ConfigFilter.java           | 45 ++++++++++++
 .../test/api/config/ConfigResolverTest.java     | 51 ++++++++++++-
 .../test/api/config/TestConfigSource.java       |  3 +
 4 files changed, 169 insertions(+), 5 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/deltaspike/blob/9c301fc2/deltaspike/core/api/src/main/java/org/apache/deltaspike/core/api/config/ConfigResolver.java
----------------------------------------------------------------------
diff --git a/deltaspike/core/api/src/main/java/org/apache/deltaspike/core/api/config/ConfigResolver.java
b/deltaspike/core/api/src/main/java/org/apache/deltaspike/core/api/config/ConfigResolver.java
index b7802a3..4cd956e 100644
--- a/deltaspike/core/api/src/main/java/org/apache/deltaspike/core/api/config/ConfigResolver.java
+++ b/deltaspike/core/api/src/main/java/org/apache/deltaspike/core/api/config/ConfigResolver.java
@@ -32,6 +32,7 @@ import java.util.logging.Logger;
 import javax.enterprise.inject.Typed;
 
 import org.apache.deltaspike.core.api.projectstage.ProjectStage;
+import org.apache.deltaspike.core.spi.config.ConfigFilter;
 import org.apache.deltaspike.core.spi.config.ConfigSource;
 import org.apache.deltaspike.core.spi.config.ConfigSourceProvider;
 import org.apache.deltaspike.core.util.ClassUtils;
@@ -58,6 +59,13 @@ public final class ConfigResolver
     private static Map<ClassLoader, ConfigSource[]> configSources
         = new ConcurrentHashMap<ClassLoader, ConfigSource[]>();
 
+    /**
+     * The content of this map will hold the List of ConfigFilters
+     * for each WebApp/EAR, etc (thus the ClassLoader).
+     */
+    private static Map<ClassLoader, List<ConfigFilter>> configFilters
+        = new ConcurrentHashMap<ClassLoader, List<ConfigFilter>>();
+
     private static volatile ProjectStage projectStage = null;
 
     private ConfigResolver()
@@ -97,6 +105,35 @@ public final class ConfigResolver
     }
 
     /**
+     * Add a {@link ConfigFilter} to the ConfigResolver.
+     * This will only affect the current WebApp
+     * (or more precisely the current ClassLoader and it's children).
+     * @param configFilter
+     */
+    public static void addConfigFilter(ConfigFilter configFilter)
+    {
+
+        List<ConfigFilter> currentConfigFilters = getConfigFilters();
+        currentConfigFilters.add(configFilter);
+    }
+
+    /**
+     * @return the {@link ConfigFilter}s for the current application.
+     */
+    public static List<ConfigFilter> getConfigFilters()
+    {
+        ClassLoader cl = ClassUtils.getClassLoader(null);
+        List<ConfigFilter> currentConfigFilters = configFilters.get(cl);
+        if (currentConfigFilters == null)
+        {
+            currentConfigFilters = new ArrayList<ConfigFilter>();
+            configFilters.put(cl, currentConfigFilters);
+        }
+
+        return currentConfigFilters;
+    }
+
+    /**
      * Resolve the property value by going through the list of configured {@link ConfigSource}s
      * and use the one with the highest priority. If no configured value has been found that
      * way we will use the defaultValue.
@@ -133,8 +170,8 @@ public final class ConfigResolver
             if (value != null)
             {
                 LOG.log(Level.FINE, "found value {0} for key {1} in ConfigSource {2}.",
-                        new Object[]{value, key, configSource.getConfigName()});
-                return value;
+                        new Object[]{filterConfigValueForLog(key, value), key, configSource.getConfigName()});
+                return filterConfigValue(key, value);
             }
 
             LOG.log(Level.FINER, "NO value found for key {0} in ConfigSource {1}.",
@@ -275,9 +312,13 @@ public final class ConfigResolver
         {
             value = configSource.getPropertyValue(key);
 
-            if (value != null && !result.contains(value))
+            if (value != null)
             {
-                result.add(value);
+                value = filterConfigValue(key, value);
+                if (!result.contains(value))
+                {
+                    result.add(value);
+                }
             }
         }
 
@@ -399,5 +440,31 @@ public final class ConfigResolver
         return value;
     }
 
+    private static String filterConfigValue(String key, String value)
+    {
+        List<ConfigFilter> currentConfigFilters = getConfigFilters();
+
+        String filteredValue = value;
+
+        for (ConfigFilter filter : currentConfigFilters)
+        {
+            filteredValue = filter.filterValue(key, filteredValue);
+        }
+        return filteredValue;
+    }
+
+    private static String filterConfigValueForLog(String key, String value)
+    {
+        List<ConfigFilter> currentConfigFilters = getConfigFilters();
+
+        String logValue = value;
+
+        for (ConfigFilter filter : currentConfigFilters)
+        {
+            logValue = filter.filterValueForLog(key, logValue);
+        }
+        return logValue;
+    }
+
 
 }

http://git-wip-us.apache.org/repos/asf/deltaspike/blob/9c301fc2/deltaspike/core/api/src/main/java/org/apache/deltaspike/core/spi/config/ConfigFilter.java
----------------------------------------------------------------------
diff --git a/deltaspike/core/api/src/main/java/org/apache/deltaspike/core/spi/config/ConfigFilter.java
b/deltaspike/core/api/src/main/java/org/apache/deltaspike/core/spi/config/ConfigFilter.java
new file mode 100644
index 0000000..5f851e2
--- /dev/null
+++ b/deltaspike/core/api/src/main/java/org/apache/deltaspike/core/spi/config/ConfigFilter.java
@@ -0,0 +1,45 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.deltaspike.core.spi.config;
+
+/**
+ * A filter which can be added to the
+ * {@link org.apache.deltaspike.core.api.config.ConfigResolver}.
+ * The filter can be used to decrypt config values or prepare
+ * values for logging.
+ */
+public interface ConfigFilter
+{
+    /**
+     * Filter the given configuration value
+     * @param key
+     * @param value
+     * @return the filtered value or the original input String if no filter shall be applied
+     */
+    String filterValue(String key, String value);
+
+    /**
+     * Filter the given configuration value for usage in logs.
+     * This might be used to mask out passwords, etc.
+     * @param key
+     * @param value
+     * @return the filtered value or the original input String if no filter shall be applied
+     */
+    String filterValueForLog(String key, String value);
+}

http://git-wip-us.apache.org/repos/asf/deltaspike/blob/9c301fc2/deltaspike/core/api/src/test/java/org/apache/deltaspike/test/api/config/ConfigResolverTest.java
----------------------------------------------------------------------
diff --git a/deltaspike/core/api/src/test/java/org/apache/deltaspike/test/api/config/ConfigResolverTest.java
b/deltaspike/core/api/src/test/java/org/apache/deltaspike/test/api/config/ConfigResolverTest.java
index d30e7de..6aa81da 100644
--- a/deltaspike/core/api/src/test/java/org/apache/deltaspike/test/api/config/ConfigResolverTest.java
+++ b/deltaspike/core/api/src/test/java/org/apache/deltaspike/test/api/config/ConfigResolverTest.java
@@ -20,6 +20,7 @@ package org.apache.deltaspike.test.api.config;
 
 import org.apache.deltaspike.core.api.config.ConfigResolver;
 import org.apache.deltaspike.core.api.projectstage.ProjectStage;
+import org.apache.deltaspike.core.spi.config.ConfigFilter;
 import org.apache.deltaspike.core.util.ProjectStageProducer;
 import org.junit.Assert;
 import org.junit.Test;
@@ -74,7 +75,8 @@ public class ConfigResolverTest
     }
 
     @Test
-    public void testGetPropertyAwarePropertyValue() {
+    public void testGetPropertyAwarePropertyValue()
+    {
         ProjectStageProducer.setProjectStage(ProjectStage.UnitTest);
 
         Assert.assertNull(ConfigResolver.getPropertyAwarePropertyValue("notexisting", null));
@@ -100,4 +102,51 @@ public class ConfigResolverTest
         Assert.assertEquals("DefaultDataSource", ConfigResolver.getPropertyAwarePropertyValue("dataSource",
"dbvendorX", null));
         Assert.assertEquals(DEFAULT_VALUE, ConfigResolver.getPropertyAwarePropertyValue("dataSourceX",
"dbvendorX", DEFAULT_VALUE));
     }
+
+    @Test
+    public void testConfigFilter()
+    {
+
+        ConfigFilter configFilter = new TestConfigFilter();
+
+        Assert.assertEquals("shouldGetDecrypted: value", configFilter.filterValue("somekey.encrypted",
"value"));
+        Assert.assertEquals("**********", configFilter.filterValueForLog("somekey.password",
"value"));
+
+        ConfigResolver.addConfigFilter(configFilter);
+
+        Assert.assertEquals("shouldGetDecrypted: value", ConfigResolver.getPropertyValue("testkey4.encrypted"));
+        Assert.assertEquals("shouldGetDecrypted: value", ConfigResolver.getProjectStageAwarePropertyValue("testkey4.encrypted"));
+        Assert.assertEquals("shouldGetDecrypted: value", ConfigResolver.getProjectStageAwarePropertyValue("testkey4.encrypted",
null));
+        Assert.assertEquals("shouldGetDecrypted: value", ConfigResolver.getPropertyAwarePropertyValue("testkey4.encrypted",
"dbvendor"));
+        Assert.assertEquals("shouldGetDecrypted: value", ConfigResolver.getPropertyAwarePropertyValue("testkey4.encrypted",
"dbvendor", null));
+
+        List<String> allPropertyValues = ConfigResolver.getAllPropertyValues("testkey4.encrypted");
+        Assert.assertNotNull(allPropertyValues);
+        Assert.assertEquals(1, allPropertyValues.size());
+        Assert.assertEquals("shouldGetDecrypted: value", allPropertyValues.get(0));
+
+    }
+
+    public static class TestConfigFilter implements ConfigFilter
+    {
+        @Override
+        public String filterValue(String key, String value)
+        {
+            if (key.contains("encrypted"))
+            {
+                return "shouldGetDecrypted: " + value;
+            }
+            return value;
+        }
+
+        @Override
+        public String filterValueForLog(String key, String value)
+        {
+            if (key.contains("password"))
+            {
+                return "**********";
+            }
+            return value;
+        }
+    }
 }

http://git-wip-us.apache.org/repos/asf/deltaspike/blob/9c301fc2/deltaspike/core/api/src/test/java/org/apache/deltaspike/test/api/config/TestConfigSource.java
----------------------------------------------------------------------
diff --git a/deltaspike/core/api/src/test/java/org/apache/deltaspike/test/api/config/TestConfigSource.java
b/deltaspike/core/api/src/test/java/org/apache/deltaspike/test/api/config/TestConfigSource.java
index d0f2c93..3b073a9 100644
--- a/deltaspike/core/api/src/test/java/org/apache/deltaspike/test/api/config/TestConfigSource.java
+++ b/deltaspike/core/api/src/test/java/org/apache/deltaspike/test/api/config/TestConfigSource.java
@@ -62,6 +62,9 @@ public class TestConfigSource implements ConfigSource
         props.put("dbvendor2.Production", "mysql");
         props.put("dbvendor2", "postgresql");
 
+        props.put("testkey4.encrypted", "value");
+        props.put("testkey4.password", "mysecretvalue");
+
     }
 
     @Override


Mime
View raw message