2

I am working on homework to my studies with Java and RabbitMQ. I am not familiar much with Spring and RabbitMQ, but I can't handle this problem.

I have 2 single application.

First one, which produces the message (bolid application) I created a producer of the message (bolid), which every 10 seconds send a message to listeners

@SpringBootApplication
public class BolidApplication implements CommandLineRunner {

    public static void main(String[] args) {
        SpringApplication.run(BolidApplication.class, args);
    }

    @Autowired
    private RabbitTemplate rabbitTemplate;

    @Override
    public void run(String... args) throws Exception {

        Bolid bolid = new Bolid();
        int i = 10;
        while (true) {
            bolid.setData(new Date());
            rabbitTemplate.setReplyAddress("bolidReply");
            rabbitTemplate.convertAndSend("RaceExchange", "raceRouting", bolid.toString());
            rabbitTemplate.convertAndSend("MonitorExchange", "raceRouting", bolid.toString());
            Thread.sleep(15000);
            i += 10;
        }
    }
}

So, I create 2 queue (RaceQueue and MonitorQueue), define exchange and bind them.

I have 2 listeners: RaceListener and MonitorListener.

There is the code of my listeners:

And the second application, which is listeners.

public class RabbitConfig {
    private static final String RACE_QUEUE = "RaceQueue";
    private static final String MONITOR_QUEUE = "MonitorQueue";

    @Bean
    Queue myQueue() {
        return new Queue(RACE_QUEUE, true);
    }

    @Bean
    Queue monitorQueue() {
        return new Queue(MONITOR_QUEUE, true);
    }

    @Bean
    Exchange myExchange() { 
        return ExchangeBuilder.topicExchange("RaceExchange")
                .durable(true)
                .build();
    }

    @Bean
    Exchange monitorExchange() { 
        return ExchangeBuilder.topicExchange("MonitorExchange")
                .durable(true)
                .build();
    }

    @Bean
    Binding binding() {
//        return new Binding(MY_QUEUE, Binding.DestinationType.QUEUE, "MyTopicExchange", "topic", null)
        return BindingBuilder
                .bind(myQueue())
                .to(myExchange())
                .with("raceRouting")
                .noargs();
    }

    @Bean
    Binding monitorBinding() {
        return BindingBuilder
                .bind(monitorQueue())
                .to(monitorExchange())
                .with("raceRouting")
                .noargs();
    }

    @Bean
    ConnectionFactory connectionFactory() {
        CachingConnectionFactory cachingConnectionFactory = new CachingConnectionFactory("localhost");
        cachingConnectionFactory.setUsername("guest");
        cachingConnectionFactory.setPassword("guest");
        return cachingConnectionFactory;
    }

    @Bean
    MessageListenerContainer rabbitRaceListener() {
        SimpleMessageListenerContainer simpleMessageListenerContainer = new SimpleMessageListenerContainer();
        simpleMessageListenerContainer.setConnectionFactory(connectionFactory());
        simpleMessageListenerContainer.setQueues(myQueue());
        simpleMessageListenerContainer.setupMessageListener(new RabbitRaceListener());
        return simpleMessageListenerContainer;
    }

    @Bean
    MessageListenerContainer rabbitMonitorListener() {

        SimpleMessageListenerContainer simpleMessageListenerContainer = new SimpleMessageListenerContainer();
        simpleMessageListenerContainer.setConnectionFactory(connectionFactory());
        simpleMessageListenerContainer.setQueues(monitorQueue());
        simpleMessageListenerContainer.setupMessageListener(new RabbitMonitorListener());
        return simpleMessageListenerContainer;
    }
}

From MonitorListener I want to use reply pattern to reply message to my first application (bolid application). So Bolid application can receive my message.

My Code for MonitorListener:

public class RabbitMonitorListener implements MessageListener {
    @Autowired
    private RabbitTemplate rabbitTemplate;
    @Override
    public void onMessage(Message message) {
        String[] splitted = new String(message.getBody()).split("\\|");
        int oilTemperature = Integer.parseInt(splitted[1].split(" ")[2]);
        int engineTemperature = Integer.parseInt(splitted[2].split(" ")[2]);
        int tirePressure = Integer.parseInt(splitted[3].split(" ")[2]);

        System.out.println("message2 = [" + new String(message.getBody()) + "]");

        if (oilTemperature > 120 || engineTemperature > 120 || tirePressure > 12) {
            System.out.println("SEND REPLY TO BOLID!");
        }
        if (oilTemperature > 150 || engineTemperature > 150 || tirePressure > 17) {
            System.out.println("SEND RELY TO BOLID!");
        }
    }
}

How can I achieve that? So here I can send the message go back to bolid and on the bolid application I can read it?

EDIT: I did some research, I want to do it like this way:

public class RabbitMonitorListener implements MessageListener {
    @Autowired
    private RabbitTemplate rabbitTemplate;

    @Override
    public void onMessage(Message message) {
        String[] splitted = new String(message.getBody()).split("\\|");
        int oilTemperature = Integer.parseInt(splitted[1].split(" ")[2]);
        int engineTemperature = Integer.parseInt(splitted[2].split(" ")[2]);
        int tirePressure = Integer.parseInt(splitted[3].split(" ")[2]);
        String response = "Hello";
        MessageProperties properties = new MessageProperties();
        Message responseMessage = new Message(response.getBytes(), properties);
        rabbitTemplate.send(message.getMessageProperties().getReplyTo(), responseMessage);

        System.out.println("message2 = [" + new String(message.getBody()) + "]");

        if (oilTemperature > 120 || engineTemperature > 120 || tirePressure > 12) {
            System.out.println("WARN MECHANICS");

        }
        if (oilTemperature > 150 || engineTemperature > 150 || tirePressure > 17) {
            System.out.println("WARN MECHANICS");
        }
    }
}

but the rabbitTemplate is null here, so I can't @Autowired it here. How can I have access to rabbitTemplate and method send in MessageListener?

1 Answer 1

2

new RabbitRaceListener() - that must be a @Bean too, to get auto wiring.

However, you are over-complicating things; the framework can take care of all of this for you.

See Request/Reply Messaging for the client side - and use convertSendAndReceive() or convertSendAndReceiveAsType().

On the server side, see Annotation-driven Listener Endpoints.

@RabbitListener(queues = "request")
public String handle(String in) {
    return in.toUpperCase();
}
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.