0
votes

I am trying to configure Spring Boot, Apache Camel, ActiveMQ all togheter. This is what I did so far:

  1. I run ActiveMQ using activemq.bat
  2. I log into the console to monitor messages
  3. I start backend service (sources below)
  4. I start frontend service (Backend and Frontend are different spring boot projects)
  5. I sucesfully send message into the que from frontend but after 20s I am getting timeout. The message appears in ActiveMQ console but it's not consumed by backend.

Here's how I configured backend:

build.gradle:

dependencies {
    compile("org.apache.camel:camel-spring-boot:2.16.0")
    compile("org.springframework.boot:spring-boot-starter-web")
    compile("org.springframework.boot:spring-boot-starter-websocket")
    compile("org.springframework:spring-messaging")
    compile("org.springframework:spring-jms")
    compile("org.springframework.security:spring-security-web")
    compile("org.springframework.security:spring-security-config")
    compile("org.springframework.boot:spring-boot-starter-data-jpa")
    compile('org.apache.camel:camel-jms:2.16.0')
    compile("org.hibernate:hibernate-core:4.0.1.Final")
    compile("mysql:mysql-connector-java:5.1.37")
    compile("log4j:log4j:1.2.16")
    compile("junit:junit:4.12")
    compile("org.mockito:mockito-all:1.8.4")
    compile('org.apache.activemq:activemq-core:5.7.0')
    compile('com.epam.training.auction:auction_common:1.0')
    testCompile("junit:junit")
}

Route Config: (I use UsersServiceImpl for testing and both ways of defining it don't work)

import org.apache.camel.RoutesBuilder;
import org.apache.camel.builder.RouteBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import com.epam.training.auction_backend.services.UsersServiceImpl;

@Configuration
public class MyRouterConfiguration {
  @Bean
  public RoutesBuilder myRouter() {
    return new RouteBuilder() {

      @Override
      public void configure() throws Exception {
          from("jms:queue:auctions").to("bean:auctionsServiceImpl");
          from("jms:queue:users").bean(UsersServiceImpl.class);
          from("jms:queue:bidding").to("bean:biddingServiceImpl");
      }
    };
  }
}

Client side, invoking method

@Override
public void registerUser(String username, String password) {
    AbstractApplicationContext context = new ClassPathXmlApplicationContext("camel-client-remoting.xml");
    UsersService usersService = context.getBean("usersServiceImpl", UsersService.class);

    System.out.println("Invoking the logging");
    UserTransferObject userTransferObject = new UserTransferObject("user", "pass");
    usersService.addUser(userTransferObject);
    System.out.println("User is logged");

    IOHelper.close(context);
}

Client xml camel config

<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       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">

  <camel:camelContext id="camel-client">
    <camel:template id="camelTemplate"/>

    <camel:proxy
        id="auctionsServiceImpl"
        serviceInterface="com.epam.training.auction.common.AuctionsService"
        serviceUrl="jms:queue:auctions"/>

    <camel:proxy
        id="usersServiceImpl"
        serviceInterface="com.epam.training.auction.common.UsersService"
        serviceUrl="jms:queue:users"/>

    <camel:proxy
        id="biddingServiceImpl"
        serviceInterface="com.epam.training.auction.common.BiddingService"
        serviceUrl="jms:queue:bidding"/>
  </camel:camelContext>

  <bean id="jmsConnectionFactory"
        class="org.apache.activemq.ActiveMQConnectionFactory">
    <property name="brokerURL" value="tcp://localhost:61616"/>
  </bean>

  <bean id="pooledConnectionFactory"
        class="org.apache.activemq.pool.PooledConnectionFactory"
        init-method="start" destroy-method="stop">
    <property name="maxConnections" value="8"/>
    <property name="connectionFactory" ref="jmsConnectionFactory"/>
  </bean>

  <bean id="jmsConfig"
        class="org.apache.camel.component.jms.JmsConfiguration">
    <property name="connectionFactory" ref="pooledConnectionFactory"/>
    <property name="concurrentConsumers" value="10"/>
  </bean>

  <bean id="jms"
        class="org.apache.activemq.camel.component.ActiveMQComponent">
    <property name="configuration" ref="jmsConfig"/>
    <property name="transacted" value="true"/>
    <property name="cacheLevelName" value="CACHE_CONSUMER"/>
  </bean>

</beans>

During sending I also get warning:

2015-11-02 11:56:21.547  WARN 16328 --- [nio-8181-exec-5] o.s.b.f.s.DefaultListableBeanFactory     : Bean creation exception on FactoryBean type check: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'usersServiceImpl': Invocation of init method failed; nested exception is org.apache.camel.ResolveEndpointFailedException: Failed to resolve endpoint: jms://queue:users due to: Cannot auto create component: jms

Common interfaces nad transfer objects are defined in 3rd project which is a dependency for both backend and frontend projects.

I feel that there's one missing part of this configuration. Please tell me what could it be.

Thanks in advance.

1

1 Answers

0
votes

You need to change

<bean id="activemq"
    class="org.apache.activemq.camel.component.ActiveMQComponent">

to

<bean id="jms"
    class="org.apache.activemq.camel.component.ActiveMQComponent">

or change your endpoint urls to .to("activemq:queue:users").

The id of your ActiveMQComponent is the name used in the .to() to identify to camel that you want to use that component definition.