Skip to content

Commit

Permalink
Merge pull request #173 from TRIP-Side-Project/dev
Browse files Browse the repository at this point in the history
pr for merge
  • Loading branch information
kwondongwook authored Dec 29, 2023
2 parents d14fd50 + 74f11e3 commit 1890c42
Show file tree
Hide file tree
Showing 9 changed files with 63 additions and 1,149 deletions.
26 changes: 13 additions & 13 deletions src/main/java/com/api/trip/common/sse/emitter/SseEmitterMap.java
Original file line number Diff line number Diff line change
Expand Up @@ -15,40 +15,40 @@
@Slf4j
public class SseEmitterMap {

private final Map<Long, SseEmitter> sseEmitterMap = new ConcurrentHashMap<>();
private final Map<String, SseEmitter> sseEmitterMap = new ConcurrentHashMap<>();

public void put(Long memberId, SseEmitter sseEmitter) {
sseEmitter.onCompletion(() -> remove(memberId));
public void put(String email, SseEmitter sseEmitter) {
sseEmitter.onCompletion(() -> remove(email));
sseEmitter.onTimeout(sseEmitter::complete);
sseEmitterMap.put(memberId, sseEmitter);
log.info("connected with {}, the number of connections is {}", memberId, sseEmitterMap.size());
sseEmitterMap.put(email, sseEmitter);
log.info("connected with {}, the number of connections is {}", email, sseEmitterMap.size());
}

public void remove(Long memberId) {
sseEmitterMap.remove(memberId);
log.info("disconnected with {}, the number of connections is {}", memberId, sseEmitterMap.size());
public void remove(String email) {
sseEmitterMap.remove(email);
log.info("disconnected with {}, the number of connections is {}", email, sseEmitterMap.size());
}

public void send(Long memberId, String eventName, Object eventData) {
SseEmitter sseEmitter = sseEmitterMap.get(memberId);
public void send(String email, String eventName, Object eventData) {
SseEmitter sseEmitter = sseEmitterMap.get(email);
try {
sseEmitter.send(
event()
.name(eventName)
.data(eventData)
);
} catch (IOException | IllegalStateException e) {
remove(memberId);
remove(email);
}
}

public void sendToAll(String eventName, Object eventData) {
SseEventBuilder sseEventBuilder = event().name(eventName).data(eventData);
sseEmitterMap.forEach((memberId, sseEmitter) -> {
sseEmitterMap.forEach((email, sseEmitter) -> {
try {
sseEmitter.send(sseEventBuilder);
} catch (IOException | IllegalStateException e) {
remove(memberId);
remove(email);
}
});
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
package com.api.trip.domain.notification.controller;

import com.api.trip.common.exception.CustomException;
import com.api.trip.common.exception.ErrorCode;
import com.api.trip.domain.member.repository.MemberRepository;
import com.api.trip.domain.notification.controller.dto.GetMyNotificationsResponse;
import com.api.trip.common.sse.emitter.SseEmitterMap;
import com.api.trip.domain.notification.controller.dto.DeleteNotificationRequest;
import com.api.trip.domain.notification.controller.dto.GetMyNotificationsResponse;
import com.api.trip.domain.notification.controller.dto.ReadNotificationRequest;
import com.api.trip.domain.notification.service.NotificationService;
import lombok.RequiredArgsConstructor;
import org.springframework.http.MediaType;
Expand All @@ -20,46 +19,35 @@
@RequiredArgsConstructor
public class NotificationController {

private final MemberRepository memberRepository;
private final NotificationService notificationService;
private final SseEmitterMap sseEmitterMap;

@GetMapping(value = "/connect", produces = MediaType.TEXT_EVENT_STREAM_VALUE)
public ResponseEntity<SseEmitter> connect() {
String email = SecurityContextHolder.getContext().getAuthentication().getName();
Long memberId = memberRepository.findByEmail(email)
.orElseThrow(() -> new CustomException(ErrorCode.UNAUTHORIZED))
.getId();

SseEmitter sseEmitter = new SseEmitter(3600000L);
sseEmitterMap.put(memberId, sseEmitter);
sseEmitterMap.send(memberId, "connect", LocalDateTime.now());
sseEmitterMap.put(email, sseEmitter);
sseEmitterMap.send(email, "connect", LocalDateTime.now());
return ResponseEntity.ok(sseEmitter);
}

@GetMapping("/send-to-all")
public void sendToAll(@RequestParam String message) {
String email = SecurityContextHolder.getContext().getAuthentication().getName();
sseEmitterMap.sendToAll("send-to-all", email + ": " + message);
}

@GetMapping("/me")
public ResponseEntity<GetMyNotificationsResponse> getMyNotifications() {
String email = SecurityContextHolder.getContext().getAuthentication().getName();
return ResponseEntity.ok(notificationService.getMyNotifications(email));
}

@PatchMapping("/{notificationId}")
public ResponseEntity<Void> readNotification(@PathVariable Long notificationId) {
@PatchMapping
public ResponseEntity<Void> readNotification(@RequestBody ReadNotificationRequest request) {
String email = SecurityContextHolder.getContext().getAuthentication().getName();
notificationService.readNotification(notificationId, email);
notificationService.readNotification(request, email);
return ResponseEntity.ok().build();
}

@DeleteMapping("/{notificationId}")
public ResponseEntity<Void> deleteNotification(@PathVariable Long notificationId) {
@DeleteMapping
public ResponseEntity<Void> deleteNotification(@RequestBody DeleteNotificationRequest request) {
String email = SecurityContextHolder.getContext().getAuthentication().getName();
notificationService.deleteNotification(notificationId, email);
notificationService.deleteNotification(request, email);
return ResponseEntity.ok().build();
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package com.api.trip.domain.notification.controller.dto;

import jakarta.validation.constraints.NotNull;
import lombok.Getter;

@Getter
public class DeleteNotificationRequest {

@NotNull(message = "itemId를 입력해 주세요.")
private Long itemId;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package com.api.trip.domain.notification.controller.dto;

import jakarta.validation.constraints.NotNull;
import lombok.Getter;

@Getter
public class ReadNotificationRequest {

@NotNull(message = "itemId를 입력해 주세요.")
private Long itemId;
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,11 @@
import org.springframework.data.jpa.repository.JpaRepository;

import java.util.List;
import java.util.Optional;

public interface NotificationRepository extends JpaRepository<Notification, Long>, NotificationRepositoryCustom {

List<Notification> findAllByMember(Member member);

Optional<Notification> findByMemberIdAndItemId(Long memberId, Long itemId);
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,9 @@
import com.api.trip.domain.itemtag.model.ItemTag;
import com.api.trip.domain.member.model.Member;
import com.api.trip.domain.member.repository.MemberRepository;
import com.api.trip.domain.notification.controller.dto.DeleteNotificationRequest;
import com.api.trip.domain.notification.controller.dto.GetMyNotificationsResponse;
import com.api.trip.domain.notification.controller.dto.ReadNotificationRequest;
import com.api.trip.domain.notification.domain.Notification;
import com.api.trip.domain.notification.repository.NotificationRepository;
import lombok.RequiredArgsConstructor;
Expand All @@ -25,17 +27,17 @@ public class NotificationService {
private final NotificationRepository notificationRepository;
private final InterestTagService interestTagService;

public void createNotification(Item item, List<String> tagNames){

public void createNotification(Item item, List<String> tagNames) {
List<Member> receivers = interestTagService.getMemberByTags(tagNames);

receivers.stream().forEach(member -> {
notificationRepository.save(Notification.builder()
.item(item)
.member(member).build());
receivers.forEach(member -> {
notificationRepository.save(
Notification.builder()
.item(item)
.member(member)
.build()
);
});


}

@Transactional(readOnly = true)
Expand All @@ -54,31 +56,23 @@ public GetMyNotificationsResponse getMyNotifications(String email) {
return GetMyNotificationsResponse.of(notifications, itemTags);
}

public void readNotification(Long notificationId, String email) {
public void readNotification(ReadNotificationRequest request, String email) {
Member member = memberRepository.findByEmail(email)
.orElseThrow(() -> new CustomException(ErrorCode.UNAUTHORIZED));

Notification notification = notificationRepository.findById(notificationId)
Notification notification = notificationRepository.findByMemberIdAndItemId(member.getId(), request.getItemId())
.orElseThrow(() -> new CustomException(ErrorCode.NOTIFICATION_NOT_FOUND));

if (notification.getMember() == member) {
throw new CustomException(ErrorCode.FORBIDDEN);
}

notification.read();
}

public void deleteNotification(Long notificationId, String email) {
public void deleteNotification(DeleteNotificationRequest request, String email) {
Member member = memberRepository.findByEmail(email)
.orElseThrow(() -> new CustomException(ErrorCode.UNAUTHORIZED));

Notification notification = notificationRepository.findById(notificationId)
Notification notification = notificationRepository.findByMemberIdAndItemId(member.getId(), request.getItemId())
.orElseThrow(() -> new CustomException(ErrorCode.NOTIFICATION_NOT_FOUND));

if (notification.getMember() == member) {
throw new CustomException(ErrorCode.FORBIDDEN);
}

notificationRepository.delete(notification);
}

Expand Down
3 changes: 0 additions & 3 deletions src/main/resources/application.yml
Original file line number Diff line number Diff line change
@@ -1,9 +1,6 @@
spring:
profiles:
active: dev
datasource:
hikari:
maximum-pool-size: 4
h2:
console:
enabled: true
Expand Down
42 changes: 0 additions & 42 deletions src/main/resources/static/index.html

This file was deleted.

Loading

0 comments on commit 1890c42

Please sign in to comment.