Building a Client-Server Application using Docker/RabbitMQ and Java/Spring Boot - Part 2

Mar 03,2018 at 02:46 pm By Ben Hutton

Part 2

Step 1 - The REST API

The first step is to build the basic App.  Since this will connected to from a Node.js based front-end a REST API is the obvious choice plus the Spring Boot website has an easy tutorial and git repo that will get us started.

To start pull down the spring-boot repo with the following command:

git clone https://github.com/spring-guides/gs-rest-service.git

Note: you will need git installed for this command to work.

First things first.  Create a test.

@Test
public void testVPSAPIRoute() throws Exception {
this.mockMvc.perform(get("/api/1.0/vpsmanager/").param("test", "content"))
.andDo(print()).andExpect(status().isOk());
}

Now that we have a test we need a route in the controller.

@RequestMapping("/api/1.0/vpsmanager")
public Greeting vpsmanager(@RequestParam(value="name", defaultValue="World") String name) {
return new Greeting(counter.incrementAndGet(),
String.format(template, name));
}


Assuming everything else is configured correctly the tests should now run.

 

Step 2 - RabbitMQ

Next to create some tests for RabbitMQ connectivity.

package com.vpsmanager;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.amqp.rabbit.core.RabbitTemplate;

import static org.junit.Assert.*;

@RunWith(SpringRunner.class)
@SpringBootTest
@AutoConfigureMockMvc
public class RabbitMQTests {

@Autowired
private RabbitTemplate rabbitTemplate;

@Autowired
private Sender sender;

@Autowired
private Receiver receiver;

@Test
public void createQueueTest() {
assertEquals(sender.createQueue(), "spring-boot");
rabbitTemplate.receive("spring-boot", 1);
}

@Test
public void publishToQueueAndRecieve() {
assertEquals("success", sender.publishItem("myitem"));
assertEquals("myitem" , receiver.getQueueItem());
}

}

Now to write the code.  I've split this up into a Sender and Reciever class.  You can put these together however I prefer things a little cleaner.

Sender Class

package com.vpsmanager;

import org.springframework.amqp.core.Queue;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Component;

@Component
public class Sender {
private String queueName = "spring-boot";

@Autowired
private RabbitTemplate rabbitTemplate;

@Bean
@Value("${this.queueName}")
private Queue queue() {
return new Queue(this.queueName);
}

public String createQueue() {
Queue queueReturn = queue();
return queueReturn.getName();
}

public String publishItem(String item) {
Queue queue = new Queue(this.queueName);
rabbitTemplate.convertAndSend(queue.getName(), item);
return "success";
}
}

Reciever Class

package com.vpsmanager;

import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

@Component
public class Receiver {
private String queueName = "spring-boot";

@Autowired
private RabbitTemplate rabbitTemplate;

public String getQueueItem() {
byte[] body = rabbitTemplate.receive(this.queueName).getBody();
return new String(body);
}
}

 

Next we will put them both together.  And again we start with some more tests.

@Test
public void testVPSAPIRoute() throws Exception {
this.mockMvc.perform(get("/api/1.0/vpsmanager/").param("test", "content"))
.andDo(print()).andExpect(status().isOk());
}

@Test
public void testVPSAPIRouteWithRabbitReturn() throws Exception {
this.mockMvc.perform(get("/api/1.0/addtoqueue/").param("queue", "spring-boot").param("value", "mytestpayload"))
.andDo(print()).andExpect(status().isOk())
.andExpect(jsonPath("$.content").value("success"));
this.mockMvc.perform(get("/api/1.0/getrabbitresponse/").param("queue", "spring-boot"))
.andDo(print()).andExpect(status().isOk())
.andExpect(jsonPath("$.content").value("mytestpayload"));
}

And now the controller should look something like this.

package com.vpsmanager;

import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class VPSController {

@Autowired
private RabbitTemplate rabbitTemplate;

@Autowired
private Sender sender;

@Autowired
private Receiver receiver;

@RequestMapping("/api/1.0/vpsmanager")
public VPSManager vpsmanager(@RequestParam(value="name", defaultValue="World") String name) {
return new VPSManager(1,"test");
}

@RequestMapping("/api/1.0/addtoqueue")
public VPSManager vpsManager(@RequestParam(value="value", defaultValue = "spring-boot") String name) {
return new VPSManager(1, sender.publishItem(name));
}

@RequestMapping("/api/1.0/getrabbitresponse")
public VPSManager rabbitResponse(@RequestParam(value = "name", defaultValue = "RabbitMQ") String name) {
return new VPSManager(1, receiver.getQueueItem());
}
}

All done.  You should now have a working API with RabbitMQ.

Leave a comment

Login to Comment

Copyright © 2017 | Ben Hutton