Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 19 additions & 0 deletions src/main/java/com/redis/cluster/config/RedisCacheConfig.java
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@
import org.springframework.data.redis.cache.RedisCacheConfiguration;
import org.springframework.data.redis.cache.RedisCacheManager;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.listener.RedisMessageListenerContainer;
import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.RedisSerializationContext;
import org.springframework.data.redis.serializer.StringRedisSerializer;

Expand Down Expand Up @@ -36,4 +39,20 @@ public RedisCacheManager cacheManager(RedisConnectionFactory connectionFactory)
return RedisCacheManager.RedisCacheManagerBuilder.fromConnectionFactory(connectionFactory).cacheDefaults(configuration)
.withInitialCacheConfigurations(cacheConfigurations).build();
}

@Bean
public RedisMessageListenerContainer RedisMessageListener(RedisConnectionFactory connectionFactory) {
RedisMessageListenerContainer container = new RedisMessageListenerContainer();
container.setConnectionFactory(connectionFactory);
return container;
}

@Bean
public RedisTemplate<String, Object> redisTemplateForObject(RedisConnectionFactory connectionFactory) {
RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
redisTemplate.setConnectionFactory(connectionFactory);
redisTemplate.setKeySerializer(new StringRedisSerializer());
redisTemplate.setValueSerializer(new GenericJackson2JsonRedisSerializer());
return redisTemplate;
}
}
63 changes: 63 additions & 0 deletions src/main/java/com/redis/cluster/controller/PubSubController.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
package com.redis.cluster.controller;

import com.redis.cluster.pubsub.RedisPublisher;
import com.redis.cluster.pubsub.RedisSubscriber;
import com.redis.cluster.pubsub.RoomMessage;
import lombok.RequiredArgsConstructor;
import org.springframework.data.redis.listener.ChannelTopic;
import org.springframework.data.redis.listener.RedisMessageListenerContainer;
import org.springframework.web.bind.annotation.*;

import javax.annotation.PostConstruct;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;

@RequiredArgsConstructor
@RequestMapping("/pubsub")
@RestController
public class PubSubController {
// topic에 발행되는 액션을 처리할 Listner
private final RedisMessageListenerContainer redisMessageListener;
// 발행자
private final RedisPublisher redisPublisher;
// 구독자
private final RedisSubscriber redisSubscriber;
// 특정 topic에 메시지를 발송할 수 있도록 topic정보를 Map에 저장
private Map<String, ChannelTopic> channels;

@PostConstruct
public void init() {
// 실행될때 topic정보를 담을 Map을 초기화
channels = new HashMap<>();
}

// 유효한 Topic 리스트 반환
@GetMapping("/room")
public Set<String> findAllRoom() {
return channels.keySet();
}

// Topic 생성하여 Listener에 등록후 Topic Map에 저장
@PutMapping("/room/{roomId}")
public void createRoom(@PathVariable String roomId) {
ChannelTopic channel = new ChannelTopic(roomId);
redisMessageListener.addMessageListener(redisSubscriber, channel);
channels.put(roomId, channel);
}

// 특정 Topic에 메시지 발송
@PostMapping("/room/{roomId}")
public void pushMessage(@PathVariable String roomId, @RequestParam String name, @RequestParam String message) {
ChannelTopic channel = channels.get(roomId);
redisPublisher.publish(channel, RoomMessage.builder().name(name).roomId(roomId).message(message).build());
}

// 특정 Topic 삭제 후 Listener 해제
@DeleteMapping("/room/{roomId}")
public void deleteRoom(@PathVariable String roomId) {
ChannelTopic channel = channels.get(roomId);
redisMessageListener.removeMessageListener(redisSubscriber, channel);
channels.remove(roomId);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -23,21 +23,18 @@ public User findOne(@PathVariable long msrl) {
}

@PostMapping("/user")
@ResponseBody
public User postUser(@RequestBody User user) {
return userJpaRepo.save(user);
}

@CachePut(value = CacheKey.USER, key = "#user.msrl")
@PutMapping("/user")
@ResponseBody
public User putUser(@RequestBody User user) {
return userJpaRepo.save(user);
}

@CacheEvict(value = CacheKey.USER, key = "#msrl")
@DeleteMapping("/user/{msrl}")
@ResponseBody
public boolean deleteUser(@PathVariable long msrl) {
userJpaRepo.deleteById(msrl);
return true;
Expand Down
17 changes: 17 additions & 0 deletions src/main/java/com/redis/cluster/pubsub/RedisPublisher.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package com.redis.cluster.pubsub;

import lombok.RequiredArgsConstructor;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.listener.ChannelTopic;
import org.springframework.stereotype.Service;

@RequiredArgsConstructor
@Service
public class RedisPublisher {

private final RedisTemplate<String, Object> redisTemplate;

public void publish(ChannelTopic topic, RoomMessage message) {
redisTemplate.convertAndSend(topic.getTopic(), message);
}
}
29 changes: 29 additions & 0 deletions src/main/java/com/redis/cluster/pubsub/RedisSubscriber.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package com.redis.cluster.pubsub;

import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.connection.Message;
import org.springframework.data.redis.connection.MessageListener;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

@Slf4j
@RequiredArgsConstructor
@Service
public class RedisSubscriber implements MessageListener {

private final ObjectMapper objectMapper;
private final RedisTemplate redisTemplate;

@Override
public void onMessage(Message message, byte[] pattern) {
try {
String body = (String) redisTemplate.getStringSerializer().deserialize(message.getBody());
RoomMessage roomMessage = objectMapper.readValue(body, RoomMessage.class);
log.info("Room - Message : {}", roomMessage.toString());
} catch (Exception e) {
log.error(e.getMessage());
}
}
}
17 changes: 17 additions & 0 deletions src/main/java/com/redis/cluster/pubsub/RoomMessage.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package com.redis.cluster.pubsub;

import lombok.*;

import java.io.Serializable;

@Getter
@Builder
@NoArgsConstructor
@AllArgsConstructor
@ToString
public class RoomMessage implements Serializable {
private static final long serialVersionUID = 2082503192322391880L;
private String roomId;
private String name;
private String message;
}
4 changes: 2 additions & 2 deletions src/main/resources/application.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ server:

logging:
level:
root: warn
root: info
com.rest.api: debug

spring:
Expand All @@ -28,4 +28,4 @@ spring:
- 15.164.98.87:6401
- 15.164.98.87:6402
max-redirects: 3
password: XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
password: XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX