Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Feature/413] "모임 활동 조회" API 캐시 적용 #414

Merged
merged 11 commits into from
Nov 24, 2024
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
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.context.properties.ConfigurationPropertiesScan;
import org.springframework.cache.annotation.EnableCaching;

@EnableCaching
@SpringBootApplication
@ConfigurationPropertiesScan
public class NamoApplication {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ public class ActivityController {
NOT_FOUND_SCHEDULE_FAILURE,
})
@GetMapping("/{scheduleId}")
public ResponseDto<List<ActivityResponse.ActivityInfoDto>> getActivity(
public ResponseDto<ActivityResponse.ActivityInfoDtoList> getActivity(
@AuthenticationPrincipal SecurityUserDetails memberInfo,
@Parameter(description = "활동을 조회할 스케줄 ID 입니다..", example = "1")
@PathVariable Long scheduleId) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.List;
import java.util.stream.Collectors;

import com.namo.spring.application.external.api.record.dto.ActivityResponse;
Expand All @@ -12,6 +13,16 @@

public class ActivityResponseConverter {

public static ActivityResponse.ActivityInfoDtoList toActivityInfoDtoList(List<Activity> activity){
List<ActivityResponse.ActivityInfoDto> list = activity.stream()
.map(ActivityResponseConverter::toActivityInfoDto)
.toList();

return ActivityResponse.ActivityInfoDtoList.builder()
.activityInfoDto(list)
.build();
}

public static ActivityResponse.ActivityInfoDto toActivityInfoDto(Activity activity) {
return ActivityResponse.ActivityInfoDto.builder()
.activityId(activity.getId())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,23 +4,44 @@
import java.time.LocalDateTime;
import java.util.List;

import com.fasterxml.jackson.annotation.JsonFormat;
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 io.swagger.v3.oas.annotations.media.Schema;

import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;

public class ActivityResponse {

@Builder
@Getter
@AllArgsConstructor
@NoArgsConstructor
public static class ActivityInfoDtoList{
private List<ActivityInfoDto> activityInfoDto;
}

@Builder
@Getter
@AllArgsConstructor
@NoArgsConstructor
@Schema(description = "활동 조회 DTO")
public static class ActivityInfoDto {
private Long activityId;
private String activityTitle;
private List<ActivityParticipantDto> activityParticipants;
@JsonSerialize(using = LocalDateTimeSerializer.class)
@JsonDeserialize(using = LocalDateTimeDeserializer.class)
@JsonFormat(shape= JsonFormat.Shape.STRING, pattern="yyyy-MM-dd HH:mm")
private LocalDateTime activityStartDate;
@JsonSerialize(using = LocalDateTimeSerializer.class)
@JsonDeserialize(using = LocalDateTimeDeserializer.class)
@JsonFormat(shape= JsonFormat.Shape.STRING, pattern="yyyy-MM-dd HH:mm")
private LocalDateTime activityEndDate;
private ActivityLocationDto activityLocation;
private BigDecimal totalAmount;
Expand All @@ -31,6 +52,7 @@ public static class ActivityInfoDto {
@Builder
@Getter
@AllArgsConstructor
@NoArgsConstructor
@Schema(description = "활동 참여자 DTO")
public static class ActivityParticipantDto {
private Long participantId;
Expand All @@ -41,6 +63,7 @@ public static class ActivityParticipantDto {
@Builder
@Getter
@AllArgsConstructor
@NoArgsConstructor
@Schema(description = "활동 장소 DTO")
public static class ActivityLocationDto {
@Schema(description = "카카오맵 좌표계 상의 x 좌표")
Expand Down Expand Up @@ -76,6 +99,7 @@ public static class ActivitySettlementParticipant {
@Builder
@Getter
@AllArgsConstructor
@NoArgsConstructor
@Schema(description = "활동 이미지 정보 DTO")
public static class ActivityImageDto {
@Schema(description = "정렬 순서", example = "1")
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.namo.spring.application.external.api.record.serivce;

import org.springframework.cache.annotation.CacheEvict;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;

Expand Down Expand Up @@ -53,6 +54,7 @@ public Activity getMyActivity(Long memberId, Long activityId) {
* @param request
* @return
*/
@CacheEvict(value = "ActivityInfoDtoList", key = "#scheduleId")
public Activity createActivity(Long memberId, Long scheduleId, ActivityRequest.CreateActivityDto request) {
Participant myParticipant = participantManageService.getParticipantByMemberAndSchedule(memberId, scheduleId);
Activity activity = activityService.createActivity(ActivityConverter.toActivity(myParticipant.getSchedule(), request));
Expand All @@ -66,18 +68,23 @@ public Activity createActivity(Long memberId, Long scheduleId, ActivityRequest.C
/**
* 활동을 업데이트 하는 메서드입니다.
* 활동 제목, 시작-종료시간, 장소, 이미지를 업데이트 합니다.
* 캐시를 무효화 합니다.
* !! 이미지 업데이트 책임은 activityImageManageService 에 있습니다.
*
* @param activity
* @param request
* @param scheduleId
*/
public void updateActivity(Activity activity, ActivityRequest.UpdateActivityDto request) {
@CacheEvict(value = "ActivityInfoDtoList", key = "#scheduleId")
public void updateActivity(Activity activity, ActivityRequest.UpdateActivityDto request, Long scheduleId) {
activity.updateInfo(request.getTitle(), request.getActivityStartDate(), request.getActivityEndDate());
Location newLocation = ActivityConverter.toLocation(request.getLocation());
activity.updateLocation(newLocation);
activityImageManageService.updateImages(activity, request);
}

public void removeActivity(Activity activity) {
@CacheEvict(value = "ActivityInfoDtoList", key = "#scheduleId")
public void removeActivity(Activity activity, Long scheduleId) {
activity.getActivityImages().forEach(activityImage ->
activityImageManageService.deleteFromCloud(activityImage.getId()));
activityImageManageService.deleteImages(activity);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import java.util.List;

import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

Expand All @@ -25,14 +26,12 @@ public class ActivityUseCase {
private final ActivityManageService activityManageService;
private final ActivityParticipantManageService activityParticipantManageService;

@Cacheable(value = "ActivityInfoDtoList", key = "#scheduleId", cacheManager = "redisCacheManager", unless = "#result==null")
@Transactional(readOnly = true)
public List<ActivityResponse.ActivityInfoDto> getActivities(Long memberId, Long scheduleId) {
public ActivityResponse.ActivityInfoDtoList getActivities(Long memberId, Long scheduleId) {
Schedule schedule = participantManageService.getParticipantByMemberAndSchedule(memberId, scheduleId).getSchedule();
List<Activity> activities = schedule.getActivityList();

return activities.stream()
.map(ActivityResponseConverter::toActivityInfoDto)
.toList();
return ActivityResponseConverter.toActivityInfoDtoList(activities);
}

@Transactional(readOnly = true)
Expand All @@ -58,7 +57,8 @@ public void createActivity(Long memberId, Long scheduleId, ActivityRequest.Creat
@Transactional
public void updateActivity(Long memberId, Long activityId, ActivityRequest.UpdateActivityDto request) {
Activity target = activityManageService.getMyActivity(memberId, activityId);
activityManageService.updateActivity(target, request);
Long scheduleId = target.getSchedule().getId();
activityManageService.updateActivity(target, request, scheduleId);
}

@Transactional
Expand All @@ -85,6 +85,7 @@ public void updateActivitySettlement(Long memberId, Long activityId,
@Transactional
public void deleteActivity(Long memberId, Long activityId) {
Activity target = activityManageService.getMyActivity(memberId, activityId);
activityManageService.removeActivity(target);
Long scheduleId = target.getSchedule().getId();
activityManageService.removeActivity(target, scheduleId);
}
}
2 changes: 2 additions & 0 deletions storage/db-mysql-v2/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -15,4 +15,6 @@ dependencies {
// flyway
implementation 'org.flywaydb:flyway-core'
implementation 'org.flywaydb:flyway-mysql'

implementation 'com.fasterxml.jackson.datatype:jackson-datatype-jsr310'
}
Original file line number Diff line number Diff line change
Expand Up @@ -63,18 +63,12 @@ public RedisTemplate<String, Object> redisTemplate() {

@Bean
@DomainRedisCacheManager
public RedisCacheManager redisCacheManager(
@DomainRedisConnectionFactory RedisConnectionFactory cf
) {
public RedisCacheManager redisCacheManager(@DomainRedisConnectionFactory RedisConnectionFactory cf) {
RedisCacheConfiguration cacheConfiguration =
RedisCacheConfiguration.defaultCacheConfig()
.serializeKeysWith(
RedisSerializationContext.SerializationPair.fromSerializer(new StringRedisSerializer())
)
.serializeValuesWith(
RedisSerializationContext.SerializationPair.fromSerializer(new GenericJackson2JsonRedisSerializer())
)
.entryTtl(Duration.ofHours(1L));
.serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(new StringRedisSerializer()))
.serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(new GenericJackson2JsonRedisSerializer()))
.entryTtl(Duration.ofHours(3L));

return RedisCacheManager.RedisCacheManagerBuilder.fromConnectionFactory(cf)
.cacheDefaults(cacheConfiguration)
Expand Down
Loading