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: (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);