Developing Applications with Red Hat build of Apache Camel for Quarkus
Developing Applications with Red Hat build of Apache Camel for Quarkus
Abstract
Preface Copy linkLink copied to clipboard!
Providing feedback on Red Hat build of Apache Camel documentation
To report an error or to improve our documentation, log in to your Red Hat Jira account and submit an issue. If you do not have a Red Hat Jira account, then you will be prompted to create an account.
Procedure
- Click the following link to create ticket
- Enter a brief description of the issue in the Summary.
- Provide a detailed description of the issue or enhancement in the Description. Include a URL to where the issue occurs in the documentation.
- Clicking Submit creates and routes the issue to the appropriate documentation team.
Chapter 1. Introduction to developing applications with Red Hat build of Apache Camel for Quarkus Copy linkLink copied to clipboard!
This guide is for developers writing Camel applications on top of Red Hat build of Apache Camel for Quarkus.
Camel components which are supported in Red Hat build of Apache Camel for Quarkus have an associated Red Hat build of Apache Camel for Quarkus extension. For more information about the Red Hat build of Apache Camel for Quarkus extensions supported in this distribution, see the Red Hat build of Apache Camel for Quarkus Extensions reference guide.
Chapter 2. Dependency management Copy linkLink copied to clipboard!
A specific Red Hat build of Apache Camel for Quarkus release is supposed to work only with a specific Quarkus release.
2.1. Quarkus tooling for starting a new project Copy linkLink copied to clipboard!
The easiest and most straightforward way to get the dependency versions right in a new project is to use one of the Quarkus tools:
- code.quarkus.redhat.com - an online project generator,
- Quarkus Maven plugin
These tools allow you to select extensions and scaffold a new Maven project.
The universe of available extensions spans over Quarkus Core, Camel Quarkus and several other third party participating projects, such as Hazelcast, Cassandra, Kogito and OptaPlanner.
The generated pom.xml will look similar to the following:
BOM stands for "Bill of Materials" - it is a pom.xml whose main purpose is to manage the versions of artifacts so that end users importing the BOM in their projects do not need to care which particular versions of the artifacts are supposed to work together. In other words, having a BOM imported in the <depependencyManagement> section of your pom.xml allows you to avoid specifying versions for the dependencies managed by the given BOM.
Which particular BOMs end up in the pom.xml file depends on extensions you have selected in the generator tool. The generator tools take care to select a minimal consistent set.
If you choose to add an extension at a later point that is not managed by any of the BOMs in your pom.xml file, you do not need to search for the appropriate BOM manually.
With the quarkus-maven-plugin you can select the extension, and the tool adds the appropriate BOM as required. You can also use the quarkus-maven-plugin to upgrade the BOM versions.
The com.redhat.quarkus.platform BOMs are aligned with each other which means that if an artifact is managed in more than one BOM, it is always managed with the same version. This has the advantage that application developers do not need to care for the compatibility of the individual artifacts that may come from various independent projects.
2.2. Combining with other BOMs Copy linkLink copied to clipboard!
When combining camel-quarkus-bom with any other BOM, think carefully in which order you import them, because the order of imports defines the precedence.
I.e. if my-foo-bom is imported before camel-quarkus-bom then the versions defined in my-foo-bom will take the precedence. This might or might not be what you want, depending on whether there are any overlaps between my-foo-bom and camel-quarkus-bom and depending on whether those versions with higher precedence work with the rest of the artifacts managed in camel-quarkus-bom.
Chapter 3. Defining Camel routes Copy linkLink copied to clipboard!
In Red Hat build of Apache Camel for Quarkus, you can define Camel routes using the following languages:
3.1. Java DSL Copy linkLink copied to clipboard!
Extending org.apache.camel.builder.RouteBuilder and using the fluent builder methods available there is the most common way of defining Camel Routes. Here is a simple example of a route using the timer component:
3.2. Endpoint DSL Copy linkLink copied to clipboard!
Since Camel 3.0, you can use fluent builders also for defining Camel endpoints. The following is equivalent with the previous example:
Builder methods for all Camel components are available via camel-quarkus-core, but you still need to add the given component’s extension as a dependency for the route to work properly. In case of the above example, it would be camel-quarkus-timer.
3.3. XML IO DSL Copy linkLink copied to clipboard!
In order to configure Camel routes, rests or templates in XML, you must add a Camel XML parser dependency to the classpath. Since Camel Quarkus 1.8.0, link:https://docs.redhat.com/en/documentation/red_hat_build_of_apache_camel/4.8/html-single/red_hat_build_of_apache_camel_for_quarkus_reference/ #extensions-xml-io-dsl[camel-quarkus-xml-io-dsl] is the best choice.
With Camel Main, you can set a property that points to the location of resources XML files such as routes, REST DSL and Route templates:
camel.main.routes-include-pattern = routes/routes.xml, file:src/main/routes/rests.xml, file:src/main/rests/route-template.xml
camel.main.routes-include-pattern = routes/routes.xml, file:src/main/routes/rests.xml, file:src/main/rests/route-template.xml
Path globbing like camel.main.routes-include-pattern = *./routes.xml currently does not work in native mode.
Route
When using XML routes with beans, it is sometime needed to refer to class name, for instance beanType=org.apache.SomeClass. In such cases, it might be needed to register the class for reflection in native mode. Refer to the Native mode section for more information.
Spring XML with <beans> or Blueprint XML with <blueprint> elements are not supported.
The route XML should be in the simplified version like:
Rest DSL
Route Templates
3.4. YAML DSL Copy linkLink copied to clipboard!
To configure routes with YAML, you must add the camel-quarkus-yaml-dsl dependency to the classpath.
With Camel Main, you can set a property that points to the location of YAML files containing routes, REST DSL and Route templates definitions:
camel.main.routes-include-pattern = routes/routes.yaml, routes/rests.yaml, rests/route-template.yaml
camel.main.routes-include-pattern = routes/routes.yaml, routes/rests.yaml, rests/route-template.yaml
Route
Rest DSL
Route Templates
Chapter 4. Configuration Copy linkLink copied to clipboard!
Camel Quarkus automatically configures and deploys a Camel Context bean which by default is started/stopped according to the Quarkus Application lifecycle. The configuration step happens at build time during Quarkus' augmentation phase and it is driven by the Camel Quarkus extensions which can be tuned using Camel Quarkus specific quarkus.camel.* properties.
quarkus.camel.* configuration properties are documented on the individual extension pages - for example see Camel Quarkus Core.
After the configuration is done, a minimal Camel Runtime is assembled and started in the RUNTIME_INIT phase.
4.1. Configuring Camel components Copy linkLink copied to clipboard!
4.1.1. application.properties Copy linkLink copied to clipboard!
To configure components and other aspects of Apache Camel through properties, make sure that your application depends on camel-quarkus-core directly or transitively. Because most Camel Quarkus extensions depend on camel-quarkus-core, you typically do not need to add it explicitly.
camel-quarkus-core brings functionalities from Camel Main to Camel Quarkus.
In the example below, you set a specific ExchangeFormatter configuration on the LogComponent via application.properties:
camel.component.log.exchange-formatter = #class:org.apache.camel.support.processor.DefaultExchangeFormatter camel.component.log.exchange-formatter.show-exchange-pattern = false camel.component.log.exchange-formatter.show-body-type = false
camel.component.log.exchange-formatter = #class:org.apache.camel.support.processor.DefaultExchangeFormatter
camel.component.log.exchange-formatter.show-exchange-pattern = false
camel.component.log.exchange-formatter.show-body-type = false
4.1.2. CDI Copy linkLink copied to clipboard!
You can also configure a component programmatically using CDI.
The recommended method is to observe the ComponentAddEvent and configure the component before the routes and the CamelContext are started:
4.1.2.1. Producing a @Named component instance Copy linkLink copied to clipboard!
Alternatively, you can create and configure the component yourself in a @Named producer method. This works as Camel uses the component URI scheme to look-up components from its registry. For example, in the case of a LogComponent Camel looks for a log named bean.
While producing a @Named component bean will usually work, it may cause subtle issues with some components.
Camel Quarkus extensions may do one or more of the following:
- Pass custom subtype of the default Camel component type. See the Vert.x WebSocket extension example.
- Perform some Quarkus specific customization of the component. See the JPA extension example.
These actions are not performed when you produce your own component instance, therefore, configuring components in an observer method is the recommended method.
- 1
- The
"log"argument of the@Namedannotation can be omitted if the name of the method is the same.
4.2. Configuration by convention Copy linkLink copied to clipboard!
In addition to support configuring Camel through properties, camel-quarkus-core allows you to use conventions to configure the Camel behavior. For example, if there is a single ExchangeFormatter instance in the CDI container, then it will automatically wire that bean to the LogComponent.
Chapter 5. Contexts and Dependency Injection (CDI) in Camel Quarkus Copy linkLink copied to clipboard!
CDI plays a central role in Quarkus and Camel Quarkus offers a first class support for it too.
You may use @Inject, @ConfigProperty and similar annotations e.g. to inject beans and configuration values to your Camel RouteBuilder, for example:
- 1
- The
@ApplicationScopedannotation is required for@Injectand@ConfigPropertyto work in aRouteBuilder. Note that the@ApplicationScopedbeans are managed by the CDI container and their life cycle is thus a bit more complex than the one of the plainRouteBuilder. In other words, using@ApplicationScopedinRouteBuildercomes with some boot time penalty and you should therefore only annotate yourRouteBuilderwith@ApplicationScopedwhen you really need it. - 2
- The value for the
timer.periodproperty is defined insrc/main/resources/application.propertiesof the example project.
Refer to the Quarkus Dependency Injection guide for more details.
5.1. Accessing CamelContext Copy linkLink copied to clipboard!
To access CamelContext just inject it into your bean:
5.2. @EndpointInject and @Produce Copy linkLink copied to clipboard!
If you are used to @org.apache.camel.EndpointInject and @org.apache.camel.Produce from plain Camel or from Camel on SpringBoot, you can continue using them on Quarkus too.
The following use cases are supported by org.apache.camel.quarkus:camel-quarkus-core:
You can use any other Camel producer endpoint URI instead of direct:myDirect*.
@EndpointInject and @Produce are not supported on setter methods - see #2579
The following use case is supported by org.apache.camel.quarkus:camel-quarkus-bean:
5.3. CDI and the Camel Bean component Copy linkLink copied to clipboard!
5.3.1. Refer to a bean by name Copy linkLink copied to clipboard!
To refer to a bean in a route definition by name, just annotate the bean with @Named("myNamedBean") and @ApplicationScoped (or some other supported scope). The @RegisterForReflection annotation is important for the native mode.
Then you can use the myNamedBean name in a route definition:
As an alternative to @Named, you may also use io.smallrye.common.annotation.Identifier to name and identify a bean.
Then refer to the identifier value within the Camel route:
We aim at supporting all use cases listed in Bean binding section of Camel documentation. Do not hesitate to file an issue if some bean binding scenario does not work for you.
5.3.2. @Consume Copy linkLink copied to clipboard!
Since Camel Quarkus 2.0.0, the camel-quarkus-bean artifact brings support for @org.apache.camel.Consume - see the Pojo consuming section of Camel documentation.
Declaring a class like the following
will automatically create the following Camel route
from("activemq:cheese").bean("foo1234", "onCheese")
from("activemq:cheese").bean("foo1234", "onCheese")
for you. Note that Camel Quarkus will implicitly add @jakarta.inject.Singleton and jakarta.inject.Named("foo1234") to the bean class, where 1234 is a hash code obtained from the fully qualified class name. If your bean has some CDI scope (such as @ApplicationScoped) or @Named("someName") set already, those will be honored in the auto-created route.
Chapter 6. Observability Copy linkLink copied to clipboard!
6.1. Health & liveness checks Copy linkLink copied to clipboard!
Health & liveness checks are supported via the MicroProfile Health extension. They can be configured via the Camel Health API or via Quarkus MicroProfile Health.
All configured checks are available on the standard MicroProfile Health endpoint URLs:
6.1.1. Health endpoint Copy linkLink copied to clipboard!
Camel provides some out of the box liveness and readiness checks. To see this working, interrogate the /q/health/live and /q/health/ready endpoints on port 9000:
curl -s localhost:9000/q/health/live
$ curl -s localhost:9000/q/health/live
curl -s localhost:9000/q/health/ready
$ curl -s localhost:9000/q/health/ready
The JSON output will contain a checks for verifying whether the CamelContext and each individual route is in the 'Started' state.
This example project contains a custom liveness check class CustomLivenessCheck and custom readiness check class CustomReadinessCheck which leverage the Camel health API. You’ll see these listed in the health JSON as 'custom-liveness-check' and 'custom-readiness-check'. On every 5th invocation of these checks, the health status of custom-liveness-check will be reported as DOWN.
You can also directly leverage MicroProfile Health APIs to create checks. Class CamelUptimeHealthCheck demonstrates how to register a readiness check.
6.2. Metrics Copy linkLink copied to clipboard!
We provide MicroProfile Metrics for exposing metrics.
Some basic Camel metrics are provided for you out of the box, and these can be supplemented by configuring additional metrics in your routes.
Metrics are available on the standard Quarkus metrics endpoint:
6.3. Monitoring a Camel application Copy linkLink copied to clipboard!
With monitoring of your applications, you can collect information about how your application behaves, such as metrics, health checks and distributed tracing.
This section uses the Observability example listed in the Red Hat build of Quarkus examples, adding observability with micrometer.
Check the Camel Quarkus User guide for prerequisites and other general information.
6.3.1. Creating a project Copy linkLink copied to clipboard!
- Start in the Development mode
Run the maven
compilecommand:mvn clean compile quarkus:dev
$ mvn clean compile quarkus:devCopy to Clipboard Copied! Toggle word wrap Toggle overflow This compiles the project, starts the application and lets the Quarkus tooling watch for changes in your workspace.
Any modifications in your project automatically take effect in the running application.
TipRefer to the Development mode section of Camel Quarkus User guide for more details.
6.3.2. Enabling metrics Copy linkLink copied to clipboard!
To enable observability features in Camel Quarkus, you must add additional dependencies to the project’s pom.xml file. The most important ones are camel-quarkus-opentelemetry and quarkus-micrometer-registry-prometheus.
Add the dependencies to your project
pom.xml:Copy to Clipboard Copied! Toggle word wrap Toggle overflow With these dependencies you benefit from both Camel Micrometer and Quarkus Micrometer.
6.3.3. Creating meters Copy linkLink copied to clipboard!
You can create meters for custom metrics in multiple ways:
6.3.3.1. Using Camel micrometer component Copy linkLink copied to clipboard!
With this method you use Routes.java.
.to("micrometer:counter:org.acme.observability.greeting-provider?tags=type=events,purpose=example")
.to("micrometer:counter:org.acme.observability.greeting-provider?tags=type=events,purpose=example")
Which will count each call to the platform-http:/greeting-provider endpoint.
6.3.3.2. Using CDI dependency injection Copy linkLink copied to clipboard!
With this method you use CDI dependency injection of the MeterRegistry:
@Inject MeterRegistry registry;
@Inject
MeterRegistry registry;
Then using it directly in a Camel Processor method to publish metrics:
void countGreeting(Exchange exchange) {
registry.counter("org.acme.observability.greeting", "type", "events", "purpose", "example").increment();
}
void countGreeting(Exchange exchange) {
registry.counter("org.acme.observability.greeting", "type", "events", "purpose", "example").increment();
}
from("platform-http:/greeting")
.removeHeaders("*")
.process(this::countGreeting)
from("platform-http:/greeting")
.removeHeaders("*")
.process(this::countGreeting)
This counts each call to the platform-http:/greeting endpoint.
6.3.3.3. Using Micrometer annotations Copy linkLink copied to clipboard!
With this method you use Micrometer annotations, by defining a bean TimerCounter.java as follows:
It can then be invoked from Camel via the bean EIP (see TimerRoute.java):
.bean("timerCounter", "count")
.bean("timerCounter", "count")
It will increment the counter metric each time the Camel timer is fired.
6.3.3.4. Browsing metrics Copy linkLink copied to clipboard!
Metrics are exposed on an HTTP endpoint at /q/metrics on port 9000.
Note we are using a different port (9000) for the management endpoint then our application (8080) is listening on. This is configured in application.properties via quarkus.management.enabled = true. See the Quarkus management interface guide for more information.
To view all Camel metrics do:
curl -s localhost:9000/q/metrics
$ curl -s localhost:9000/q/metrics
To view only our previously created metrics, use:
curl -s localhost:9000/q/metrics | grep -i 'purpose="example"'
$ curl -s localhost:9000/q/metrics | grep -i 'purpose="example"'
and you should see 3 lines of different metrics (with the same value, as they are all triggered by the timer).
Maybe you’ve noticed the Prometheus output format. If you would rather use the JSON format, please follow the Quarkus Micrometer management interface configuration guide.
6.3.4. Tracing Copy linkLink copied to clipboard!
To be able to diagnose problems in Camel Quarkus applications, you can start tracing messages. We will use OpenTelemetry standard suited for cloud environments.
All you need is to add the dependencies camel-quarkus-opentelemetry and quarkus-micrometer-registry-prometheus to your project pom.xml:
Then configure the OpenTelemetry exporter in application.properties:
# We are using a property placeholder to be able to test this example in convenient way in a cloud environment
quarkus.otel.exporter.otlp.traces.endpoint = http://${TELEMETRY_COLLECTOR_COLLECTOR_SERVICE_HOST:localhost}:4317
# We are using a property placeholder to be able to test this example in convenient way in a cloud environment
quarkus.otel.exporter.otlp.traces.endpoint = http://${TELEMETRY_COLLECTOR_COLLECTOR_SERVICE_HOST:localhost}:4317
For information about other OpenTelemetry exporters, refer to the Camel Quarkus OpenTelemetry extension documentation.
To view tracing events, start a tracing server. A simple way of doing this is with Docker Compose:
docker-compose up -d
$ docker-compose up -d
With the server running, browse to http://localhost:16686. Then choose 'camel-quarkus-observability' from the 'Service' drop down and click the 'Find Traces' button.
The platform-http consumer route introduces a random delay to simulate latency, hence the overall time of each trace should be different. When viewing a trace, you should see a hierarchy of 6 spans showing the progression of the message exchange through each endpoint.
6.3.5. Packaging and running the application Copy linkLink copied to clipboard!
Once you are done with developing you can package and run the application.
For more details about the JVM mode and Native mode, see the "Package and run" section of the Camel Quarkus User guide
6.3.5.1. JVM mode Copy linkLink copied to clipboard!
mvn clean package java -jar target/quarkus-app/quarkus-run.jar ... [io.quarkus] (main) camel-quarkus-examples-... started in 1.163s. Listening on: http://0.0.0.0:8080
$ mvn clean package
$ java -jar target/quarkus-app/quarkus-run.jar
...
[io.quarkus] (main) camel-quarkus-examples-... started in 1.163s. Listening on: http://0.0.0.0:8080
6.3.5.2. Native mode Copy linkLink copied to clipboard!
Native mode requires having GraalVM and other tools installed. Please check the Prerequisites section of Camel Quarkus User guide.
To prepare a native executable using GraalVM, run the following command:
mvn clean package -Pnative ./target/*-runner ... [io.quarkus] (main) camel-quarkus-examples-... started in 0.013s. Listening on: http://0.0.0.0:8080 ...
$ mvn clean package -Pnative
$ ./target/*-runner
...
[io.quarkus] (main) camel-quarkus-examples-... started in 0.013s. Listening on: http://0.0.0.0:8080
...
Chapter 7. Native mode Copy linkLink copied to clipboard!
For additional information about compiling and testing application in native mode, see Producing a native executable in the Compiling your Quarkus applications to native executables guide.
7.1. Character encodings Copy linkLink copied to clipboard!
By default, not all Charsets are available in native mode.
Charset.defaultCharset(), US-ASCII, ISO-8859-1, UTF-8, UTF-16BE, UTF-16LE, UTF-16
Charset.defaultCharset(), US-ASCII, ISO-8859-1, UTF-8, UTF-16BE, UTF-16LE, UTF-16
If you expect your application to need any encoding not included in this set or if you see an UnsupportedCharsetException thrown in the native mode, please add the following entry to your application.properties:
quarkus.native.add-all-charsets = true
quarkus.native.add-all-charsets = true
See also quarkus.native.add-all-charsets in Quarkus documentation.
7.2. Locale Copy linkLink copied to clipboard!
By default, only the building JVM default locale is included in the native image. Quarkus provides a way to set the locale via application.properties, so that you do not need to rely on LANG and LC_* environement variables:
quarkus.native.user-country=US quarkus.native.user-language=en
quarkus.native.user-country=US
quarkus.native.user-language=en
There is also support for embedding multiple locales into the native image and for selecting the default locale via Mandrel command line options -H:IncludeLocales=fr,en, H:+IncludeAllLocales and -H:DefaultLocale=de. You can set those via the Quarkus quarkus.native.additional-build-args property.
7.3. Embedding resources in the native executable Copy linkLink copied to clipboard!
Resources accessed via Class.getResource(), Class.getResourceAsStream(), ClassLoader.getResource(), ClassLoader.getResourceAsStream(), etc. at runtime need to be explicitly listed for including in the native executable.
This can be done using Quarkus quarkus.native.resources.includes and quarkus.native.resources.excludes properties in application.properties file as demonstrated below:
quarkus.native.resources.includes = docs/*,images/* quarkus.native.resources.excludes = docs/ignored.adoc,images/ignored.png
quarkus.native.resources.includes = docs/*,images/*
quarkus.native.resources.excludes = docs/ignored.adoc,images/ignored.png
In the example above, resources named docs/included.adoc and images/included.png would be embedded in the native executable while docs/ignored.adoc and images/ignored.png would not.
resources.includes and resources.excludes are both lists of comma separated Ant-path style glob patterns.
Refer to Red Hat build of Apache Camel for Quarkus Extensions Reference for more details.
7.4. Using the onException clause in native mode Copy linkLink copied to clipboard!
When using Camel onException handling in native mode, it is your responsibility to register the exception classes for reflection.
For instance, having a camel context with onException handling:
onException(MyException.class).handled(true);
from("direct:route-that-could-produce-my-exception").throw(MyException.class);
onException(MyException.class).handled(true);
from("direct:route-that-could-produce-my-exception").throw(MyException.class);
The class mypackage.MyException should be registered for reflection. For more information, see Registering classes for reflection.
7.5. Registering classes for reflection Copy linkLink copied to clipboard!
By default, dynamic reflection is not available in native mode. Classes for which reflective access is needed, have to be registered for reflection at compile time.
In many cases, application developers do not need to care because Quarkus extensions are able to detect the classes that require the reflection and register them automatically.
However, in some situations, Quarkus extensions may miss some classes and it is up to the application developer to register them. There are two ways to do that:
The
@io.quarkus.runtime.annotations.RegisterForReflectionannotation can be used to register classes on which it is used, or it can also register third party classes via itstargetsattribute.Copy to Clipboard Copied! Toggle word wrap Toggle overflow The
quarkus.camel.native.reflectionoptions inapplication.properties:quarkus.camel.native.reflection.include-patterns = org.apache.commons.lang3.tuple.* quarkus.camel.native.reflection.exclude-patterns = org.apache.commons.lang3.tuple.*Triple
quarkus.camel.native.reflection.include-patterns = org.apache.commons.lang3.tuple.* quarkus.camel.native.reflection.exclude-patterns = org.apache.commons.lang3.tuple.*TripleCopy to Clipboard Copied! Toggle word wrap Toggle overflow For these options to work properly, the artifacts containing the selected classes must either contain a Jandex index ('META-INF/jandex.idx') or they must be registered for indexing using the 'quarkus.index-dependency.*' options in 'application.properties' - for example:
quarkus.index-dependency.commons-lang3.group-id = org.apache.commons quarkus.index-dependency.commons-lang3.artifact-id = commons-lang3
quarkus.index-dependency.commons-lang3.group-id = org.apache.commons quarkus.index-dependency.commons-lang3.artifact-id = commons-lang3Copy to Clipboard Copied! Toggle word wrap Toggle overflow
7.6. Registering classes for serialization Copy linkLink copied to clipboard!
If serialization support is requested via quarkus.camel.native.reflection.serialization-enabled, the classes listed in CamelSerializationProcessor.BASE_SERIALIZATION_CLASSES are automatically registered for serialization.
You can register more classes using @RegisterForReflection(serialization = true).
Chapter 8. Kubernetes Copy linkLink copied to clipboard!
This guide describes different ways to configure and deploy a Camel Quarkus application on kubernetes. It also describes some specific use cases for Knative and Service Binding.
8.1. Kubernetes Copy linkLink copied to clipboard!
Quarkus supports generating resources for vanilla Kubernetes, OpenShift and Knative. Furthermore, Quarkus can deploy the application to a target Kubernetes cluster by applying the generated manifests to the target cluster’s API Server. More information in the Quarkus Kubernetes guide.
8.2. Knative Copy linkLink copied to clipboard!
The Camel Quarkus extensions whose consumers support Knative deployment are:
8.3. Service binding Copy linkLink copied to clipboard!
Quarkus also supports the Service Binding Specification for Kubernetes to bind services to applications.
The following Camel Quarkus extensions can be used with Service Binding:
Chapter 9. Quarkus CXF security guide Copy linkLink copied to clipboard!
This chapter provides information about security when working with Quarkus CXF extensions.
9.1. Security guide Copy linkLink copied to clipboard!
The security guide documents various security related aspects of Quarkus CXF:
9.1.1. SSL, TLS and HTTPS Copy linkLink copied to clipboard!
This section documents various use cases related to SSL, TLS and HTTPS.
The sample code snippets used in this section come from the WS-SecurityPolicy integration test in the source tree of Quarkus CXF
9.1.1.1. Client SSL configuration Copy linkLink copied to clipboard!
If your client is going to communicate with a server whose SSL certificate is not trusted by the client’s operating system, then you need to set up a custom trust store for your client.
Tools like openssl or Java keytool are commonly used for creating and maintaining truststores.
We have examples for both tools in the Quarkus CXF source tree:
Once you have prepared the trust store, you need to configure your client to use it.
9.1.1.1.1. Set the client trust store in application.properties Copy linkLink copied to clipboard!
This is the easiest way to set the client trust store. The key role is played by the following properties:
Here is an example:
application.properties
- 1
pkcs12andjksare two commonly used keystore formats. PKCS12 is the default Java keystore format since Java 9. We recommend using PKCS12 rather than JKS, because it offers stronger cryptographic algorithms, it is extensible, standardized, language-neutral and widely supported.- 2
- The referenced
client-truststore.pkcs12file has to be available either in the classpath or in the file system.
9.1.1.2. Server SSL configuration Copy linkLink copied to clipboard!
To make your services available over the HTTPS protocol, you need to set up server keystore in the first place. The server SSL configuration is driven by Vert.x, the HTTP layer of Quarkus. Quarkus HTTP guide provides the information about the configuration options.
Here is a basic example:
application.properties
# Server side SSL quarkus.tls.key-store.p12.path = localhost-keystore.pkcs12 quarkus.tls.key-store.p12.password = localhost-keystore-password quarkus.tls.key-store.p12.alias = localhost quarkus.tls.key-store.p12.alias-password = localhost-keystore-password
# Server side SSL
quarkus.tls.key-store.p12.path = localhost-keystore.pkcs12
quarkus.tls.key-store.p12.password = localhost-keystore-password
quarkus.tls.key-store.p12.alias = localhost
quarkus.tls.key-store.p12.alias-password = localhost-keystore-password
9.1.1.3. Mutual TLS (mTLS) authentication Copy linkLink copied to clipboard!
So far, we have explained the simple or single-sided case where only the server proves its identity through an SSL certificate and the client has to be set up to trust that certificate. Mutual TLS authentication goes by letting also the client prove its identity using the same means of public key cryptography.
Hence, for the Mutual TLS (mTLS) authentication, in addition to setting up the server keystore and client truststore as described above, you need to set up the keystore on the client side and the truststore on the server side.
The tools for creating and maintaining the stores are the same and the configuration properties to use are pretty much analogous to the ones used in the Simple TLS case.
The mTLS integration test in the Quarkus CXF source tree can serve as a good starting point.
The keystores and truststores are created with openssl (or alternatively with Java Java keytool)
Here is the application.properties file:
application.properties
9.1.1.4. Enforce SSL through WS-SecurityPolicy Copy linkLink copied to clipboard!
The requirement for the clients to connect through HTTPS can be defined in a policy.
The functionality is provided by quarkus-cxf-rt-ws-security extension.
Here is an example of a policy file:
https-policy.xml
The policy has to be referenced from a service endpoint interface (SEI):
HttpsPolicyHelloService.java
With this setup in place, any request delivered over HTTP will be rejected by the PolicyVerificationInInterceptor:
ERROR [org.apa.cxf.ws.pol.PolicyVerificationInInterceptor] Inbound policy verification failed: These policy alternatives can not be satisfied:
{http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702}TransportBinding: TLS is not enabled
...
ERROR [org.apa.cxf.ws.pol.PolicyVerificationInInterceptor] Inbound policy verification failed: These policy alternatives can not be satisfied:
{http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702}TransportBinding: TLS is not enabled
...
9.1.2. Authentication and authorization Copy linkLink copied to clipboard!
The sample code snippets shown in this section come from the Client and server integration test in the source tree of Quarkus CXF. You may want to use it as a runnable example.
9.1.2.1. Client HTTP basic authentication Copy linkLink copied to clipboard!
Use the following client configuration options provided by quarkus-cxf extension to pass the username and password for HTTP basic authentication:
Here is an example:
application.properties
quarkus.cxf.client.basicAuth.wsdl = http://localhost:${quarkus.http.test-port}/soap/basicAuth?wsdl
quarkus.cxf.client.basicAuth.client-endpoint-url = http://localhost:${quarkus.http.test-port}/soap/basicAuth
quarkus.cxf.client.basicAuth.username = bob
quarkus.cxf.client.basicAuth.password = bob234
quarkus.cxf.client.basicAuth.wsdl = http://localhost:${quarkus.http.test-port}/soap/basicAuth?wsdl
quarkus.cxf.client.basicAuth.client-endpoint-url = http://localhost:${quarkus.http.test-port}/soap/basicAuth
quarkus.cxf.client.basicAuth.username = bob
quarkus.cxf.client.basicAuth.password = bob234
9.1.2.1.1. Accessing WSDL protected by basic authentication Copy linkLink copied to clipboard!
By default, the clients created by Quarkus CXF do not send the Authorization header, unless you set the quarkus.cxf.client."client-name".secure-wsdl-access to true:
application.properties
quarkus.cxf.client.basicAuthSecureWsdl.wsdl = http://localhost:${quarkus.http.test-port}/soap/basicAuth?wsdl
quarkus.cxf.client.basicAuthSecureWsdl.client-endpoint-url = http://localhost:${quarkus.http.test-port}/soap/basicAuthSecureWsdl
quarkus.cxf.client.basicAuthSecureWsdl.username = bob
quarkus.cxf.client.basicAuthSecureWsdl.password = ${client-server.bob.password}
quarkus.cxf.client.basicAuthSecureWsdl.secure-wsdl-access = true
quarkus.cxf.client.basicAuthSecureWsdl.wsdl = http://localhost:${quarkus.http.test-port}/soap/basicAuth?wsdl
quarkus.cxf.client.basicAuthSecureWsdl.client-endpoint-url = http://localhost:${quarkus.http.test-port}/soap/basicAuthSecureWsdl
quarkus.cxf.client.basicAuthSecureWsdl.username = bob
quarkus.cxf.client.basicAuthSecureWsdl.password = ${client-server.bob.password}
quarkus.cxf.client.basicAuthSecureWsdl.secure-wsdl-access = true
9.1.2.2. Mutual TLS (mTLS) authentication Copy linkLink copied to clipboard!
See the Mutual TLS (mTLS) authentication section in SSL, TLS and HTTPS guide.
9.1.2.3. Securing service endpoints Copy linkLink copied to clipboard!
The server-side authentication and authorization is driven by Quarkus Security, especially when it comes to
There is a basic example in our Client and server integration test. Its key parts are:
-
io.quarkus:quarkus-elytron-security-properties-filedependency as an Identity provider Basic authentication enabled and users with their roles configured in
application.properties:application.properties
Copy to Clipboard Copied! Toggle word wrap Toggle overflow -
Role-based access control enfoced via
@RolesAllowedannotation:
BasicAuthHelloServiceImpl.java
9.1.3. Authentication enforced by WS-SecurityPolicy Copy linkLink copied to clipboard!
You can enforce authentication through WS-SecurityPolicy, instead of Mutual TLS and Basic HTTP authentication for clients and services.
To enforce authentication through WS-SecurityPolicy, follow these steps:
- Add a supporting tokens policy to an endpoint in the WSDL contract.
-
On the server side, implement an authentication callback handler and associate it with the endpoint in
application.propertiesor via environment variables. Credentials received from clients are authenticated by the callback handler. -
On the client side, provide credentials through either configuration in
application.propertiesor environment variables. Alternatively, you can implement an authentication callback handler to pass the credentials.
9.1.3.1. Specifying an Authentication Policy Copy linkLink copied to clipboard!
If you want to enforce authentication on a service endpoint, associate a supporting tokens policy assertion with the relevant endpoint binding and specify one or more token assertions under it.
There are several different kinds of supporting tokens policy assertions, whose XML element names all end with SupportingTokens (for example, SupportingTokens, SignedSupportingTokens, and so on). For a complete list, see the Supporting Tokens section of the WS-SecurityPolicy specification.
9.1.3.2. UsernameToken policy assertion example Copy linkLink copied to clipboard!
The sample code snippets used in this section come from the WS-SecurityPolicy integration test in the source tree of Quarkus CXF. You may want to use it as a runnable example.
The following listing shows an example of a policy that requires a WS-Security UsernameToken (which contains username/password credentials) to be included in the security header.
username-token-policy.xml
There are two ways how you can associate this policy file with a service endpoint:
Reference the policy on the Service Endpoint Interface (SEI) like this:
UsernameTokenPolicyHelloService.java
@WebService(serviceName = "UsernameTokenPolicyHelloService") @Policy(placement = Policy.Placement.BINDING, uri = "username-token-policy.xml") public interface UsernameTokenPolicyHelloService extends AbstractHelloService { ... }@WebService(serviceName = "UsernameTokenPolicyHelloService") @Policy(placement = Policy.Placement.BINDING, uri = "username-token-policy.xml") public interface UsernameTokenPolicyHelloService extends AbstractHelloService { ... }Copy to Clipboard Copied! Toggle word wrap Toggle overflow -
Include the policy in your WSDL contract and reference it via
PolicyReferenceelement.
When you have the policy in place, configure the credentials on the service endpoint and the client:
application.properties
In the above listing, usernameTokenPasswordCallback is a name of a @jakarta.inject.Named bean implementing javax.security.auth.callback.CallbackHandler. Quarkus CXF will lookup a bean with this name in the CDI container.
Here is an example implementation of the bean:
UsernameTokenPasswordCallback.java
To test the whole setup, you can create a simple @QuarkusTest:
UsernameTokenTest.java
When running the test via mvn test -Dtest=UsernameTokenTest, you should see a SOAP message being logged with a Security header containing Username and Password:
Log output of the UsernameTokenTest
9.1.3.3. SAML v1 and v2 policy assertion examples Copy linkLink copied to clipboard!
The WS-SecurityPolicy integration test contains also analogous examples with SAML v1 and SAML v2 assertions.
Chapter 10. Camel Security Copy linkLink copied to clipboard!
This chapter provides information about Camel route security options.
10.1. Camel security overview Copy linkLink copied to clipboard!
Camel offers several forms & levels of security capabilities that can be utilized on Camel routes. These various forms of security may be used in conjunction with each other or separately.
The broad categories offered are:
- Route Security - Authentication and Authorization services to proceed on a route or route segment
- Payload Security - Data Formats that offer encryption/decryption services at the payload level
- Endpoint Security - Security offered by components that can be utilized by endpointUri associated with the component
- Configuration Security - Security offered by encrypting sensitive information from configuration files or external Secured Vault systems.
Camel offers the JSSE Utility for configuring SSL/TLS related aspects of a number of Camel components.
10.2. Route Security Copy linkLink copied to clipboard!
Authentication and Authorization Services
Camel offers Route Policy driven security capabilities that may be wired into routes or route segments. A route policy in Camel utilizes a strategy pattern for applying interceptors on Camel Processors. It’s offering the ability to apply cross-cutting concerns (for example. security, transactions etc) of a Camel route.
10.3. Payload Security Copy linkLink copied to clipboard!
Camel offers encryption/decryption services to secure payloads or selectively apply encryption/decryption capabilities on portions/sections of a payload.
The dataformats offering encryption/decryption of payloads utilizing Marshal are:
10.4. Endpoint Security Copy linkLink copied to clipboard!
Some components in Camel offer an ability to secure their endpoints (using interceptors etc) and therefore ensure that they offer the ability to secure payloads as well as provide authentication/authorization capabilities at endpoints created using the components.
10.5. Configuration Security Copy linkLink copied to clipboard!
Camel offers the Properties component to externalize configuration values to properties files. Those values could contain sensitive information such as usernames and passwords.
Those values can be encrypted and automatic decrypted by Camel using:
Camel also support accessing the secured configuration from an external vault systems.
10.5.1. Configuration Security using Vaults Copy linkLink copied to clipboard!
The following Vaults are supported by Camel:
10.5.1.1. Using AWS Vault Copy linkLink copied to clipboard!
To use AWS Secrets Manager you need to provide accessKey, secretKey and the region. This can be done using environmental variables before starting the application:
export $CAMEL_VAULT_AWS_ACCESS_KEY=accessKey export $CAMEL_VAULT_AWS_SECRET_KEY=secretKey export $CAMEL_VAULT_AWS_REGION=region
export $CAMEL_VAULT_AWS_ACCESS_KEY=accessKey
export $CAMEL_VAULT_AWS_SECRET_KEY=secretKey
export $CAMEL_VAULT_AWS_REGION=region
You can also configure the credentials in the application.properties file such as:
camel.vault.aws.accessKey = accessKey camel.vault.aws.secretKey = secretKey camel.vault.aws.region = region
camel.vault.aws.accessKey = accessKey
camel.vault.aws.secretKey = secretKey
camel.vault.aws.region = region
If you want instead to use the AWS default credentials provider, you’ll need to provide the following env variables:
export $CAMEL_VAULT_AWS_USE_DEFAULT_CREDENTIALS_PROVIDER=true export $CAMEL_VAULT_AWS_REGION=region
export $CAMEL_VAULT_AWS_USE_DEFAULT_CREDENTIALS_PROVIDER=true
export $CAMEL_VAULT_AWS_REGION=region
You can also configure the credentials in the application.properties file such as:
camel.vault.aws.defaultCredentialsProvider = true camel.vault.aws.region = region
camel.vault.aws.defaultCredentialsProvider = true
camel.vault.aws.region = region
It is also possible to specify a particular profile name for accessing AWS Secrets Manager
export $CAMEL_VAULT_AWS_USE_PROFILE_CREDENTIALS_PROVIDER=true export $CAMEL_VAULT_AWS_PROFILE_NAME=test-account export $CAMEL_VAULT_AWS_REGION=region
export $CAMEL_VAULT_AWS_USE_PROFILE_CREDENTIALS_PROVIDER=true
export $CAMEL_VAULT_AWS_PROFILE_NAME=test-account
export $CAMEL_VAULT_AWS_REGION=region
You can also configure the credentials in the application.properties file such as:
camel.vault.aws.profileCredentialsProvider = true camel.vault.aws.profileName = test-account camel.vault.aws.region = region
camel.vault.aws.profileCredentialsProvider = true
camel.vault.aws.profileName = test-account
camel.vault.aws.region = region
At this point you’ll be able to reference a property in the following way by using aws: as prefix in the {{ }} syntax:
Where route will be the name of the secret stored in the AWS Secrets Manager Service.
You could specify a default value in case the secret is not present on AWS Secret Manager:
In this case if the secret doesn’t exist, the property will fallback to "default" as value.
Also, you are able to get particular field of the secret, if you have for example a secret named database of this form:
You’re able to do get single secret value in your route, like for example:
Or re-use the property as part of an endpoint.
You could specify a default value in case the particular field of secret is not present on AWS Secret Manager:
In this case if the secret doesn’t exist or the secret exists, but the username field is not part of the secret, the property will fallback to "admin" as value.
For the moment we are not considering the rotation function, if any will be applied, but it is in the work to be done.
The only requirement is adding camel-aws-secrets-manager JAR to your Camel application.
10.5.1.2. Using Google Secret Manager GCP Vault Copy linkLink copied to clipboard!
To use GCP Secret Manager you need to provide serviceAccountKey file and GCP projectId. This can be done using environmental variables before starting the application:
export $CAMEL_VAULT_GCP_SERVICE_ACCOUNT_KEY=file:////path/to/service.accountkey export $CAMEL_VAULT_GCP_PROJECT_ID=projectId
export $CAMEL_VAULT_GCP_SERVICE_ACCOUNT_KEY=file:////path/to/service.accountkey
export $CAMEL_VAULT_GCP_PROJECT_ID=projectId
You can also configure the credentials in the application.properties file such as:
camel.vault.gcp.serviceAccountKey = accessKey camel.vault.gcp.projectId = secretKey
camel.vault.gcp.serviceAccountKey = accessKey
camel.vault.gcp.projectId = secretKey
If you want instead to use the GCP default client instance, you’ll need to provide the following env variables:
export $CAMEL_VAULT_GCP_USE_DEFAULT_INSTANCE=true export $CAMEL_VAULT_GCP_PROJECT_ID=projectId
export $CAMEL_VAULT_GCP_USE_DEFAULT_INSTANCE=true
export $CAMEL_VAULT_GCP_PROJECT_ID=projectId
You can also configure the credentials in the application.properties file such as:
camel.vault.gcp.useDefaultInstance = true camel.vault.aws.projectId = region
camel.vault.gcp.useDefaultInstance = true
camel.vault.aws.projectId = region
At this point you’ll be able to reference a property in the following way by using gcp: as prefix in the {{ }} syntax:
Where route will be the name of the secret stored in the GCP Secret Manager Service.
You could specify a default value in case the secret is not present on GCP Secret Manager:
In this case if the secret doesn’t exist, the property will fallback to "default" as value.
Also, you are able to get particular field of the secret, if you have for example a secret named database of this form:
You’re able to do get single secret value in your route, like for example:
Or re-use the property as part of an endpoint.
You could specify a default value in case the particular field of secret is not present on GCP Secret Manager:
In this case if the secret doesn’t exist or the secret exists, but the username field is not part of the secret, the property will fallback to "admin" as value.
For the moment we are not considering the rotation function, if any will be applied, but it is in the work to be done.
There are only two requirements: - Adding camel-google-secret-manager JAR to your Camel application. - Give the service account used permissions to do operation at secret management level (for example accessing the secret payload, or being admin of secret manager service)
10.5.1.3. Using Azure Key Vault Copy linkLink copied to clipboard!
To use this function you’ll need to provide credentials to Azure Key Vault Service as environment variables:
export $CAMEL_VAULT_AZURE_TENANT_ID=tenantId export $CAMEL_VAULT_AZURE_CLIENT_ID=clientId export $CAMEL_VAULT_AZURE_CLIENT_SECRET=clientSecret export $CAMEL_VAULT_AZURE_VAULT_NAME=vaultName
export $CAMEL_VAULT_AZURE_TENANT_ID=tenantId
export $CAMEL_VAULT_AZURE_CLIENT_ID=clientId
export $CAMEL_VAULT_AZURE_CLIENT_SECRET=clientSecret
export $CAMEL_VAULT_AZURE_VAULT_NAME=vaultName
You can also configure the credentials in the application.properties file such as:
camel.vault.azure.tenantId = accessKey camel.vault.azure.clientId = clientId camel.vault.azure.clientSecret = clientSecret camel.vault.azure.vaultName = vaultName
camel.vault.azure.tenantId = accessKey
camel.vault.azure.clientId = clientId
camel.vault.azure.clientSecret = clientSecret
camel.vault.azure.vaultName = vaultName
Or you can enable the usage of Azure Identity in the following way:
export $CAMEL_VAULT_AZURE_IDENTITY_ENABLED=true export $CAMEL_VAULT_AZURE_VAULT_NAME=vaultName
export $CAMEL_VAULT_AZURE_IDENTITY_ENABLED=true
export $CAMEL_VAULT_AZURE_VAULT_NAME=vaultName
You can also enable the usage of Azure Identity in the application.properties file such as:
camel.vault.azure.azureIdentityEnabled = true camel.vault.azure.vaultName = vaultName
camel.vault.azure.azureIdentityEnabled = true
camel.vault.azure.vaultName = vaultName
At this point you’ll be able to reference a property in the following way:
Where route will be the name of the secret stored in the Azure Key Vault Service.
You could specify a default value in case the secret is not present on Azure Key Vault Service:
In this case if the secret doesn’t exist, the property will fallback to "default" as value.
Also you are able to get particular field of the secret, if you have for example a secret named database of this form:
You’re able to do get single secret value in your route, like for example:
Or re-use the property as part of an endpoint.
You could specify a default value in case the particular field of secret is not present on Azure Key Vault:
In this case if the secret doesn’t exist or the secret exists, but the username field is not part of the secret, the property will fallback to "admin" as value.
For the moment we are not considering the rotation function, if any will be applied, but it is in the work to be done.
The only requirement is adding the camel-azure-key-vault jar to your Camel application.
10.5.1.4. Using Hashicorp Vault Copy linkLink copied to clipboard!
To use this function, you’ll need to provide credentials for Hashicorp vault as environment variables:
export $CAMEL_VAULT_HASHICORP_TOKEN=token export $CAMEL_VAULT_HASHICORP_HOST=host export $CAMEL_VAULT_HASHICORP_PORT=port export $CAMEL_VAULT_HASHICORP_SCHEME=http/https
export $CAMEL_VAULT_HASHICORP_TOKEN=token
export $CAMEL_VAULT_HASHICORP_HOST=host
export $CAMEL_VAULT_HASHICORP_PORT=port
export $CAMEL_VAULT_HASHICORP_SCHEME=http/https
You can also configure the credentials in the application.properties file such as:
camel.vault.hashicorp.token = token camel.vault.hashicorp.host = host camel.vault.hashicorp.port = port camel.vault.hashicorp.scheme = scheme
camel.vault.hashicorp.token = token
camel.vault.hashicorp.host = host
camel.vault.hashicorp.port = port
camel.vault.hashicorp.scheme = scheme
At this point, you’ll be able to reference a property in the following way:
Where route will be the name of the secret stored in the Hashicorp Vault instance, in the 'secret' engine.
You could specify a default value in case the secret is not present on Hashicorp Vault instance:
In this case, if the secret doesn’t exist in the 'secret' engine, the property will fall back to "default" as value.
Also, you are able to get a particular field of the secret, if you have, for example, a secret named database of this form:
You’re able to do get single secret value in your route, in the 'secret' engine, like for example:
Or re-use the property as part of an endpoint.
You could specify a default value in case the particular field of secret is not present on Hashicorp Vault instance, in the 'secret' engine:
In this case, if the secret doesn’t exist or the secret exists (in the 'secret' engine) but the username field is not part of the secret, the property will fall back to "admin" as value.
There is also the syntax to get a particular version of the secret for both the approach, with field/default value specified or only with secret:
This approach will return the RAW route secret with version '2', in the 'secret' engine.
This approach will return the route secret value with version '2' or default value in case the secret doesn’t exist or the version doesn’t exist (in the 'secret' engine).
This approach will return the username field of the database secret with version '2' or admin in case the secret doesn’t exist or the version doesn’t exist (in the 'secret' engine).
10.5.1.5. Automatic Camel context reloading on Secret Refresh while using AWS Secrets Manager Copy linkLink copied to clipboard!
Being able to reload Camel context on a Secret Refresh, could be done by specifying the usual credentials (the same used for AWS Secret Manager Property Function).
With Environment variables:
export $CAMEL_VAULT_AWS_USE_DEFAULT_CREDENTIALS_PROVIDER=accessKey export $CAMEL_VAULT_AWS_REGION=region
export $CAMEL_VAULT_AWS_USE_DEFAULT_CREDENTIALS_PROVIDER=accessKey
export $CAMEL_VAULT_AWS_REGION=region
or as plain Camel main properties:
camel.vault.aws.useDefaultCredentialProvider = true camel.vault.aws.region = region
camel.vault.aws.useDefaultCredentialProvider = true
camel.vault.aws.region = region
Or by specifying accessKey/SecretKey and region, instead of using the default credentials provider chain.
To enable the automatic refresh you’ll need additional properties to set:
camel.vault.aws.refreshEnabled=true camel.vault.aws.refreshPeriod=60000 camel.vault.aws.secrets=Secret camel.main.context-reload-enabled = true
camel.vault.aws.refreshEnabled=true
camel.vault.aws.refreshPeriod=60000
camel.vault.aws.secrets=Secret
camel.main.context-reload-enabled = true
where camel.vault.aws.refreshEnabled will enable the automatic context reload, camel.vault.aws.refreshPeriod is the interval of time between two different checks for update events and camel.vault.aws.secrets is a regex representing the secrets we want to track for updates.
Note that camel.vault.aws.secrets is not mandatory: if not specified the task responsible for checking updates events will take into accounts or the properties with an aws: prefix.
The only requirement is adding the camel-aws-secrets-manager jar to your Camel application.
10.5.1.6. Automatic Camel context reloading on Secret Refresh while using AWS Secrets Manager with Eventbridge and AWS SQS Services Copy linkLink copied to clipboard!
Another option is to use AWS EventBridge in conjunction with the AWS SQS service.
On the AWS side, the following resources need to be created:
- an AWS Couldtrail trail
- an AWS SQS Queue
- an Eventbridge rule of the following kind
This rule will make the event related to AWS Secrets Manager filtered
- You need to set the a Rule target to the AWS SQS Queue for Eventbridge rule
- You need to give permission to the Eventbrige rule, to write on the above SQS Queue. For doing this you’ll need to define a json file like this:
{
"Policy": "{\"Version\":\"2012-10-17\",\"Id\":\"<queue_arn>/SQSDefaultPolicy\",\"Statement\":[{\"Sid\": \"EventsToMyQueue\", \"Effect\": \"Allow\", \"Principal\": {\"Service\": \"events.amazonaws.com\"}, \"Action\": \"sqs:SendMessage\", \"Resource\": \"<queue_arn>\", \"Condition\": {\"ArnEquals\": {\"aws:SourceArn\": \"<eventbridge_rule_arn>\"}}}]}"
}
{
"Policy": "{\"Version\":\"2012-10-17\",\"Id\":\"<queue_arn>/SQSDefaultPolicy\",\"Statement\":[{\"Sid\": \"EventsToMyQueue\", \"Effect\": \"Allow\", \"Principal\": {\"Service\": \"events.amazonaws.com\"}, \"Action\": \"sqs:SendMessage\", \"Resource\": \"<queue_arn>\", \"Condition\": {\"ArnEquals\": {\"aws:SourceArn\": \"<eventbridge_rule_arn>\"}}}]}"
}
Change the values for queue_arn and eventbridge_rule_arn, save the file with policy.json name and run the following command with AWS CLI
aws sqs set-queue-attributes --queue-url <queue_url> --attributes file://policy.json
aws sqs set-queue-attributes --queue-url <queue_url> --attributes file://policy.json
where queue_url is the AWS SQS Queue URL of the just created Queue.
Now you should be able to set up the configuration on the Camel side. To enable the SQS notification add the following properties:
where queue_url is the AWS SQS Queue URL of the just created Queue.
Whenever an event of PutSecretValue for the Secret named 'Secret' will happen, a message will be enqueued in the AWS SQS Queue and consumed on the Camel side and a context reload will be triggered.
10.5.1.7. Automatic Camel context reloading on Secret Refresh while using Google Secret Manager Copy linkLink copied to clipboard!
Being able to reload Camel context on a Secret Refresh, could be done by specifying the usual credentials (the same used for Google Secret Manager Property Function).
With Environment variables:
export $CAMEL_VAULT_GCP_USE_DEFAULT_INSTANCE=true export $CAMEL_VAULT_GCP_PROJECT_ID=projectId
export $CAMEL_VAULT_GCP_USE_DEFAULT_INSTANCE=true
export $CAMEL_VAULT_GCP_PROJECT_ID=projectId
or as plain Camel main properties:
camel.vault.gcp.useDefaultInstance = true camel.vault.aws.projectId = projectId
camel.vault.gcp.useDefaultInstance = true
camel.vault.aws.projectId = projectId
Or by specifying a path to a service account key file, instead of using the default instance.
To enable the automatic refresh you’ll need additional properties to set:
where camel.vault.gcp.refreshEnabled will enable the automatic context reload, camel.vault.gcp.refreshPeriod is the interval of time between two different checks for update events and camel.vault.gcp.secrets is a regex representing the secrets we want to track for updates.
Note that camel.vault.gcp.secrets is not mandatory: if not specified the task responsible for checking updates events will take into accounts or the properties with an gcp: prefix.
The camel.vault.gcp.subscriptionName is the subscription name created in relation to the Google PubSub topic associated with the tracked secrets.
This mechanism while make use of the notification system related to Google Secret Manager: through this feature, every secret could be associated to one up to ten Google Pubsub Topics. These topics will receive events related to life cycle of the secret.
There are only two requirements: - Adding camel-google-secret-manager JAR to your Camel application. - Give the service account used permissions to do operation at secret management level (for example accessing the secret payload, or being admin of secret manager service and also have permission over the Pubsub service)
10.5.1.8. Automatic Camel context reloading on Secret Refresh while using Azure Key Vault Copy linkLink copied to clipboard!
Being able to reload Camel context on a Secret Refresh, could be done by specifying the usual credentials (the same used for Azure Key Vault Property Function).
With Environment variables:
export $CAMEL_VAULT_AZURE_TENANT_ID=tenantId export $CAMEL_VAULT_AZURE_CLIENT_ID=clientId export $CAMEL_VAULT_AZURE_CLIENT_SECRET=clientSecret export $CAMEL_VAULT_AZURE_VAULT_NAME=vaultName
export $CAMEL_VAULT_AZURE_TENANT_ID=tenantId
export $CAMEL_VAULT_AZURE_CLIENT_ID=clientId
export $CAMEL_VAULT_AZURE_CLIENT_SECRET=clientSecret
export $CAMEL_VAULT_AZURE_VAULT_NAME=vaultName
or as plain Camel main properties:
camel.vault.azure.tenantId = accessKey camel.vault.azure.clientId = clientId camel.vault.azure.clientSecret = clientSecret camel.vault.azure.vaultName = vaultName
camel.vault.azure.tenantId = accessKey
camel.vault.azure.clientId = clientId
camel.vault.azure.clientSecret = clientSecret
camel.vault.azure.vaultName = vaultName
If you want to use Azure Identity with environment variables, you can do in the following way:
export $CAMEL_VAULT_AZURE_IDENTITY_ENABLED=true export $CAMEL_VAULT_AZURE_VAULT_NAME=vaultName
export $CAMEL_VAULT_AZURE_IDENTITY_ENABLED=true
export $CAMEL_VAULT_AZURE_VAULT_NAME=vaultName
You can also enable the usage of Azure Identity in the application.properties file such as:
camel.vault.azure.azureIdentityEnabled = true camel.vault.azure.vaultName = vaultName
camel.vault.azure.azureIdentityEnabled = true
camel.vault.azure.vaultName = vaultName
To enable the automatic refresh you’ll need additional properties to set:
where camel.vault.azure.refreshEnabled will enable the automatic context reload, camel.vault.azure.refreshPeriod is the interval of time between two different checks for update events and camel.vault.azure.secrets is a regex representing the secrets we want to track for updates.
where camel.vault.azure.eventhubConnectionString is the eventhub connection string to get notification from, camel.vault.azure.blobAccountName, camel.vault.azure.blobContainerName and camel.vault.azure.blobAccessKey are the Azure Storage Blob parameters for the checkpoint store needed by Azure Eventhub.
Note that camel.vault.azure.secrets is not mandatory: if not specified the task responsible for checking updates events will take into accounts or the properties with an azure: prefix.
The only requirement is adding the camel-azure-key-vault jar to your Camel application.