This is an automated email from the ASF dual-hosted git repository.

davsclaus pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/camel.git

commit c60fb63702d3c315f3baa0472f36b637bc32a527
Author: Claus Ibsen <claus.ib...@gmail.com>
AuthorDate: Wed Aug 18 16:57:40 2021 +0200

    Polish and cleanup documentation
---
 .../modules/ROOT/pages/bean-integration.adoc       |  50 +-
 .../ROOT/pages/using-propertyplaceholder.adoc      | 795 +++++----------------
 2 files changed, 227 insertions(+), 618 deletions(-)

diff --git a/docs/user-manual/modules/ROOT/pages/bean-integration.adoc 
b/docs/user-manual/modules/ROOT/pages/bean-integration.adoc
index 1fe440b..17495ff 100644
--- a/docs/user-manual/modules/ROOT/pages/bean-integration.adoc
+++ b/docs/user-manual/modules/ROOT/pages/bean-integration.adoc
@@ -3,11 +3,10 @@
 
 Camel supports the integration of beans and POJOs in a number of ways.
 
-[[BeanIntegration-Annotations]]
 == Annotations
 
 If a bean is defined in Spring XML or scanned using
-the Spring component scanning mechanism and a *<camelContext>* is used
+the Spring component scanning mechanism, and a *<camelContext>* is used
 or a `CamelBeanPostProcessor` then we process a number of Camel
 annotations to do various things such as injecting resources or
 producing, consuming or routing messages.
@@ -48,9 +47,48 @@ See more details at:
 See the 
https://github.com/apache/camel-examples/tree/master/examples/camel-example-pojo-messaging[POJO
 Messaging Example]
 for how to use the annotations for routing and messaging.
 
-[[BeanIntegration-BeanComponent]]
-== Bean Component
+== Using @PropertyInject
 
-The xref:components::bean-component.adoc[Bean] component allows one to invoke 
a particular
-method.
+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;
+----
diff --git a/docs/user-manual/modules/ROOT/pages/using-propertyplaceholder.adoc 
b/docs/user-manual/modules/ROOT/pages/using-propertyplaceholder.adoc
index 9957100..30b35c9 100644
--- a/docs/user-manual/modules/ROOT/pages/using-propertyplaceholder.adoc
+++ b/docs/user-manual/modules/ROOT/pages/using-propertyplaceholder.adoc
@@ -20,40 +20,6 @@ See the 
xref:components::properties-component.adoc[Properties] documentation for
 to configure Camel to known from which location(a) to load properties.
 
 
-[TIP]
-**Resolving property from Java code** +
-You can use the method `resolveProperty` on the `PropertiesComponent` to 
resolve a single property from Java code.
-Or use the method `resolvePropertyPlaceholders` on the `CamelContext` to 
resolve (one or more) property placeholder(s) from a string that.
-
-
-
-
-
-
-== Bridging Spring and Camel Property Placeholders
-TODO: Remove or move to legacy camel with spring xml files
-
-From *Camel 2.10*: Spring's property placeholder can be bridged with
-Camel's. See below for more details.
-
-The property placeholder is typically used when trying to do any of the
-following:
-
-* Lookup or creating endpoints
-* Lookup of beans in the xref:registry.adoc[Registry]
-* Additional supported in Spring XML (see below in examples)
-* Using Blueprint `PropertyPlaceholder` with Camel
-xref:components::properties-component.adoc[Properties] component
-* Using `@PropertyInject` to inject a property in a POJO
-* *Camel 2.14.1* Using default value if a property does not exists
-* *Camel 2.14.1* Include out of the box functions, to lookup property
-values from OS environment variables, JVM system properties, or the
-service idiom
-* *Camel 2.14.1* Using custom functions, which can be plugged into the
-property component
-* *Camel 3.9* Marking a property as optional, meaning that a property is not 
set if the property key does not exists
-
-
 == Property placeholder syntax
 
 The value of a Camel property can be obtained by specifying its key name
@@ -113,6 +79,28 @@ file:foo
 Then the option `bufferSize` is not in specified at all, and this would allow 
Camel to
 use the standard default value for `bufferSize` if any exists.
 
+=== Reverse a boolean value
+
+If a property placeholder is a boolean value, then it is possible to negate 
(reverse) the value by using `!` as prefix in the key.
+
+[source,properties]
+----
+integration.ftpEnabled=true
+----
+
+[source,java]
+----
+from("ftp:....").autoStartup("{{integration.ftpEnabled}}")
+    .to("kafka:cheese")
+
+from("jms:....").autoStartup("{{!integration.ftpEnabled}}")
+    .to("kafka:cheese")
+----
+
+In the example above then the FTP route or the JMS route should only be 
started. So if the FTP is enabled then JMS should be disable, and vise-versa.
+We can do this be negating the `autoStartup` in the JMS route, by using 
`!integration.ftpEnabled` as the key.
+
+
 == Example using property placeholders
 
 When using property placeholders in the endpoint URIs you should use this with 
the syntax `{{key}}` as shown in this example:
@@ -238,7 +226,7 @@ This can also be done when using 
xref:consumertemplate.adoc[ConsumerTemplate], s
 Object body = template.receiveBody("{{cool.start}}");
 ----
 
-== Using property placeholders with simple language
+== Using property placeholders with Simple language
 
 The xref:components:languages:simple-language.adoc[Simple] language now also 
support using property
 placeholders, for example in the route below:
@@ -277,416 +265,129 @@ from("direct:start")
   .transform().simple("Hi ${body} do you think ${properties:cheese.quote}?");
 ----
 
+== Resolving property placeholders from Java code
 
+If you need to resolve property placeholder(s) from some Java code, then Camel 
has two APIs for this:
 
-[[UsingPropertyPlaceholder-UsingPropertyPlaceholdersforAnyKindofAttributeintheXMLDSL]]
-== Using Property Placeholders for Any Kind of Attribute in the XML DSL
-
-*Since Camel 2.7*
-
-If you use OSGi Blueprint then this only works from *2.11.1* or *2.10.5*
-on.
-
-Previously it was only the `xs:string` type attributes in the XML DSL
-that support placeholders. For example often a timeout attribute would
-be a `xs:int` type and thus you cannot set a string value as the
-placeholder key. This is now possible from Camel 2.7 on using a special
-placeholder namespace.
-
-In the example below we use the `prop` prefix for the namespace
-`\http://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 xref:{eip-vc}:eips:multicast-eip.adoc[Multicast] to indicate that 
the option
-`stopOnException` should be the value of the placeholder with the key
-`stop`.
-
-[source,xml]
-----
-<beans xmlns="http://www.springframework.org/schema/beans"; 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance";
-       xmlns:prop="http://camel.apache.org/schema/placeholder";
-       xsi:schemaLocation="
-           http://www.springframework.org/schema/beans 
http://www.springframework.org/schema/beans/spring-beans.xsd
-           http://camel.apache.org/schema/spring 
http://camel.apache.org/schema/spring/camel-spring.xsd";>
-    <!-- Notice in the declaration above, we have defined the prop prefix as 
the Camel placeholder namespace -->
-    <bean id="damn" class="java.lang.IllegalArgumentException">
-        <constructor-arg index="0" value="Damn"/>
-    </bean>
-    <camelContext xmlns="http://camel.apache.org/schema/spring";>
-        <propertyPlaceholder id="properties" 
location="classpath:org/apache/camel/component/properties/myprop.properties"
-                             xmlns="http://camel.apache.org/schema/spring"/>
-        <route>
-            <from uri="direct:start"/>
-            <!-- use prop namespace, to define a property placeholder, which 
maps to option stopOnException={{stop}} -->
-            <multicast prop:stopOnException="stop">
-            <to uri="mock:a"/>
-            <throwException ref="damn"/>
-            <to uri="mock:b"/>
-            </multicast>
-        </route>
-    </camelContext>
-</beans>
-----
-
-In our properties file we have the value defined as:
-....
-stop=true
-....
-
-
-[[UsingPropertyPlaceholder-UsingPropertyPlaceholderintheJavaDSL]]
-== Using Property Placeholder in the Java DSL
-
-*Since Camel 2.7*
+- You can use the method `resolveProperty` on the `PropertiesComponent` to 
resolve a single property from Java code.
+- Use the method `resolvePropertyPlaceholders` on the `CamelContext` to 
resolve (one or more) property placeholder(s) in a String.
 
-Likewise we have added support for defining placeholders in the Java DSL
-using the new `placeholder` DSL as shown in the following equivalent
-example:
+For example to resolve a placeholder with key foo, you can do:
 
 [source,java]
 ----
-from("direct:start")
-    // use a property placeholder for the option stopOnException on the 
Multicast EIP
-    // which should have the value of {{stop}} key being looked up in the 
properties file
-    .multicast()
-    .placeholder("stopOnException", "stop")
-    .to("mock:a")
-    .throwException(new IllegalAccessException("Damn"))
-    .to("mock:b");
-----
-
-
-[[UsingPropertyPlaceholder-UsingBlueprintPropertyPlaceholderwithCamelRoutes]]
-== Using Blueprint Property Placeholder with Camel Routes
-
-*Since Camel 2.7*
-
-Camel supports xref:using-osgi-blueprint-with-camel.adoc[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>
+Optional<String> prop = 
camelContext.getPropertiesComponent().resolveProperty("foo");
+if (prop.isPresent()) {
+    String value = prop.get();
+    ....
+}
 ----
 
-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 `{{ }}` 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 `{{ }}` 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"
-                             prefixToken="[[" suffixToken="]]" 
propertyPrefix="prefix."/>
-        <!-- in the route we can use {{ }} placeholders which will lookup in 
blueprint -->
-        <route>
-            <from uri="direct:start"/>
-            <to uri="mock:foo"/>
-            <to uri="[[result]]"/>
-        </route>
-    </camelContext>
-</blueprint>
-----
+This API is to lookup a single property and returns a `java.util.Optional` 
type.
 
-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:
+The `CamelContext` have another API which is capable of resolving multiple 
placeholders, and interpolate placeholders from an input String.
+Lets try with an example to explain this:
 
 [source,java]
 ----
-location="blueprint:myblueprint.placeholder,classpath:myproperties.properties"
+String msg = camelContext.resolvePropertyPlaceholders("{{greeting}} Camel 
user, Camel is {{cool}} dont you think?");
 ----
 
-Each location is separated by comma.
+The input string is a text statement which have two placeholders that will be 
resolved, for example:
 
-[[UsingPropertyPlaceholder-OverridingBlueprintPropertyPlaceholdersOutsideCamelContext]]
-== Overriding Blueprint Property Placeholders Outside CamelContext
-
-*Since Camel 2.10.4*
-
-When using Blueprint property placeholder in the Blueprint XML file, you
-can declare the properties directly in the XML file as shown below:
-
-[source,xml]
+[source,properties]
 ----
-<!-- blueprint property placeholders -->
-<cm:property-placeholder persistent-id="my-placeholders" 
update-strategy="reload">
-  <cm:default-properties>
-    <cm:property name="greeting" value="Hello"/>
-    <cm:property name="destination" value="mock:result"/>
-  </cm:default-properties>
-</cm:property-placeholder>
-
-<!-- a bean that uses a blueprint property placeholder -->
-<bean id="myCoolBean" class="org.apache.camel.test.blueprint.MyCoolBean">
-  <property name="say" value="${greeting}"/>
-</bean>
-
-<camelContext xmlns="http://camel.apache.org/schema/blueprint";>
-
-  <route>
-    <from uri="direct:start"/>
-    <bean ref="myCoolBean" method="saySomething"/>
-    <to uri="{{destination}}"/>
-  </route>
-
-</camelContext>
+greeting = Hi
+cool = awesome
 ----
 
-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 `{{ }}` notation.
+Will be resolved to:
 
-Now if you want to override these Blueprint properties from an unit
-test, you can do this as shown below:
-
-[source,java]
+[source,text]
 ----
-protected String useOverridePropertiesWithConfigAdmin(Dictionary props) {
-    // add the properties we want to override
-    props.put("greeting", "Bye");
-
-    // return the PID of the config-admin we are using in the blueprint xml 
file
-    return "my-placeholders";
-}
+Hi Camel user, Camel is awesome dont you think?
 ----
 
-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.
-
-[[UsingPropertyPlaceholder-Usinga.cfgor.propertiesFileForBlueprintPropertyPlaceholders]]
-== Using a `.cfg` or `.properties` File For Blueprint Property Placeholders
+== Using property placeholders for any kind of attribute in Spring XML files
 
-*Since Camel 2.10.4*
+Previously it was only the `xs:string` type attributes in the XML DSL
+that support placeholders. For example often a timeout attribute would
+be a `xs:int` type and thus you cannot set a string value as the
+placeholder key. This is now possible using a special
+placeholder namespace.
 
-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 ServiceMix/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.
+In the example below we use the `prop` prefix for the namespace
+`\http://camel.apache.org/schema/placeholder`. Now we can use `prop:` as prefix
+to configure any kind of XML attributes in Spring XML files.
 
-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`.
+In the example below we want to use a placeholder for the `stopOnException` 
option in
+the xref:{eip-vc}:eips:multicast-eip.adoc[Multicast] EIP. The 
`stopOnException` is a `xs:boolean` type,
+so we cannot configure this as:
 
 [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.1.0";
-           xsi:schemaLocation="
-             http://aries.apache.org/blueprint/xmlns/blueprint-cm/v1.1.0 
http://aries.apache.org/schemas/blueprint-cm/blueprint-cm-1.1.0.xsd
-             http://www.osgi.org/xmlns/blueprint/v1.0.0 
https://www.osgi.org/xmlns/blueprint/v1.0.0/blueprint.xsd";>
-
-<!-- blueprint property placeholders, that will use etc/stuff.cfg as the 
properties file -->
-<cm:property-placeholder persistent-id="stuff" update-strategy="reload"/>
-
-<!-- a bean that uses a blueprint property placeholder -->
-<bean id="myCoolBean" class="org.apache.camel.test.blueprint.MyCoolBean">
-  <property name="say" value="${greeting}"/>
-</bean>
-
-<camelContext xmlns="http://camel.apache.org/schema/blueprint";>
-
-  <route>
-    <from uri="direct:start"/>
-    <bean ref="myCoolBean" method="saySomething"/>
-    <to uri="mock:result"/>
-  </route>
-
-</camelContext>
-----
-
-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:
-
-[source,java]
-----
-@Override
-protected String[] loadConfigAdminConfigurationFile() {
-    // String[0] = tell Camel the path of the .cfg file to use for OSGi 
ConfigAdmin in the blueprint XML file
-    // String[1] = tell Camel the persistence-id of the 
cm:property-placeholder in the blueprint XML file
-    return new String[]{"src/test/resources/etc/stuff.cfg", "stuff"};
-}
-----
-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 second
-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,java]
-----
-== this is a comment
-greeting=Bye
+<multicast stopOnException="{{stop}}">
+   ...
+</multicast>
 ----
 
+Instead, we must use the `prop:` namespace, so we must add this namespace
+in the top of the XML file in the `<beans>` tag.
 
-[[UsingPropertyPlaceholder-Usinga.cfgfileandOverridingPropertiesforBlueprintPropertyPlaceholders]]
-== Using a `.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:
+To configure the option we must then use the `prop:optionName` 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.1.0";
-           xsi:schemaLocation="
-             http://aries.apache.org/blueprint/xmlns/blueprint-cm/v1.1.0 
http://aries.apache.org/schemas/blueprint-cm/blueprint-cm-1.1.0.xsd
-             http://www.osgi.org/xmlns/blueprint/v1.0.0 
https://www.osgi.org/xmlns/blueprint/v1.0.0/blueprint.xsd";>
-
-  <!-- blueprint property placeholders, that will use etc/stuff.cfg as the 
properties file -->
-  <cm:property-placeholder persistent-id="stuff" update-strategy="reload">
-    <cm:default-properties>
-      <cm:property name="greeting" value="Hello" />
-      <cm:property name="echo" value="Hey" />
-      <cm:property name="destination" value="mock:original" />
-    </cm:default-properties>
-  </cm:property-placeholder>
-
-  <!-- a bean that uses a blueprint property placeholder -->
-  <bean id="myCoolBean" class="org.apache.camel.test.blueprint.MyCoolBean">
-    <property name="say" value="${greeting}"/>
-    <property name="echo" value="${echo}"/>
-  </bean>
-
-  <camelContext xmlns="http://camel.apache.org/schema/blueprint";>
-
-    <route>
-      <from uri="direct:start"/>
-      <bean ref="myCoolBean" method="saySomething"/>
-      <to uri="{{destination}}"/>
-      <bean ref="myCoolBean" method="echoSomething"/>
-      <to uri="{{destination}}"/>
-    </route>
-
-  </camelContext>
-
-</blueprint>
+<multicast prop:stopOnException="stop">
+  ...
+</multicast>
 ----
 
-And in the unit test class we do as follows:
+The complete example is below:
 
-[source,java]
+[source,xml]
 ----
-/**
- * This example will load a Blueprint .cfg file (which will initialize 
configadmin), and also override its property
- * placeholders from this unit test source code directly (the change will 
reload blueprint container).
- */
-public class ConfigAdminLoadConfigurationFileAndOverrideTest extends 
CamelBlueprintTestSupport {
-
-    @Override
-    protected String getBlueprintDescriptor() {
-        // which blueprint XML file to use for this test
-        return 
"org/apache/camel/test/blueprint/configadmin-loadfileoverride.xml";
-    }
-
-    @Override
-    protected String[] loadConfigAdminConfigurationFile() {
-        // which .cfg file to use, and the name of the persistence-id
-        return new String[]{"src/test/resources/etc/stuff.cfg", "stuff"};
-    }
-
-    @Override
-    protected String useOverridePropertiesWithConfigAdmin(Dictionary props) 
throws Exception {
-        // override / add extra properties
-        props.put("destination", "mock:extra");
-
-        // return the persistence-id to use
-        return "stuff";
-    }
-
-    @Test
-    public void testConfigAdmin() throws Exception {
-        // mock:original comes from <cm:default-properties>/<cm:property 
name="destination" value="mock:original" />
-        getMockEndpoint("mock:original").setExpectedMessageCount(0);
-        // mock:result comes from loadConfigAdminConfigurationFile()
-        getMockEndpoint("mock:result").setExpectedMessageCount(0);
-        // mock:extra comes from useOverridePropertiesWithConfigAdmin()
-        getMockEndpoint("mock:extra").expectedBodiesReceived("Bye World", "Yay 
Bye WorldYay Bye World");
-
-        template.sendBody("direct:start", "World");
+<beans xmlns="http://www.springframework.org/schema/beans"; 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance";
+       xmlns:prop="http://camel.apache.org/schema/placeholder";
+       xsi:schemaLocation="
+           http://www.springframework.org/schema/beans 
http://www.springframework.org/schema/beans/spring-beans.xsd
+           http://camel.apache.org/schema/spring 
http://camel.apache.org/schema/spring/camel-spring.xsd";>
 
-        assertMockEndpointsSatisfied();
-    }
+    <bean id="damn" class="java.lang.IllegalArgumentException">
+        <constructor-arg index="0" value="Damn"/>
+    </bean>
 
-}
+    <camelContext xmlns="http://camel.apache.org/schema/spring";>
+        <propertyPlaceholder id="properties" 
location="classpath:myprop.properties"/>
+        <route>
+            <from uri="direct:start"/>
+            <!-- use prop namespace, to define a property placeholder, which 
maps to option stopOnException={{stop}} -->
+            <multicast prop:stopOnException="stop">
+                <to uri="mock:a"/>
+                <throwException ref="damn"/>
+                <to uri="mock:b"/>
+            </multicast>
+        </route>
+    </camelContext>
+</beans>
 ----
 
-And the `etc/stuff.cfg` configuration file contains:
+In our properties file we have the value defined as:
 
-[source,java]
+[source,properties]
 ----
-greeting=Bye
-echo=Yay
-destination=mock:result
+stop = true
 ----
 
 
-[[UsingPropertyPlaceholder-BridgingSpringandCamelPropertyPlaceholders-1]]
-== Bridging Spring and Camel Property Placeholders
+== Bridging Camel property placeholders with Spring XML files
 
-*Since Camel 2.10*
+NOTE: If you are using Spring Boot then this does not apply.
+This is only for legacy Camel and Spring applications which are using Spring 
XML files.
 
 The Spring Framework does not allow third-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
+mechanism. However, you can bridge Spring and Camel by declaring a
 Spring bean with the type
 `org.apache.camel.spring.spi.BridgePropertyPlaceholderConfigurer`,
 which is a Spring
@@ -731,262 +432,125 @@ tag as shown below:
 
 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 `{{ }}`.
-
-[[UsingPropertyPlaceholder-ClashingSpringPropertyPlaceholderswithCamelsLanguage]]
-== Clashing Spring Property Placeholders with Camels 
xref:components:languages:simple-language.adoc[Simple] Language
-
-Take notice when using Spring bridging placeholder then the
-spring `${}` syntax clashes with the 
xref:components:languages:simple-language.adoc[Simple] in
-Camel, and therefore take care.
-
-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:components:languages: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`.
-
-[[UsingPropertyPlaceholder-OverridingPropertiesfromCamelTestKit]]
-== Overriding Properties from Camel Test Kit
-
-*Since Camel 2.10*
-
-When xref:testing.adoc[Testing] with Camel and using the
-xref:components::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. This is now possible from Camel 2.10, as the Camel test
-kits, e.g., `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.
-
-[source,java]
-----
-@Override
-protected Properties useOverridePropertiesWithPropertiesComponent() {
-    Properties extra = new Properties();
-    extra.put("destination", "mock:extra");
-    extra.put("greeting", "Bye");
-    return extra;
-}
-----
-
-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.
-
-
-[[UsingPropertyPlaceholder-UsingPropertyInject]]
-== Using `@PropertyInject`
-
-*Since Camel 2.12*
-
-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;
+placeholder notation with `{{key}}`.
 
-    @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;
-----
-
-
-[[UsingPropertyPlaceholder-UsingOutoftheBoxFunctions]]
-== Using Out of the Box Functions
-
-*Since Camel 2.14.1*
+== Using out of the box functions
 
-The xref:components::properties-component.adoc[Properties] component includes 
the following
-functions out of the box
+The xref:components::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.host` - **Camel 2.16.1: **A function to lookup the
-property from OS environment variables using the service naming idiom
-returning the hostname part only.
-* `service.port` - **Camel 2.16.1: **A function to lookup the
-property from OS environment variables using the service naming idiom
-returning the port part only.
+* `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:
+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";>
+  <camelContext xmlns="http://camel.apache.org/schema/blueprint";>
     <route>
-        <from uri="direct:start"/>
-        <to uri="{{env:SOMENAME}}"/>
-        <to uri="{{sys:MyJvmPropertyName}}"/>
+      <from uri="direct:start"/>
+      <to uri="{{env:SOMENAME}}"/>
+      <to uri="{{sys:MyJvmPropertyName}}"/>
     </route>
-</camelContext>
+  </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.
-
+You can use default values as well, so if the property does not exist, 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";>
+  <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}}"/>
+      <from uri="direct:start"/>
+      <to uri="{{env:SOMENAME:log:foo}}"/>
+      <to uri="{{sys:MyJvmPropertyName:log:bar}}"/>
     </route>
-</camelContext>
+  </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`
+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
+* __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
+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
 
-export $FOO_SERVICE_HOST=myserver export $FOO_SERVICE_PORT=8888
+[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 xref:components::http-component.adoc[HTTP] component to make the HTTP call:
+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>
+  <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:
+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>
+  <route>
+    <from uri="direct:start"/>
+    <to uri="http://{`{service:FOO:localhost:8080}`}/myapp"/>
+  </route>
 </camelContext>
 ----
 
-[[UsingPropertyPlaceholder-UsingCustomFunctions]]
-== Using Custom Functions (advanced)
+== Using custom functions (advanced)
 
-*Since Camel 2.14.1*
+The xref:components::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.
 
-The xref:components::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
+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" location="none" 
ignoreMissingLocation="true">
+<beans>
+    <bean id="beerFunction" class="MyBeerFunction"/>
+
+    <camelContext>
+      <propertyPlaceholder id="properties">
         <propertiesFunction ref="beerFunction"/>
-    </propertyPlaceholder>
-    <route>
+      </propertyPlaceholder>
+
+      <route>
         <from uri="direct:start"/>
         <to uri="{{beer:FOO}}"/>
         <to uri="{{beer:BAR}}"/>
-    </route>
-</camelContext>
+      </route>
+    </camelContext>
+</beans>
 ----
 
-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 - e.g., 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`.
+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();
@@ -994,12 +558,10 @@ public static final class MyBeerFunction implements 
PropertiesFunction {
 }
 ----
 
-The function must implement
-the `org.apache.camel.spi.PropertiesFunction`
-interface. The method `getName` is  the name of the function, e.g.,
-`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.
+The function must implement the `org.apache.camel.spi.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:
 
@@ -1009,22 +571,31 @@ PropertiesComponent pc = 
context.getPropertiesComponent();
 pc.addFunction(new MyBeerFunction());
 ----
 
-== Negate boolean value
+== Writing custom property sources (advanced)
 
-If a property placeholder is a boolean value, then it is possible to negate 
(reverse) the value by using `!` as prefix in the key.
+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.
 
-[source,java]
-----
-// properties
-integration.ftpEnabled=true
+A `PropertySource` can define that it supports loading all its properties
+(by implementing `LoadablePropertiesSource`) from the source at once, for 
example from file system.
+This allows Camel properties component to load these properties at once during 
startup.
 
-// route
-from("ftp:....").autoStartup("{{integration.ftpEnabled}}")
-    .to("kafka:cheese")
+=== Using third party property sources
 
-from("jms:....").autoStartup("{{!integration.ftpEnabled}}")
-    .to("kafka:cheese")
+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 discovered 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 xref:components:others:microprofile-config.adoc[MicroProfile Config] 
component as an example.
+
+You can also register 3rd-party property sources via Java API:
+
+[source,java]
+----
+PropertiesComponent pc = context.getPropertiesComponent();
+pc.addPropertySource(myPropertySource);
 ----
 
-In the example above then the FTP route or the JMS route should only be 
started. So if the FTP is enabled then JMS should be disable, and vise-versa.
-We can do this be negating the `autoStartup` in the JMS route, by using 
`!integration.ftpEnabled` as the key.

Reply via email to