Repository: camel
Updated Branches:
  refs/heads/master ca660ed24 -> 9218c6637


CAMEL-10045: camel-spring-boot - Allow to load sensitive options from external 
file


Project: http://git-wip-us.apache.org/repos/asf/camel/repo
Commit: http://git-wip-us.apache.org/repos/asf/camel/commit/9218c663
Tree: http://git-wip-us.apache.org/repos/asf/camel/tree/9218c663
Diff: http://git-wip-us.apache.org/repos/asf/camel/diff/9218c663

Branch: refs/heads/master
Commit: 9218c6637063c69e7985f23e5d1e4400693f04b0
Parents: ca660ed
Author: Claus Ibsen <davscl...@apache.org>
Authored: Fri Jul 1 10:57:26 2016 +0200
Committer: Claus Ibsen <davscl...@apache.org>
Committed: Fri Jul 1 14:22:06 2016 +0200

----------------------------------------------------------------------
 .../spring/boot/CamelAutoConfiguration.java     | 20 +++++
 .../boot/CamelConfigurationProperties.java      | 20 +++++
 .../camel/spring/boot/FilePropertySource.java   | 81 ++++++++++++++++++++
 .../boot/CamelConfigurationLocationsTest.java   | 61 +++++++++++++++
 .../src/test/secret/do-not-tell.properties      | 18 +++++
 5 files changed, 200 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/camel/blob/9218c663/components/camel-spring-boot/src/main/java/org/apache/camel/spring/boot/CamelAutoConfiguration.java
----------------------------------------------------------------------
diff --git 
a/components/camel-spring-boot/src/main/java/org/apache/camel/spring/boot/CamelAutoConfiguration.java
 
b/components/camel-spring-boot/src/main/java/org/apache/camel/spring/boot/CamelAutoConfiguration.java
index a293b6e..a2a760e 100644
--- 
a/components/camel-spring-boot/src/main/java/org/apache/camel/spring/boot/CamelAutoConfiguration.java
+++ 
b/components/camel-spring-boot/src/main/java/org/apache/camel/spring/boot/CamelAutoConfiguration.java
@@ -27,18 +27,26 @@ import 
org.apache.camel.component.properties.PropertiesComponent;
 import org.apache.camel.component.properties.PropertiesParser;
 import org.apache.camel.spring.CamelBeanPostProcessor;
 import org.apache.camel.spring.SpringCamelContext;
+import org.apache.camel.util.ObjectHelper;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 import 
org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
 import 
org.springframework.boot.context.properties.EnableConfigurationProperties;
 import org.springframework.context.ApplicationContext;
 import org.springframework.context.annotation.Bean;
 import org.springframework.context.annotation.Configuration;
 import org.springframework.context.annotation.Import;
+import org.springframework.core.env.ConfigurableEnvironment;
+import org.springframework.core.env.Environment;
+import org.springframework.core.env.MutablePropertySources;
 
 @Configuration
 @EnableConfigurationProperties(CamelConfigurationProperties.class)
 @Import(TypeConversionConfiguration.class)
 public class CamelAutoConfiguration {
 
+    private static final Logger LOG = 
LoggerFactory.getLogger(CamelAutoConfiguration.class);
+
     /**
      * Spring-aware Camel context for the application. Auto-detects and loads 
all routes available in the Spring context.
      */
@@ -47,6 +55,18 @@ public class CamelAutoConfiguration {
     CamelContext camelContext(ApplicationContext applicationContext,
                               CamelConfigurationProperties config) {
 
+        if (ObjectHelper.isNotEmpty(config.getFileConfigurations())) {
+            Environment env = applicationContext.getEnvironment();
+            if (env instanceof ConfigurableEnvironment) {
+                MutablePropertySources sources = ((ConfigurableEnvironment) 
env).getPropertySources();
+                if (sources != null) {
+                    if (!sources.contains("camel-file-configuration")) {
+                        sources.addFirst(new 
FilePropertySource("camel-file-configuration", applicationContext, 
config.getFileConfigurations()));
+                    }
+                }
+            }
+        }
+
         CamelContext camelContext = new SpringCamelContext(applicationContext);
         SpringCamelContext.setNoStart(true);
 

http://git-wip-us.apache.org/repos/asf/camel/blob/9218c663/components/camel-spring-boot/src/main/java/org/apache/camel/spring/boot/CamelConfigurationProperties.java
----------------------------------------------------------------------
diff --git 
a/components/camel-spring-boot/src/main/java/org/apache/camel/spring/boot/CamelConfigurationProperties.java
 
b/components/camel-spring-boot/src/main/java/org/apache/camel/spring/boot/CamelConfigurationProperties.java
index 8f65c9d..e88b6e3 100644
--- 
a/components/camel-spring-boot/src/main/java/org/apache/camel/spring/boot/CamelConfigurationProperties.java
+++ 
b/components/camel-spring-boot/src/main/java/org/apache/camel/spring/boot/CamelConfigurationProperties.java
@@ -62,6 +62,18 @@ public class CamelConfigurationProperties {
     private String xmlRests = "classpath:camel-rest/*.xml";
 
     /**
+     * Directory to load additional configuration files that contains
+     * configuration values that takes precedence over any other configuration.
+     * This can be used to refer to files that may have secret configuration 
that
+     * has been mounted on the file system for containers.
+     * <p/>
+     * You must use either <tt>file:</tt> or <tt>classpath:</tt> as prefix to 
load
+     * from file system or classpath. Then you can specify a pattern to load
+     * from sub directories and a name pattern such as 
<tt>file:/var/app/secret/*.properties</tt>
+     */
+    private String fileConfigurations;
+
+    /**
      * Whether to use the main run controller to ensure the Spring-Boot 
application
      * keeps running until being stopped or the JVM terminated.
      * You typically only need this if you run Spring-Boot standalone.
@@ -322,4 +334,12 @@ public class CamelConfigurationProperties {
     public void setJmxCreateConnector(boolean jmxCreateConnector) {
         this.jmxCreateConnector = jmxCreateConnector;
     }
+
+    public String getFileConfigurations() {
+        return fileConfigurations;
+    }
+
+    public void setFileConfigurations(String fileConfigurations) {
+        this.fileConfigurations = fileConfigurations;
+    }
 }

http://git-wip-us.apache.org/repos/asf/camel/blob/9218c663/components/camel-spring-boot/src/main/java/org/apache/camel/spring/boot/FilePropertySource.java
----------------------------------------------------------------------
diff --git 
a/components/camel-spring-boot/src/main/java/org/apache/camel/spring/boot/FilePropertySource.java
 
b/components/camel-spring-boot/src/main/java/org/apache/camel/spring/boot/FilePropertySource.java
new file mode 100644
index 0000000..e2aa295
--- /dev/null
+++ 
b/components/camel-spring-boot/src/main/java/org/apache/camel/spring/boot/FilePropertySource.java
@@ -0,0 +1,81 @@
+/**
+ * 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.camel.spring.boot;
+
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.util.Properties;
+
+import org.apache.camel.util.ObjectHelper;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.context.ApplicationContext;
+import org.springframework.core.env.PropertySource;
+import org.springframework.core.io.Resource;
+
+/**
+ * To load properties from files, such as a secret mounted to the container.
+ */
+public class FilePropertySource extends PropertySource {
+
+    private static final Logger LOG = 
LoggerFactory.getLogger(FilePropertySource.class);
+
+    // properties for all the loaded files
+    private final Properties properties;
+
+    public FilePropertySource(String name, ApplicationContext 
applicationContext, String directory) {
+        super(name);
+        ObjectHelper.notEmpty(directory, "directory");
+
+        Properties loaded = new Properties();
+        try {
+            Resource[] files = applicationContext.getResources(directory);
+            for (Resource file : files) {
+                if (file.exists()) {
+                    try (FileInputStream fis = new 
FileInputStream(file.getFile())) {
+                        LOG.debug("Loading properties from file: {}", file);
+                        Properties extra = new Properties();
+                        extra.load(fis);
+                        if (!extra.isEmpty()) {
+                            loaded.putAll(extra);
+                        }
+                    } catch (IOException e) {
+                        // ignore
+                    }
+                }
+            }
+        } catch (IOException e) {
+            // ignore
+        }
+
+        // if we loaded any files then store as properties
+        if (loaded.isEmpty()) {
+            properties = null;
+            LOG.warn("No properties found while loading from: {}", directory);
+        } else {
+            properties = loaded;
+            LOG.info("Loaded {} properties from: {}", properties.size(), 
directory);
+        }
+    }
+
+    @Override
+    public Object getProperty(String name) {
+        Object answer = properties != null ? properties.getProperty(name) : 
null;
+        LOG.trace("getProperty {} -> {}", name, answer);
+        return answer;
+    }
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/9218c663/components/camel-spring-boot/src/test/java/org/apache/camel/spring/boot/CamelConfigurationLocationsTest.java
----------------------------------------------------------------------
diff --git 
a/components/camel-spring-boot/src/test/java/org/apache/camel/spring/boot/CamelConfigurationLocationsTest.java
 
b/components/camel-spring-boot/src/test/java/org/apache/camel/spring/boot/CamelConfigurationLocationsTest.java
new file mode 100644
index 0000000..2d8691a
--- /dev/null
+++ 
b/components/camel-spring-boot/src/test/java/org/apache/camel/spring/boot/CamelConfigurationLocationsTest.java
@@ -0,0 +1,61 @@
+/**
+ * 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.camel.spring.boot;
+
+import org.apache.camel.CamelContext;
+import org.apache.camel.ProducerTemplate;
+import org.apache.camel.builder.RouteBuilder;
+import org.junit.Assert;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
+import org.springframework.boot.test.IntegrationTest;
+import org.springframework.boot.test.SpringApplicationConfiguration;
+import org.springframework.context.annotation.Bean;
+import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
+
+@RunWith(SpringJUnit4ClassRunner.class)
+@EnableAutoConfiguration
+@SpringApplicationConfiguration(classes = 
CamelConfigurationLocationsTest.class)
+@IntegrationTest("camel.springboot.file-configurations=file:src/test/secret/*.properties")
+public class CamelConfigurationLocationsTest extends Assert {
+
+    @Autowired
+    CamelContext camelContext;
+
+    @Autowired
+    ProducerTemplate producerTemplate;
+
+    @Bean
+    RouteBuilder routeBuilder() {
+        return new RouteBuilder() {
+            @Override
+            public void configure() throws Exception {
+                from("direct:foo")
+                    .to("stub:foo?password={{mypassword}}");
+            }
+        };
+    }
+
+    @Test
+    public void shouldSecret() throws InterruptedException {
+        Object endpoint = camelContext.hasEndpoint("stub:foo?password=1234");
+        assertNotNull(endpoint);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/9218c663/components/camel-spring-boot/src/test/secret/do-not-tell.properties
----------------------------------------------------------------------
diff --git 
a/components/camel-spring-boot/src/test/secret/do-not-tell.properties 
b/components/camel-spring-boot/src/test/secret/do-not-tell.properties
new file mode 100644
index 0000000..277c8c0
--- /dev/null
+++ b/components/camel-spring-boot/src/test/secret/do-not-tell.properties
@@ -0,0 +1,18 @@
+#
+# 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.
+#
+
+mypassword=1234
\ No newline at end of file

Reply via email to