Skip to content
Open
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
5 changes: 5 additions & 0 deletions com.sparta.cupeed.hub/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,11 @@ dependencies {
implementation 'org.springframework.boot:spring-boot-starter-security'
implementation 'com.auth0:java-jwt:4.4.0'

// redis
implementation 'org.springframework.boot:spring-boot-starter-data-redis'
// LocalDate type 직렬화
implementation 'com.fasterxml.jackson.datatype:jackson-datatype-jsr310'

testImplementation 'org.springframework.boot:spring-boot-starter-test'
testRuntimeOnly 'org.junit.platform:junit-platform-launcher'
}
Expand Down
12 changes: 12 additions & 0 deletions com.sparta.cupeed.hub/docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,18 @@ services:
retries: 5
restart: unless-stopped

# Redis 캐시
redis:
image: redis:alpine
container_name: cupeed-hub-redis
ports:
- "6379:6379"
volumes:
- redis_data:/data
restart: unless-stopped

Comment on lines +21 to +30
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cupeed 최상단에 적용해주세용 최상단에도 redis 설정 포트가 6379라 hub 관련된 redis 포트 변경해주세욥

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

최상단꺼를 같이 사용하는건지 모르겠네여?ㅜㅠ

volumes:
postgres_data:
driver: local
redis_data:
driver: local
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@
import java.util.UUID;
import java.util.stream.Collectors;

import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.CachePut;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.cache.annotation.Caching;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

Expand All @@ -17,9 +21,11 @@
import com.sparta.cupeed.hub.presentation.HubInternalResponseDtoV1;

import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;

// @Transactional: 애플리케이션 서비스에서 트랜잭션을 관리합니다.
// 이 서비스는 도메인 객체(Hub)를 로드하고, 도메인의 비즈니스 메서드를 호출하며, 결과를 저장소에 저장하는 '조율자' 역할을 합니다.
@Slf4j
@Service
@RequiredArgsConstructor
public class HubService {
Expand All @@ -29,6 +35,7 @@ public class HubService {

// 1. 허브 생성 (POST /v1/hubs)
@Transactional
@CacheEvict(value = "CacheHubs", allEntries = true)
public HubResponseDto createHub(CreateHubCommand command) {
// ⭐ 주소를 이용해 위도/경도 조회 ⭐
Coordinates coordinates = geocodingService.getCoordinatesFromAddress(command.getAddress());
Expand All @@ -50,6 +57,7 @@ public HubResponseDto createHub(CreateHubCommand command) {

// 2. 허브 단건 조회 (GET /v1/hubs/{hubId})
@Transactional(readOnly = true)
@Cacheable(value = "CacheHub", key = "#hubId")
public HubResponseDto getHubById(UUID hubId) {
Hub hub = hubRepository.findById(hubId)
.orElseThrow(() -> new IllegalArgumentException("존재하지 않은 ID입니다." + hubId));
Expand All @@ -58,14 +66,21 @@ public HubResponseDto getHubById(UUID hubId) {

// 3. 허브 목록 조회 (GET /v1/hubs)
@Transactional(readOnly = true)
@Cacheable("CacheHubs")
public List<HubResponseDto> getAllHubs() {
log.info("허브 목록 조회");
return hubRepository.findAll().stream()
.map(HubResponseDto::mapToResponse)
.collect(Collectors.toList());
}

// 4. 허브 수정 (PUT /v1/hubs/{hubId})
@Transactional
@CachePut(value = "CacheHub", key = "#hubId")
@Caching(evict = {
@CacheEvict(value = "CacheHub", key = "#hubId"), // 단건 캐쉬 삭제
@CacheEvict(value = "CacheHubs", allEntries = true) // 목록 캐쉬 삭제
})
public HubResponseDto updateHub(UUID hubId, UpdateHubCommand command) {
// 1. Repository를 통해 Hub 애그리거트 루트를 로드
Hub hub = hubRepository.findById(hubId)
Expand All @@ -85,6 +100,10 @@ public HubResponseDto updateHub(UUID hubId, UpdateHubCommand command) {

// 5. 허브 삭제 (DELETE /v1/hubs/{hubId})
@Transactional
@Caching(evict = {
@CacheEvict(value = "CacheHub", key = "#hubId"),
@CacheEvict(value = "CacheHubs", allEntries = true)
})
public void deleteHub(UUID hubId) {
Hub hub = hubRepository.findById(hubId)
.orElseThrow(() -> new IllegalArgumentException("존재하지 않은 ID입니다." + hubId));
Expand All @@ -99,6 +118,7 @@ public HubInternalResponseDtoV1 getInternalHubByName(String hubName) {
return HubInternalResponseDtoV1.of(hub);
}

@Cacheable(value = "CacheHub", key = "#name")
public HubResponseDto getHubByName(String name) {
Hub hub = hubRepository.findByName(name)
.orElseThrow(() -> new IllegalArgumentException("존재하지 않은 허브 이름입니다."));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,10 @@
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;

@Getter
@Setter
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

세터가 아니라 메서드로 만들어야 할까요?ㅜㅠ

@Builder
@NoArgsConstructor
@AllArgsConstructor
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
package com.sparta.cupeed.hub.infrastructure.redis;

// 나머지 import 문들

import java.time.Duration;

import org.springframework.cache.annotation.EnableCaching;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.cache.CacheKeyPrefix;
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.serializer.GenericJackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.RedisSerializationContext;
import org.springframework.data.redis.serializer.StringRedisSerializer;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;

@Configuration
@EnableCaching
public class CacheConfig {

@Bean
// CacheManager로 진행해도 정상 동작
public RedisCacheManager cacheManager(
RedisConnectionFactory redisConnectionFactory
) {

ObjectMapper objectMapper = new ObjectMapper()
.registerModule(new JavaTimeModule())
.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);

objectMapper.activateDefaultTyping(
objectMapper.getPolymorphicTypeValidator(),
ObjectMapper.DefaultTyping.NON_FINAL
// JsonTypeInfo.As.PROPERTY
);

GenericJackson2JsonRedisSerializer serializer = new GenericJackson2JsonRedisSerializer(objectMapper);

// 설정 구성을 먼저 진행한다.
// Redis를 이용해서 Spring Cache를 사용할 때
// Redis 관련 설정을 모아두는 클래스
RedisCacheConfiguration configuration = RedisCacheConfiguration
.defaultCacheConfig()
// null을 캐싱 할것인지
.disableCachingNullValues()
// 기본 캐시 유지 시간 (Time To Live)
.entryTtl(Duration.ofSeconds(120))
// 캐시를 구분하는 접두사 설정
.computePrefixWith(CacheKeyPrefix.simple())
// 캐시에 저장할 값을 어떻게 직렬화 / 역직렬화 할것인지
// .serializeValuesWith(SerializationPair.fromSerializer(RedisSerializer.json()))
.serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(new StringRedisSerializer()))
.serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(serializer));
;

return RedisCacheManager
.builder(redisConnectionFactory)
.cacheDefaults(configuration)
.build();
}
}
6 changes: 6 additions & 0 deletions com.sparta.cupeed.hub/src/main/resources/application.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,12 @@ spring:
init:
mode: always

# 3. Redis 설정
data:
redis:
host: localhost
port: 6379

server:
Comment on lines +28 to 34
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

도커 컴포즈 파일 변경하시고 설정 파일도 맞춰서 수정해서 욜려주시면감사하게씁니당 ㅎㅅㅎ

port: 20040

Expand Down