This is an automated email from the ASF dual-hosted git repository. davsclaus pushed a commit to branch CAMEL-13947 in repository https://gitbox.apache.org/repos/asf/camel.git
commit b653d05415016f75b36dd73a490ca34695145083 Author: Claus Ibsen <claus.ib...@gmail.com> AuthorDate: Thu Sep 26 13:22:41 2019 +0200 CAMEL-13947: PropertiesComponent should be a static service and resolved like other similar features. --- docs/gulpfile.js | 2 +- .../modules/ROOT/pages/properties-component.adoc | 833 --------------------- .../ROOT/pages/using-propertyplaceholder.adoc | 123 +-- 3 files changed, 9 insertions(+), 949 deletions(-) diff --git a/docs/gulpfile.js b/docs/gulpfile.js index 4202af8..37c31bf 100644 --- a/docs/gulpfile.js +++ b/docs/gulpfile.js @@ -80,7 +80,7 @@ function deleteUserManualSymlinks() { } function createUserManualSymlinks() { - return src(['../core/camel-base/src/main/docs/*.adoc', '../core/camel-core-engine/src/main/docs/eips/*.adoc']) + return src(['../core/camel-base/src/main/docs/*-language.adoc', '../core/camel-core-engine/src/main/docs/eips/*.adoc']) // Antora disabled symlinks, there is an issue open // https://gitlab.com/antora/antora/issues/188 // to reinstate symlink support, until that's resolved diff --git a/docs/user-manual/modules/ROOT/pages/properties-component.adoc b/docs/user-manual/modules/ROOT/pages/properties-component.adoc deleted file mode 100644 index 7cd2bc8..0000000 --- a/docs/user-manual/modules/ROOT/pages/properties-component.adoc +++ /dev/null @@ -1,833 +0,0 @@ -[[properties-component]] -= Properties Component -:page-source: core/camel-base/src/main/docs/properties-component.adoc - -*Available as of Camel version 2.3* - -The properties component is used for property placeholders in your Camel application, such as endpoint URIs. -It is *not* a regular Camel component with producer and consumer for routing messages. However for historical -reasons it was named `PropertiesComponent` and this name is commonly known and therfore we keep using it. - -== Spring Boot Auto-Configuration - -The component supports 10 options, which are listed below. - - - -[width="100%",cols="2,5,^1,2",options="header"] -|=== -| Name | Description | Default | Type -| *camel.component.properties.auto-discover-properties-sources* | Whether to automatically discovery instances of PropertiesSource from registry and service factory. | true | Boolean -| *camel.component.properties.default-fallback-enabled* | If false, the component does not attempt to find a default for the key by looking after the colon separator. | true | Boolean -| *camel.component.properties.encoding* | Encoding to use when loading properties file from the file system or classpath. If no encoding has been set, then the properties files is loaded using ISO-8859-1 encoding (latin-1) as documented by java.util.Properties#load(java.io.InputStream) | | String -| *camel.component.properties.environment-variable-mode* | Sets the OS environment variables mode (0 = never, 1 = fallback, 2 = override). The default mode (override) is to use OS environment variables if present, and override any existing properties. OS environment variable mode is checked before JVM system property mode | 2 | Integer -| *camel.component.properties.ignore-missing-location* | Whether to silently ignore if a location cannot be located, such as a properties file not found. | false | Boolean -| *camel.component.properties.initial-properties* | Sets initial properties which will be used before any locations are resolved. The option is a java.util.Properties type. | | String -| *camel.component.properties.location* | A list of locations to load properties. You can use comma to separate multiple locations. This option will override any default locations and only use the locations from this option. | | String -| *camel.component.properties.override-properties* | Sets a special list of override properties that take precedence and will use first, if a property exist. The option is a java.util.Properties type. | | String -| *camel.component.properties.properties-parser* | To use a custom PropertiesParser. The option is a org.apache.camel.component.properties.PropertiesParser type. | | String -| *camel.component.properties.system-properties-mode* | Sets the JVM system property mode (0 = never, 1 = fallback, 2 = override). The default mode (override) is to use system properties if present, and override any existing properties. OS environment variable mode is checked before JVM system property mode | 2 | Integer -|=== - -[TIP] -**Resolving property from Java code** + -You can use the method `resolvePropertyPlaceholders` on the -`CamelContext` to resolve a property from any Java code. - -== Using PropertyPlaceholder - -Camel now provides a new `PropertiesComponent` in *camel-core* which -allows you to use property placeholders when defining Camel -Endpoint URIs. - -This works much like you would do if using Spring's -`<property-placeholder>` tag. However Spring have a limitation which -prevents 3rd party frameworks to leverage Spring property placeholders -to the fullest. See more at -xref:manual::faq/how-do-i-use-spring-property-placeholder-with-camel-xml.adoc[How do -I use Spring Property Placeholder with Camel XML]. - -[TIP] -**Bridging Spring and Camel property placeholders** + -You can bridge the Spring property placeholder -with Camel, see further below for more details. - -The property placeholder is generally in use when doing: - -* lookup or creating endpoints -* lookup of beans in the Registry -* additional supported in Spring XML (see below in examples) -* using Blueprint PropertyPlaceholder with Camel -xref:properties-component.adoc[Properties] component -* using `@PropertyInject` to inject a property in a POJO -* Using default value if a property does not exists -* Include out of the box functions, to lookup property -values from OS environment variables, JVM system properties, or the -service idiom. -* Using custom functions, which can be plugged into the -property component. - -== Syntax - -The syntax to use Camel's property placeholder is to use `{\{key\}}` for -example `{{file.uri}}` where `file.uri` is the property key. - -You can use property placeholders in parts of the endpoint URI's which -for example you can use placeholders for parameters in the URIs. - -You can specify a default value to use if -a property with the key does not exists, eg `file.url:/some/path` where -the default value is the text after the colon (eg /some/path). - -NOTE: Do not use colon in the property key. The colon is used as a separator -token when you are providing a default value. - -== Defining location - -The properties component need to know a location(s) where to resolve the -properties. You can define 1 to many locations. If you define the -location in a single String property you can separate multiple locations -with comma such as: - -[source,java] ----- -pc.setLocation("com/mycompany/myprop.properties,com/mycompany/other.properties"); ----- - -You can set which location can be discarded if missing by by setting the ``optional`` attribute, which is false by default, i.e: - -[source,java] ----- -pc.setLocations( - "com/mycompany/override.properties;optional=true" - "com/mycompany/defaults.properties"); ----- - -== Using system and environment variables in locations - -The location now supports using placeholders for JVM system properties -and OS environments variables. - -For example: - -[source] ----- -location=file:${karaf.home}/etc/foo.properties ----- - -In the location above we defined a location using the file scheme using -the JVM system property with key `karaf.home`. - -To use an OS environment variable instead you would have to prefix with -env: - -[source] ----- -location=file:${env:APP_HOME}/etc/foo.properties ----- - -Where `APP_HOME` is an OS environment. - -NOTE: Some OS'es (such as Linux) do not support dashes in environment variable names, -so here we are using `APP_HOME`. But if you specify `APP-HOME` then Camel 3 will automatic lookup -the value as `APP_HOME` (with underscore) as fallback. - -You can have multiple placeholders in the same location, such as: - -[source] ----- -location=file:${env:APP_HOME}/etc/${prop.name}.properties ----- - -== Configuring in Java DSL - -You have to create and register the `PropertiesComponent` under the name -`properties` such as: - -[source,java] ----- -PropertiesComponent pc = camelContext.getPropertiesComponent(); -pc.setLocation("classpath:com/mycompany/myprop.properties"); ----- - -== Configuring in Spring XML - -Spring XML offers two variations to configure. You can define a spring -bean as a `PropertiesComponent` which resembles the way done in Java -DSL. Or you can use the `<propertyPlaceholder>` tag. - -[source,xml] ----- -<bean id="properties" class="org.apache.camel.component.properties.PropertiesComponent"> - <property name="location" value="classpath:com/mycompany/myprop.properties"/> -</bean> ----- - -Using the `<propertyPlaceholder>` tag makes the configuration a bit more -fresh such as: - -[source,xml] ----- -<camelContext ...> - <propertyPlaceholder id="properties" location="com/mycompany/myprop.properties"/> -</camelContext> ----- - -Setting the properties location through the location tag works just fine but sometime you have a number of resources to take into account and starting from *Camel 2.19.0* you can set the properties location with a dedicated propertiesLocation: - -[source,xml] ----- -<camelContext ...> - <propertyPlaceholder id="myPropertyPlaceholder"> - <propertiesLocation - resolver = "classpath" - path = "com/my/company/something/my-properties-1.properties" - optional = "false"/> - <propertiesLocation - resolver = "classpath" - path = "com/my/company/something/my-properties-2.properties" - optional = "false"/> - <propertiesLocation - resolver = "file" - path = "${karaf.home}/etc/my-override.properties" - optional = "true"/> - </propertyPlaceholder> -</camelContext> ----- - -[TIP] -**Specifying the cache option inside XML** + -Camel supports specifying a value for the cache option both -inside the Spring as well as the Blueprint XML. - -== Using a Properties from the Registry - -For example in OSGi you may want to expose a service which returns the -properties as a `java.util.Properties` object. - -Then you could setup the xref:properties-component.adoc[Properties] component as -follows: - -[source,xml] ----- - <propertyPlaceholder id="properties" location="ref:myProperties"/> ----- - -Where `myProperties` is the id to use for lookup in the OSGi registry. -Notice we use the `ref:` prefix to tell Camel that it should lookup the -properties for the Registry. - -== Examples using properties component - -When using property placeholders in the endpoint URIs you can either use -the `properties:` component or define the placeholders directly in the -URI. We will show example of both cases, starting with the former. - -[source,java] ----- -// properties -cool.end=mock:result - -// route -from("direct:start").to("{{cool.end}}"); ----- - -You can also use placeholders as a part of the endpoint uri: - -[source,java] ----- -// properties -cool.foo=result - -// route -from("direct:start").to("mock:{{cool.foo}}"); ----- - -In the example above the to endpoint will be resolved to `mock:result`. - -You can also have properties with refer to each other such as: - -[source,java] ----- -// properties -cool.foo=result -cool.concat=mock:{{cool.foo}} - -// route -from("direct:start").to("mock:{{cool.concat}}"); ----- - -Notice how `cool.concat` refer to another property. - -And you can use placeholders several times: - -[source,java] ----- -// properties -cool.start=direct:start -cool.showid=true -cool.result=result - -// route -from("{{cool.start}}") - .to("log:{{cool.start}}?showBodyType=false&showExchangeId={{cool.showid}}") - .to("mock:{{cool.result}}"); ----- - -You can also your property placeholders when using -ProducerTemplate for example: - -[source,java] ----- -template.sendBody("{{cool.start}}", "Hello World"); ----- - -== Example with xref:manual::simple-language.adoc[Simple] language - -The xref:manual::simple-language.adoc[Simple] language now also support using property -placeholders, for example in the route below: - -[source,java] ----- -// properties -cheese.quote=Camel rocks - -// route -from("direct:start") - .transform().simple("Hi ${body} do you think ${properties:cheese.quote}?"); ----- - -== Additional property placeholder supported in Spring XML - -The property placeholders is also supported in many of the Camel Spring -XML tags such as -`<package>, <packageScan>, <contextScan>, <jmxAgent>, <endpoint>, <routeBuilder>, <proxy>` -and the others. - -The example below has property placeholder in the `<jmxAgent>` tag: - -You can also define property placeholders in the various attributes on -the `<camelContext>` tag such as `trace` as shown here: - -== Using JVM system properties or Environment variables as override or fallback values - -The properties components supports using JVM system properties and also OS environment variables -as values which can either be used as override or fallback values. - -The default mode is that both of them are in override mode, and they are check in the following order: - -1. OS environment variable (override mode) -2. JVM system property (override mode) -3. Property files and other locations -4. OS environment variable (fallback mode) -5. JVM system property (fallback mode) - -The check stops at first found property value for the key. - -You can control these modes using the `systemPropertiesMode` and `environmentVariableMode` -options on the properties component. - -== Using property placeholders for any kind of attribute in the XML DSL - -In the example below we use the `prop` prefix for the namespace -camel.apache.org/schema/placeholder by which we can use the -`prop` prefix in the attributes in the XML DSLs. Notice how we use that -in the Multicast to indicate that the option -`stopOnException` should be the value of the placeholder with the key -"stop". - -In our properties file we have the value defined as - -[source] ----- -stop=true ----- - -== Using Blueprint property placeholder with Camel routes - -Camel supports Blueprint -which also offers a property placeholder service. Camel supports -convention over configuration, so all you have to do is to define the -OSGi Blueprint property placeholder in the XML file as shown below: - -[source,xml] ----- -<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0" - xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" - xmlns:cm="http://aries.apache.org/blueprint/xmlns/blueprint-cm/v1.0.0" - xsi:schemaLocation=" - http://www.osgi.org/xmlns/blueprint/v1.0.0 https://www.osgi.org/xmlns/blueprint/v1.0.0/blueprint.xsd"> - - <!-- OSGI blueprint property placeholder --> - <cm:property-placeholder id="myblueprint.placeholder" persistent-id="camel.blueprint"> - <!-- list some properties as needed --> - <cm:default-properties> - <cm:property name="result" value="mock:result"/> - </cm:default-properties> - </cm:property-placeholder> - - <camelContext xmlns="http://camel.apache.org/schema/blueprint"> - <!-- in the route we can use {{ }} placeholders which will lookup in blueprint - as Camel will auto detect the OSGi blueprint property placeholder and use it --> - <route> - <from uri="direct:start"/> - <to uri="mock:foo"/> - <to uri="{{result}}"/> - </route> - </camelContext> -</blueprint> ----- - -=== Using OSGi blueprint property placeholders in Camel routes - -By default Camel detects and uses OSGi blueprint property placeholder -service. You can disable this by setting the attribute -`useBlueprintPropertyResolver` to false on the `<camelContext>` -definition. - -=== About placeholder syntax - -Notice how we can use the Camel syntax for placeholders `{{` and `}}` in the -Camel route, which will lookup the value from OSGi blueprint. - -The blueprint syntax for placeholders is `${ }`. So outside the -`<camelContext>` you must use the `${ }` syntax. Where as inside -`<camelContext>` you must use `{{` and `}}` syntax. - -OSGi blueprint allows you to configure the syntax, so you can actually -align those if you want. - -You can also explicit refer to a specific OSGi blueprint property -placeholder by its id. For that you need to use the Camel's -`<propertyPlaceholder>` as shown in the example below: - -[source,xml] ----- -<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0" - xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" - xmlns:cm="http://aries.apache.org/blueprint/xmlns/blueprint-cm/v1.0.0" - xsi:schemaLocation=" - http://www.osgi.org/xmlns/blueprint/v1.0.0 https://www.osgi.org/xmlns/blueprint/v1.0.0/blueprint.xsd"> - - <!-- OSGI blueprint property placeholder --> - <cm:property-placeholder id="myblueprint.placeholder" persistent-id="camel.blueprint"> - <!-- list some properties as needed --> - <cm:default-properties> - <cm:property name="prefix.result" value="mock:result"/> - </cm:default-properties> - </cm:property-placeholder> - - <camelContext xmlns="http://camel.apache.org/schema/blueprint"> - <!-- using Camel properties component and refer to the blueprint property placeholder by its id --> - <propertyPlaceholder id="properties" location="blueprint:myblueprint.placeholder"/> - - <!-- in the route we can use {{ }} placeholders which will lookup in blueprint --> - <route> - <from uri="direct:start"/> - <to uri="mock:foo"/> - <to uri="{{prefix.result}}"/> - </route> - </camelContext> -</blueprint> ----- - - -== Explicit referring to a OSGi blueprint placeholder in Camel - -Notice how we use the `blueprint` scheme to refer to the OSGi blueprint -placeholder by its id. This allows you to mix and match, for example you -can also have additional schemes in the location. For example to load a -file from the classpath you can do: - -[source] ----- -location="blueprint:myblueprint.placeholder,classpath:myproperties.properties" ----- - -Each location is separated by comma. - -== Overriding Blueprint property placeholders outside CamelContext - -When using Blueprint property placeholder in the Blueprint XML file, you -can declare the properties directly in the XML file as shown below: - -Notice that we have a `<bean>` which refers to one of the properties. And -in the Camel route we refer to the other using the `{{` and `}}` notation. - -Now if you want to override these Blueprint properties from an unit -test, you can do this as shown below: - -To do this we override and implement the -`useOverridePropertiesWithConfigAdmin` method. We can then put the -properties we want to override on the given props parameter. And the -return value *must* be the `persistence-id` of the -`<cm:property-placeholder>` tag, which you define in the blueprint XML -file. - -== Using .cfg or .properties file for Blueprint property placeholders - -When using Blueprint property placeholder in the Blueprint XML file, you -can declare the properties in a `.properties` or `.cfg` file. If you use -Apache ServieMix / Karaf then this container has a convention that it -loads the properties from a file in the etc directory with the naming -`etc/pid.cfg`, where `pid` is the `persistence-id`. - -For example in the blueprint XML file we have the -`persistence-id="stuff"`, which mean it will load the configuration file -as `etc/stuff.cfg`. - -Now if you want to unit test this blueprint XML file, then you can -override the `loadConfigAdminConfigurationFile` and tell Camel which -file to load as shown below: - -Notice that this method requires to return a `String[]` with 2 values. The -1st value is the path for the configuration file to load. -The 2nd value is the `persistence-id` of the `<cm:property-placeholder>` -tag. - -The `stuff.cfg` file is just a plain properties file with the property -placeholders such as: - -[source] ----- -== this is a comment -greeting=Bye ----- - -== Using .cfg file and overriding properties for Blueprint property placeholders - -You can do both as well. Here is a complete example. First we have the -Blueprint XML file: - -And in the unit test class we do as follows: - -And the `etc/stuff.cfg` configuration file contains - -[source] ----- -greeting=Bye -echo=Yay -destination=mock:result ----- - -== Bridging Spring and Camel property placeholders - -The Spring Framework does not allow 3rd party frameworks such as Apache -Camel to seamless hook into the Spring property placeholder mechanism. -However you can easily bridge Spring and Camel by declaring a Spring -bean with the type -`org.apache.camel.spring.spi.BridgePropertyPlaceholderConfigurer`, which -is a Spring -`org.springframework.beans.factory.config.PropertyPlaceholderConfigurer` -type. - -To bridge Spring and Camel you must define a single bean as shown below: - -*Bridging Spring and Camel property placeholders* - -You *must not* use the spring <context:property-placeholder> namespace -at the same time; this is not possible. - -After declaring this bean, you can define property placeholders using -both the Spring style, and the Camel style within the <camelContext> tag -as shown below: - -*Using bridge property placeholders* - -Notice how the hello bean is using pure Spring property placeholders -using the `${ }` notation. And in the Camel routes we use the Camel -placeholder notation with `{{` and `}}`. - -== Clashing Spring property placeholders with Camels Simple language - -Take notice when using Spring bridging placeholder then the spring `${ }` -syntax clashes with the xref:manual::simple-language.adoc[Simple] in Camel, and therefore -take care. For example: - -[source,xml] ----- -<setHeader name="Exchange.FILE_NAME"> - <simple>{{file.rootdir}}/${in.header.CamelFileName}</simple> -</setHeader> ----- - -clashes with Spring property placeholders, and you should use `$simple{ }` -to indicate using the xref:manual::simple-language.adoc[Simple] language in Camel. - -[source,xml] ----- -<setHeader name="Exchange.FILE_NAME"> - <simple>{{file.rootdir}}/$simple{in.header.CamelFileName}</simple> -</setHeader> ----- - -An alternative is to configure the `PropertyPlaceholderConfigurer` with -`ignoreUnresolvablePlaceholders` option to `true`. - -== Overriding properties from Camel test kit - -When Testing with Camel and using the -xref:properties-component.adoc[Properties] component, you may want to be able to -provide the properties to be used from directly within the unit test -source code. + -Camel test kits, eg `CamelTestSupport` class offers the following methods - -* `useOverridePropertiesWithPropertiesComponent` -* `ignoreMissingLocationWithPropertiesComponent` - -So for example in your unit test classes, you can override the -`useOverridePropertiesWithPropertiesComponent` method and return a -`java.util.Properties` that contains the properties which should be -preferred to be used. - -=== Providing properties from within unit test source - -This can be done from any of the Camel Test kits, such as camel-test, -camel-test-spring, and camel-test-blueprint. - -The `ignoreMissingLocationWithPropertiesComponent` can be used to -instruct Camel to ignore any locations which was not discoverable, for -example if you run the unit test, in an environment that does not have -access to the location of the properties. - -== Using @PropertyInject - -Camel allows to inject property placeholders in POJOs using the -`@PropertyInject` annotation which can be set on fields and setter -methods. - -For example you can use that with `RouteBuilder` classes, such as shown -below: - -[source,java] ----- -public class MyRouteBuilder extends RouteBuilder { - - @PropertyInject("hello") - private String greeting; - - @Override - public void configure() throws Exception { - from("direct:start") - .transform().constant(greeting) - .to("{{result}}"); - } - -} ----- - -Notice we have annotated the greeting field with `@PropertyInject` and -define it to use the key `"hello"`. Camel will then lookup the property -with this key and inject its value, converted to a String type. - -You can also use multiple placeholders and text in the key, for example -we can do: - -[source,java] ----- -@PropertyInject("Hello {{name}} how are you?") -private String greeting; ----- - -This will lookup the placeholder with they key `"name"`. - -You can also add a default value if the key does not exists, such as: - -[source,java] ----- -@PropertyInject(value = "myTimeout", defaultValue = "5000") -private int timeout; ----- - -== Using out of the box functions - -The xref:properties-component.adoc[Properties] component includes the following -functions out of the box - -* `env` - A function to lookup the property from OS environment variables -* `sys` - A function to lookup the property from Java JVM system -properties -* `service` - A function to lookup the property from OS environment -variables using the service naming idiom -* `service.name` - A function to lookup the -property from OS environment variables using the service naming idiom -returning the hostname part only -* `service.port` - A function to lookup the -property from OS environment variables using the service naming idiom -returning the port part only - -As you can see these functions is intended to make it easy to lookup -values from the environment. As they are provided out of the box, they -can easily be used as shown below: - -[source,xml] ----- - <camelContext xmlns="http://camel.apache.org/schema/blueprint"> - - <route> - <from uri="direct:start"/> - <to uri="{`{env:SOMENAME}`}"/> - <to uri="{`{sys:MyJvmPropertyName}`}"/> - </route> - </camelContext> ----- - -You can use default values as well, so if the property does not exists, -you can define a default value as shown below, where the default value -is a `log:foo` and `log:bar` value. - -[source,xml] ----- - <camelContext xmlns="http://camel.apache.org/schema/blueprint"> - - <route> - <from uri="direct:start"/> - <to uri="{`{env:SOMENAME:log:foo}`}"/> - <to uri="{`{sys:MyJvmPropertyName:log:bar}`}"/> - </route> - </camelContext> ----- - - - -The service function is for looking up a service which is defined using -OS environment variables using the service naming idiom, to refer to a -service location using `hostname : port` - -* __NAME__**_SERVICE_HOST** -* __NAME__**_SERVICE_PORT** - -in other words the service uses `_SERVICE_HOST` and `_SERVICE_PORT` as -prefix. So if the service is named FOO, then the OS environment -variables should be set as - -[source] ----- -export $FOO_SERVICE_HOST=myserver -export $FOO_SERVICE_PORT=8888 ----- - -For example if the FOO service a remote HTTP service, then we can refer -to the service in the Camel endpoint uri, and use -the HTTP component to make the HTTP call: - -[source,xml] ----- -<camelContext xmlns="http://camel.apache.org/schema/blueprint"> - <route> - <from uri="direct:start"/> - <to uri="http://{`{service:FOO}`}/myapp"/> - </route> -</camelContext> ----- - -And we can use default values if the service has not been defined, for -example to call a service on localhost, maybe for unit testing etc - -[source,xml] ----- -<camelContext xmlns="http://camel.apache.org/schema/blueprint"> - <route> - <from uri="direct:start"/> - <to uri="http://{`{service:FOO:localhost:8080}`}/myapp"/> - </route> -</camelContext> ----- - -== Using custom functions (advanced) - -The xref:properties-component.adoc[Properties] component allow to plugin 3rd party -functions which can be used during parsing of the property placeholders. -These functions are then able to do custom logic to resolve the -placeholders, such as looking up in databases, do custom computations, -or whatnot. The name of the function becomes the prefix used in the -placeholder. This is best illustrated in the example code below - -[source,xml] ----- -<bean id="beerFunction" class="MyBeerFunction"/> - -<camelContext xmlns="http://camel.apache.org/schema/blueprint"> - <propertyPlaceholder id="properties"> - <propertiesFunction ref="beerFunction"/> - </propertyPlaceholder> - - <route> - <from uri="direct:start"/> - <to uri="{`{beer:FOO}`}"/> - <to uri="{`{beer:BAR}`}"/> - </route> -</camelContext> ----- - -NOTE: The location attribute (on propertyPlaceholder tag) is not mandatory - -Here we have a Camel XML route where we have defined the -`<propertyPlaceholder>` to use a custom function, which we refer to be the -bean id - eg the `beerFunction`. As the beer function uses `"beer"` as its -name, then the placeholder syntax can trigger the beer function by -starting with `beer:value`. - -The implementation of the function is only two methods as shown below: - -[source,java] ----- -public static final class MyBeerFunction implements PropertiesFunction { - - @Override - public String getName() { - return "beer"; - } - - @Override - public String apply(String remainder) { - return "mock:" + remainder.toLowerCase(); - } -} ----- - -The function must implement -the `org.apache.camel.component.properties.PropertiesFunction` -interface. The method `getName` is the name of the function, eg beer. -And the `apply` method is where we implement the custom logic to do. As -the sample code is from an unit test, it just returns a value to refer -to a mock endpoint. - -To register a custom function from Java code is as shown below: - -[source,java] ----- -PropertiesComponent pc = (org.apache.camel.componennt.properties.PropertiesComponent) context.getPropertiesComponent(); -pc.addFunction(new MyBeerFunction()); ----- - - -== Using 3rd-party properties sources - -The properties component allows to plugin 3rd party sources to load and lookup properties via the `PropertySource` -API from camel-api. For example the `camel-microprofile-config` component is implemented using this. -The 3rd-party `PropertySource` can automatic be discoverd from classpath when Camel is starting up. -This is done by include the file `META-INF/services/org/apache/camel/property-source-factory` file -which refers to the fully qualified class name of the `PropertySource` implementation. -See the `camel-microprofile-config` for an example. - -You can also register 3rd-part property sources via Java API - -[source,java] ----- -PropertiesComponent pc = ... -pc.addPropertySource(myPropertySource); ----- - -=== LoadablePropertySource - -A `PropertySource` can define that it supports loading all its properties from the source at once, -for example from file system. This allows Camel properties component to load these properties at once -during startup. - -=== PropertySource - -The regular `PropertySource` will lookup the property on-demand, for example to lookup -values from a backend source such as a database or HashiCorp Vault etc. - - diff --git a/docs/user-manual/modules/ROOT/pages/using-propertyplaceholder.adoc b/docs/user-manual/modules/ROOT/pages/using-propertyplaceholder.adoc index 8180bdf..a4cd784 100644 --- a/docs/user-manual/modules/ROOT/pages/using-propertyplaceholder.adoc +++ b/docs/user-manual/modules/ROOT/pages/using-propertyplaceholder.adoc @@ -140,48 +140,6 @@ You can have multiple placeholders in the same location, such as: location=file:${env:APP_HOME}/etc/${prop.name}.properties -[[UsingPropertyPlaceholder-UsingSystemorEnvironmentVariablestoConfigurePropertyPrefixesandSuffixes]] -== Using System or Environment Variables to Configure Property Prefixes and Suffixes - -From *Camel 2.12.5, 2.13.3, 2.14.0*: `propertyPrefix`, -`propertySuffix` configuration properties support the use of -placeholders for de-referencing JVM system properties and OS -environments variables. - -Example: - -Assume the `PropertiesComponent` is configured with the following -properties file: - -[source,java] ----- -textdev.endpoint = result1 -test.endpoint = result2 ----- - -The same properties file is then referenced from a route definition: - - -[source,java] ----- -PropertiesComponent pc = context.getComponent("properties", -PropertiesComponent.class); pc.setPropertyPrefix("${stage}."); -// ... -context.addRoutes(new RouteBuilder() { - @Override - public void configure() throws Exception { - from("direct:start") - .to("properties:mock:{{endpoint}}"); - } -}); ----- - -By using the configuration options `propertyPrefix` it's possible to -change the target endpoint simply by changing the value of the system -property `stage` either to `dev` (the message will be routed -to `mock:result1`) or `test` (the message will be routed -to `mock:result2`). - [[UsingPropertyPlaceholder-ConfiguringinJavaDSL]] == Configuring in Java DSL @@ -191,9 +149,8 @@ name `properties` such as: [source,java] ---- -PropertiesComponent pc = new PropertiesComponent(); +PropertiesComponent pc = camelContext.getPropertiesComponent(); pc.setLocation("classpath:com/mycompany/myprop.properties"); -context.addComponent("properties", pc); ---- [[UsingPropertyPlaceholder-ConfiguringinSpringXML]] @@ -276,7 +233,7 @@ cool.end=mock:result // route from("direct:start") - .to("properties:{{cool.end}}"); + .to("{{cool.end}}"); ---- You can also use placeholders as a part of the endpoint URI: @@ -288,7 +245,7 @@ cool.foo=result // route from("direct:start") - .to("properties:mock:{{cool.foo}}"); + .to("mock:{{cool.foo}}"); ---- In the example above the to endpoint will be resolved to @@ -305,39 +262,12 @@ cool.concat=mock:{{cool.foo}} // route from("direct:start") - .to("properties:mock:{{cool.concat}}"); + .to("mock:{{cool.concat}}"); ---- Notice how `cool.concat` refer to another property. -The `properties:` component also offers you to override and provide a -location in the given URI using the `locations` option: - - -[source,java] ----- -from("direct:start") - .to("properties:bar.end?locations=com/mycompany/bar.properties"); ----- - -[[UsingPropertyPlaceholder-Examples]] -== Examples - -You can also use property placeholders directly in the endpoint URIs -without having to use `properties:`. - - -[source,java] ----- -// properties -cool.foo=result - -// route -from("direct:start") - .to("mock:{{cool.foo}}"); ----- - -And you can use them in multiple wherever you want them: +And you can use placeholders several times: [source,java] ---- @@ -437,43 +367,6 @@ Example using property placeholders in the attributes of `<camelContext>`: ---- -[[UsingPropertyPlaceholder-OverridingaPropertySettingUsingaJVMSystemProperty]] -== Overriding a Property Setting Using a JVM System Property - -*Available as of Camel 2.5* - -It is possible to override a property value at runtime using a JVM -System property without the need to restart the application to pick up -the change. This may also be accomplished from the command line by -creating a JVM System property of the same name as the property it -replaces with a new value. - -Example: - - -[source,java] ----- -PropertiesComponent pc = context.getComponent("properties", PropertiesComponent.class); -pc.setCache(false); -System.setProperty("cool.end", "mock:override"); -System.setProperty("cool.result", "override"); -context.addRoutes(new RouteBuilder() { - @Override - public void configure() throws Exception { - from("direct:start").to("properties:cool.end"); - from("direct:foo").to("properties:mock:{{cool.result}}"); - } -}); -context.start(); -getMockEndpoint("mock:override").expectedMessageCount(2); -template.sendBody("direct:start", "Hello World"); -template.sendBody("direct:foo", "Hello Foo"); -System.clearProperty("cool.end"); -System.clearProperty("cool.result"); -assertMockEndpointsSatisfied(); ----- - - [[UsingPropertyPlaceholder-UsingPropertyPlaceholdersforAnyKindofAttributeintheXMLDSL]] == Using Property Placeholders for Any Kind of Attribute in the XML DSL @@ -590,7 +483,7 @@ service. You can disable this by setting the attribute `useBlueprintPropertyResolver` to false on the `<camelContext>` definition. -=== About placeholder syntaxes +=== About placeholder syntax Notice how we can use the Camel syntax for placeholders `{{ }}` in the Camel route, which will lookup the value from OSGi blueprint. @@ -1141,7 +1034,7 @@ example to call a service on localhost, maybe for unit testing etc: ---- [[UsingPropertyPlaceholder-UsingCustomFunctions]] -== Using Custom Functions +== Using Custom Functions (advanced) *Available as of Camel 2.14.1* @@ -1200,7 +1093,7 @@ To register a custom function from Java code is as shown below: [source,java] ---- -PropertiesComponent pc = context.getComponent("properties", PropertiesComponent.class); +PropertiesComponent pc = (org.apache.camel.componennt.properties.PropertiesComponent) context.getPropertiesComponent(); pc.addFunction(new MyBeerFunction()); ----