Skip to content
Advertisement

Why my REST api created with camel servlet doesn’t expose?

I’m currently struggling with exposing the REST api in my project using Apache Camel. When I run the project it seems to be fine in the console, but it just doesn’t work:

curl http://127.0.0.1:8080/materials

curl: (7) Failed to connect to 127.0.0.1 port 8080: Connection refused

Here’s the pom.xml file:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
     xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.example</groupId>
<artifactId>Packages</artifactId>
<version>1.0-SNAPSHOT</version>

<properties>
    <maven.compiler.source>11</maven.compiler.source>
    <maven.compiler.target>11</maven.compiler.target>
</properties>

<dependencies>
    <dependency>
        <groupId>org.apache.camel</groupId>
        <artifactId>camel-core</artifactId>
        <version>3.12.0</version>
    </dependency>
    <dependency>
        <groupId>org.apache.camel</groupId>
        <artifactId>camel-jackson</artifactId>
        <version>3.12.0</version>
    </dependency>

    <dependency>
        <groupId>org.apache.camel</groupId>
        <artifactId>camel-jdbc</artifactId>
        <version>3.12.0</version>
    </dependency>
    <dependency>
        <groupId>org.apache.camel</groupId>
        <artifactId>camel-jsonpath</artifactId>
        <version>3.12.0</version>
    </dependency>
    <dependency>
        <groupId>org.apache.commons</groupId>
        <artifactId>commons-dbcp2</artifactId>
        <version>2.8.0</version>
    </dependency>
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <version>8.0.28</version>
    </dependency>
    <dependency>
        <groupId>org.apache.logging.log4j</groupId>
        <artifactId>log4j-api</artifactId>
        <version>2.17.2</version>
    </dependency>
    <dependency>
        <groupId>org.apache.logging.log4j</groupId>
        <artifactId>log4j-core</artifactId >
        <version>2.17.2</version>
    </dependency>
    <dependency>
        <groupId>org.apache.activemq</groupId>
        <artifactId>activemq-client</artifactId>
        <version>5.16.2</version>
    </dependency>
    <dependency>
        <groupId>org.apache.activemq</groupId>
        <artifactId>activemq-camel</artifactId>
        <version>5.16.4</version>
    </dependency>
    <dependency>
        <groupId>org.apache.camel</groupId>
        <artifactId>camel-jaxb</artifactId>
        <version>3.12.0</version>
    </dependency>
    <dependency>
        <groupId>org.apache.camel</groupId>
        <artifactId>camel-jaxb-starter</artifactId>
        <version>2.25.4</version>
    </dependency>
    <dependency>
        <groupId>org.apache.camel</groupId>
        <artifactId>camel-jms</artifactId>
        <version>3.15.0</version>
    </dependency>
    <dependency>
        <groupId>org.apache.activemq</groupId>
        <artifactId>activemq-broker</artifactId>
        <version>5.16.4</version>
    </dependency>
    <dependency>
        <groupId>javax.xml.bind</groupId>
        <artifactId>jaxb-api</artifactId>
        <version>2.4.0-b180830.0359</version>
    </dependency>
    <dependency>
        <groupId>com.fasterxml.jackson.jaxrs</groupId>
        <artifactId>jackson-jaxrs-xml-provider</artifactId>
        <version>2.13.2</version>
    </dependency>
    <dependency>
        <groupId>commons-validator</groupId>
        <artifactId>commons-validator</artifactId>
        <version>1.7</version>
    </dependency>
    <dependency>
        <groupId>org.apache.camel</groupId>
        <artifactId>camel-rest</artifactId>
        <version>3.12.0</version>
    </dependency>
    <dependency>
        <groupId>org.apache.camel</groupId>
        <artifactId>camel-servlet</artifactId>
        <version>3.12.0</version>
    </dependency>
    <dependency>
        <groupId>javax.servlet</groupId>
        <artifactId>javax.servlet-api</artifactId>
        <version>3.1.0</version>
    </dependency>
    <dependency>
        <groupId>org.apache.camel</groupId>
        <artifactId>camel-servlet-starter</artifactId>
        <version>3.0.0-RC3</version>
    </dependency>
    <dependency>
        <groupId>org.apache.camel</groupId>
        <artifactId>camel-jackson-starter</artifactId>
        <version>3.0.0-RC3</version>
    </dependency>
</dependencies>
</project>

Here’s the code I wrote:

package com.release11.output;

import com.release11.xjc.materials.ObjectFactory;
import org.apache.activemq.ActiveMQConnectionFactory;
import org.apache.camel.CamelContext;
import org.apache.camel.builder.RouteBuilder;
import org.apache.camel.component.jms.JmsComponent;
import org.apache.camel.converter.jaxb.JaxbDataFormat;
import org.apache.camel.impl.DefaultCamelContext;
import org.apache.camel.model.rest.RestBindingMode;
import javax.jms.Connection;
import javax.xml.bind.JAXBContext;


public class OutputAdapter1 {

public static void main(String[] args) throws Exception{

    ActiveMQConnectionFactory connectionFactory = new ActiveMQConnectionFactory("tcp://127.0.0.1:61616");

    Connection connection = connectionFactory.createConnection();
    connection.start();

    CamelContext context = new DefaultCamelContext();
    context.addComponent("activemq", JmsComponent.jmsComponentAutoAcknowledge(connectionFactory));

    context.addRoutes(new RouteBuilder() {
        @Override
        public void configure() throws Exception {
        JAXBContext jaxbContext = JAXBContext.newInstance(ObjectFactory.class);
        JaxbDataFormat xmlDataFormat = new JaxbDataFormat(jaxbContext);
            xmlDataFormat.setIgnoreJAXBElement(false);

        restConfiguration()
                    .component("servlet")
                    .host("localhost")
                    .port("8080")
                    .bindingMode(RestBindingMode.auto);

        from("activemq:topic:MATERIALS_ENRICHED")
                    .unmarshal(xmlDataFormat)
                    .filter(simple("${body.type} in 'A1,A2,A3'"))
                .to("direct:materials");

        rest("/materials")
                    .get().route()
                    .to("direct:materials");
        }
    });
    context.start();
}
}

I’m not sure to put the build output here because it’s quite long so I’ll put only a fragment where those routes start:

12:47:22.591 [main] DEBUG org.apache.camel.component.jms.JmsConsumer – Started listener container org.apache.camel.component.jms.DefaultJmsMessageListenerContainer@52045dbe on destination MATERIALS_ENRICHED 12:47:22.591 [main] DEBUG org.apache.camel.impl.engine.InternalRouteStartupManager – Route: route1 started and consuming from: activemq://topic:MATERIALS_ENRICHED 12:47:22.593 [main] DEBUG org.apache.camel.impl.engine.InternalRouteStartupManager – Route: route2 >>> Route[rest://get:/materials?consumerComponentName=servlet&routeId=route2 -> null] 12:47:22.593 [main] DEBUG org.apache.camel.impl.engine.InternalRouteStartupManager – Starting consumer (order: 1001) on route: route2 12:47:22.593 [main] DEBUG org.apache.camel.support.DefaultConsumer – Build consumer: Consumer[servlet:/materials?httpMethodRestrict=GET] 12:47:22.593 [main] DEBUG org.apache.camel.support.DefaultConsumer – Init consumer: Consumer[servlet:/materials?httpMethodRestrict=GET] 12:47:22.593 [main] DEBUG org.apache.camel.support.DefaultConsumer – Starting consumer: Consumer[servlet:/materials?httpMethodRestrict=GET] 12:47:22.595 [main] DEBUG org.apache.camel.http.common.DefaultHttpRegistry – Registering consumer for path /materials providers present: 0 12:47:22.595 [main] DEBUG org.apache.camel.impl.engine.InternalRouteStartupManager – Route: route2 started and consuming from: servlet:/materials 12:47:22.597 [main] INFO org.apache.camel.impl.engine.AbstractCamelContext – Routes startup summary (total:2 started:2) 12:47:22.597 [main] INFO org.apache.camel.impl.engine.AbstractCamelContext – Started route1 (activemq://topic:MATERIALS_ENRICHED) 12:47:22.597 [main] INFO org.apache.camel.impl.engine.AbstractCamelContext – Started route2 (rest://get:/materials) 12:47:22.597 [main] INFO org.apache.camel.impl.engine.AbstractCamelContext – Apache Camel 3.12.0 (camel-1) started in 525ms (build:81ms init:296ms start:148ms) 12:47:22.610 [main] DEBUG org.apache.camel.impl.DefaultCamelContext – start() took 457 millis

Please inform me in the comments shall I put the full build output so I’ll edit the ticket. Please help me. Thanks.

Advertisement

Answer

The component camel-servlet is not meant to be used in standalone mode as you are trying to do. It is meant to be used when you deploy your Camel application on a Servlet container or an Application Server.

In standalone mode, if you want to expose a rest endpoint, you should rather use a component like camel-undertow, camel-jetty, camel-netty-http or camel-platform-http (you can find the full list here).


Assuming that you want to use undertow, you will have to follow the next steps

In your pom file you need to replace camel-rest with camel-undertow, as next:

<dependency>
    <groupId>org.apache.camel</groupId>
    <artifactId>camel-undertow</artifactId>
    <version>3.12.0</version>
</dependency>

Then, you just need to change your rest configuration to use undertow and it should be good:

restConfiguration()
    .component("undertow")
    .port(8080)
    .bindingMode(RestBindingMode.auto);
Advertisement