Apache Camel to consume xml content from Spring Boot API end-point - EIP sample
In this article will be explaining how to use Apache camel for an EIP pattern to consume and xml file from the REST end-point.
The consumed xml message can be sent to JMS queue, in this case I have set up the Artemis broker.
For this code example, 2.23.0 version of Apache Camel is used. This should also work with 3+ version. The code below uses Spring DSL.
The route starts with timer
component which invokes the route to call the HTTP REST end point to consume xml using camel-http4
camel component.
The consumed xml content will also be stored under the folder specified in wire-tap component path.
The consumed XML content is then pushed to Artemis Queue. The Artmies Client configuration using Qpid (AMPQ) client, is defined within the context file.
The commented context also contains configuring JMS Artemis client as well.
In order to use https end point, we have to set the SSL parameters within camel context, which will be the key store information. This is also commented for demonstration purpose.
Note:
- For creating a Spring boot application to producer XML response refer the blog post from this link.
After creating a simple maven project and include in the dependencies in the pom.xml below, store the context xml content below under /src/main/resources/META-INF/spring
folder as context-camel.xml
. This context file name will be passed as argument Camel Main class to execute the process.
- The commented code explains additional information.
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:camel="http://camel.apache.org/schema/spring"
xmlns:util="http://www.springframework.org/schema/util"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://camel.apache.org/schema/spring
http://camel.apache.org/schema/spring/camel-spring.xsd
http://www.springframework.org/schema/util
http://www.springframework.org/schema/util/spring-util.xsd">
<!-- Below can be used if we are going to hit the https end point.
using camel-http4 lib, and https4 scheme. the keystore should be generated using cert java keytool
{{}} in the camel context will be resolved from the properties file
The poperties file should be passed as parameter to the been
<bean id="properties" class="org.apache.camel.spring.spi.BridgePropertyPlaceholderConfigurer">
<property name="locations">
<list value="file://path/to/properties-file" />
</property>
</bean>
-->
<!--
<camel:sslContextParameters id="sslContextParams">
<camel:keyManagers keyPassword="{{password-from-congiguration-file}}">
<camel:keyStore resource="{{key-store-path}}" password="{{key-store-password}}"/>
</camel:keyManagers>
</camel:sslContextParameters>
-->
<!-- below bean configuration is used when we include aretmis jms client dependecies since this uses JMS client -->
<!--
<bean id="jmsConnectionFactory" class="org.apache.activemq.artemis.jms.client.ActiveMQJMSConnectionFactory">
<constructor-arg index="0" value="tcp://localhost:61616?wireFormat.maxInactivityDuration=500000"/>
</bean>
-->
<!-- When using the artemis-jms client then instead of AMQPComponent, we need to use JmsComponent -->
<!--
<bean id="jms" class="org.apache.camel.component.jms.JmsComponent">
<property name="configuration" ref="jmsConfig" />
</bean>
-->
<!-- use below when using Qpid client -->
<bean id="jmsConnectionFactory" class="org.apache.qpid.jms.JmsConnectionFactory">
<property name="remoteURI" value="amqp://localhost:5672" /> <!-- broker.xml of Artemis should enable the amqp port-->
</bean>
<bean id="jmsPooledConnectionFactory" class="org.messaginghub.pooled.jms.JmsPoolConnectionFactory" init-method="start" destroy-method="stop">
<property name="maxConnections" value="5" />
<property name="connectionFactory" ref="jmsConnectionFactory" />
</bean>
<bean id="jmsConfig" class="org.apache.camel.component.jms.JmsConfiguration">
<property name="connectionFactory" ref="jmsPooledConnectionFactory" />
<property name="concurrentConsumers" value="5" />
</bean>
<!-- uses the AMQP component -->
<bean id="jms" class="org.apache.camel.component.amqp.AMQPComponent">
<property name="configuration" ref="jmsConfig" />
</bean>
<!-- If we wanted to run this job on a scheduled basis we can use Quartz Scheduler
Below is the bean definition, but in order to create a bean we need camel-quartz2 dependency included -->
<!-- <bean id="quartz2" class="org.apache.camel.component.quartz2.QuartzComponent" /> -->
<camelContext id="XMLContentProcessing" xmlns="http://camel.apache.org/schema/spring" streamCache="true">
<endpoint id="demoQueue" uri="jms:queue:content_queue" />
<camel:route id="contentProcessRote" autoStartup="true">
<!-- We can use quartz2 scheduler like below, requires the bean as mentioned above -->
<!-- <camel:from uri="quartz2://demoScheduler?cron=0+0/5+*+*+*+?"/> -->
<!-- In below the from scheme timer component is used -->
<camel:from uri="timer://foo?fixedRate=true&period=60000"/>
<camel:to uri="http4://localhost:8080/content"/> <!-- include camel-http4 dependency -->
<camel:setHeader headerName="Endpoint1XMLContent">
<camel:constant>ENDPOINT1</camel:constant>
</camel:setHeader>
<camel:to uri="direct:sendXMLToRoute"/>
</camel:route>
<camel:route id="sendMessageToQueue" >
<camel:from uri="direct:sendXMLToRoute"/>
<choice>
<when>
<simple>${body.length} == 0</simple>
<camel:log logName="com.rest.xml.log" loggingLevel="INFO" message="${header.location}, breadcrumbId = ${header.breadcrumbId} MESSAGE DROPPED. "/>
<stop></stop>
</when>
<otherwise>
<camel:log logName="com.rest.xml.log" loggingLevel="INFO" message="${header.location}, breadcrumbId = ${header.breadcrumbId} MESSAGE PROCESED. "/>
<camel:wireTap uri="file:///paht/to/location/for/message/backup"/>
<camel:setHeader headerName="MessageType">
<camel:constant>XML</camel:constant>
</camel:setHeader>
<camel:convertBodyTo type="java.lang.byte[]"></camel:convertBodyTo>
<camel:to uri="ref:demoQueue" />
</otherwise>
</choice>
</camel:route>
</camelContext>
</beans>
Below is the pom.xml with the required dependencies to run the above code.
Create simple maven project in Eclipse, use the below pom.xml for dependencies.
<?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>com.demo.artemis</groupId>
<artifactId>artemis-demo</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>artemis-demo</name>
<description>A simple artemis-demo</description>
<!-- FIXME change it to the project's website -->
<url>http://www.example.com</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
<apache.camel.version>2.23.0</apache.camel.version>
<apache.artemis.version>2.12.0</apache.artemis.version>
<pooled-jms-version>1.1.1</pooled-jms-version>
</properties>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
</dependency>
<dependency>
<groupId>org.apache.camel</groupId>
<artifactId>camel-core</artifactId>
<version>${apache.camel.version}</version>
</dependency>
<dependency>
<groupId>org.apache.camel</groupId>
<artifactId>camel-jms</artifactId>
<version>${apache.camel.version}</version>
</dependency>
<dependency>
<groupId>org.apache.camel</groupId>
<artifactId>camel-spring</artifactId>
<version>${apache.camel.version}</version>
</dependency>
<dependency>
<groupId>org.apache.camel</groupId>
<artifactId>camel-context</artifactId>
<version>${apache.camel.version}</version>
</dependency>
<dependency>
<groupId>org.apache.activemq</groupId>
<artifactId>artemis-jms-client</artifactId>
<version>${apache.artemis.version}</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-api</artifactId>
<version>2.17.1</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
<version>2.17.1</version>
</dependency>
<!-- SLF4J Bridge -->
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-slf4j-impl</artifactId>
<version>2.17.1</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.33</version>
</dependency>
<dependency>
<groupId>org.messaginghub</groupId>
<artifactId>pooled-jms</artifactId>
<version>${pooled-jms-version}</version>
</dependency>
<dependency>
<groupId>org.apache.qpid</groupId>
<artifactId>qpid-jms-client</artifactId>
<version>0.54.0</version>
</dependency>
<dependency>
<groupId>org.apache.camel</groupId>
<artifactId>camel-amqp</artifactId>
<version>${apache.camel.version}</version>
</dependency>
<dependency>
<groupId>org.apache.camel</groupId>
<artifactId>camel-http4</artifactId>
<version>${apache.camel.version}</version>
<scope>runtime</scope>
<!-- use the same version as your Camel core version -->
</dependency>
</dependencies>
<build>
<pluginManagement>
<plugins>
<plugin>
<artifactId>maven-clean-plugin</artifactId>
<version>3.1.0</version>
</plugin>
<plugin>
<artifactId>maven-site-plugin</artifactId>
<version>3.7.1</version>
</plugin>
<plugin>
<artifactId>maven-project-info-reports-plugin</artifactId>
<version>3.0.0</version>
</plugin>
<plugin>
<artifactId>maven-resources-plugin</artifactId>
<version>3.0.2</version>
</plugin>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.0</version>
</plugin>
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.22.1</version>
</plugin>
<plugin>
<artifactId>maven-jar-plugin</artifactId>
<version>3.0.2</version>
</plugin>
<plugin>
<artifactId>maven-install-plugin</artifactId>
<version>2.5.2</version>
</plugin>
<plugin>
<artifactId>maven-deploy-plugin</artifactId>
<version>2.8.2</version>
</plugin>
</plugins>
</pluginManagement>
</build>
</project>
Below is the simple LOG4J2 configuration to display debug level message in the Eclipse IDE console.
status = debug
name = PropertiesConfig
filters = threshold
filter.threshold.type = ThresholdFilter
filter.threshold.level = debug
appenders = console
appender.console.type = Console
appender.console.name = STDOUT
appender.console.layout.type = PatternLayout
appender.console.layout.pattern = %d{yyyy-MM-dd HH:mm:ss} %-5p %c{1}:%L - %m%n
rootLogger.level = debug
rootLogger.appenderRefs = stdout
rootLogger.appenderRef.stdout.ref = STDOUT
Snapshot of the message pushed to Artemis broker.
To execute the above code within the Eclipse IDE:
- With Apache Camel version 2.23.0, we can use the core class
org.apache.camel.spring.Main
passing the context xml as argument like-ac context-camel.xml
.