I have functional code, but I want to ask if this approach is correct when I use 'publisher in the controller' or if it is commonly used that way. I will post the entire code here where I use RabbitMQ and Redis. If you have any comments on other aspects of the code, feel free to write them.
Do i need to have redis config when its not being used? Are the values stored into redis only by the key: iot-data?
DOCKER
services:
redis:
container_name: "redis-server"
image: redis:latest
ports:
- "6379:6379"
volumes:
- ./tmp/redis_data:/var/lib/redis/data
rabbitmq:
image: rabbitmq:3-management-alpine
container_name: 'rabbitmq'
ports:
- 5672:5672
- 15672:15672
volumes:
- ~/.docker-conf/rabbitmq/data/:/var/lib/rabbitmq/
- ~/.docker-conf/rabbitmq/log/:/var/log/rabbitmq
REDIS
app.properties
spring.cache.type=redis
spring.redis.host=127.0.0.1
spring.redis.port=6379
public class RedisConfig {
@Bean
public JedisConnectionFactory jedisConnectionFactory() {
return new JedisConnectionFactory();
}
@Bean
public RedisTemplate<String, Object> redisTemplate() {
RedisTemplate<String, Object> template = new RedisTemplate<>();
template.setConnectionFactory(jedisConnectionFactory());
return template;
}
}
- Redis controller just for testing the redis cache
@RestController
public class RedisController {
@Autowired
private RedisTemplate redisTemplate;
@GetMapping("/api/redis")
public List<String> readIotData() {
return redisTemplate.opsForList().range("iot-data", 0, 20);
}
RABBITMQ
@Configuration
public class RabbitmqConfig {
@Bean
public RabbitAdmin rabbitAdmin(ConnectionFactory connectionFactory) {
return new RabbitAdmin(connectionFactory);
}
@Bean
public FanoutExchange fanout() {
return new FanoutExchange("iot-data");
}
private static class ReceiverConfig {
@Bean
public Queue myQueue() {
return new Queue("", true);
}
@Bean
public Binding binding(FanoutExchange fanout, Queue myQueue) {
return BindingBuilder.bind(myQueue).to(fanout);
}
}
}
@Component
public class RabbitmqListener {
@Autowired
private RedisTemplate redisTemplate;
private static final String EXCHANGE_NAME = "iot-data";
@RabbitListener(autoStartup="true",
bindings=@QueueBinding(value = @Queue,
exchange=@Exchange(name=EXCHANGE_NAME,
type= ExchangeTypes.FANOUT,
durable = "true")))
public void consoleOutputReceiver(String message) {
System.out.println("Received message: " + message);
}
@RabbitListener(autoStartup="true",
bindings=@QueueBinding(value = @Queue,
exchange=@Exchange(name=EXCHANGE_NAME,
type= ExchangeTypes.FANOUT,
durable = "true")))
public void redisOutputReceiver(String message) throws IOException {
ObjectMapper mapper = new ObjectMapper();
CreateDto dto = mapper.readValue(message, CreateDto.class);
redisTemplate.opsForList().leftPush("iot-data", message);
}
}
- rabbitmq publisher
@RestController
@RequestMapping("api")
public class Controller {
@PostMapping("/test")
public void post(@RequestBody CreateDto dto) throws Exception{
ConnectionFactory factory = new ConnectionFactory();
factory.setHost("localhost");
try(Connection connection = factory.newConnection();
Channel channel = connection.createChannel()) {
channel.exchangeDeclare("iot-data", "fanout", true);
ObjectMapper mapper = new ObjectMapper();
String jsonDto = mapper.writeValueAsString(dto);
channel.basicPublish("iot-data","", null, jsonDto.getBytes("UTF-8"));
Thread.sleep(2000);
}
}
}