diff --git a/src/main/java/com/anywayclear/controller/AlarmController.java b/src/main/java/com/anywayclear/controller/AlarmController.java index bf575ab..25cc09b 100644 --- a/src/main/java/com/anywayclear/controller/AlarmController.java +++ b/src/main/java/com/anywayclear/controller/AlarmController.java @@ -33,10 +33,9 @@ public ResponseEntity createTopic(@PathVariable String topicName) { return ResponseEntity.created(URI.create("api/alarms/" + topic)).build(); } - @PostMapping(value = "/topic/{topicName}/subscribe", produces = "text/event-stream") + @GetMapping(value = "/topic/{topicName}/subscribe", produces = "text/event-stream") public ResponseEntity subscribeTopic(@PathVariable String topicName, @AuthenticationPrincipal OAuth2User oAuth2User, @RequestHeader(value = "Last-Event_ID", required = false) String lastEventId, HttpServletResponse response) { -// alarmService.subscribeTopic(topicName); System.out.println("OAuth UserName : " + oAuth2User); return new ResponseEntity<>(alarmService.subscribeTopic(topicName, "username", lastEventId, LocalDateTime.now()), HttpStatus.OK); } @@ -58,7 +57,7 @@ public ResponseEntity getSubscribeAlarmList(@PathVariable Str return ResponseEntity.ok(alarmService.getSubscribeAlarmList(memberId)); } @GetMapping("/{memberId}/dibs") - public ResponseEntity getDibAlarmList(@PathVariable String memberId, @PageableDefault(size = 10, sort = "id", direction = Sort.Direction.DESC) Pageable pageable) { - return ResponseEntity.ok(alarmService.getDibAlarmList(memberId, pageable)); + public ResponseEntity getDibAlarmList(@PathVariable String memberId) { + return ResponseEntity.ok(alarmService.getDibAlarmList(memberId)); } } diff --git a/src/main/java/com/anywayclear/controller/DibController.java b/src/main/java/com/anywayclear/controller/DibController.java index f93f7b6..1b3ec3e 100644 --- a/src/main/java/com/anywayclear/controller/DibController.java +++ b/src/main/java/com/anywayclear/controller/DibController.java @@ -1,8 +1,11 @@ package com.anywayclear.controller; import com.anywayclear.dto.request.DibCreateRequest; +import com.anywayclear.dto.response.DibResponse; import com.anywayclear.dto.response.DibResponseList; import com.anywayclear.dto.response.IsDibResponse; +import com.anywayclear.dto.response.MultiResponse; +import com.anywayclear.entity.Dib; import com.anywayclear.service.DibService; import org.springframework.data.domain.Pageable; import org.springframework.data.domain.Sort; @@ -30,9 +33,9 @@ public ResponseEntity createDib(@Valid @RequestBody DibCreateRequest reque return ResponseEntity.created(URI.create("api/dibs/" + id)).build(); } - @GetMapping - public ResponseEntity getDibList(@RequestParam(name = "userId") String userId, @PageableDefault(size = 10, sort = "id", direction = Sort.Direction.DESC) Pageable pageable) { - return ResponseEntity.ok(dibService.getDibList(userId, pageable)); + @GetMapping("/{userId}") + public ResponseEntity> getDibList(@PathVariable("userId") String userId, Pageable pageable) { + return ResponseEntity.ok(dibService.getDibPage(userId, pageable)); } @GetMapping("/{produce-id}/member") diff --git a/src/main/java/com/anywayclear/dto/response/DibResponse.java b/src/main/java/com/anywayclear/dto/response/DibResponse.java index a9ab261..cff99b0 100644 --- a/src/main/java/com/anywayclear/dto/response/DibResponse.java +++ b/src/main/java/com/anywayclear/dto/response/DibResponse.java @@ -44,14 +44,14 @@ public DibResponse(Long id, String title, int startPrice, String image, String s this.userId = userId; } - public static DibResponse toResponse(Produce produce) { + public static DibResponse toResponse(Dib dib) { return DibResponse.builder() - .id(produce.getId()) - .title(produce.getName()) - .startPrice(produce.getStartPrice()) - .image(produce.getImage()) - .sellerName(produce.getSeller().getNickname()) - .userId(produce.getSeller().getUserId()) + .id(dib.getProduce().getId()) + .title(dib.getProduce().getName()) + .startPrice(dib.getProduce().getStartPrice()) + .image(dib.getProduce().getImage()) + .sellerName(dib.getProduce().getSeller().getNickname()) + .userId(dib.getProduce().getSeller().getUserId()) .build(); } } diff --git a/src/main/java/com/anywayclear/dto/response/DibResponseList.java b/src/main/java/com/anywayclear/dto/response/DibResponseList.java index a4eea6a..67456ab 100644 --- a/src/main/java/com/anywayclear/dto/response/DibResponseList.java +++ b/src/main/java/com/anywayclear/dto/response/DibResponseList.java @@ -15,13 +15,11 @@ @Getter @NoArgsConstructor(access = AccessLevel.PRIVATE) public class DibResponseList { - private Page dibResponseList; + private List dibResponseList; - public DibResponseList(final List dibList, Pageable pageable) { - this.dibResponseList = new PageImpl<>(dibList.stream() + public DibResponseList(final List dibList) { + this.dibResponseList = dibList.stream() .map(DibResponse::toResponse) - .collect(Collectors.toList()), - pageable, - dibList.size()); + .collect(Collectors.toList()); } } diff --git a/src/main/java/com/anywayclear/repository/DibRepository.java b/src/main/java/com/anywayclear/repository/DibRepository.java index 5bff690..1cd8c50 100644 --- a/src/main/java/com/anywayclear/repository/DibRepository.java +++ b/src/main/java/com/anywayclear/repository/DibRepository.java @@ -12,7 +12,9 @@ public interface DibRepository extends JpaRepository { - List findAllByConsumer(Member member); // 찜 중인 농산물 찾기 + Page findAllByConsumer(Member member, Pageable pageable); // 찜 중인 농산물 찾기 (페이지) + + List findAllByConsumer(Optional member); // 찜 중인 농산물 찾기 List findAllByProduce(Produce produce); // 해당 농산물을 찜한 소비자 찾기 diff --git a/src/main/java/com/anywayclear/repository/SSEInMemoryRepository.java b/src/main/java/com/anywayclear/repository/SSEInMemoryRepository.java index 3be6d94..d6eb323 100644 --- a/src/main/java/com/anywayclear/repository/SSEInMemoryRepository.java +++ b/src/main/java/com/anywayclear/repository/SSEInMemoryRepository.java @@ -10,20 +10,17 @@ import java.util.stream.Collectors; @Repository -public class SSEInMemoryRepository implements SSERepository{ +public class SSEInMemoryRepository{ private final Map sseEmitterMap = new ConcurrentHashMap<>(); - @Override public void put(String key, SseEmitter sseEmitter) { sseEmitterMap.put(key, sseEmitter); } - @Override public Optional get(String key) { return Optional.ofNullable(sseEmitterMap.get(key)); } - @Override public List getListByKeyPrefix(String keyPrefix){ return sseEmitterMap.keySet().stream() .filter(key -> key.startsWith(keyPrefix)) @@ -31,16 +28,19 @@ public List getListByKeyPrefix(String keyPrefix){ .collect(Collectors.toList()); } - @Override public List getKeyListByKeyPrefix(String keyPrefix){ return sseEmitterMap.keySet().stream() .filter(key -> key.startsWith(keyPrefix)) .collect(Collectors.toList()); } - - @Override public void remove(String key) { sseEmitterMap.remove(key); } + + public void deleteAllByKeyPrefix(String keyPrefix) { + sseEmitterMap.forEach((key, emitter) -> { + if (key.startsWith(keyPrefix)) sseEmitterMap.remove(key); + }); + } } diff --git a/src/main/java/com/anywayclear/repository/SSERepository.java b/src/main/java/com/anywayclear/repository/SSERepository.java index ba5933f..085f2ad 100644 --- a/src/main/java/com/anywayclear/repository/SSERepository.java +++ b/src/main/java/com/anywayclear/repository/SSERepository.java @@ -19,4 +19,6 @@ public interface SSERepository { List getKeyListByKeyPrefix(String keyPrefix); void remove(String key); + + void deleteAllByKeyPrefix(String keyPrefix); } diff --git a/src/main/java/com/anywayclear/service/AlarmService.java b/src/main/java/com/anywayclear/service/AlarmService.java index 3558982..fbe89b9 100644 --- a/src/main/java/com/anywayclear/service/AlarmService.java +++ b/src/main/java/com/anywayclear/service/AlarmService.java @@ -2,7 +2,12 @@ import com.anywayclear.dto.response.*; import com.anywayclear.entity.Alarm; +import com.anywayclear.entity.Dib; +import com.anywayclear.entity.Member; +import com.anywayclear.repository.DibRepository; +import com.anywayclear.repository.MemberRepository; import com.anywayclear.repository.SSEInMemoryRepository; +import com.anywayclear.repository.SubscribeRepository; import lombok.RequiredArgsConstructor; import org.springframework.data.domain.Pageable; import org.springframework.data.redis.core.RedisTemplate; @@ -14,11 +19,8 @@ import javax.annotation.PostConstruct; import java.io.IOException; import java.time.LocalDateTime; -import java.util.HashSet; +import java.util.*; -import java.util.List; -import java.util.Map; -import java.util.Set; import java.util.concurrent.ConcurrentHashMap; import java.util.stream.Collectors; @@ -42,8 +44,11 @@ public class AlarmService { // 구독 목록 불러오기 위한 서비스 private final SubscribeService subscribeService; - // 찜 목록 불러오기 위한 서비스 - private final DibService dibService; + // 찜 목록 불러오기 위한 리포지토리 + private final DibRepository dibRepository; + + // 유저Id로 유저 객체를 찾기 위한 리포지토리 + private final MemberRepository memberRepository; // topic 이름으로 topic 정보를 가져와 메시지를 발송할 수 있도록 Map에 저장 private Map channels; @@ -63,23 +68,9 @@ public String createTopic(String topicName) { // 신규 Topic을 생성하고 Li } public SseEmitter subscribeTopic(String topicName, String userId, String lastEventId, LocalDateTime now) { -// RedisPubSubAdapter listener = new RedisPubSubAdapter() { -// @Override -// public void message(String channel, String message) { -// System.out.println(String.format("subscribe -> Channel: %s, Message: %s", channel, message)); -// } -// }; -// -// StatefulRedisPubSubConnection pubsubConn = Main.redisClient.connectPubSub(); -// pubsubConn.addListener(listener); -// RedisPubSubAsyncCommands async = pubsubConn.async(); -// async.subscribe(topicName); -// -//// application flow continues - // Pub/Sub Topic 찾아서 리스너 연결 - ChannelTopic topic = channels.get(topicName); - redisMessageListener.addMessageListener(redisSubscribeService, topic); +// ChannelTopic topic = channels.get(topicName); +// redisMessageListener.addMessageListener(redisSubscribeService, topic); // SSE 연결 // emitter에 키에 토픽, 유저 정보를 담기 @@ -100,7 +91,7 @@ public SseEmitter subscribeTopic(String topicName, String userId, String lastEve sseRepository.put(key, emitter); try { emitter.send(SseEmitter.event() - .name("CONNCECTED") + .name("CONNCECTED") // 클라이언트에서 식별하는 이벤트 이름 .id(key) .data("subscribe")); } catch (IOException exception) { @@ -147,14 +138,15 @@ public AlarmResponseList getSubscribeAlarmList(String memberId) { // 해당 유 return new AlarmResponseList(alarmList); } - public AlarmResponseList getDibAlarmList(String memberId, Pageable pageable) { // 해당 유저의 알림 리스트 불러오기 + public AlarmResponseList getDibAlarmList(String memberId) { // 해당 유저의 알림 리스트 불러오기 // 패턴 매칭 사용 -> member:memberId:alarm:* // [1] 유저의 찜 목록 불러오기 - DibResponseList dibResponseList = dibService.getDibList(memberId, pageable); + Optional member = memberRepository.findByUserId(memberId); + List dibList = dibRepository.findAllByConsumer(member); Set keys = new HashSet<>(); // Set을 사용하여 중복된 값 제거 - for (DibResponse response : dibResponseList.getDibResponseList()) { - String produce = response.getId().toString(); // Response 객체에서 sender 필드 값을 추출 + for (Dib dib : dibList) { + String produce = dib.getProduce().getId().toString(); // Response 객체에서 sender 필드 값을 추출 keys.add(produce); // keys 집합에 sender 값 추가 } diff --git a/src/main/java/com/anywayclear/service/DibService.java b/src/main/java/com/anywayclear/service/DibService.java index 67f7722..4a736f5 100644 --- a/src/main/java/com/anywayclear/service/DibService.java +++ b/src/main/java/com/anywayclear/service/DibService.java @@ -4,6 +4,7 @@ import com.anywayclear.dto.response.DibResponse; import com.anywayclear.dto.response.DibResponseList; import com.anywayclear.dto.response.IsDibResponse; +import com.anywayclear.dto.response.MultiResponse; import com.anywayclear.entity.Dib; import com.anywayclear.entity.Member; import com.anywayclear.entity.Produce; @@ -45,16 +46,14 @@ public Long createDib(DibCreateRequest request) { public DibResponse getDib(Long id) { Dib dib = dibRepository.findById(id).orElseThrow(() -> new RuntimeException("아이디가 없습니다.")); - return DibResponse.toResponse(dib.getProduce()); + return DibResponse.toResponse(dib); } - public DibResponseList getDibList(String userId, Pageable pageable) { // 찜 중인 농산물 리스트 반환 + public MultiResponse getDibPage(String userId, Pageable pageable) { // 찜 중인 농산물 리스트 반환 Member member = memberRepository.findByUserId(userId).orElseThrow(() -> new RuntimeException("해당 userId의 유저가 없습니다.")); - List dibList = dibRepository.findAllByConsumer(member) - .stream() - .map(Dib::getProduce) - .collect(Collectors.toList()); - return new DibResponseList(dibList, pageable); + Page dibPage = dibRepository.findAllByConsumer(member, pageable); + List dibResponseList = dibPage.map(DibResponse::toResponse).getContent(); + return new MultiResponse<>(dibResponseList, dibPage); } public IsDibResponse getIsDib(String userId, long produceId) {