Using Camel-Undertow component supporting http2 connection

Using Camel-Undertow component supporting http2 connection

This article would help to configure http2 protocol support for the camel-undertow component.

  • Camel’s undertow component use embedded undertow web-container of version undertow-core:jar:1.4.21. This version also supports the http2 connection.
  • I have used camel version 2.21.0-SNAPSHOT from upstream https://github.com/apache/camel.
  • Also, the curl version to test application using camel-undertow component is 7.53.1. This curl version supports –http2 flag for sending an http2 request.
  • I have also used nghttp to test application from linux terminal. However, this article is not about http2 insights.
  • For http2 details, I found articles [1] and [2] helpful.

1. The project structure is depicted below.

[csp@dhcppc1 undertow-camel-testing]$ tree
.
├── pom.xml
├── README.md
└── src
    └── main
        └── resources
            └── META-INF
                └── spring
                    └── camel-context.xml

2. In pom.xml, we would have to setup the following dependencies.


<dependency>
<groupId>org.apache.camel</groupId>
<artifactId>camel-core</artifactId>
<version>${camel.version}</version>
</dependency>
<dependency>
<groupId>org.apache.camel</groupId>
<artifactId>camel-spring</artifactId>
<version>${camel.version}</version>
</dependency>
<dependency>
<groupId>org.apache.camel</groupId>
<artifactId>camel-undertow</artifactId>
<version>${camel.version}</version>
</dependency>
<dependency>
<groupId>org.apache.camel</groupId>
<artifactId>camel-http-common</artifactId>
<version>${camel.version}</version>
</dependency>

3. With camel version:


<properties>
<camel.version>2.21.0-SNAPSHOT</camel.version>
</properties>

4. Now, one can use spring-based dsl and configure camel-undertow component below way. Let say we named this file as camel-context.xml.


<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 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">
<camelContext id="cbr-example-context" xmlns="http://camel.apache.org/schema/spring">
<route id="cbr-route" trace="true">
<from id="_from1" uri="undertow:http://localhost:7766/foo/bar"/>
<setBody id="_setBody1">
<constant&gt;Sending Response&lt;/constant>
</setBody>
<log id="_log5" message="Headers ${in.headers}"/>
<log id="_log5" message="Done processing ${body}"/>
</route>
</camelContext>
<bean class="org.apache.camel.component.undertow.UndertowComponent" id="undertow">
<property name="hostOptions" ref="undertowHostOptions"/>
</bean>
<bean
class="org.apache.camel.component.undertow.UndertowHostOptions" id="undertowHostOptions">
<property name="http2Enabled" value="true"/>
</bean>
</beans>

5. Point to note above http2Enabled is set to true for UndertowHostOptions class, by default it is set to false. This UndertowHostOptions is then referred to UndertowComponent, which is then used in camel route.
6. We can use camel-maven-plugin in pom.xml then we can run this using maven command mvn camel:run.


<plugin>
<groupId&>org.apache.camel</groupId>
<artifactId>camel-maven-plugin</artifactId>
<version>${camel.version}</version>
<configuration>
<fileApplicationContextUri>src/main/resources/META-INF/spring/camel-context.xml</fileApplicationContextUri>
</configuration>
</plugin>

7. Once successfully run, this should expose an http service at http://localhost:7766/foo/bar.
8. We can test this using curl and nghttp commands from linux terminal. I used Fedora 26 where curl command with http2 support was available. For RHEL7, I used nghttp utility to test the http2 connection.
9. Using curl command.

[csp@dhcppc1 undertow-camel-testing]$ curl -v --http2 http://localhost:7766/foo/bar
* Trying ::1...
* TCP_NODELAY set
* connect to ::1 port 7766 failed: Connection refused
* Trying 127.0.0.1...
* TCP_NODELAY set
* Connected to localhost (127.0.0.1) port 7766 (#0)
> GET /foo/bar HTTP/1.1
> Host: localhost:7766
> User-Agent: curl/7.53.1
> Accept: */*
> Connection: Upgrade, HTTP2-Settings
> Upgrade: h2c
> HTTP2-Settings: AAMAAABkAARAAAAAAAIAAAAA
> 
< HTTP/1.1 101 Switching Protocols
< Connection: Upgrade
< Upgrade: h2c
< Date: Sun, 10 Dec 2017 08:43:58 GMT
* Received 101
* Using HTTP2, server supports multi-use
* Connection state changed (HTTP/2 confirmed)
* Copying HTTP/2 data in stream buffer to connection buffer after upgrade: len=0
* Connection state changed (MAX_CONCURRENT_STREAMS updated)!
< HTTP/2 200 
< accept: */*
< http2-settings: AAMAAABkAARAAAAAAAIAAAAA
< breadcrumbid: ID-dhcppc1-1512886066149-0-25
< content-length: 16
< user-agent: curl/7.53.1
< date: Sun, 10 Dec 2017 08:43:58 GMT
< 
* Connection #0 to host localhost left intact
Sending Response

10. Using nghttp command.

cpandey@cpandey camel-undertow]$ nghttp -v http://localhost:7766/foo/bar
[ERROR] Could not connect to the address ::1
Trying next address 127.0.0.1
[  0.000] Connected
[  0.000] send SETTINGS frame <length=12, flags=0x00, stream_id=0>
          (niv=2)
          [SETTINGS_MAX_CONCURRENT_STREAMS(0x03):100]
          [SETTINGS_INITIAL_WINDOW_SIZE(0x04):65535]
[  0.000] send PRIORITY frame <length=5, flags=0x00, stream_id=3>
          (dep_stream_id=0, weight=201, exclusive=0)
[  0.000] send PRIORITY frame <length=5, flags=0x00, stream_id=5>
          (dep_stream_id=0, weight=101, exclusive=0)
[  0.000] send PRIORITY frame <length=5, flags=0x00, stream_id=7>
          (dep_stream_id=0, weight=1, exclusive=0)
[  0.000] send PRIORITY frame <length=5, flags=0x00, stream_id=9>
          (dep_stream_id=7, weight=1, exclusive=0)
[  0.000] send PRIORITY frame <length=5, flags=0x00, stream_id=11>
          (dep_stream_id=3, weight=1, exclusive=0)
[  0.000] send HEADERS frame <length=45, flags=0x25, stream_id=13>
          ; END_STREAM | END_HEADERS | PRIORITY
          (padlen=0, dep_stream_id=11, weight=16, exclusive=0)
          ; Open new stream
          :method: GET
          :path: /foo/bar
          :scheme: http
          :authority: localhost:7766
          accept: */*
          accept-encoding: gzip, deflate
          user-agent: nghttp2/1.21.1
[  0.001] recv SETTINGS frame <length=18, flags=0x00, stream_id=0>
          [SETTINGS_HEADER_TABLE_SIZE(0x01):4096]
          [SETTINGS_MAX_FRAME_SIZE(0x05):16384]
          [SETTINGS_INITIAL_WINDOW_SIZE(0x04):65535]
[  0.001] send SETTINGS frame <length=0, flags=0x01, stream_id=0>
          ; ACK
          (niv=0)
[  0.001] recv SETTINGS frame <length=0, flags=0x01, stream_id=0>
          ; ACK
          (niv=0)
[  0.003] recv (stream_id=13) :status: 200
[  0.003] recv (stream_id=13) accept: */*
[  0.003] recv (stream_id=13) accept-encoding: gzip, deflate
[  0.003] recv (stream_id=13) breadcrumbid: ID-cpandey-pnq-csb-1512577017865-0-3
[  0.003] recv (stream_id=13, sensitive) content-length: 16
[  0.003] recv (stream_id=13) user-agent: nghttp2/1.21.1
[  0.003] recv (stream_id=13, sensitive) date: Wed, 06 Dec 2017 17:11:51 GMT
[  0.003] recv HEADERS frame <length=88, flags=0x04, stream_id=13>
          ; END_HEADERS
          (padlen=0)
          ; First response header
Sending Response[  0.003] recv DATA frame <length=16, flags=0x01, stream_id=13>
          ; END_STREAM
[  0.003] send GOAWAY frame <length=8, flags=0x00, stream_id=0>
          (last_stream_id=0, error_code=NO_ERROR(0x00), opaque_data(0)=[])

Everything you need to grow your career.

With your free Red Hat Developer program membership, unlock our library of cheat sheets and ebooks on next-generation application development.

SIGN UP

1. http://undertow.io/blog/2015/04/27/An-in-depth-overview-of-HTTP2.html
2. https://developers.google.com/web/fundamentals/performance/http2/


Whether you are new to Containers or have experience, downloading this cheat sheet can assist you when encountering tasks you haven’t done lately.

Join the Red Hat Developer Program (it’s free) and get access to related cheat sheets, books, and product downloads.

To learn more, visit our Linux containers or microservices Topic pages.

To learn more, visit our Join the Red Hat Developer Program (it’s free) and get access to related cheat sheets (e.g. containers), books (e.g. microservices), and product downloads that can help you with your microservices and/or container application development.

Who’s your Brent?

To learn more, visit our DevOps Topic page.

Join the Red Hat Developer Program (it’s free) and get access to related cheat sheets, books, and product downloads that can help you with your DevOps efforts.

Download and learn more about Red Hat JBoss Fuse, an innovative modular, cloud-ready architecture, powerful management and automation, and world class developer productivity. It is Java™ EE 7 certified and features powerful, enterprise-grade features such as high availability clustering, distributed caching, messaging, transactions, and a full web services stack.

For more information about Red Hat OpenShift and other related topics, visit: OpenShift, OpenShift Online.

Share