-
Notifications
You must be signed in to change notification settings - Fork 5
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #112 from prgrms-be-devcourse/feature/NAYB-139
[NAYB-139] feat : 신상품 조회 시 Redis에서 가져온다.
- Loading branch information
Showing
10 changed files
with
314 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
53 changes: 53 additions & 0 deletions
53
src/main/java/com/prgrms/nabmart/domain/item/service/ItemCacheService.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
package com.prgrms.nabmart.domain.item.service; | ||
|
||
import com.prgrms.nabmart.domain.item.service.response.ItemRedisDto; | ||
import java.time.LocalDateTime; | ||
import java.time.temporal.ChronoUnit; | ||
import java.util.List; | ||
import lombok.RequiredArgsConstructor; | ||
import org.springframework.data.redis.core.ListOperations; | ||
import org.springframework.data.redis.core.RedisTemplate; | ||
import org.springframework.scheduling.annotation.Scheduled; | ||
import org.springframework.stereotype.Service; | ||
|
||
@Service | ||
@RequiredArgsConstructor | ||
public class ItemCacheService { | ||
|
||
private final RedisTemplate<String, ItemRedisDto> redisTemplate; | ||
private static final String NEW_PRODUCTS_KEY = "new_products"; | ||
|
||
public void saveNewItem(final ItemRedisDto itemRedisDto) { | ||
redisTemplate.opsForList().rightPush(NEW_PRODUCTS_KEY, itemRedisDto); | ||
} | ||
|
||
public List<ItemRedisDto> getNewItems() { | ||
ListOperations<String, ItemRedisDto> listOperations = redisTemplate.opsForList(); | ||
Long itemCount = listOperations.size(NEW_PRODUCTS_KEY); | ||
if (itemCount == null || itemCount == 0) { | ||
return null; | ||
} | ||
|
||
return listOperations.range(NEW_PRODUCTS_KEY, 0, -1); | ||
} | ||
|
||
@Scheduled(cron = "0 0 * * * *") | ||
public void deleteOldProducts() { | ||
LocalDateTime twoWeeksAgo = LocalDateTime.now().minus(2, ChronoUnit.WEEKS); | ||
|
||
ListOperations<String, ItemRedisDto> items = redisTemplate.opsForList(); | ||
Long itemCount = items.size(NEW_PRODUCTS_KEY); | ||
|
||
if (itemCount == null || itemCount == 0) { | ||
return; | ||
} | ||
|
||
for (int i = 0; i < itemCount; i++) { | ||
ItemRedisDto item = items.index(NEW_PRODUCTS_KEY, i); | ||
if (item != null && item.createdAt().isBefore(twoWeeksAgo)) { | ||
items.remove(NEW_PRODUCTS_KEY, 1, item); | ||
i--; | ||
} | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
24 changes: 24 additions & 0 deletions
24
src/main/java/com/prgrms/nabmart/domain/item/service/response/FindNewItemsResponse.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
package com.prgrms.nabmart.domain.item.service.response; | ||
|
||
import java.util.List; | ||
import java.util.stream.Collectors; | ||
|
||
public record FindNewItemsResponse(List<FindNewItemResponse> items) { | ||
|
||
public static FindNewItemsResponse from(List<FindNewItemResponse> items) { | ||
List<FindNewItemResponse> findNewItemResponses = items.stream() | ||
.map(item -> FindNewItemResponse.of(item.itemId, item.name, item.price, item.discount, | ||
item.reviewCount, item.rate)) | ||
.collect(Collectors.toList()); | ||
return new FindNewItemsResponse(findNewItemResponses); | ||
} | ||
|
||
public record FindNewItemResponse(Long itemId, String name, int price, int discount, | ||
Long reviewCount, double rate) { | ||
|
||
public static FindNewItemResponse of(final Long itemId, final String name, final int price, final int discount, | ||
final Long reviewCount, final double rate) { | ||
return new FindNewItemResponse(itemId, name, price, discount, reviewCount, rate); | ||
} | ||
} | ||
} |
22 changes: 22 additions & 0 deletions
22
src/main/java/com/prgrms/nabmart/domain/item/service/response/ItemRedisDto.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
package com.prgrms.nabmart.domain.item.service.response; | ||
|
||
import com.fasterxml.jackson.databind.annotation.JsonDeserialize; | ||
import com.fasterxml.jackson.databind.annotation.JsonSerialize; | ||
import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer; | ||
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer; | ||
import com.prgrms.nabmart.domain.item.Item; | ||
import java.time.LocalDateTime; | ||
|
||
public record ItemRedisDto(Long itemId, String name, int price, int discount, | ||
@JsonSerialize(using = LocalDateTimeSerializer.class) | ||
@JsonDeserialize(using = LocalDateTimeDeserializer.class) | ||
LocalDateTime createdAt | ||
) { | ||
|
||
public static ItemRedisDto from(final Item item) { | ||
return new ItemRedisDto( | ||
item.getItemId(), item.getName(), item.getPrice(), item.getDiscount(), | ||
item.getCreatedAt() | ||
); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
94 changes: 94 additions & 0 deletions
94
src/test/java/com/prgrms/nabmart/domain/item/service/ItemCacheServiceTest.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,94 @@ | ||
package com.prgrms.nabmart.domain.item.service; | ||
|
||
import static org.assertj.core.api.AssertionsForClassTypes.assertThat; | ||
|
||
import com.prgrms.nabmart.base.RedisTestContainerConfig; | ||
import com.prgrms.nabmart.domain.category.MainCategory; | ||
import com.prgrms.nabmart.domain.category.SubCategory; | ||
import com.prgrms.nabmart.domain.category.fixture.CategoryFixture; | ||
import com.prgrms.nabmart.domain.item.Item; | ||
import com.prgrms.nabmart.domain.item.service.response.ItemRedisDto; | ||
import com.prgrms.nabmart.domain.item.support.ItemFixture; | ||
import java.util.List; | ||
import lombok.extern.slf4j.Slf4j; | ||
import org.junit.jupiter.api.AfterEach; | ||
import org.junit.jupiter.api.BeforeEach; | ||
import org.junit.jupiter.api.DisplayName; | ||
import org.junit.jupiter.api.Nested; | ||
import org.junit.jupiter.api.Test; | ||
import org.springframework.beans.factory.annotation.Autowired; | ||
import org.springframework.boot.test.context.SpringBootTest; | ||
import org.springframework.data.redis.core.RedisCallback; | ||
import org.springframework.data.redis.core.RedisTemplate; | ||
import org.springframework.transaction.annotation.Transactional; | ||
|
||
@Slf4j | ||
@Transactional | ||
@SpringBootTest | ||
class ItemCacheServiceTest extends RedisTestContainerConfig { | ||
|
||
@Autowired | ||
private ItemCacheService itemCacheService; | ||
|
||
@Autowired | ||
private RedisTemplate<String, ItemRedisDto> redisTemplate; | ||
|
||
private static final String NEW_PRODUCTS_KEY = "new_products"; | ||
Item item; | ||
MainCategory mainCategory; | ||
SubCategory subCategory; | ||
|
||
@BeforeEach | ||
void setUp() { | ||
mainCategory = CategoryFixture.mainCategory(); | ||
subCategory = CategoryFixture.subCategory(mainCategory); | ||
item = ItemFixture.item(mainCategory, subCategory); | ||
} | ||
|
||
@AfterEach | ||
public void cleanupRedis() { | ||
redisTemplate.execute((RedisCallback<Object>) connection -> { | ||
connection.flushDb(); | ||
return null; | ||
}); | ||
} | ||
|
||
@Nested | ||
@DisplayName("새롭게 등록된 상품을 Redis에도 등록한다.") | ||
class SaveItemRedisTest { | ||
|
||
@Test | ||
@DisplayName("성공") | ||
void saveNewItem() { | ||
// Given | ||
ItemRedisDto itemRedisDto = ItemRedisDto.from(item); | ||
|
||
// When | ||
itemCacheService.saveNewItem(itemRedisDto); | ||
|
||
// Then | ||
assertThat(redisTemplate.opsForList().size(NEW_PRODUCTS_KEY)).isEqualTo(1); | ||
} | ||
} | ||
|
||
@Nested | ||
@DisplayName("Redis에서 신상품을 조회한다.") | ||
class getNewItemsTest { | ||
|
||
@Test | ||
@DisplayName("성공") | ||
void getNewItems() { | ||
// Given | ||
ItemRedisDto itemRedisDto = ItemRedisDto.from(item); | ||
List<ItemRedisDto> expectedItems = List.of(itemRedisDto); | ||
|
||
itemCacheService.saveNewItem(itemRedisDto); | ||
|
||
// When | ||
List<ItemRedisDto> result = itemCacheService.getNewItems(); | ||
|
||
// Then | ||
assertThat(result).isEqualTo(expectedItems); | ||
} | ||
} | ||
} |
Oops, something went wrong.