Chapter 4. Configuring Camel K integrations

There are two configuration phases in a Camel K integration life cycle:

  • Build time - When Camel Quarkus builds a Camel K integration, it consumes build-time properties.
  • Runtime - When a Camel K integration is running, the integration uses runtime properties or configuration information from local files, OpenShift ConfigMaps, or Secrets.

You provide configure information by using the following options with the kamel run command:

For example, you can use build-time and runtime options to quickly configure a datasource in Camel K as shown in the link: Connect Camel K with databases sample configuration.

4.1. Specifying build-time configuration properties

You might need to provide property values to the Camel Quarkus runtime so that it can build a Camel K integration. For more information about Quarkus configurations that take effect during build time, see the Quarkus Build Time configuration documentation. You can specify build-time properties directly at the command line or by referencing a property file. If a property is defined in both places, the value specified directly at the command line takes precedence over the value in the property file.

Prerequisites

Procedure

  • Specify the --build-property option with the Camel K kamel run command:

    kamel run --build-property <quarkus-property>=<property-value> <camel-k-integration>

    For example, the following Camel K integration (named my-simple-timer.yaml) uses the quarkus.application.name configuration option:

    - from:
       uri: "timer:tick"
       steps:
         - set-body:
             constant: "{{quarkus.application.name}}"
         - to: "log:info"

    To override the default application name, specify a value for the quarkus.application.name property when you run the integration.

    For example, to change the name from my-simple-timer to my-favorite-app:

    kamel run --build-property quarkus.application.name=my-favorite-app my-simple-timer.yaml
  • To provide more than one build-time property, add additional --build-property options to the kamel run command:

    kamel run --build-property <quarkus-property1>=<property-value1> -build-property=<quarkus-property2>=<property-value12> <camel-k-integration>

    Alternately, if you need to specify multiple properties, you can create a property file and specify the property file with the --build-property file option:

    kamel run --build-property file:<property-filename> <camel-k-integration>

    For example, the following property file (named quarkus.properties) defines two Quarkus properties:

    quarkus.application.name = my-favorite-app
    quarkus.banner.enabled = true

    The quarkus.banner.enabled property specifies to display the Quarkus banner when the integration starts up.

    To specify the quarkus.properties file with the Camel K kamel run command:

    kamel run --build-property file:quarkus.properties my-simple-timer.yaml

    Quarkus parses the property file and uses the property values to configure the Camel K integration.

Additional resources

For information about Camel Quarkus as the runtime for Camel K integrations, see Quarkus Trait.

4.2. Specifying runtime configuration options

You can specify the following runtime configuration information for a Camel K integration to use when it is running:

  • Runtime properties that you provide at the command line or in a .properties file.
  • Configuration values that you want the Camel K operator to process and parse as runtime properties when the integration starts. You can provide the configuration values in a local text file, an OpenShift ConfigMap, or an OpenShift secret.
  • Resource information that is not parsed as a property file when the integration starts. You can provide resource information in a local text file, a binary file, an OpenShift ConfigMap, or an OpenShift secret.

Use the following kamel run options:

  • --property

    Use the --property option to specify runtime properties directly at the command line or by referencing a Java *.properties file. The Camel K operator appends the contents of the properties file to the running integration’s user.properties file.

  • --config

    Use the --config option to provide configuration values that you want the Camel K operator to process and parse as runtime properties when the integration starts.

    You can provide a local text file (1 MiB maximum file size), a ConfigMap (3MB) or a Secret (3MB). The file must be a UTF-8 resource. The materialized file (that is generated at integration startup from the file that you provide) is made available at the classpath level so that you can reference it in your integration code without having to provide an exact location.

    Note: If you need to provide a non-UTF-8 resource (for example, a binary file), use the --resource option.

  • --resource

    Use the --resource option to provide a resource for the integration to access when it is running. You can provide a local text or a binary file (1 MiB maximum file size), a ConfigMap (3MB maximum), or a Secret (3MB maximum). Optionally, you can specify the destination of the file that is materialized for the resource. For example, if you want to set an HTTPS connection, use the --resource option to provide an SSL certificate (a binary file) that is expected in a specified location.

    The Camel K operator does not parse the resource for properties and does not add the resource to the classpath. (If you want to add the resource to the classpath, you can use the JVM trait in your integration).

4.2.1. Providing runtime properties

You can specify runtime properties directly at the command line or by referencing a Java *.properties file by using the kamel run command’s --property option.

When you run an integration with the --property option, the Camel K operator appends the properties to the running integration’s user.properties file.

4.2.1.1. Providing runtime properties at the command line

You can configure properties for Camel K integrations on the command line at runtime. When you define a property in an integration by using a property placeholder, for example, {{my.message}}, you can specify the property value on the command line, for example --property my.message=Hello. You can specify multiple properties in a single command.

Procedure

  1. Develop a Camel integration that uses a property. The following simple example includes a {{my.message}} property placeholder:

    ...
    - from:
       uri: "timer:tick"
       steps:
         - set-body:
             constant: "{{my.message}}"
         - to: "log:info"
    ...
  2. Run the integration by using the following syntax to set the property value at runtime.

    kamel run --property <property>=<value> <integration>

    Alternately, you can use the --p shorthand notation (in place of --property):

    kamel run --property <property>=<value> <integration>

    For example:

    kamel run --property my.message="Hola Mundo" HelloCamelK.java --dev

    or

    kamel run --p my.message="Hola Mundo" HelloCamelK.java --dev

    Here is the example result:

    ...
    [1] 2020-04-13 15:39:59.213 INFO  [main] ApplicationRuntime - Listener org.apache.camel.k.listener.RoutesDumper@6e0dec4a executed in phase Started
    [1] 2020-04-13 15:40:00.237 INFO  [Camel (camel-k) thread #1 - timer://java] info - Exchange[ExchangePattern: InOnly, BodyType: String, Body: Hola Mundo from java]
    ...

4.2.1.2. Providing runtime properties in a property file

You can configure multiple properties for Camel K integrations by specifying a property file (*.properties) on the command line at runtime. When you define properties in an integration using property placeholders, for example, {{my.items}}, you can specify the property values on the command line by using a properties file, for example --p file my-integration.properties.

Procedure

  1. Create an integration properties file. The following example is from a file named my.properties:

    my.key.1=hello
    my.key.2=world
  2. Develop a Camel integration that uses properties that are defined in the properties file. The following example Routing.java integration uses the {{my.key.1}} and {{my.key.2=world}} property placeholders:

    import org.apache.camel.builder.RouteBuilder;
    
    public class Routing extends RouteBuilder {
      @Override
      public void configure() throws Exception {
    
        from("timer:property-file")
           .routeId("property-file")
           .log("property file content is: {{my.key.1}} {{my.key.2}}");
    
      }
    }
  3. Run the integration by using the following syntax to reference the property file:

    kamel run --property file:<my-file.properties> <integration>

    Alternately, you can use the --p shorthand notation (in place of --property):

    kamel run --p file:<my-file.properties> <integration>

    For example:

    kamel run Routing.java --property:file=my.properties --dev

4.2.2. Providing configuration values

You can provide configuration values that you want the Camel K operator to process and parse as runtime properties by using the kamel run command’s --config option. You can provide the configuration values in a local text (UTF-8) file, an OpenShift ConfigMap, or an OpenShift secret.

When you run the integration, the Camel K operator materializes the provided file and adds it to the classpath so that you can reference the configuration values in your integration code without having to provide an exact location.

4.2.2.1. Specifying a text file

If you have a UTF-8 text file that contains configuration values, you can use the --config file:/path/to/file option to make the file available (with the same file name) on the running integration’s classpath.

Prerequisites

  • Setting up your Camel K development environment
  • You have one or more (non-binary) text files that contain configuration values.

    For example, create a file named resources-data.txt that contains the following line of text:

    the file body

Procedure

  1. Create a Camel K integration that references the text file that contains configuration values.

    For example, the following integration (ConfigFileRoute.java) expects the resources-data.txt file to be available on the classpath at runtime:

    import org.apache.camel.builder.RouteBuilder;
    
    public class ConfigFileRoute extends RouteBuilder {
      @Override
      public void configure() throws Exception {
    
        from("timer:config-file")
            .setBody()
                .simple("resource:classpath:resources-data.txt")
            .log("resource file content is: ${body}");
    
      }
    }
  2. Run the integration and use the --config option to specify the text file so that it is available to the running integration. For example:

    kamel run --config file:resources-data.txt ConfigFileRoute.java --dev

    Optionally, you can provide more than one file by adding the --config option repeatedly, for example:

    kamel run --config file:resources-data1.txt --config file:resources-data2.txt ConfigFileRoute.java --dev

4.2.2.2. Specifying a ConfigMap

If you have an OpenShift ConfigMap that contains configuration values, and you need to materialize a ConfigMap so that it is available to your Camel K integration, use the --config configmap:<configmap-name> syntax.

Prerequisites

  • Setting up your Camel K development environment
  • You have one or more ConfigMap files stored on your OpenShift cluster.

    For example, you can create a ConfigMap by using the following command:

    oc create configmap my-cm --from-literal=my-configmap-key="configmap content"

Procedure

  1. Create a Camel K integration that references the ConfigMap.

    For example, the following integration (named ConfigConfigmapRoute.java) references a configuration value named my-configmap-key in a ConfigMap named my-cm.

    import org.apache.camel.builder.RouteBuilder;
    
    public class ConfigConfigmapRoute extends RouteBuilder {
      @Override
      public void configure() throws Exception {
    
        from("timer:configmap")
            .setBody()
                 .simple("resource:classpath:my-configmap-key")
            .log("configmap content is: ${body}");
    
      }
    }
  2. Run the integration and use the --config option to materialize the ConfigMap file so that it is available to the running integration. For example:

    kamel run --config configmap:my-cm ConfigConfigmapRoute.java --dev

    When the integration starts, the Camel K operator mounts an OpenShift volume with the ConfigMap’s content.

Note: If you specify a ConfigMap that is not yet available on the cluster, the Integration waits and starts only after the ConfigMap becomes available.

4.2.2.3. Specifying a Secret

You can use an OpenShift Secret to securely contain configuration information. To materialize a secret so that it is available to your Camel K integration, you can use the --config secret syntax.

Prerequisites

  • Setting up your Camel K development environment
  • You have one or more Secrets stored on your OpenShift cluster.

    For example, you can create a Secret by using the following command:

    oc create secret generic my-sec --from-literal=my-secret-key="very top secret"

Procedure

  1. Create a Camel K integration that references the ConfigMap.

    For example, the following integration (named ConfigSecretRoute.java) references the my-secret property that is in a Secret named my-sec:

    import org.apache.camel.builder.RouteBuilder;
    
    public class ConfigSecretRoute extends RouteBuilder {
      @Override
      public void configure() throws Exception {
    
        from("timer:secret")
            .setBody()
                .simple("resource:classpath:my-secret")
            .log("secret content is: ${body}");
    
      }
    }
  2. Run the integration and use the --config option to materialize the Secret so that it is available to the running integration. For example:

    kamel run --config secret:my-sec ConfigSecretRoute.java --dev

    When the integration starts, the Camel K operator mounts an OpenShift volume with the Secret’s content.

4.2.2.4. Referencing properties that are contained in ConfigMaps or Secrets

When you run an integration and you specify a ConfigMap or Secret with the --config option, the Camel K operator parses the ConfigMap or Secret as a runtime property file. Within your integration, you can reference the properties as you would reference any other runtime property.

Procedure

  1. Create a text file that contains properties.

    For example, create a file named my.properties that contains the following properties:

    my.key.1=hello
    my.key.2=world
  2. Create a ConfigMap or a Secret based on the properties file.

    For example, use the following command to create a secret from the my.properties file:

    oc create secret generic my-sec --from-file my.properties
  3. In the integration, refer to the properties defined in the Secret.

    For example, the following integration (named ConfigSecretPropertyRoute.java) references the my.key.1 and my.key.2 properties:

    import org.apache.camel.builder.RouteBuilder;
    
    public class ConfigSecretPropertyRoute extends RouteBuilder {
      @Override
      public void configure() throws Exception {
    
        from("timer:secret")
            .routeId("secret")
            .log("{{my.key.1}} {{my.key.2}}");
    
      }
    }
  4. Run the integration and use the --config option to specify the Secret that contains the my.key.1 and my.key.2 properties.

    For example:

    kamel run --config secret:my-sec ConfigSecretPropertyRoute.java --dev

4.2.2.5. Filtering configuration values obtained from a ConfigMap or Secret

ConfigMaps and Secrets can hold more than one source. For example, the following command creates a secret (my-sec-multi) from two sources:

oc create secret generic my-sec-multi --from-literal=my-secret-key="very top secret" --from-literal=my-secret-key-2="even more secret"

You can limit the quantity of information that your integration retrieves to just one source by using the /key notation after with the --config configmap or --config secret options.

Prerequisites

Procedure

  1. Create an integration that uses configuration values from only one of the sources in the ConfigMap or Secret.

    For example, the following integration (ConfigSecretKeyRoute.java) uses the property from only one of the sources in the my-sec-multi secret.

    import org.apache.camel.builder.RouteBuilder;
    
    public class ConfigSecretKeyRoute extends RouteBuilder {
      @Override
      public void configure() throws Exception {
    
        from("timer:secret")
          .setBody()
              .simple("resource:classpath:my-secret-key-2")
          .log("secret content is: ${body}");
      }
    }
  2. Run the integration by using the --config secret option and the /key notation.

    For example:

    kamel run --config secret:my-sec-multi/my-secret-key-2 ConfigSecretKeyRoute.java --dev
  3. Check the integration pod to verify that only the specified source (for example, my-secret-key-2) is mounted.

    For example, run the following command to list all volumes for a pod:

    oc set volume pod/<pod-name> --all

4.2.3. Providing resources to a running integration

You can provide a resource for the integration to use when it is running by specifying the kamel run command’s --resource option. You can specify a local text file (1 MiB maximum file size), a ConfigMap (3MB) or a Secret (3MB). You can optionally specify the destination of the file that is materialized for the resource. For example, if you want to set an HTTPS connection, you use the --resource option because you must provide an SSL certificate which is a binary file that is expected in a known location.

When you use the --resource option, the Camel K operator does not parse the resource looking for runtime properties and it does not add the resource to the classpath. (If you want to add the resource to the classpath, you can use the JVM trait.

4.2.3.1. Specifying a text or binary file as a resource

If you have a text or binary file that contains configuration values, you can use the --resource file:/path/to/file option to materialize the file. By default, the Camel K operator copies the materialized file to the /etc/camel/resources/ directory. Optionally, you can specify a different destination directory as described in Specifying a destination path for a resource.

Prerequisites

Procedure

  1. Create a Camel K integration that reads the contents of a file that you provide.

    For example, the following integration (ResourceFileBinaryRoute.java) unzips and reads the resources-data.zip file:

    import org.apache.camel.builder.RouteBuilder;
    
    public class ResourceFileBinaryRoute extends RouteBuilder {
      @Override
      public void configure() throws Exception {
    
        from("file:/etc/camel/resources/?fileName=resources-data.zip&noop=true&idempotent=false")
            .unmarshal().zipFile()
            .log("resource file unzipped content is: ${body}");
    
      }
    }
  2. Run the integration and use the --resource option to copy the file to the default destination directory (/etc/camel/resources/). For example:

    kamel run --resource file:resources-data.zip ResourceFileBinaryRoute.java -d camel-zipfile --dev

    Note: If you specify a binary file, a binary representation of the contents of the file is created and decoded transparently in the integration.

    Optionally, you can provide more than one resource by adding the --resource option repeatedly, for example:

    kamel run --resource file:resources-data1.txt --resource file:resources-data2.txt ResourceFileBinaryRoute.java -d camel-zipfile --dev

4.2.3.2. Specifying a ConfigMap as a resource

If you have an OpenShift ConfigMap that contains configuration values, and you need to materialize the ConfigMap as a resource for an integration, use the --resource <configmap-file> option.

Prerequisites

  • Setting up your Camel K development environment
  • You have one or more ConfigMap files stored on your OpenShift cluster. For example, you can create a ConfigMap by using the following command:

    oc create configmap my-cm --from-literal=my-configmap-key="configmap content"

Procedure

  1. Create a Camel K integration that references a ConfigMap stored on your OpenShift cluster.

    For example, the following integration (named ResourceConfigmapRoute.java) references a ConfigMap named my-cm that contains my-configmap-key.

    import org.apache.camel.builder.RouteBuilder;
    
    public class ResourceConfigmapRoute extends RouteBuilder {
      @Override
      public void configure() throws Exception {
    
        from("file:/etc/camel/resources/my-cm/?fileName=my-configmap-key&noop=true&idempotent=false")
            .log("resource file content is: ${body}");
    
      }
    }
  2. Run the integration and use the --resource option to materialize the ConfigMap file in the default /etc/camel/resources/ directory so that it is available to the running integration.

    For example:

    kamel run --resource configmap:my-cm ResourceConfigmapRoute.java --dev

    When the integration starts, the Camel K operator mounts a volume with the ConfigMap’s content (for example, my-configmap-key).

Note: If you specify a ConfigMap that is not yet available on the cluster, the Integration waits and starts only after the ConfigMap becomes available.

4.2.3.3. Specifying a Secret as a resource

If you have an OpenShift Secret that contains configuration information, and you need to materialize it as a resource that is available to one or more integrations, use the --resource <secret> syntax.

Prerequisites

  • Setting up your Camel K development environment
  • You have one or more Secrets files stored on your OpenShift cluster. For example, you can create a Secret by using the following command:

    oc create secret generic my-sec --from-literal=my-secret-key="very top secret"

Procedure

  1. Create a Camel K integration that references a Secret stored on your OpenShift cluster.

    For example, the following integration (named ResourceSecretRoute.java) references the my-sec Secret:

    import org.apache.camel.builder.RouteBuilder;
    
    public class ResourceSecretRoute extends RouteBuilder {
      @Override
      public void configure() throws Exception {
    
          from("file:/etc/camel/resources/my-sec/?fileName=my-secret-key&noop=true&idempotent=false")
              .log("resource file content is: ${body}");
    
      }
    }
  2. Run the integration and use the --resource option to materialize the Secret in the default /etc/camel/resources/ directory so that it is available to the running integration.

    For example:

    kamel run --resource secret:my-sec ResourceSecretRoute.java --dev

    When the integration starts, the Camel K operator mounts a volume with the Secret’s content (for example, my-sec).

Note: If you specify a Secret that is not yet available on the cluster, the Integration waits and starts only after the Secret becomes available.

4.2.3.4. Specifying a destination path for a resource

The /etc/camel/resources/ directory is the default location for mounting a resource that you specify with the --resource option. If you need to specify a different directory on which to mount a resource, use the --resource @path syntax.

Prerequisites

Procedure

  1. Create a Camel K integration that references the file, ConfigMap or Secret that contains configuration properties. For example, the following integration (named ResourceFileLocationRoute.java) references the myprops file:

    import org.apache.camel.builder.RouteBuilder;
    
    public class ResourceFileLocationRoute extends RouteBuilder {
      @Override
      public void configure() throws Exception {
    
          from("file:/tmp/?fileName=input.txt&noop=true&idempotent=false")
             .log("resource file content is: ${body}");
    
      }
    }
  2. Run the integration and use the --resource option with the @path syntax and specify where to mount the resource content (either a file, ConfigMap or Secret):

    For example, the following command specifies to use the /tmp directory to mount the input.txt file:

    kamel run --resource file:resources-data.txt@/tmp/input.txt ResourceFileLocationRoute.java --dev
  3. Check the integration’s pod to verify that the file (for example, input.txt) was mounted in the correct location (for example, in the tmp directory ). For example, run the following command:

    oc exec <pod-name> -- cat /tmp/input.txt

4.2.3.5. Filtering ConfigMap or Secret data

When you create a ConfigMap or a Secret, you can specify more than one source of information. For example, the following command creates a ConfigMap (named my-cm-multi) from two sources:

oc create configmap my-cm-multi --from-literal=my-configmap-key="configmap content" --from-literal=my-configmap-key-2="another content"

When you run an integration with the --resource option, a ConfigMap or Secret that was created with more than one source, by default, both sources are materialized.

If you want to limit the quantity of information to recover from a ConfigMap or Secret, you can specify the --resource option’s /key notation after the ConfigMap or Secret name. For example, --resource configmap:my-cm/my-key or --resource secret:my-secret/my-key.

You can limit the quantity of information that your integration retrieves to just one resource by using the /key notation after with the --resource configmap or --resource secret options.

Prerequisites

Procedure

  1. Create an integration that uses configuration values from only one of the resources in the ConfigMap or Secret. For example, the following integration (named ResourceConfigmapKeyLocationRoute.java) references the my-cm-multi ConfigMap:

    import org.apache.camel.builder.RouteBuilder;
    
    public class ResourceConfigmapKeyLocationRoute extends RouteBuilder {
      @Override
      public void configure() throws Exception {
    
        from("file:/tmp/app/data/?fileName=my-configmap-key-2&noop=true&idempotent=false")
           .log("resource file content is: ${body} consumed from
            ${header.CamelFileName}");
    
      }
    }
  2. Run the integration and use the --resource option with the @path syntax and specify where to mount the source content (either a file, ConfigMap or Secret):

    For example, the following command specifies to use only one of the sources (my-configmap-key-2@) contained within the ConfigMap and to use the /tmp/app/data directory to mount it:

    kamel run --resource configmap:my-cm-multi/my-configmap-key-2@/tmp/app/data ResourceConfigmapKeyLocationRoute.java --dev
  3. Check the integration’s pod to verify that only one file (for example, my-configmap-key-2) was mounted in the correct location (for example, in the /tmp/app/data directory). For example, run the following command:

    oc exec <pod-name> -- cat /tmp/app/data/my-configmap-key-2

4.3. Configuring Camel integration components

You can configure Camel components programmatically in your integration code or by using configuration properties on the command line at runtime. You can configure Camel components using the following syntax:

camel.component.${scheme}.${property}=${value}

For example, to change the queue size of the Camel seda component for staged event-driven architecture, you can configure the following property on the command line:

camel.component.seda.queueSize=10

Procedure

  • Enter the kamel run command and specify the Camel component configuration using the --property option. For example:

    kamel run --property camel.component.seda.queueSize=10 examples/Integration.java

4.4. Configuring Camel K integration dependencies

Camel K automatically resolves a wide range of dependencies that are required to run your integration code. However, you can explicitly add dependencies on the command line at runtime using the kamel run --dependency option.

The following example integration uses Camel K automatic dependency resolution:

...
  from("imap://admin@myserver.com")
    .to("seda:output")
...

Because this integration has an endpoint starting with the imap: prefix, Camel K can automatically add the camel-mail component to the list of required dependencies. The seda: endpoint belongs to camel-core, which is automatically added to all integrations, so Camel K does not add additional dependencies for this component.

Camel K automatic dependency resolution is transparent to the user at runtime. This is very useful in development mode because you can quickly add all the components that you need without exiting the development loop.

You can explicitly add a dependency using the kamel run --dependency or -d option. You might need to use this to specify dependencies that are not included in the Camel catalog. You can specify multiple dependencies on the command line.

Procedure

  • Enter the kamel run command and specify dependencies using the -d option. For example:

    kamel run -d mvn:com.google.guava:guava:26.0-jre -d camel-mina2 Integration.java
Note

You can disable automatic dependency resolution by disabling the dependencies trait: -trait dependencies.enabled=false. However, this is not recommended in most cases.