Developing Applications with Red Hat build of Apache Camel for Quarkus


Red Hat build of Apache Camel 4.4

Developing Applications with Red Hat build of Apache Camel for Quarkus

Red Hat build of Apache Camel Documentation Team Red Hat build of Apache Camel Support Team http://access.redhat.com/support

Abstract

This guide is for developers writing Camel applications on top of Red Hat build of Apache Camel for Quarkus.

Preface

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

  1. Click the following link to create ticket
  2. Enter a brief description of the issue in the Summary.
  3. Provide a detailed description of the issue or enhancement in the Description. Include a URL to where the issue occurs in the documentation.
  4. 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

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

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

The easiest and most straightforward way to get the dependency versions right in a new project is to use one of the Quarkus tools:

These tools allow you to select extensions and scaffold a new Maven project.

Tip

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:

<project>
  ...
  <properties>
    <quarkus.platform.artifact-id>quarkus-bom</quarkus.platform.artifact-id>
    <quarkus.platform.group-id>com.redhat.quarkus.platform</quarkus.platform.group-id>
    <quarkus.platform.version>
        <!-- The latest 3.8.x version from https://maven.repository.redhat.com/ga/com/redhat/quarkus/platform/quarkus-bom -->
    </quarkus.platform.version>
    ...
  </properties>
  <dependencyManagement>
    <dependencies>
      <!-- The BOMs managing the dependency versions -->
      <dependency>
        <groupId>${quarkus.platform.group-id}</groupId>
        <artifactId>quarkus-bom</artifactId>
        <version>${quarkus.platform.version}</version>
        <type>pom</type>
        <scope>import</scope>
      </dependency>
      <dependency>
        <groupId>${quarkus.platform.group-id}</groupId>
        <artifactId>quarkus-camel-bom</artifactId>
        <version>${quarkus.platform.version}</version>
        <type>pom</type>
        <scope>import</scope>
      </dependency>
    </dependencies>
  </dependencyManagement>

  <dependencies>
    <!-- The extensions you chose in the project generator tool -->
    <dependency>
      <groupId>org.apache.camel.quarkus</groupId>
      <artifactId>camel-quarkus-sql</artifactId>
      <!-- No explicit version required here and below -->
    </dependency>
    ...
  </dependencies>
  ...
</project>
Note

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

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

In Red Hat build of Apache Camel for Quarkus, you can define Camel routes using the following languages:

3.1. Java DSL

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:

import org.apache.camel.builder.RouteBuilder;

public class TimerRoute extends RouteBuilder {

    @Override
    public void configure() throws Exception {
        from("timer:foo?period=1000")
                .log("Hello World");
    }
}

3.2. Endpoint DSL

Since Camel 3.0, you can use fluent builders also for defining Camel endpoints. The following is equivalent with the previous example:

import org.apache.camel.builder.RouteBuilder;
import static org.apache.camel.builder.endpoint.StaticEndpointBuilders.timer;

public class TimerRoute extends RouteBuilder {

    @Override
    public void configure() throws Exception {
        from(timer("foo").period(1000))
                .log("Hello World");
    }
}
Note

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

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://access.redhat.com/documentation/en-us/red_hat_build_of_apache_camel/4.4/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
Note

Path globbing like camel.main.routes-include-pattern = *./routes.xml currently does not work in native mode.

Route

<routes xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xmlns="http://camel.apache.org/schema/spring"
        xsi:schemaLocation="
            http://camel.apache.org/schema/spring
            http://camel.apache.org/schema/spring/camel-spring.xsd">

    <route id="xml-route">
        <from uri="timer:from-xml?period=1000"/>
        <log message="Hello XML!"/>
    </route>

</routes>

Warning

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.

Warning

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

<rests xmlns="http://camel.apache.org/schema/spring">
    <rest id="greeting" path="/greeting">
        <get path="/hello">
            <to uri="direct:greet"/>
        </get>
    </rest>
</rests>

Route Templates

<routeTemplates xmlns="http://camel.apache.org/schema/spring">
    <routeTemplate id="myTemplate">
        <templateParameter name="name"/>
        <templateParameter name="greeting"/>
        <templateParameter name="myPeriod" defaultValue="3s"/>
        <route>
            <from uri="timer:{{name}}?period={{myPeriod}}"/>
            <setBody><simple>{{greeting}} ${body}</simple></setBody>
            <log message="${body}"/>
        </route>
    </routeTemplate>
</routeTemplates>

3.4. YAML DSL

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

Route

- route:
    id: "my-yaml-route"
    from:
      uri: "timer:from-yaml?period=1000"
      steps:
        - set-body:
            constant: "Hello YAML!"
        - to: "log:from-yaml"

Rest DSL

- rest:
    get:
      - path: "/greeting"
        to: "direct:greet"

- route:
    id: "rest-route"
    from:
      uri: "direct:greet"
      steps:
        - set-body:
            constant: "Hello YAML!"

Route Templates

- route-template:
    id: "myTemplate"
    parameters:
      - name: "name"
      - name: "greeting"
        defaultValue: "Hello"
      - name: "myPeriod"
        defaultValue: "3s"
    from:
      uri: "timer:{{name}}?period={{myPeriod}}"
      steps:
      - set-body:
          expression:
            simple: "{{greeting}} ${body}"
      - log: "${body}"

- templated-route:
    route-template-ref: "myTemplate"
    parameters:
      - name: "name"
        value: "tick"
      - name: "greeting"
        value: "Bonjour"
      - name: "myPeriod"
        value: "5s"

Chapter 4. Configuration

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.

Note

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

4.1.1. application.properties

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

4.1.2. CDI

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:

import jakarta.enterprise.context.ApplicationScoped;
import jakarta.enterprise.event.Observes;
import org.apache.camel.quarkus.core.events.ComponentAddEvent;
import org.apache.camel.component.log.LogComponent;
import org.apache.camel.support.processor.DefaultExchangeFormatter;

@ApplicationScoped
public static class EventHandler {
    public void onComponentAdd(@Observes ComponentAddEvent event) {
        if (event.getComponent() instanceof LogComponent) {
            /* Perform some custom configuration of the component */
            LogComponent logComponent = ((LogComponent) event.getComponent());
            DefaultExchangeFormatter formatter = new DefaultExchangeFormatter();
            formatter.setShowExchangePattern(false);
            formatter.setShowBodyType(false);
            logComponent.setExchangeFormatter(formatter);
        }
    }
}
4.1.2.1. Producing a @Named component instance

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.

Warning

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.

import jakarta.enterprise.context.ApplicationScoped;
import jakarta.inject.Named;

import org.apache.camel.component.log.LogComponent;
import org.apache.camel.support.processor.DefaultExchangeFormatter;

@ApplicationScoped
public class Configurations {
    /**
     * Produces a {@link LogComponent} instance with a custom exchange formatter set-up.
     */
    @Named("log") 1
    LogComponent log() {
        DefaultExchangeFormatter formatter = new DefaultExchangeFormatter();
        formatter.setShowExchangePattern(false);
        formatter.setShowBodyType(false);

        LogComponent component = new LogComponent();
        component.setExchangeFormatter(formatter);

        return component;
    }
}
1
The "log" argument of the @Named annotation can be omitted if the name of the method is the same.

4.2. Configuration by convention

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

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:

import jakarta.enterprise.context.ApplicationScoped;
import jakarta.inject.Inject;
import org.apache.camel.builder.RouteBuilder;
import org.eclipse.microprofile.config.inject.ConfigProperty;

@ApplicationScoped 1
public class TimerRoute extends RouteBuilder {

    @ConfigProperty(name = "timer.period", defaultValue = "1000") 2
    String period;

    @Inject
    Counter counter;

    @Override
    public void configure() throws Exception {
        fromF("timer:foo?period=%s", period)
                .setBody(exchange -> "Incremented the counter: " + counter.increment())
                .to("log:cdi-example?showExchangePattern=false&showBodyType=false");
    }
}
1
The @ApplicationScoped annotation is required for @Inject and @ConfigProperty to work in a RouteBuilder. Note that the @ApplicationScoped beans are managed by the CDI container and their life cycle is thus a bit more complex than the one of the plain RouteBuilder. In other words, using @ApplicationScoped in RouteBuilder comes with some boot time penalty and you should therefore only annotate your RouteBuilder with @ApplicationScoped when you really need it.
2
The value for the timer.period property is defined in src/main/resources/application.properties of the example project.
Tip

Refer to the Quarkus Dependency Injection guide for more details.

5.1. Accessing CamelContext

To access CamelContext just inject it into your bean:

import jakarta.inject.Inject;
import jakarta.enterprise.context.ApplicationScoped;
import java.util.stream.Collectors;
import java.util.List;
import org.apache.camel.CamelContext;

@ApplicationScoped
public class MyBean {

    @Inject
    CamelContext context;

    public List<String> listRouteIds() {
        return context.getRoutes().stream().map(Route::getId).sorted().collect(Collectors.toList());
    }
}

5.2. @EndpointInject and @Produce

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:

import jakarta.enterprise.context.ApplicationScoped;
import org.apache.camel.EndpointInject;
import org.apache.camel.FluentProducerTemplate;
import org.apache.camel.Produce;
import org.apache.camel.ProducerTemplate;

@ApplicationScoped
class MyBean {

    @EndpointInject("direct:myDirect1")
    ProducerTemplate producerTemplate;

    @EndpointInject("direct:myDirect2")
    FluentProducerTemplate fluentProducerTemplate;

    @EndpointInject("direct:myDirect3")
    DirectEndpoint directEndpoint;

    @Produce("direct:myDirect4")
    ProducerTemplate produceProducer;

    @Produce("direct:myDirect5")
    FluentProducerTemplate produceProducerFluent;

}

You can use any other Camel producer endpoint URI instead of direct:myDirect*.

Warning

@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:

import jakarta.enterprise.context.ApplicationScoped;
import org.apache.camel.Produce;

@ApplicationScoped
class MyProduceBean {

    public interface ProduceInterface {
        String sayHello(String name);
    }

    @Produce("direct:myDirect6")
    ProduceInterface produceInterface;

    void doSomething() {
        produceInterface.sayHello("Kermit")
    }

}

5.3. CDI and the Camel Bean component

5.3.1. Refer to a bean by name

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.

import jakarta.enterprise.context.ApplicationScoped;
import jakarta.inject.Named;
import io.quarkus.runtime.annotations.RegisterForReflection;

@ApplicationScoped
@Named("myNamedBean")
@RegisterForReflection
public class NamedBean {
    public String hello(String name) {
        return "Hello " + name + " from the NamedBean";
    }
}

Then you can use the myNamedBean name in a route definition:

import org.apache.camel.builder.RouteBuilder;
public class CamelRoute extends RouteBuilder {
    @Override
    public void configure() {
        from("direct:named")
                .bean("myNamedBean", "hello");
        /* ... which is an equivalent of the following: */
        from("direct:named")
                .to("bean:myNamedBean?method=hello");
    }
}

As an alternative to @Named, you may also use io.smallrye.common.annotation.Identifier to name and identify a bean.

import jakarta.enterprise.context.ApplicationScoped;
import io.quarkus.runtime.annotations.RegisterForReflection;
import io.smallrye.common.annotation.Identifier;

@ApplicationScoped
@Identifier("myBeanIdentifier")
@RegisterForReflection
public class MyBean {
    public String hello(String name) {
        return "Hello " + name + " from MyBean";
    }
}

Then refer to the identifier value within the Camel route:

import org.apache.camel.builder.RouteBuilder;
public class CamelRoute extends RouteBuilder {
    @Override
    public void configure() {
        from("direct:start")
                .bean("myBeanIdentifier", "Camel");
    }
}
Note

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

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

import org.apache.camel.Consume;
public class Foo {

  @Consume("activemq:cheese")
  public void onCheese(String name) {
    ...
  }
}

will automatically create the following Camel route

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

6.1. Health & liveness checks

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.2. Metrics

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:

Chapter 7. Native mode

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

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

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

See also quarkus.native.add-all-charsets in Quarkus documentation.

7.2. Locale

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

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

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

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

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);

The class mypackage.MyException should be registered for reflection. For more information, see Registering classes for reflection.

7.5. Registering classes for reflection

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:

  1. The @io.quarkus.runtime.annotations.RegisterForReflection annotation can be used to register classes on which it is used, or it can also register third party classes via its targets attribute.

    import io.quarkus.runtime.annotations.RegisterForReflection;
    
    @RegisterForReflection
    class MyClassAccessedReflectively {
    }
    
    @RegisterForReflection(
        targets = {
            org.third-party.Class1.class,
            org.third-party.Class2.class
        }
    )
    class ReflectionRegistrations {
    }
  2. The quarkus.camel.native.reflection options in application.properties:

    quarkus.camel.native.reflection.include-patterns = org.apache.commons.lang3.tuple.*
    quarkus.camel.native.reflection.exclude-patterns = org.apache.commons.lang3.tuple.*Triple

    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

7.6. Registering classes for serialization

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

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

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. For more information, see the Quarkus Kubernetes guide.

8.2. Knative

The Camel Quarkus extensions whose consumers support Knative deployment are:

8.3. Service binding

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:

Legal Notice

Copyright © 2025 Red Hat, Inc.
The text of and illustrations in this document are licensed by Red Hat under a Creative Commons Attribution–Share Alike 3.0 Unported license ("CC-BY-SA"). An explanation of CC-BY-SA is available at http://creativecommons.org/licenses/by-sa/3.0/. In accordance with CC-BY-SA, if you distribute this document or an adaptation of it, you must provide the URL for the original version.
Red Hat, as the licensor of this document, waives the right to enforce, and agrees not to assert, Section 4d of CC-BY-SA to the fullest extent permitted by applicable law.
Red Hat, Red Hat Enterprise Linux, the Shadowman logo, the Red Hat logo, JBoss, OpenShift, Fedora, the Infinity logo, and RHCE are trademarks of Red Hat, Inc., registered in the United States and other countries.
Linux® is the registered trademark of Linus Torvalds in the United States and other countries.
Java® is a registered trademark of Oracle and/or its affiliates.
XFS® is a trademark of Silicon Graphics International Corp. or its subsidiaries in the United States and/or other countries.
MySQL® is a registered trademark of MySQL AB in the United States, the European Union and other countries.
Node.js® is an official trademark of Joyent. Red Hat is not formally related to or endorsed by the official Joyent Node.js open source or commercial project.
The OpenStack® Word Mark and OpenStack logo are either registered trademarks/service marks or trademarks/service marks of the OpenStack Foundation, in the United States and other countries and are used with the OpenStack Foundation's permission. We are not affiliated with, endorsed or sponsored by the OpenStack Foundation, or the OpenStack community.
All other trademarks are the property of their respective owners.
Red Hat logoGithubRedditYoutubeTwitter

Learn

Try, buy, & sell

Communities

About Red Hat Documentation

We help Red Hat users innovate and achieve their goals with our products and services with content they can trust.

Making open source more inclusive

Red Hat is committed to replacing problematic language in our code, documentation, and web properties. For more details, see the Red Hat Blog.

About Red Hat

We deliver hardened solutions that make it easier for enterprises to work across platforms and environments, from the core datacenter to the network edge.

© 2024 Red Hat, Inc.