openwebbeans-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From rmannibu...@apache.org
Subject [openwebbeans-meecrowave] branch master updated: MEECROWAVE-203 adding configuration.complete support for meecrowave.properties
Date Mon, 15 Jul 2019 09:32:03 GMT
This is an automated email from the ASF dual-hosted git repository.

rmannibucau pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/openwebbeans-meecrowave.git


The following commit(s) were added to refs/heads/master by this push:
     new dbe6d21  MEECROWAVE-203 adding configuration.complete support for meecrowave.properties
dbe6d21 is described below

commit dbe6d21304feffab0de729606ee5c4097f5176ed
Author: Romain Manni-Bucau <rmannibucau@gmail.com>
AuthorDate: Mon Jul 15 11:31:57 2019 +0200

    MEECROWAVE-203 adding configuration.complete support for meecrowave.properties
---
 .../java/org/apache/meecrowave/Meecrowave.java     | 26 ++++++-
 .../java/org/apache/meecrowave/MeecrowaveTest.java | 86 ++++++++++++++++++++++
 .../content/meecrowave-core/configuration.adoc     |  6 +-
 pom.xml                                            |  2 +-
 4 files changed, 116 insertions(+), 4 deletions(-)

diff --git a/meecrowave-core/src/main/java/org/apache/meecrowave/Meecrowave.java b/meecrowave-core/src/main/java/org/apache/meecrowave/Meecrowave.java
index 0028c60..748cd6f 100644
--- a/meecrowave-core/src/main/java/org/apache/meecrowave/Meecrowave.java
+++ b/meecrowave-core/src/main/java/org/apache/meecrowave/Meecrowave.java
@@ -2051,8 +2051,9 @@ public class Meecrowave implements AutoCloseable {
 
         public Builder loadFrom(final String resource) {
             // load all of those files on the classpath, sorted by ordinal
-            Properties config = PropertyLoader.getProperties(resource);
-            if (config == null) {
+            Properties config = PropertyLoader.getProperties(resource,
+                    sortedProperties -> mergeProperties(resource, sortedProperties));
+            if (config == null || config.isEmpty()) {
                 final File file = new File(resource);
                 if (file.exists()) {
                     config = new Properties();
@@ -2369,6 +2370,27 @@ public class Meecrowave implements AutoCloseable {
         public void setMeecrowaveProperties(final String meecrowaveProperties) {
             this.meecrowaveProperties = meecrowaveProperties;
         }
+
+        private Properties mergeProperties(final String resource, final List<Properties>
sortedProperties) {
+            Properties mergedProperties = new Properties();
+            Properties master = null;
+            for (final Properties p : sortedProperties)
+            {
+                if (Boolean.parseBoolean(p.getProperty("configuration.complete", "false")))
{
+                    if (master != null) {
+                        throw new IllegalArgumentException("Ambiguous '" + resource + "',
" +
+                                "multiple " + resource + " with configuration.complete=true");
+                    }
+                    master = p;
+                }
+                mergedProperties.putAll(p);
+            }
+
+            if (master != null) {
+                return master;
+            }
+            return mergedProperties;
+        }
     }
 
     public static class ValueTransformers implements Function<String, String> {
diff --git a/meecrowave-core/src/test/java/org/apache/meecrowave/MeecrowaveTest.java b/meecrowave-core/src/test/java/org/apache/meecrowave/MeecrowaveTest.java
index a652d76..94916dc 100644
--- a/meecrowave-core/src/test/java/org/apache/meecrowave/MeecrowaveTest.java
+++ b/meecrowave-core/src/test/java/org/apache/meecrowave/MeecrowaveTest.java
@@ -28,6 +28,7 @@ import org.superbiz.app.InterfaceApi;
 import org.superbiz.app.RsApp;
 import org.superbiz.app.TestJsonEndpoint;
 
+import java.io.ByteArrayInputStream;
 import java.io.File;
 import java.io.FileOutputStream;
 import java.io.FileWriter;
@@ -35,10 +36,17 @@ import java.io.IOException;
 import java.io.InputStream;
 import java.io.OutputStream;
 import java.io.Writer;
+import java.net.MalformedURLException;
 import java.net.URL;
+import java.net.URLConnection;
+import java.net.URLStreamHandler;
+import java.nio.charset.StandardCharsets;
+import java.util.Enumeration;
 import java.util.Properties;
 import java.util.stream.Stream;
 
+import static java.util.Arrays.asList;
+import static java.util.Collections.enumeration;
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertTrue;
@@ -46,6 +54,37 @@ import static org.junit.Assert.fail;
 
 public class MeecrowaveTest {
     @Test
+    public void conflictingConfig() throws MalformedURLException {
+        withConfigClassLoader(() -> {
+            try {
+                new Meecrowave.Builder().loadFrom("test.config.properties");
+                fail("should have failed since it conflicts");
+            } catch (final IllegalArgumentException iae) {
+                // ok
+            }
+        }, configUrl("configuration.complete=true\nf=1"), configUrl("configuration.complete=true\nf=2"));
+    }
+
+    @Test
+    public void masterConfig() throws MalformedURLException {
+        withConfigClassLoader(() -> {
+            final Meecrowave.Builder builder = new Meecrowave.Builder();
+            builder.loadFrom("test.config.properties");
+            assertEquals(1, builder.getHttpPort());
+        }, configUrl("http=2"), configUrl("configuration.complete=true\nhttp=1"), configUrl("http=3"));
+    }
+
+    @Test
+    public void mergedConfig() throws MalformedURLException {
+        withConfigClassLoader(() -> {
+            final Meecrowave.Builder builder = new Meecrowave.Builder();
+            builder.loadFrom("test.config.properties");
+            assertEquals(2, builder.getHttpPort());
+            assertEquals(4, builder.getHttpsPort());
+        }, configUrl("http=2\nconfiguration.ordinal=2\nhttps=4"), configUrl("http=3\nconfiguration.ordinal=1"));
+    }
+
+    @Test
     public void configBinding() {
         final MyConfig config = new Meecrowave.Builder()
                 .property("my-prefix-port", "1234")
@@ -160,4 +199,51 @@ public class MeecrowaveTest {
         @CliOption(name = "my-prefix-bool", description = "")
         private boolean bool;
     }
+
+    private static URL configUrl(final String content) throws MalformedURLException {
+        return new URL("memory", null, -1, "test.config.properties", new MemoryHandler(content));
+    }
+
+    private static void withConfigClassLoader(final Runnable test, final URL... urls) {
+        final Thread thread = Thread.currentThread();
+        final ClassLoader loader = thread.getContextClassLoader();
+        thread.setContextClassLoader(new ClassLoader(loader) {
+            @Override
+            public Enumeration<URL> getResources(final String name) throws IOException
{
+                return "test.config.properties".equals(name) ? enumeration(asList(urls))
: super.getResources(name);
+            }
+        });
+        try {
+            test.run();
+        } finally {
+            thread.setContextClassLoader(loader);
+        }
+    }
+
+    private static class MemoryHandler extends URLStreamHandler
+    {
+        private final String content;
+
+        private MemoryHandler(final String content)
+        {
+            this.content = content;
+        }
+
+        @Override
+        protected URLConnection openConnection(final URL u) {
+            return new URLConnection(u)
+            {
+                @Override
+                public void connect()
+                {
+                    // no-op
+                }
+
+                @Override
+                public InputStream getInputStream() {
+                    return new ByteArrayInputStream(content.getBytes(StandardCharsets.UTF_8));
+                }
+            };
+        }
+    }
 }
diff --git a/meecrowave-doc/src/main/jbake/content/meecrowave-core/configuration.adoc b/meecrowave-doc/src/main/jbake/content/meecrowave-core/configuration.adoc
index c49a74d..06e60e7 100755
--- a/meecrowave-doc/src/main/jbake/content/meecrowave-core/configuration.adoc
+++ b/meecrowave-doc/src/main/jbake/content/meecrowave-core/configuration.adoc
@@ -124,7 +124,11 @@ Finally you can use any dotted attribute to configure the valve (see
example aft
 - `configurationCustomizer.x=y` will set `x` to `y` for the customizer
 
 TIP: Out of the box, any `Builder` instance will read `meecrowave.properties`.
-`meecrowave.properties` uses CLI names (without the leading `--`).
+`meecrowave.properties` uses CLI names (without the leading `--`). It loads all available
files from the classpath,
+they are merged using `configuration.ordinal` key (exactly like Apache OpenWebBeans does
for its configuration).
+It also supports `configuration.complete=[true|false]` which enables a single file to host
it with the `true` value
+and will consider this file as the merged result of all potential files found in the classpath.
It is useful to
+avoid an implicit merging and can typically be used in `conf/meecrowave.properties` in bundle
mode.
 See link:{context_rootpath}/meecrowave-core/cli.html[CLI] page for the list.
 
 === Valve configuration
diff --git a/pom.xml b/pom.xml
index 446a8aa..77efdc8 100644
--- a/pom.xml
+++ b/pom.xml
@@ -51,7 +51,7 @@
 
     <junit.version>4.13-beta-3</junit.version>
     <tomcat.version>9.0.22</tomcat.version>
-    <openwebbeans.version>2.0.11</openwebbeans.version>
+    <openwebbeans.version>2.0.12-SNAPSHOT</openwebbeans.version>
     <cxf.version>3.3.2</cxf.version>
     <johnzon.version>1.1.13-SNAPSHOT</johnzon.version>
     <log4j2.version>2.11.2</log4j2.version>


Mime
View raw message