Search code examples
javaspringapache-camelcamel-rest

Changing Camel REST HTTP Binding Configuration


I'm using Camel REST with Camel servlet handling the REST transport and want to change the way headers from the exchange are processed in HTTP requests and responses. I'm using Spring XML to configure my application. Here's the relevant configuration I'm using:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:camel="http://camel.apache.org/schema/spring"
       xsi:schemaLocation="
            http://www.springframework.org/schema/beans
            http://www.springframework.org/schema/beans/spring-beans.xsd
            http://www.springframework.org/schema/context
            http://www.springframework.org/schema/context/spring-context.xsd
            http://camel.apache.org/schema/spring
            http://camel.apache.org/schema/spring/camel-spring.xsd">
    <!-- Custom Camel Configuration //////////////////////////////////////////////////////////////////////////////// -->
    <bean id="myHttpBinding" class="com.example.MyHttpBinding"/>
    <bean id="servlet"       class="org.apache.camel.component.servlet.ServletComponent">
        <property name="httpBinding" ref="myHttpBinding"/>
    </bean>

    <!-- Routes //////////////////////////////////////////////////////////////////////////////////////////////////// -->
    <camel:camelContext id="myCamelContext">
        <camel:contextScan/>

        <camel:restConfiguration component="servlet" enableCORS="true" bindingMode="json" skipBindingOnErrorCode="false">
            <camel:corsHeaders key="Access-Control-Allow-Methods" value="PATCH, PUT, POST, DELETE, GET, OPTIONS, HEAD"/>
            <camel:corsHeaders key="Access-Control-Allow-Origin"  value="*"/>
            <camel:corsHeaders key="Access-Control-Allow-Headers" value="*"/>
        </camel:restConfiguration>
    </camel:camelContext>
</beans>

When the routes are created, I see that the endpoints are configured with MyHttpBinding set. However, incoming requests are still using ServletRestHttpBinding. This is because when Camel creates the consumer, it executes this block of code:

if (!map.containsKey("httpBinding")) {
    // use the rest binding, if not using a custom http binding
    HttpBinding binding = new ServletRestHttpBinding();
    binding.setHeaderFilterStrategy(endpoint.getHeaderFilterStrategy());
    binding.setTransferException(endpoint.isTransferException());
    binding.setEagerCheckContentAvailable(endpoint.isEagerCheckContentAvailable());
    endpoint.setHttpBinding(binding);
}

How can I set the HTTP binding in a way that Camel will respect it?


Solution

  • Because Camel ultimately looks for the httpBinding property on the endpoint to determine the binding strategy to use, the REST component has to be configured to add that property to the endpoint like so:

    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
           xmlns:context="http://www.springframework.org/schema/context"
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           xmlns:camel="http://camel.apache.org/schema/spring"
           xsi:schemaLocation="
                http://www.springframework.org/schema/beans
                http://www.springframework.org/schema/beans/spring-beans.xsd
                http://www.springframework.org/schema/context
                http://www.springframework.org/schema/context/spring-context.xsd
                http://camel.apache.org/schema/spring
                http://camel.apache.org/schema/spring/camel-spring.xsd">
        <!-- Custom Camel Configuration //////////////////////////////////////////////////////////////////////////////// -->
        <bean id="myHttpBinding" class="com.example.MyHttpBinding"/>
    
        <!-- Routes //////////////////////////////////////////////////////////////////////////////////////////////////// -->
        <camel:camelContext id="myCamelContext">
            <camel:contextScan/>
    
            <camel:restConfiguration component="servlet" enableCORS="true" bindingMode="json" skipBindingOnErrorCode="false">
                <camel:endpointProperty key="httpBinding"                  value="myHttpBinding"/>
                <camel:corsHeaders      key="Access-Control-Allow-Methods" value="PATCH, PUT, POST, DELETE, GET, OPTIONS, HEAD"/>
                <camel:corsHeaders      key="Access-Control-Allow-Origin"  value="*"/>
                <camel:corsHeaders      key="Access-Control-Allow-Headers" value="*"/>
            </camel:restConfiguration>
        </camel:camelContext>
    </beans>
    

    Note that I removed the custom servlet component because it wasn't necessary.