diff --git a/camel-k-core/api/src/main/java/org/apache/camel/k/Runtime.java b/camel-k-core/api/src/main/java/org/apache/camel/k/Runtime.java index b1948046f..9b301a639 100644 --- a/camel-k-core/api/src/main/java/org/apache/camel/k/Runtime.java +++ b/camel-k-core/api/src/main/java/org/apache/camel/k/Runtime.java @@ -16,12 +16,9 @@ */ package org.apache.camel.k; -import java.util.Arrays; -import java.util.Collection; import java.util.HashMap; import java.util.Map; import java.util.Properties; -import java.util.stream.Collectors; import org.apache.camel.CamelContext; import org.apache.camel.Ordered; @@ -33,7 +30,14 @@ import static org.apache.camel.util.CollectionHelper.mapOf; public interface Runtime extends HasCamelContext, AutoCloseable { - + /** + * Returns the camel context adapting it to the specialized type. + * + * @see HasCamelContext#getCamelContext() + * @see CamelContext#adapt(Class) + * + * @return the camel context. + */ default T getCamelContext(Class type) { return getCamelContext().adapt(type); } @@ -45,27 +49,22 @@ default Registry getRegistry() { return getCamelContext().getRegistry(); } - default void setInitialProperties(Properties properties) { - getCamelContext().getPropertiesComponent().setInitialProperties(properties); - } - - default void setInitialProperties(Map properties) { - Properties p = new Properties(); - p.putAll(properties); - - setInitialProperties(p); - } - - default void setInitialProperties(String key, String value, String... keyVals) { - setInitialProperties( - mapOf(HashMap::new, key, value, keyVals) - ); - } - + /** + * Sets a special list of properties that take precedence and will use first, if a property exist. + * + * @see org.apache.camel.spi.PropertiesComponent#setOverrideProperties(Properties) + * @param properties the properties to set + */ default void setProperties(Properties properties) { getCamelContext().getPropertiesComponent().setOverrideProperties(properties); } + /** + * Sets a special list of properties that take precedence and will use first, if a property exist. + * + * @see org.apache.camel.spi.PropertiesComponent#setOverrideProperties(Properties) + * @param properties the properties to set + */ default void setProperties(Map properties) { Properties p = new Properties(); p.putAll(properties); @@ -73,12 +72,27 @@ default void setProperties(Map properties) { setProperties(p); } - default void setProperties(String key, String value, String... keyVals) { + /** + * Sets a special list of properties that take precedence and will use first, if a property exist. + * + * @see org.apache.camel.spi.PropertiesComponent#setOverrideProperties(Properties) + * @param key the mapping's key + * @param value the mapping's value + * @param entries containing the keys and values from which the map is populated + * + */ + default void setProperties(String key, String value, String... entries) { setProperties( - mapOf(HashMap::new, key, value, keyVals) + mapOf(HashMap::new, key, value, entries) ); } + /** + * Sets a special list of properties that take precedence and will use first, if a property exist. + * + * @see org.apache.camel.spi.PropertiesComponent#setOverrideProperties(Properties) + * @param builder the builder which will create the routes + */ default void addRoutes(RoutesBuilder builder) { try { getCamelContext().addRoutes(builder); @@ -87,20 +101,6 @@ default void addRoutes(RoutesBuilder builder) { } } - default void setPropertiesLocations(Collection locations) { - getCamelContext().getPropertiesComponent().setLocation( - locations.stream() - .map(location -> location.startsWith("file:") ? location : "file:" + location) - .distinct() - .sorted() - .collect(Collectors.joining(",")) - ); - } - - default void setPropertiesLocations(String... locations) { - setPropertiesLocations(Arrays.asList(locations)); - } - /** * Lifecycle method used to stops the entire integration. */ diff --git a/camel-k-core/api/src/main/java/org/apache/camel/k/SourceLoader.java b/camel-k-core/api/src/main/java/org/apache/camel/k/SourceLoader.java index 0b15130d1..602de9889 100644 --- a/camel-k-core/api/src/main/java/org/apache/camel/k/SourceLoader.java +++ b/camel-k-core/api/src/main/java/org/apache/camel/k/SourceLoader.java @@ -34,7 +34,6 @@ public interface SourceLoader { * @param runtime the runtime. * @param source the source to load. * @return the RoutesBuilder. - * @throws Exception */ RoutesBuilder load(Runtime runtime, Source source); diff --git a/camel-k-core/support/src/main/java/org/apache/camel/k/listener/PropertiesConfigurer.java b/camel-k-core/support/src/main/java/org/apache/camel/k/listener/PropertiesConfigurer.java index 5baeb4aa8..2dadca5ef 100644 --- a/camel-k-core/support/src/main/java/org/apache/camel/k/listener/PropertiesConfigurer.java +++ b/camel-k-core/support/src/main/java/org/apache/camel/k/listener/PropertiesConfigurer.java @@ -20,7 +20,6 @@ import org.apache.camel.k.Runtime; import org.apache.camel.k.support.Constants; import org.apache.camel.k.support.KubernetesPropertiesFunction; -import org.apache.camel.k.support.PropertiesSupport; public class PropertiesConfigurer extends AbstractPhaseListener { public PropertiesConfigurer() { @@ -34,13 +33,6 @@ public int getOrder() { @Override protected void accept(Runtime runtime) { - runtime.setInitialProperties( - PropertiesSupport.loadApplicationProperties() - ); - runtime.setPropertiesLocations( - PropertiesSupport.resolveUserPropertiesLocations() - ); - // // Register properties functions to resolve k8s secrets or config maps like: // diff --git a/camel-k-core/support/src/main/java/org/apache/camel/k/support/DelegatingRuntime.java b/camel-k-core/support/src/main/java/org/apache/camel/k/support/DelegatingRuntime.java index 9cce10f3c..c853d7712 100644 --- a/camel-k-core/support/src/main/java/org/apache/camel/k/support/DelegatingRuntime.java +++ b/camel-k-core/support/src/main/java/org/apache/camel/k/support/DelegatingRuntime.java @@ -16,7 +16,6 @@ */ package org.apache.camel.k.support; -import java.util.Collection; import java.util.Map; import java.util.Properties; @@ -42,21 +41,6 @@ public Registry getRegistry() { return runtime.getRegistry(); } - @Override - public void setInitialProperties(Properties properties) { - runtime.setInitialProperties(properties); - } - - @Override - public void setInitialProperties(Map properties) { - runtime.setInitialProperties(properties); - } - - @Override - public void setInitialProperties(String key, String value, String... keyVals) { - runtime.setInitialProperties(key, value, keyVals); - } - @Override public void setProperties(Properties properties) { runtime.setProperties(properties); @@ -77,16 +61,6 @@ public void addRoutes(RoutesBuilder builder) { runtime.addRoutes(builder); } - @Override - public void setPropertiesLocations(Collection locations) { - runtime.setPropertiesLocations(locations); - } - - @Override - public void setPropertiesLocations(String... locations) { - runtime.setPropertiesLocations(locations); - } - @Override public void stop() throws Exception { runtime.stop(); diff --git a/camel-k-core/support/src/main/java/org/apache/camel/k/support/PropertiesSupport.java b/camel-k-core/support/src/main/java/org/apache/camel/k/support/PropertiesSupport.java index b88d64d39..43a93e416 100644 --- a/camel-k-core/support/src/main/java/org/apache/camel/k/support/PropertiesSupport.java +++ b/camel-k-core/support/src/main/java/org/apache/camel/k/support/PropertiesSupport.java @@ -16,22 +16,9 @@ */ package org.apache.camel.k.support; -import java.io.IOException; -import java.io.Reader; -import java.nio.file.FileVisitResult; -import java.nio.file.FileVisitor; -import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.Paths; -import java.nio.file.SimpleFileVisitor; -import java.nio.file.attribute.BasicFileAttributes; -import java.util.Collection; import java.util.HashMap; -import java.util.LinkedHashSet; import java.util.Map; -import java.util.Objects; import java.util.Properties; -import java.util.Set; import java.util.function.Predicate; import org.apache.camel.CamelContext; @@ -41,7 +28,6 @@ import org.apache.camel.spi.PropertyConfigurer; import org.apache.camel.support.PropertyBindingSupport; import org.apache.camel.support.service.ServiceHelper; -import org.apache.camel.util.ObjectHelper; public final class PropertiesSupport { private PropertiesSupport() { @@ -103,93 +89,4 @@ public static T bindProperties(CamelContext context, T target, Predicate resolveUserPropertiesLocations() { - final String conf = resolveUserPropertiesLocation(); - final Set locations = new LinkedHashSet<>(); - - // Additional locations - if (ObjectHelper.isNotEmpty(conf)) { - Path root = Paths.get(conf); - FileVisitor visitor = new SimpleFileVisitor<>() { - @Override - public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException { - Objects.requireNonNull(file); - Objects.requireNonNull(attrs); - - final String path = file.toFile().getAbsolutePath(); - if (path.endsWith(".properties")) { - locations.add(path); - } - - return FileVisitResult.CONTINUE; - } - }; - - if (Files.exists(root)) { - try { - Files.walkFileTree(root, visitor); - } catch (IOException e) { - throw new RuntimeException(e); - } - } - } - - return locations; - } } diff --git a/camel-k-core/support/src/main/java/org/apache/camel/k/support/RuntimeSupport.java b/camel-k-core/support/src/main/java/org/apache/camel/k/support/RuntimeSupport.java index b21130749..16df12d2a 100644 --- a/camel-k-core/support/src/main/java/org/apache/camel/k/support/RuntimeSupport.java +++ b/camel-k-core/support/src/main/java/org/apache/camel/k/support/RuntimeSupport.java @@ -16,8 +16,19 @@ */ package org.apache.camel.k.support; +import java.io.IOException; import java.io.InputStream; +import java.io.Reader; +import java.nio.charset.StandardCharsets; +import java.nio.file.FileVisitResult; +import java.nio.file.FileVisitor; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.nio.file.SimpleFileVisitor; +import java.nio.file.attribute.BasicFileAttributes; import java.util.ArrayList; +import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Objects; @@ -294,4 +305,77 @@ public static String getRuntimeVersion() { return Objects.requireNonNull(version, "Could not determine Camel K Runtime version"); } + // ********************************* + // + // Properties + // + // ********************************* + + public static Map loadApplicationProperties() { + final String conf = System.getProperty(Constants.PROPERTY_CAMEL_K_CONF, System.getenv(Constants.ENV_CAMEL_K_CONF)); + final Map properties = new HashMap<>(); + + if (ObjectHelper.isEmpty(conf)) { + return properties; + } + + try { + Path confPath = Paths.get(conf); + + if (Files.exists(confPath)) { + try (Reader reader = Files.newBufferedReader(confPath)) { + Properties p = new Properties(); + p.load(reader); + p.forEach((key, value) -> properties.put(String.valueOf(key), String.valueOf(value))); + } + } + } catch (IOException e) { + throw new RuntimeException(e); + } + + return properties; + } + + public static Map loadUserProperties() { + final String conf = System.getProperty(Constants.PROPERTY_CAMEL_K_CONF_D, System.getenv(Constants.ENV_CAMEL_K_CONF_D)); + final Map properties = new HashMap<>(); + + if (ObjectHelper.isEmpty(conf)) { + return properties; + } + + FileVisitor visitor = new SimpleFileVisitor<>() { + @Override + public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException { + Objects.requireNonNull(file); + Objects.requireNonNull(attrs); + + if (file.toFile().getAbsolutePath().endsWith(".properties")) { + try (Reader reader = Files.newBufferedReader(file)) { + Properties p = new Properties(); + p.load(reader); + p.forEach((key, value) -> properties.put(String.valueOf(key), String.valueOf(value))); + } + } else { + properties.put( + file.getFileName().toString(), + Files.readString(file, StandardCharsets.UTF_8)); + } + + return FileVisitResult.CONTINUE; + } + }; + + Path root = Paths.get(conf); + + if (Files.exists(root)) { + try { + Files.walkFileTree(root, visitor); + } catch (IOException e) { + throw new RuntimeException(e); + } + } + + return properties; + } } diff --git a/camel-k-runtime/runtime/src/main/java/org/apache/camel/k/quarkus/Application.java b/camel-k-runtime/runtime/src/main/java/org/apache/camel/k/quarkus/Application.java index 91c89b825..50da09917 100644 --- a/camel-k-runtime/runtime/src/main/java/org/apache/camel/k/quarkus/Application.java +++ b/camel-k-runtime/runtime/src/main/java/org/apache/camel/k/quarkus/Application.java @@ -63,11 +63,6 @@ public void addRoutes(RoutesBuilder builder) { main.configure().addRoutesBuilder(builder); } - @Override - public void setInitialProperties(Properties properties) { - main.setInitialProperties(properties); - } - @Override public void setProperties(Properties properties) { main.setOverrideProperties(properties); diff --git a/camel-k-runtime/runtime/src/main/java/org/apache/camel/k/quarkus/ApplicationConfigSourceProvider.java b/camel-k-runtime/runtime/src/main/java/org/apache/camel/k/quarkus/ApplicationConfigSourceProvider.java index cef2910a0..77fffb207 100644 --- a/camel-k-runtime/runtime/src/main/java/org/apache/camel/k/quarkus/ApplicationConfigSourceProvider.java +++ b/camel-k-runtime/runtime/src/main/java/org/apache/camel/k/quarkus/ApplicationConfigSourceProvider.java @@ -16,28 +16,23 @@ */ package org.apache.camel.k.quarkus; -import java.util.Collections; -import java.util.Properties; +import java.util.List; +import java.util.Map; import io.smallrye.config.PropertiesConfigSource; -import org.apache.camel.k.support.PropertiesSupport; +import org.apache.camel.k.support.RuntimeSupport; import org.eclipse.microprofile.config.spi.ConfigSource; import org.eclipse.microprofile.config.spi.ConfigSourceProvider; public class ApplicationConfigSourceProvider implements ConfigSourceProvider { @Override public Iterable getConfigSources(ClassLoader forClassLoader) { - final Properties applicationProperties = PropertiesSupport.loadProperties(); - final Properties quarkusProperties = new Properties(); + final Map appProperties = RuntimeSupport.loadApplicationProperties(); + final Map usrProperties = RuntimeSupport.loadUserProperties(); - for (String name : applicationProperties.stringPropertyNames()) { - if (name.startsWith("quarkus.")) { - quarkusProperties.put(name, applicationProperties.get(name)); - } - } - - return Collections.singletonList( - new PropertiesConfigSource(quarkusProperties, "camel-k") + return List.of( + new PropertiesConfigSource(appProperties, "camel-k-app", ConfigSource.DEFAULT_ORDINAL), + new PropertiesConfigSource(usrProperties, "camel-k-usr", ConfigSource.DEFAULT_ORDINAL + 1) ); } } diff --git a/itests/camel-k-itests-runtime/src/main/java/org/apache/camel/k/quarkus/it/Application.java b/itests/camel-k-itests-runtime/src/main/java/org/apache/camel/k/quarkus/it/Application.java index 92391ac54..cf4c85542 100644 --- a/itests/camel-k-itests-runtime/src/main/java/org/apache/camel/k/quarkus/it/Application.java +++ b/itests/camel-k-itests-runtime/src/main/java/org/apache/camel/k/quarkus/it/Application.java @@ -57,13 +57,6 @@ public JsonObject inspect() { .add( "routes-collector", instance(CamelMain.class).map(BaseMainSupport::getRoutesCollector).map(Object::getClass).map(Class::getName).orElse("")) - .add( - "properties-locations", - Json.createArrayBuilder(instance(CamelContext.class) - .map(CamelContext::getPropertiesComponent) - .map(PropertiesComponent.class::cast) - .map(PropertiesComponent::getLocations) - .orElseGet(Collections::emptyList))) .build(); } @@ -88,27 +81,16 @@ public String property(@PathParam("name") String name) { .flatMap(pc -> pc.resolveProperty(name)).orElse(""); } - @GET - @Path("/initial-property/{name}") - @Produces(MediaType.TEXT_PLAIN) - public String initialProperty(@PathParam("name") String name) { - return (String)instance(CamelContext.class) - .map(CamelContext::getPropertiesComponent) - .map(PropertiesComponent.class::cast) - .map(pc -> pc.getInitialProperties().get(name)) - .orElse(""); - } - @SuppressWarnings("unchecked") @GET - @Path("/initial-properties") + @Path("/properties") @Produces(MediaType.APPLICATION_JSON) - public JsonObject initialProperties() { + public JsonObject properties() { return Json.createObjectBuilder( instance(CamelContext.class) .map(CamelContext::getPropertiesComponent) .map(PropertiesComponent.class::cast) - .map(PropertiesComponent::getInitialProperties) + .map(PropertiesComponent::loadProperties) .map(Map.class::cast) .orElseGet(Collections::emptyMap) ).build(); diff --git a/itests/camel-k-itests-runtime/src/test/java/org/apache/camel/k/quarkus/it/RuntimeTest.java b/itests/camel-k-itests-runtime/src/test/java/org/apache/camel/k/quarkus/it/RuntimeTest.java index 3d7f41a43..19fea587c 100644 --- a/itests/camel-k-itests-runtime/src/test/java/org/apache/camel/k/quarkus/it/RuntimeTest.java +++ b/itests/camel-k-itests-runtime/src/test/java/org/apache/camel/k/quarkus/it/RuntimeTest.java @@ -16,14 +16,11 @@ */ package org.apache.camel.k.quarkus.it; -import java.util.Map; - import javax.ws.rs.core.MediaType; import io.quarkus.test.junit.QuarkusTest; import io.restassured.path.json.JsonPath; import org.apache.camel.k.quarkus.Application; -import org.apache.camel.k.support.PropertiesSupport; import org.apache.camel.quarkus.core.FastCamelContext; import org.junit.jupiter.api.Test; @@ -50,25 +47,6 @@ public void inspect() { .isEqualTo(Application.Runtime.class.getName()); assertThat(p.getString("routes-collector")) .isEqualTo(Application.NoRoutesCollector.class.getName()); - assertThat(p.getList("properties-locations", String.class)) - .contains("file:" + System.getProperty("camel.k.conf.d", System.getenv("CAMEL_K_CONF_D")) + "/001/conf.properties") - .contains("file:" + System.getProperty("camel.k.conf.d", System.getenv("CAMEL_K_CONF_D")) + "/002/conf.properties"); - } - - @SuppressWarnings("unchecked") - @Test - public void initialProperties() { - Map initialProperties = given() - .accept(MediaType.APPLICATION_JSON) - .get("/test/initial-properties") - .then() - .statusCode(200) - .extract() - .body().jsonPath().getMap(".", String.class, String.class); - - assertThat(initialProperties).containsExactlyEntriesOf((Map)PropertiesSupport.loadApplicationProperties()); - assertThat(initialProperties).containsEntry("root.key", "root.value"); - assertThat(initialProperties).containsEntry("a.key", "a.root"); } @Test @@ -78,5 +56,6 @@ public void properties() { given().get("/test/property/001.key").then().statusCode(200).body(is("001.value")); given().get("/test/property/002.key").then().statusCode(200).body(is("002.value")); given().get("/test/property/a.key").then().statusCode(200).body(is("a.002")); + given().get("/test/property/flat-property").then().statusCode(200).body(is("flat-value")); } } \ No newline at end of file diff --git a/itests/camel-k-itests-runtime/src/test/resources/conf.d/003/flat-property b/itests/camel-k-itests-runtime/src/test/resources/conf.d/003/flat-property new file mode 100644 index 000000000..313b57de3 --- /dev/null +++ b/itests/camel-k-itests-runtime/src/test/resources/conf.d/003/flat-property @@ -0,0 +1 @@ +flat-value \ No newline at end of file