Content-Type validation in camel REST DSL

735 views Asked by At

I have a Camel Spring Boot application that exposes a REST endpoint for which i only want to support media type of "application/json". My REST DSL configuration is as follows -

        restConfiguration()
                .component("netty-http")
                .port(8081)
                .bindingMode(RestBindingMode.json)
                .clientRequestValidation(true)
                .skipBindingOnErrorCode(true);

        rest("/api")
                .post("/earn")
                .consumes("application/json")
                .produces("application/json")
                .bindingMode(RestBindingMode.json)
                .to("direct:earn");

With this setup, i expect to receive a "415 Unsupported Media Type" response for a Content-Type other than "application/json". (https://camel.apache.org/manual/latest/rest-dsl.html#_client_request_validation)

"text/plain" is behaving as expected -

curl http://localhost:8081/api/earn -ik -XPOST --data '{"name":"abcd","points":20}' -H "Content-Type: text/plain"
HTTP/1.1 415 Unsupported Media Type
content-length: 0
Accept: */*
User-Agent: curl/7.55.1
content-type: text/plain
connection: keep-alive

But, on omitting the Content-Type header, the validation doesn't seem to kick in. The request is processed by the route and later fails during json parsing because body is missing.

curl http://localhost:8081/api/earn -ik -XPOST
HTTP/1.1 500 Internal Server Error
content-length: 15
Accept: */*
Long-Running-Action: A7A649D7ADDBD87-0000000000000037
User-Agent: curl/7.55.1
content-type: application/json
connection: keep-alive

With a Content-Type of "application/x-www-form-urlencoded" and a JSON payload, i get no reply at all -

curl http://localhost:8081/api/earn -ik -XPOST --data '{"name":"abcd","points":20}' -H "Content-Type: application/x-www-form-urlencoded"
curl: (52) Empty reply from server

and an exception on the server -

2021-09-14 14:35:49.807 DEBUG 12236 --- [erExecutorGroup] o.a.camel.component.netty.NettyConsumer  : Channel: [id: 0xc93560d1, L:/0:0:0:0:0:0:0:1:8081 - R:/0:0:0:0:0:0:0:1:54534] received body: HttpObjectAggregator$AggregatedFullHttpRequest(decodeResult: success, version: HTTP/1.1, content: CompositeByteBuf(ridx: 0, widx: 27, cap: 27, components=1))
POST /api/earn HTTP/1.1
Host: localhost:8081
User-Agent: curl/7.55.1
Accept: */*
Content-Type: application/x-www-form-urlencoded
content-length: 27
2021-09-14 14:35:49.810 DEBUG 12236 --- [erExecutorGroup] o.a.c.c.netty.http.NettyHttpConsumer     : Closing channel as an exception was thrown from Netty

java.lang.IllegalArgumentException: Invalid parameter, expected to be a pair but was {"name":"abcd","points":20}
    at org.apache.camel.component.netty.http.DefaultNettyHttpBinding.populateCamelHeaders(DefaultNettyHttpBinding.java:279) ~[camel-netty-http-3.11.1.jar:3.11.1]
    at org.apache.camel.component.netty.http.RestNettyHttpBinding.populateCamelHeaders(RestNettyHttpBinding.java:52) ~[camel-netty-http-3.11.1.jar:3.11.1]
    at org.apache.camel.component.netty.http.DefaultNettyHttpBinding.toCamelMessage(DefaultNettyHttpBinding.java:100) ~[camel-netty-http-3.11.1.jar:3.11.1]
    at org.apache.camel.component.netty.http.handlers.HttpServerChannelHandler.createExchange(HttpServerChannelHandler.java:351) ~[camel-netty-http-3.11.1.jar:3.11.1]
    at org.apache.camel.component.netty.handlers.ServerChannelHandler.channelRead0(ServerChannelHandler.java:90) ~[camel-netty-3.11.1.jar:3.11.1]
    at org.apache.camel.component.netty.http.handlers.HttpServerChannelHandler.channelRead0(HttpServerChannelHandler.java:224) ~[camel-netty-http-3.11.1.jar:3.11.1]
    at io.netty.channel.SimpleChannelInboundHandler.channelRead(SimpleChannelInboundHandler.java:99) ~[netty-transport-4.1.63.Final.jar:4.1.63.Final]
    at org.apache.camel.component.netty.http.handlers.HttpServerMultiplexChannelHandler.channelRead0(HttpServerMultiplexChannelHandler.java:162) ~[camel-netty-http-3.11.1.jar:3.11.1]
    at io.netty.channel.SimpleChannelInboundHandler.channelRead(SimpleChannelInboundHandler.java:99) ~[netty-transport-4.1.63.Final.jar:4.1.63.Final]
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379) ~[netty-transport-4.1.63.Final.jar:4.1.63.Final]
    at io.netty.channel.AbstractChannelHandlerContext.access$600(AbstractChannelHandlerContext.java:61) ~[netty-transport-4.1.63.Final.jar:4.1.63.Final]
    at io.netty.channel.AbstractChannelHandlerContext$7.run(AbstractChannelHandlerContext.java:370) ~[netty-transport-4.1.63.Final.jar:4.1.63.Final]
    at io.netty.util.concurrent.DefaultEventExecutor.run(DefaultEventExecutor.java:66) ~[netty-common-4.1.63.Final.jar:4.1.63.Final]
    at io.netty.util.concurrent.SingleThreadEventExecutor$4.run(SingleThreadEventExecutor.java:989) ~[netty-common-4.1.63.Final.jar:4.1.63.Final]
    at io.netty.util.internal.ThreadExecutorMap$2.run(ThreadExecutorMap.java:74) ~[netty-common-4.1.63.Final.jar:4.1.63.Final]
    at java.base/java.lang.Thread.run(Thread.java:834) ~[na:na]

Spring boot version - 2.5.4, Camel - 3.11.1

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.5.4</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    
    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.apache.camel.springboot</groupId>
                <artifactId>camel-spring-boot-dependencies</artifactId>
                <version>3.11.1</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

Netty http

       <dependency>
            <groupId>org.apache.camel.springboot</groupId>
            <artifactId>camel-netty-http-starter</artifactId>
        </dependency>

How do i configure the route to consistently throw a 415 for all unsupported media types?

0

There are 0 answers