You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@camel.apache.org by ff...@apache.org on 2019/08/19 18:50:43 UTC

[camel] branch master updated: [CAMEL-13876]enable camel-undertow component to set custom HttpHandler

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

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


The following commit(s) were added to refs/heads/master by this push:
     new e90f0a6  [CAMEL-13876]enable camel-undertow component to set custom HttpHandler
e90f0a6 is described below

commit e90f0a69233cf1caa332b69870cc9d70fd4e0178
Author: Freeman Fang <fr...@gmail.com>
AuthorDate: Mon Aug 19 14:50:24 2019 -0400

    [CAMEL-13876]enable camel-undertow component to set custom HttpHandler
---
 .../src/main/docs/undertow-component.adoc          |   3 +-
 .../undertow/CamelUndertowHttpHandler.java         |  23 ++++
 .../camel/component/undertow/UndertowConsumer.java |  14 +++
 .../camel/component/undertow/UndertowEndpoint.java |  22 ++++
 .../component/undertow/MapIdentityManager.java     | 122 +++++++++++++++++++++
 .../undertow/UndertowBasicAuthHandler.java         |  76 +++++++++++++
 .../undertow/UndertowHandlersSpringTest.java       | 104 ++++++++++++++++++
 .../src/test/resources/HandlersSpringTest.xml      |  67 +++++++++++
 .../dsl/UndertowEndpointBuilderFactory.java        |  38 +++++++
 9 files changed, 468 insertions(+), 1 deletion(-)

diff --git a/components/camel-undertow/src/main/docs/undertow-component.adoc b/components/camel-undertow/src/main/docs/undertow-component.adoc
index 1a9da73..7a3eee9 100644
--- a/components/camel-undertow/src/main/docs/undertow-component.adoc
+++ b/components/camel-undertow/src/main/docs/undertow-component.adoc
@@ -78,7 +78,7 @@ with the following path and query parameters:
 |===
 
 
-=== Query Parameters (25 parameters):
+=== Query Parameters (26 parameters):
 
 
 [width="100%",cols="2,5,^1,2",options="header"]
@@ -92,6 +92,7 @@ with the following path and query parameters:
 | *optionsEnabled* (consumer) | Specifies whether to enable HTTP OPTIONS for this Servlet consumer. By default OPTIONS is turned off. | false | boolean
 | *exceptionHandler* (consumer) | To let the consumer use a custom ExceptionHandler. Notice if the option bridgeErrorHandler is enabled then this option is not in use. By default the consumer will deal with exceptions, that will be logged at WARN or ERROR level and ignored. |  | ExceptionHandler
 | *exchangePattern* (consumer) | Sets the exchange pattern when the consumer creates an exchange. |  | ExchangePattern
+| *handlers* (consumer) | Specifies a comma-delimited set of io.undertow.server.HttpHandler instances in your Registry (such as your Spring ApplicationContext). These handlers are added to the Undertow handler chain (for example, to add security). Important: You can not use different handlers with different Undertow endpoints using the same port number. The handlers is associated to the port number. If you need different handlers, then use different port numbers. |  | String
 | *cookieHandler* (producer) | Configure a cookie handler to maintain a HTTP session |  | CookieHandler
 | *keepAlive* (producer) | Setting to ensure socket is not closed due to inactivity | true | Boolean
 | *lazyStartProducer* (producer) | Whether the producer should be started lazy (on the first message). By starting lazy you can use this to allow CamelContext and routes to startup in situations where a producer may otherwise fail during starting and cause the route to fail being started. By deferring this startup to be lazy then the startup failure can be handled during routing messages via Camel's routing error handlers. Beware that when the first message is processed then creating and [...]
diff --git a/components/camel-undertow/src/main/java/org/apache/camel/component/undertow/CamelUndertowHttpHandler.java b/components/camel-undertow/src/main/java/org/apache/camel/component/undertow/CamelUndertowHttpHandler.java
new file mode 100644
index 0000000..4d6f3c8
--- /dev/null
+++ b/components/camel-undertow/src/main/java/org/apache/camel/component/undertow/CamelUndertowHttpHandler.java
@@ -0,0 +1,23 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.component.undertow;
+
+import io.undertow.server.HttpHandler;
+
+public interface CamelUndertowHttpHandler extends HttpHandler {
+    void setNext(HttpHandler nextHandler);
+}
diff --git a/components/camel-undertow/src/main/java/org/apache/camel/component/undertow/UndertowConsumer.java b/components/camel-undertow/src/main/java/org/apache/camel/component/undertow/UndertowConsumer.java
index a3e7675..0cf1dae 100644
--- a/components/camel-undertow/src/main/java/org/apache/camel/component/undertow/UndertowConsumer.java
+++ b/components/camel-undertow/src/main/java/org/apache/camel/component/undertow/UndertowConsumer.java
@@ -93,6 +93,9 @@ public class UndertowConsumer extends DefaultConsumer implements HttpHandler {
                         "common",
                         AccessLogHandler.class.getClassLoader());
             }
+            if (endpoint.getHandlers() != null) {
+                httpHandler = this.wrapHandler(httpHandler, endpoint);
+            }
             endpoint.getComponent().registerEndpoint(endpoint.getHttpHandlerRegistrationInfo(), endpoint.getSslContext(), Handlers.httpContinueRead(
                     // wrap with EagerFormParsingHandler to enable undertow form parsers
                     httpHandler));
@@ -170,6 +173,8 @@ public class UndertowConsumer extends DefaultConsumer implements HttpHandler {
         sendResponse(httpExchange, camelExchange);
     }
 
+    
+    
     private void sendResponse(HttpServerExchange httpExchange, Exchange camelExchange) throws IOException, NoTypeConversionAvailableException {
         Object body = getResponseBody(httpExchange, camelExchange);
 
@@ -265,5 +270,14 @@ public class UndertowConsumer extends DefaultConsumer implements HttpHandler {
         }
         return result;
     }
+    
+    private HttpHandler wrapHandler(HttpHandler handler, UndertowEndpoint endpoint) {
+        HttpHandler nextHandler = handler;
+        for (CamelUndertowHttpHandler h : endpoint.getHandlers()) {
+            h.setNext(nextHandler);
+            nextHandler = h;
+        }
+        return nextHandler;
+    }
 
 }
diff --git a/components/camel-undertow/src/main/java/org/apache/camel/component/undertow/UndertowEndpoint.java b/components/camel-undertow/src/main/java/org/apache/camel/component/undertow/UndertowEndpoint.java
index be7ec15..1cb7e85 100644
--- a/components/camel-undertow/src/main/java/org/apache/camel/component/undertow/UndertowEndpoint.java
+++ b/components/camel-undertow/src/main/java/org/apache/camel/component/undertow/UndertowEndpoint.java
@@ -17,6 +17,7 @@
 package org.apache.camel.component.undertow;
 
 import java.net.URI;
+import java.util.List;
 import java.util.Locale;
 import java.util.Map;
 import javax.net.ssl.SSLContext;
@@ -104,6 +105,12 @@ public class UndertowEndpoint extends DefaultEndpoint implements AsyncEndpoint,
     private Integer sendTimeout = 30000;
     @UriParam(label = "consumer,websocket", defaultValue = "false")
     private boolean fireWebSocketChannelEvents;
+    @UriParam(label = "consumer,advanced", javaType = "java.lang.String",
+        description = "Specifies a comma-delimited set of Undertow HttpHandler instances to lookup in your Registry."
+        + " These handlers are added to the Undertow handler chain (for example, to add security)."
+        + " Important: You can not use different handlers with different Undertow endpoints using the same port number."
+        + " The handlers is associated to the port number. If you need different handlers, then use different port numbers.")
+    private List<CamelUndertowHttpHandler> handlers;
 
     public UndertowEndpoint(String uri, UndertowComponent component) {
         super(uri, component);
@@ -496,5 +503,20 @@ public class UndertowEndpoint extends DefaultEndpoint implements AsyncEndpoint,
     public void setAccessLogReceiver(AccessLogReceiver accessLogReceiver) {
         this.accessLogReceiver = accessLogReceiver;
     }
+    
+    public List<CamelUndertowHttpHandler> getHandlers() {
+        return handlers;
+    }
+
+    /**
+     * Specifies a comma-delimited set of io.undertow.server.HttpHandler instances in your Registry (such as your Spring ApplicationContext).
+     * These handlers are added to the Undertow handler chain (for example, to add security).
+     * Important: You can not use different handlers with different Undertow endpoints using the same port number.
+     * The handlers is associated to the port number. If you need different handlers, then use different port numbers.
+     */
+    public void setHandlers(List<CamelUndertowHttpHandler> handlers) {
+        this.handlers = handlers;
+    }
+
 
 }
diff --git a/components/camel-undertow/src/test/java/org/apache/camel/component/undertow/MapIdentityManager.java b/components/camel-undertow/src/test/java/org/apache/camel/component/undertow/MapIdentityManager.java
new file mode 100644
index 0000000..db110b7
--- /dev/null
+++ b/components/camel-undertow/src/test/java/org/apache/camel/component/undertow/MapIdentityManager.java
@@ -0,0 +1,122 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.component.undertow;
+
+import static java.nio.charset.StandardCharsets.UTF_8;
+
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+import java.security.Principal;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.Map;
+import java.util.Set;
+
+import io.undertow.security.idm.Account;
+import io.undertow.security.idm.Credential;
+import io.undertow.security.idm.DigestCredential;
+import io.undertow.security.idm.IdentityManager;
+import io.undertow.security.idm.PasswordCredential;
+import io.undertow.util.HexConverter;
+
+class MapIdentityManager implements IdentityManager {
+
+    private final Map<String, char[]> users;
+
+    MapIdentityManager(final Map<String, char[]> users) {
+        this.users = users;
+    }
+
+    @Override
+    public Account verify(Account account) {
+        // An existing account so for testing assume still valid.
+        return account;
+    }
+
+    @Override
+    public Account verify(String id, Credential credential) {
+        Account account = getAccount(id);
+        if (account != null && verifyCredential(account, credential)) {
+            return account;
+        }
+
+        return null;
+    }
+
+    @Override
+    public Account verify(Credential credential) {
+        return null;
+    }
+
+    private boolean verifyCredential(Account account, Credential credential) {
+        if (credential instanceof PasswordCredential) {
+            char[] password = ((PasswordCredential) credential).getPassword();
+            char[] expectedPassword = users.get(account.getPrincipal().getName());
+
+            return Arrays.equals(password, expectedPassword);
+        } else if (credential instanceof DigestCredential) {
+            DigestCredential digCred = (DigestCredential) credential;
+            MessageDigest digest = null;
+            try {
+                digest = digCred.getAlgorithm().getMessageDigest();
+
+                digest.update(account.getPrincipal().getName().getBytes(UTF_8));
+                digest.update((byte) ':');
+                digest.update(digCred.getRealm().getBytes(UTF_8));
+                digest.update((byte) ':');
+                char[] expectedPassword = users.get(account.getPrincipal().getName());
+                digest.update(new String(expectedPassword).getBytes(UTF_8));
+
+                return digCred.verifyHA1(HexConverter.convertToHexBytes(digest.digest()));
+            } catch (NoSuchAlgorithmException e) {
+                throw new IllegalStateException("Unsupported Algorithm", e);
+            } finally {
+                digest.reset();
+            }
+        }
+        return false;
+    }
+
+    private Account getAccount(final String id) {
+        if (users.containsKey(id)) {
+            return new Account() {
+
+                private static final long serialVersionUID = 1L;
+                private final Principal principal = new Principal() {
+
+                    @Override
+                    public String getName() {
+                        return id;
+                    }
+                };
+
+                @Override
+                public Principal getPrincipal() {
+                    return principal;
+                }
+
+                @Override
+                public Set<String> getRoles() {
+                    return Collections.emptySet();
+                }
+
+            };
+        }
+        return null;
+    }
+
+}
diff --git a/components/camel-undertow/src/test/java/org/apache/camel/component/undertow/UndertowBasicAuthHandler.java b/components/camel-undertow/src/test/java/org/apache/camel/component/undertow/UndertowBasicAuthHandler.java
new file mode 100644
index 0000000..1e1f5a7
--- /dev/null
+++ b/components/camel-undertow/src/test/java/org/apache/camel/component/undertow/UndertowBasicAuthHandler.java
@@ -0,0 +1,76 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.component.undertow;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+
+import io.undertow.security.api.AuthenticationMechanism;
+import io.undertow.security.api.AuthenticationMode;
+import io.undertow.security.handlers.AuthenticationCallHandler;
+import io.undertow.security.handlers.AuthenticationConstraintHandler;
+import io.undertow.security.handlers.AuthenticationMechanismsHandler;
+import io.undertow.security.handlers.SecurityInitialHandler;
+import io.undertow.security.idm.IdentityManager;
+import io.undertow.security.impl.BasicAuthenticationMechanism;
+import io.undertow.server.HttpHandler;
+import io.undertow.server.HttpServerExchange;
+
+public class UndertowBasicAuthHandler implements CamelUndertowHttpHandler {
+
+    private HttpHandler next;
+    private HttpHandler securityHandler;
+    private IdentityManager identityManager;
+
+    @Override
+    public void handleRequest(HttpServerExchange exchange) throws Exception {
+        if (identityManager == null) {
+            buildIdMgr();
+        }
+        if (securityHandler == null) {
+            buildSecurityHandler();
+        }
+        this.securityHandler.handleRequest(exchange);
+    }
+
+    private void buildSecurityHandler() {
+        HttpHandler handler = this.next;
+        handler = new AuthenticationCallHandler(handler);
+        handler = new AuthenticationConstraintHandler(handler);
+        final List<AuthenticationMechanism> mechanisms
+            = Collections.<AuthenticationMechanism>singletonList(new BasicAuthenticationMechanism("My Realm"));
+        handler = new AuthenticationMechanismsHandler(handler, mechanisms);
+        this.securityHandler = new SecurityInitialHandler(AuthenticationMode.PRO_ACTIVE, identityManager, handler);
+
+    }
+
+
+    private void buildIdMgr() {
+        final Map<String, char[]> users = new HashMap<>(1);
+        users.put("guest", "secret".toCharArray());
+
+        identityManager = new MapIdentityManager(users);
+    }
+    
+    public void setNext(HttpHandler nextHandler) {
+        this.next = nextHandler;
+    }
+
+}
diff --git a/components/camel-undertow/src/test/java/org/apache/camel/component/undertow/UndertowHandlersSpringTest.java b/components/camel-undertow/src/test/java/org/apache/camel/component/undertow/UndertowHandlersSpringTest.java
new file mode 100644
index 0000000..f3f719d
--- /dev/null
+++ b/components/camel-undertow/src/test/java/org/apache/camel/component/undertow/UndertowHandlersSpringTest.java
@@ -0,0 +1,104 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.component.undertow;
+import java.net.URL;
+
+import javax.annotation.Resource;
+
+import org.apache.camel.CamelExecutionException;
+import org.apache.camel.EndpointInject;
+import org.apache.camel.Produce;
+import org.apache.camel.ProducerTemplate;
+import org.apache.camel.component.mock.MockEndpoint;
+import org.apache.camel.http.common.HttpOperationFailedException;
+
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.test.context.ContextConfiguration;
+import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.fail;
+
+@RunWith(SpringJUnit4ClassRunner.class)
+@ContextConfiguration(locations = {"/HandlersSpringTest.xml"})
+public class UndertowHandlersSpringTest {
+
+    private Integer port;
+
+    @Produce
+    private ProducerTemplate template;
+
+    @EndpointInject("mock:input")
+    private MockEndpoint mockEndpoint;
+
+    @BeforeClass
+    public static void setUpJaas() throws Exception {
+        URL trustStoreUrl = UndertowHttpsSpringTest.class.getClassLoader().getResource("ssl/keystore.jks");
+        System.setProperty("javax.net.ssl.trustStore", trustStoreUrl.toURI().getPath());
+    }
+
+    @AfterClass
+    public static void tearDownJaas() throws Exception {
+        System.clearProperty("java.security.auth.login.config");
+    }
+
+    @Test
+    public void testBasicAuthConsumer() throws Exception {
+        mockEndpoint.expectedBodiesReceived("Hello World");
+        // username:password is guest:secret
+        String auth = "Basic Z3Vlc3Q6c2VjcmV0";
+        String out = template.requestBodyAndHeader("undertow:http://localhost:" + port + "/spring", "Hello World", 
+                                                   "Authorization", auth, String.class);
+        assertEquals("Bye World", out);
+
+        mockEndpoint.assertIsSatisfied();
+    }
+    
+    @Test
+    public void testBasicAuthConsumerWthWrongPassword() throws Exception {
+        mockEndpoint.expectedBodiesReceived("Hello World");
+        // username:password is guest:secret
+        String auth = "Basic Z3Vlc3Q6c2Vjc";
+        try {
+            String out = template.requestBodyAndHeader("undertow:http://localhost:" + port + "/spring", "Hello World", 
+                                                   "Authorization", auth, String.class);
+            fail("Should send back 401");
+            assertEquals("Bye World", out);
+
+            mockEndpoint.assertIsSatisfied();
+         
+        } catch (CamelExecutionException e) {
+            org.apache.camel.http.common.HttpOperationFailedException cause = (HttpOperationFailedException)e.getCause();
+            assertEquals(401, cause.getStatusCode());
+        }
+
+    }
+
+    public Integer getPort() {
+        return port;
+    }
+
+    @Resource(name = "dynaPort")
+    public void setPort(Integer port) {
+        this.port = port;
+    }
+
+}
+
diff --git a/components/camel-undertow/src/test/resources/HandlersSpringTest.xml b/components/camel-undertow/src/test/resources/HandlersSpringTest.xml
new file mode 100644
index 0000000..34c7ff6
--- /dev/null
+++ b/components/camel-undertow/src/test/resources/HandlersSpringTest.xml
@@ -0,0 +1,67 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+    Licensed to the Apache Software Foundation (ASF) under one or more
+    contributor license agreements.  See the NOTICE file distributed with
+    this work for additional information regarding copyright ownership.
+    The ASF licenses this file to You under the Apache License, Version 2.0
+    (the "License"); you may not use this file except in compliance with
+    the License.  You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+
+-->
+<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+       xmlns:camel="http://camel.apache.org/schema/spring"
+       xmlns:util="http://www.springframework.org/schema/util"
+       xmlns="http://www.springframework.org/schema/beans"
+       xsi:schemaLocation="
+       http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
+       http://camel.apache.org/schema/spring http://camel.apache.org/schema/spring/camel-spring.xsd
+       http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd
+    ">
+
+    <camel:sslContextParameters id="sslContextParameters">
+        <camel:keyManagers keyPassword="password">
+            <camel:keyStore resource="ssl/keystore.jks" password="password"/>
+        </camel:keyManagers>
+        <camel:trustManagers>
+            <camel:keyStore resource="ssl/keystore.jks" password="password"/>
+        </camel:trustManagers>
+    </camel:sslContextParameters>
+
+    <camel:sslContextParameters id="sslClient" />
+
+    <bean id="dynaPort" class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">
+        <property name="targetClass">
+            <value>org.apache.camel.test.AvailablePortFinder</value>
+        </property>
+        <property name="targetMethod">
+            <value>getNextAvailable</value>
+        </property>
+    </bean>
+
+    <util:list id="handlers" value-type="io.undertow.server.HttpHandler">
+        <bean class="org.apache.camel.component.undertow.UndertowBasicAuthHandler"/>
+    </util:list>
+
+    <camelContext id="camel" xmlns="http://camel.apache.org/schema/spring">
+        <endpoint id="input" uri="undertow:http://localhost:#{dynaPort}/spring?handlers=#handlers"/>
+
+        <route>
+            <from uri="ref:input"/>
+            <to uri="mock:input"/>
+            <transform>
+                <simple>Bye World</simple>
+            </transform>
+        </route>
+
+    </camelContext>
+
+</beans>
diff --git a/core/camel-endpointdsl/src/main/java/org/apache/camel/builder/endpoint/dsl/UndertowEndpointBuilderFactory.java b/core/camel-endpointdsl/src/main/java/org/apache/camel/builder/endpoint/dsl/UndertowEndpointBuilderFactory.java
index 5c70e7c..8354789 100644
--- a/core/camel-endpointdsl/src/main/java/org/apache/camel/builder/endpoint/dsl/UndertowEndpointBuilderFactory.java
+++ b/core/camel-endpointdsl/src/main/java/org/apache/camel/builder/endpoint/dsl/UndertowEndpointBuilderFactory.java
@@ -17,6 +17,7 @@
 package org.apache.camel.builder.endpoint.dsl;
 
 import java.util.Map;
+import java.util.Set;
 import javax.annotation.Generated;
 import org.apache.camel.ExchangePattern;
 import org.apache.camel.builder.EndpointConsumerBuilder;
@@ -328,6 +329,43 @@ public interface UndertowEndpointBuilderFactory {
             return this;
         }
         /**
+         * Specifies a comma-delimited set of io.undertow.server.HttpHandler
+         * instances in your Registry (such as your Spring ApplicationContext).
+         * These handlers are added to the Undertow handler chain (for example,
+         * to add security). Important: You can not use different handlers with
+         * different Undertow endpoints using the same port number. The handlers
+         * is associated to the port number. If you need different handlers,
+         * then use different port numbers.
+         * 
+         * The option is a:
+         * <code>java.util.Set&lt;org.apache.camel.component.undertow.HttpHandlerRegistrationInfo&gt;</code> type.
+         * 
+         * Group: consumer (advanced)
+         */
+        default AdvancedUndertowEndpointConsumerBuilder handlers(
+                Set<Object> handlers) {
+            setProperty("handlers", handlers);
+            return this;
+        }
+        /**
+         * Specifies a comma-delimited set of io.undertow.server.HttpHandler
+         * instances in your Registry (such as your Spring ApplicationContext).
+         * These handlers are added to the Undertow handler chain (for example,
+         * to add security). Important: You can not use different handlers with
+         * different Undertow endpoints using the same port number. The handlers
+         * is associated to the port number. If you need different handlers,
+         * then use different port numbers.
+         * 
+         * The option will be converted to a
+         * <code>java.util.Set&lt;org.apache.camel.component.undertow.HttpHandlerRegistrationInfo&gt;</code> type.
+         * 
+         * Group: consumer (advanced)
+         */
+        default AdvancedUndertowEndpointConsumerBuilder handlers(String handlers) {
+            setProperty("handlers", handlers);
+            return this;
+        }
+        /**
          * Which Undertow AccessLogReciever should be used Will use
          * JBossLoggingAccessLogReceiver if not specifid.
          *