Endpoint DSL
Endpoint-DSL is a builder API that allows using type-safe endpoint URL configurations.
The Endpoint DSL is exclusively available as part of the Java DSL.
The DSL can be accessed in several ways, but the main one is to switch to using an EndpointRouteBuilder
instead of the usual RouteBuilder
. This builder provides access to all of Camel endpoint builders which are defined through inheritance on the org.apache.camel.builder.endpoint.EndpointRouteBuilder
.
Using Endpoint DSL
The following is an example of an FTP route using the standard RouteBuilder
Java DSL:
public class MyRoutes extends RouteBuilder {
@Override
public void configure() {
from("ftp://foo@myserver?password=secret&recursive=true&" +
"ftpClient.dataTimeout=30000&" +
"ftpClientConfig.serverLanguageCode=fr")
.to("bean:doSomething");
}
}
The same Java statement can be rewritten in the following more type-safe and readable way using the new EndpointRouteBuilder
that allows using the Endpoint-DSL:
public class MyRoutes extends EndpointRouteBuilder {
@Override
public void configure() throws Exception {
from(ftp("myserver").account("foo").password("secret").recursive(true)
.advanced()
.ftpClientParameters(Collections.singletonMap("dataTimeout", 30000))
.ftpClientConfig(Collections.singletonMap("serverLanguageCode", "fr")))
.to(bean("something"));
}
}
Type Safety
Similar to the Component DSL, uses the meta-model, which is extracted from the source and written in various JSON files, to generate a fluent DSL for each component. This fluent DSL provides type safety for parameters.
Using custom component names
The Endpoint-DSL uses the default name of the Component, so in the example above the name is ftp
. There can be use-cases where you may have multiple Camel components of the same type registered with different names. An example is if you have two JMS broker systems (for example ActiveMQ and WebSphereMQ).
Then you can set up two Camel JMS components with unique names such as: myAMQ
and myWMQ
The Endpoint-DSL can use these names with the jms
fluent builder as shown:
from(jms("myWMQ", "cheese").concurrentConsumers(5))
.to(jms("myAMQ", "smelly"));
Notice how we can refer to their names as the first parameter in the jms
fluent builder. The example would then consume messages from WebSphereMQ queue named cheese and route to ActiveMQ on a queue named smelly.
Headers' name
The endpoint-dsl can also be used to be assisted when selecting the name of a header to set or to get. The headers' name builder is accessible directly from the method of the class EndpointRouteBuilder
without argument whose name is the scheme of the target component.
In the example below the method file()
available from EndpointRouteBuilder
, gives access to the methods corresponding to the name of the headers of the file component. Here the method fileName()
is called to get the name of the header for the name of the file.
public class MyRoutes extends EndpointRouteBuilder {
@Override
public void configure() {
from(/*some endpoint*/)
// Some route start
.setHeader(file().fileName(), constant("foo.txt"))
// Some route end
;
}
}
Using Endpoint-DSL outside route builders
You can use the type-safe endpoint-dsl outside route builders with:
-
With the
FluentProducerTemplate
to send messages -
Creating an
Endpoint
For example to send a message to Kafka you can use the FluentProducerTemplate
import static org.apache.camel.builder.endpoint.StaticEndpointBuilders.kafka;
context.createFluentProducerTemplate()
.to(kafka("start").clientId("myClient").brokers("{{myBrokers}}").partitionKey("myKey"))
.withBody("Hello World")
.send();
To use the endpoint-dsl with kafka you need to static import kafka
from the class: org.apache.camel.builder.endpoint.StaticEndpointBuilders
which has all the Camel components.
An endpoint can also be created in Java code via the endpoint-dsl as shown:
import static org.apache.camel.builder.endpoint.StaticEndpointBuilders.paho;
Endpoint mqtt = paho("sensor").clientId("myClient").userName("scott").password("tiger")
.resolve(context);
You can then set all the options via the type-safe DSL and then the endpoint can be resolved (created) by calling resolve
with CamelContext
as parameter.
If you want to inject an endpoint into your POJO or RouteBuilder
class using endpoint-dsl, then this can be done similar to the previous example, but with one important difference:
import org.apache.camel.BindToRegistry;
import org.apache.camel.EndpointInject;
import org.apache.camel.Produce;
import org.apache.camel.builder.EndpointProducerBuilder;
import static org.apache.camel.builder.endpoint.StaticEndpointBuilders.paho;
@BindToRegistry
public class MyPojo {
@Produce
private FluentProducerTemplate producer;
private final EndpointProducerBuilder mqtt = paho("sensor").clientId("myClient").userName("scott").password("tiger");
public void sendToSensor(String data) {
producer.withBody(data).to(mqtt).send();
}
}
The MyPojo
is a class that with standalone Camel can be discovered and registered with the @BindToRegistry
annotation. If you use Spring Boot, or Quarkus etc then you should use their kind of annotations for this.
That’s not the point of this example, it is the Endpoint DSL to configure the MQTT endpoint (camel-paho). The endpoint is configured the same way as before by the type-safe endpoint-dsl by static importing the paho
, and then use its fluent builder methods to configure. Notice how the returned type is EndpointProducerBuilder
. That type is not an Endpoint
instance as it’s not resolved (i.e. it’s only a builder for an endpoint). This means that the builder can be code and compiled before CamelContext
is created and started.
At runtime, we want to use this endpoint to send messages to MQTT server; this is done in the sendToSensor
method where we are using FluentProducerTemplate
that is capable of using the EndpointProducerBuilder
as the endpoint in shown with: .to(mqtt)
.