Issue
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.
Solution
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);
Answered By - Nicolas Filotto
Answer Checked By - Pedro (JavaFixing Volunteer)