Skip to content

Commit

Permalink
Merge pull request #35 from RumosZin/feat/#22
Browse files Browse the repository at this point in the history
[feat] Spring RabbitMQ 설정 및 PhotoRequest Producer 생성 (#22)
  • Loading branch information
win-luck authored Aug 15, 2024
2 parents 622d370 + 8aca07b commit 56056c7
Show file tree
Hide file tree
Showing 7 changed files with 164 additions and 2 deletions.
2 changes: 2 additions & 0 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,8 @@ dependencies {
implementation 'org.springframework.boot:spring-boot-starter-mail'
implementation 'org.springframework.boot:spring-boot-starter-thymeleaf'
implementation 'nz.net.ultraq.thymeleaf:thymeleaf-layout-dialect'
// Rabbit MQ
implementation 'org.springframework.boot:spring-boot-starter-amqp'
}

tasks.named('test') {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
package gdsc.cau.puangbe.common.config.RabbitMq;

import lombok.RequiredArgsConstructor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.amqp.core.Binding;
import org.springframework.amqp.core.BindingBuilder;
import org.springframework.amqp.core.DirectExchange;
import org.springframework.amqp.rabbit.connection.CachingConnectionFactory;
import org.springframework.amqp.rabbit.connection.ConnectionFactory;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.amqp.support.converter.Jackson2JsonMessageConverter;
import org.springframework.amqp.support.converter.MessageConverter;
import org.springframework.amqp.core.Queue;

@RequiredArgsConstructor
@Configuration
public class RabbitMqConfig {
private final RabbitMqProperties rabbitMqProperties;
private final RabbitMqInfo rabbitMqInfo;

@Bean
public Queue queue() {
return new Queue(rabbitMqInfo.getQueueName());
}

/**
* 지정된 Exchange 이름으로 Direct Exchange Bean 생성
*/
@Bean
public DirectExchange directExchange() {
return new DirectExchange(rabbitMqInfo.getExchangeName());
}

/**
* 주어진 Queue와 Exchange Binding
* Routing Key 을 이용하여 Binding Bean 생성
**/
@Bean
public Binding binding(Queue queue, DirectExchange exchange) {
return BindingBuilder.bind(queue).to(exchange).with(rabbitMqInfo.getQueueName());
}

/**
* RabbitMQ 연동을 위한 ConnectionFactory 빈을 생성하여 반환
**/
@Bean
public CachingConnectionFactory connectionFactory() {
CachingConnectionFactory connectionFactory = new CachingConnectionFactory();
connectionFactory.setHost(rabbitMqProperties.getHost());
connectionFactory.setPort(rabbitMqProperties.getPort());
connectionFactory.setUsername(rabbitMqProperties.getUsername());
connectionFactory.setPassword(rabbitMqProperties.getPassword());
return connectionFactory;
}

/**
* RabbitTemplate
* ConnectionFactory 로 연결 후 실제 작업을 위한 Template
*/
@Bean
public RabbitTemplate rabbitTemplate(ConnectionFactory connectionFactory) {
RabbitTemplate rabbitTemplate = new RabbitTemplate(connectionFactory);
rabbitTemplate.setMessageConverter(jackson2JsonMessageConverter());
return rabbitTemplate;
}

/**
* 직렬화 (메세지를 JSON 으로 변환하는 Message Converter)
*/
@Bean
public MessageConverter jackson2JsonMessageConverter() {
return new Jackson2JsonMessageConverter();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package gdsc.cau.puangbe.common.config.RabbitMq;

import lombok.Getter;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Configuration;

@Getter
@Configuration
@ConfigurationProperties(prefix = "rabbitmq")
public class RabbitMqInfo {

/**
* Exchange : Producer로부터 전달받은 메시지를 어떤 메시지 큐로 전송할 지 결정
*/
@Value("${rabbitmq.exchange.name}")
private String exchangeName;

/**
* Routing : Exchange에서 해당하는 key에 맞게 Queue에 분배
*/
@Value("${rabbitmq.routing.key}")
private String routingKey;

/**
* Queue : Consumer가 소비하기 전까지 메시지 보관
*/
@Value("${rabbitmq.queue.name}")
private String queueName;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package gdsc.cau.puangbe.common.config.RabbitMq;


import lombok.AllArgsConstructor;
import lombok.Getter;
import org.springframework.boot.context.properties.ConfigurationProperties;

/**
* spring.rabbitmq 의 prefix 을 가지는 값들을
* RabbitMqProperties 클래스 필드로 바인딩 한 후 사용
*/
@ConfigurationProperties(prefix = "spring.rabbitmq")
@AllArgsConstructor
@Getter
public class RabbitMqProperties {
private String host;
private int port;
private String username;
private String password;
}
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ public class PhotoRequestServiceImpl implements PhotoRequestService {
private final UserRepository userRepository;
private final RedisTemplate<String, Long> redisTemplate;
private final ObjectMapper mapper;
private final RabbitMqService rabbitMqService;

//이미지 처리 요청 생성 (RabbitMQ호출)
@Override
Expand Down Expand Up @@ -67,8 +68,7 @@ public Long createImage(CreateImageDto dto, Long userId){
.build();
String message = mapper.writeValueAsString(imageInfo);

// TODO: RabbitMQ 호출
// 1. RabbitMQ를 호출해서 message를 큐에 함께 넣어서 파이썬에서 접근할 수 있도록 한다.
rabbitMqService.sendMessage(message); // 1. RabbitMQ를 호출해서 message를 큐에 함께 넣어서 파이썬에서 접근할 수 있도록 한다.
// 2. Redis에 <String keyName, Long requestId> 형식으로 진행되고 있는 request 정보를 저장한다.
// 3. 추후 사진이 완성된다면 requestId를 통해 request를 찾아서 상태를 바꾸고 1:1 관계인 result에 접근해서 imageUrl를 수정한다.
// 4. 즉, 파이썬에서 스프링으로 향하는 POST API는 {requestId, imageUrl}이 필수적으로 존재해야 한다.
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package gdsc.cau.puangbe.photorequest.service;

import gdsc.cau.puangbe.photorequest.dto.ImageInfo;

public interface RabbitMqService {
public void sendMessage(String message);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package gdsc.cau.puangbe.photorequest.service;

import gdsc.cau.puangbe.common.config.RabbitMq.RabbitMqInfo;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.stereotype.Service;

@Service
@RequiredArgsConstructor
@Slf4j
public class RabbitMqServiceImpl implements RabbitMqService{

private final RabbitTemplate rabbitTemplate;
private final RabbitMqInfo rabbitMqInfo;

/**
* 1. Queue 로 메세지를 발행
* 2. Producer 역할 -> Direct Exchange (메시지의 routing key와 정확히 일치하는 binding된 Queue로 routing)
**/
public void sendMessage(String message) {
this.rabbitTemplate.convertAndSend(rabbitMqInfo.getExchangeName(), rabbitMqInfo.getRoutingKey(), message);
log.info("**Message Send**: {}", message);
log.info("messagge queue: {}", rabbitMqInfo.getQueueName());
log.info("messagge exchange: {}", rabbitMqInfo.getExchangeName());
log.info("messagge routingKey: {}", rabbitMqInfo.getRoutingKey());
}
}

0 comments on commit 56056c7

Please sign in to comment.