Skip to content

Commit 62bc9c6

Browse files
authored
Merge branch 'dev' into feat/#80
2 parents c84017f + c440d7b commit 62bc9c6

File tree

9 files changed

+187
-76
lines changed

9 files changed

+187
-76
lines changed

β€Žbuild.gradle.ktsβ€Ž

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,9 @@ dependencies {
4747

4848
//redis
4949
implementation("org.springframework.boot:spring-boot-starter-data-redis")
50+
implementation ("org.redisson:redisson-spring-boot-starter:3.42.0") // redis message broker(lock)
51+
implementation ("org.springframework.session:spring-session-data-redis")
52+
5053

5154
// Security
5255
implementation("org.springframework.boot:spring-boot-starter-security")

β€Žsrc/main/java/cmf/commitField/domain/chat/chatRoom/repository/ChatRoomRepository.javaβ€Ž

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,10 @@
11
package cmf.commitField.domain.chat.chatRoom.repository;
22

33
import cmf.commitField.domain.chat.chatRoom.entity.ChatRoom;
4-
import jakarta.persistence.LockModeType;
5-
import jakarta.persistence.QueryHint;
64
import org.springframework.data.domain.Page;
75
import org.springframework.data.domain.Pageable;
86
import org.springframework.data.jpa.repository.JpaRepository;
9-
import org.springframework.data.jpa.repository.Lock;
107
import org.springframework.data.jpa.repository.Query;
11-
import org.springframework.data.jpa.repository.QueryHints;
128
import org.springframework.data.repository.query.Param;
139
import org.springframework.stereotype.Repository;
1410

@@ -17,8 +13,8 @@
1713
@Repository
1814
public interface ChatRoomRepository extends JpaRepository<ChatRoom, Long> {
1915

20-
@Lock(LockModeType.PESSIMISTIC_WRITE)
21-
@QueryHints({@QueryHint(name = "javax.persistence.lock.timeout", value ="1000")})
16+
// @Lock(LockModeType.PESSIMISTIC_WRITE)
17+
// @QueryHints({@QueryHint(name = "javax.persistence.lock.timeout", value ="1000")})
2218
Optional<ChatRoom> findById(Long aLong);
2319

2420
Optional<ChatRoom> findChatRoomById(Long id);

β€Žsrc/main/java/cmf/commitField/domain/chat/chatRoom/service/ChatRoomServiceImpl.javaβ€Ž

Lines changed: 72 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -12,24 +12,33 @@
1212
import cmf.commitField.global.error.ErrorCode;
1313
import cmf.commitField.global.exception.CustomException;
1414
import lombok.RequiredArgsConstructor;
15+
import org.redisson.api.RLock;
16+
import org.redisson.api.RedissonClient;
1517
import org.springframework.data.domain.Page;
1618
import org.springframework.data.domain.Pageable;
1719
import org.springframework.stereotype.Service;
20+
import org.springframework.transaction.annotation.Isolation;
1821
import org.springframework.transaction.annotation.Transactional;
1922

2023
import java.time.LocalDateTime;
2124
import java.util.ArrayList;
2225
import java.util.List;
2326
import java.util.Objects;
27+
import java.util.concurrent.TimeUnit;
2428

2529
@Service
2630
@RequiredArgsConstructor
2731
public class ChatRoomServiceImpl implements ChatRoomService {
2832

2933
private final ChatRoomRepository chatRoomRepository;
34+
35+
private final ChatMessageRepository chatMessageRepository;
36+
3037
private final UserRepository userRepository;
38+
3139
private final UserChatRoomRepository userChatRoomRepository;
32-
private final ChatMessageRepository chatMessageRepository;
40+
41+
private final RedissonClient redissonClient;
3342

3443
@Override
3544
@Transactional
@@ -61,38 +70,6 @@ public void createRoom(ChatRoomRequest chatRoomRequest, Long userId) {
6170
userChatRoomRepository.save(userChatRoom);
6271
}
6372

64-
@Override
65-
@Transactional
66-
public void joinRoom(Long roomId, Long userId) {
67-
// μœ μ € 쑰회
68-
User findUser = userRepository.findById(userId)
69-
.orElseThrow(() -> new CustomException(ErrorCode.NOT_FOUND_USER));
70-
71-
// room 쑰회
72-
ChatRoom chatRoom = chatRoomRepository.findById(roomId)
73-
.orElseThrow(() -> new CustomException(ErrorCode.NOT_FOUND_ROOM));
74-
75-
// ν˜„μž¬ 인원 수 쑰회
76-
Long currentUserCount = userChatRoomRepository.countByChatRoomId(roomId);
77-
// μ±„νŒ…λ°©μ΄ 꽉 찼을 경우 μ˜ˆμ™Έ 처리
78-
if (currentUserCount >= chatRoom.getUserCountMax()) {
79-
throw new CustomException(ErrorCode.ROOM_USER_FULL);
80-
}
81-
82-
// 이미 μ°Έμ—¬ν•œ 방인지 확인
83-
if (userChatRoomRepository.existsByChatRoomIdAndUserId(roomId, userId)) {
84-
throw new CustomException(ErrorCode.ALREADY_JOIN_ROOM);
85-
}
86-
87-
88-
// user_chatroom 관계 생성
89-
UserChatRoom userChatRoom = UserChatRoom.builder()
90-
.user(findUser)
91-
.chatRoom(chatRoom)
92-
.build();
93-
userChatRoomRepository.save(userChatRoom);
94-
}
95-
9673
// λ°© 쑰회 DTO λ³€ν™˜ λ©”μ„œλ“œ μΆ”μΆœ
9774
private static List<ChatRoomDto> getChatRoomDtos(Page<ChatRoom> all) {
9875
List<ChatRoomDto> chatRoomList = new ArrayList<>();
@@ -110,6 +87,7 @@ private static List<ChatRoomDto> getChatRoomDtos(Page<ChatRoom> all) {
11087
return chatRoomList;
11188
}
11289

90+
11391
// μ±„νŒ…λ°© 전체 쑰회
11492
@Override
11593
@Transactional(readOnly = true)
@@ -135,12 +113,57 @@ public List<ChatRoomDto> getUserByRoomPartList(Long userId, Pageable pageable) {
135113
return getChatRoomDtos(allByUserIdAndUserChatRooms);
136114
}
137115

116+
@Override
117+
@Transactional(isolation = Isolation.READ_UNCOMMITTED)
118+
public void joinRoom(Long roomId, Long userId) {
119+
RLock lock = redissonClient.getLock("joinRoomLock:" + roomId);
120+
try {
121+
boolean available = lock.tryLock(1, TimeUnit.SECONDS);
122+
123+
if (!available) {
124+
throw new CustomException(ErrorCode.FAILED_GET_LOCK);
125+
}
126+
// μœ μ € 쑰회
127+
User findUser = getUser(userId);
128+
129+
// room 쑰회
130+
ChatRoom chatRoom = chatRoomRepository.findById(roomId) // lock (κΈ°μ‘΄)
131+
.orElseThrow(() -> new CustomException(ErrorCode.NOT_FOUND_ROOM));
132+
133+
// user_chatroom ν˜„μž¬ 인원 카운트 (λΉ„μ¦ˆλ‹ˆμŠ€ 둜직)
134+
Long currentUserCount = userChatRoomRepository.countNonLockByChatRoomId(roomId); // lock (κΈ°μ‘΄)
135+
136+
List<Long> userChatRoomByChatRoomId = userChatRoomRepository
137+
.findUserChatRoomByChatRoom_Id(roomId);
138+
139+
if (userChatRoomByChatRoomId.contains(userId)) {
140+
throw new CustomException(ErrorCode.ALREADY_JOIN_ROOM);
141+
}
142+
143+
// chatroom μž…μž₯
144+
if (currentUserCount >= chatRoom.getUserCountMax()) {
145+
throw new CustomException(ErrorCode.ROOM_USER_FULL);
146+
}
147+
148+
UserChatRoom userChatRoom = UserChatRoom.builder()
149+
.user(findUser)
150+
.chatRoom(chatRoom)
151+
.build();
152+
userChatRoomRepository.save(userChatRoom);
153+
// λΉ„μ¦ˆλ‹ˆμŠ€ 둜직 끝
154+
} catch (InterruptedException e) {
155+
throw new CustomException(ErrorCode.FAILED_GET_LOCK);
156+
} finally {
157+
lock.unlock();
158+
}
159+
160+
161+
}
162+
138163
@Override
139164
@Transactional
140165
public void outRoom(Long userId, Long roomId) {
141-
ChatRoom room = chatRoomRepository
142-
.findChatRoomById(roomId)
143-
.orElseThrow(() -> new CustomException(ErrorCode.NO_ROOM_FOUND));
166+
ChatRoom room = getChatRoom(roomId);
144167
// λ°©μž₯이 μ•„λ‹ˆλΌλ©΄
145168
if (!Objects.equals(room.getRoomCreator(), userId)) {
146169
userChatRoomRepository.deleteUserChatRoomByChatRoom_IdAndUserId(roomId, userId);
@@ -153,13 +176,10 @@ public void outRoom(Long userId, Long roomId) {
153176

154177
}
155178

156-
157179
@Override
158180
@Transactional
159181
public void deleteRoom(Long userId, Long roomId) {
160-
ChatRoom room = chatRoomRepository
161-
.findChatRoomById(roomId)
162-
.orElseThrow(() -> new CustomException(ErrorCode.NO_ROOM));
182+
ChatRoom room = getChatRoom(roomId);
163183
//λ°©μž₯이 아닐 경우, μ‚­μ œ λΆˆκ°€
164184
if (!Objects.equals(room.getRoomCreator(), userId)) {
165185
throw new CustomException(ErrorCode.NOT_ROOM_CREATOR);
@@ -169,8 +189,19 @@ public void deleteRoom(Long userId, Long roomId) {
169189
userChatRoomRepository.deleteUserChatRoomByChatRoom_Id(roomId);
170190
chatRoomRepository.deleteById(roomId);
171191

172-
}
192+
}
193+
194+
private User getUser(Long userId) {
195+
return userRepository.findById(userId)
196+
.orElseThrow(() -> new CustomException(ErrorCode.NOT_FOUND_USER));
197+
}
173198

174199

200+
private ChatRoom getChatRoom(Long roomId) {
201+
return chatRoomRepository
202+
.findChatRoomById(roomId)
203+
.orElseThrow(() -> new CustomException(ErrorCode.NONE_ROOM));
204+
205+
}
175206

176207
}

β€Žsrc/main/java/cmf/commitField/domain/chat/userChatRoom/repository/UserChatRoomRepository.javaβ€Ž

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,8 @@
11
package cmf.commitField.domain.chat.userChatRoom.repository;
22

33
import cmf.commitField.domain.chat.userChatRoom.entity.UserChatRoom;
4-
import jakarta.persistence.LockModeType;
5-
import jakarta.persistence.QueryHint;
64
import org.springframework.data.jpa.repository.JpaRepository;
7-
import org.springframework.data.jpa.repository.Lock;
85
import org.springframework.data.jpa.repository.Query;
9-
import org.springframework.data.jpa.repository.QueryHints;
106
import org.springframework.data.repository.query.Param;
117
import org.springframework.stereotype.Repository;
128

@@ -15,8 +11,8 @@
1511
@Repository
1612
public interface UserChatRoomRepository extends JpaRepository<UserChatRoom, Long> {
1713

18-
@Lock(LockModeType.PESSIMISTIC_WRITE)
19-
@QueryHints({@QueryHint(name = "javax.persistence.lock.timeout", value = "1000")})
14+
// @Lock(LockModeType.PESSIMISTIC_WRITE)
15+
// @QueryHints({@QueryHint(name = "javax.persistence.lock.timeout", value = "1000")})
2016
Long countByChatRoomId(Long roomId); // 비관적 락
2117

2218
// @Query("select count(*) from UserChatRoom u where u.chatRoom.id = ?1 ")
@@ -32,7 +28,8 @@ public interface UserChatRoomRepository extends JpaRepository<UserChatRoom, Long
3228
boolean existsByChatRoomIdAndUserId(Long roomId, Long userId);
3329
// νŠΉμ • 방에 μ°Έμ—¬ν•œ λͺ¨λ“  UserChatRoom 관계 쑰회
3430
List<UserChatRoom> findByChatRoom_Id(Long chatRoomId);
35-
31+
@Query("select u.user.id from UserChatRoom u where u.chatRoom.id = ?1")
32+
List<Long> findUserChatRoomByChatRoom_Id(Long chatRoomId);
3633

3734

3835
}

β€Žsrc/main/java/cmf/commitField/domain/commit/totalCommit/controller/TotalCommitController.javaβ€Ž

Lines changed: 33 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,10 @@
22

33
import cmf.commitField.domain.commit.totalCommit.dto.TotalCommitResponseDto;
44
import cmf.commitField.domain.commit.totalCommit.service.TotalCommitService;
5+
import cmf.commitField.domain.user.entity.CustomOAuth2User;
56
import lombok.RequiredArgsConstructor;
7+
import org.springframework.security.core.annotation.AuthenticationPrincipal;
68
import org.springframework.web.bind.annotation.GetMapping;
7-
import org.springframework.web.bind.annotation.PathVariable;
89
import org.springframework.web.bind.annotation.RestController;
910

1011
import java.time.LocalDateTime;
@@ -15,41 +16,62 @@
1516
public class TotalCommitController {
1617
private final TotalCommitService totalCommitService;
1718

18-
@GetMapping("/api/commits/{username}")
19-
public TotalCommitResponseDto getTotalCommits(@PathVariable String username) {
19+
// @GetMapping("/api/commits/{username}")
20+
// public TotalCommitResponseDto getTotalCommits(@PathVariable String username) {
21+
// return totalCommitService.getTotalCommitCount(username);
22+
// }
23+
24+
// λ‘œκ·ΈμΈν•œ μ‚¬μš©μžμ˜ username 이용
25+
@GetMapping("/api/commits")
26+
public TotalCommitResponseDto getTotalCommits(@AuthenticationPrincipal CustomOAuth2User oAuth2User) {
27+
String username = oAuth2User.getName(); // CustomOAuth2User의 getName()은 user.getUsername()을 λ°˜ν™˜
28+
2029
return totalCommitService.getTotalCommitCount(username);
2130
}
2231

2332
// λ΄„ μ‹œμ¦Œ(3/1 - 5/31)
24-
@GetMapping("/api/commits/{username}/spring")
25-
public TotalCommitResponseDto getSpringSeasonCommits(@PathVariable String username) {
33+
// @GetMapping("/api/commits/{username}/spring")
34+
// public TotalCommitResponseDto getSpringSeasonCommits(@PathVariable String username) {
35+
// int currentYear = LocalDateTime.now().getYear(); // ν˜„μž¬λŠ” ν…ŒμŠ€νŠΈμš©μœΌλ‘œ 2024 λŒ€μž…
36+
// LocalDateTime since = LocalDateTime.of(2024, 3, 1, 0, 0);
37+
// LocalDateTime until = LocalDateTime.of(2024, 5, 31, 23, 59, 59);
38+
// return totalCommitService.getSeasonCommits(username, since, until);
39+
// }
40+
41+
// λ§ˆμ°¬κ°€μ§€λ‘œ λ‘œκ·ΈμΈν•œ μ‚¬μš©μžμ˜ username 이용
42+
@GetMapping("/api/commits/spring")
43+
public TotalCommitResponseDto getSpringSeasonCommits(@AuthenticationPrincipal CustomOAuth2User oAuth2User) {
44+
String username = oAuth2User.getName();
2645
int currentYear = LocalDateTime.now().getYear(); // ν˜„μž¬λŠ” ν…ŒμŠ€νŠΈμš©μœΌλ‘œ 2024 λŒ€μž…
2746
LocalDateTime since = LocalDateTime.of(2024, 3, 1, 0, 0);
2847
LocalDateTime until = LocalDateTime.of(2024, 5, 31, 23, 59, 59);
2948
return totalCommitService.getSeasonCommits(username, since, until);
3049
}
3150

3251
// 여름 μ‹œμ¦Œ(6/1 - 8/31)
33-
@GetMapping("/api/commits/{username}/summer")
34-
public TotalCommitResponseDto getSummerSeasonCommits(@PathVariable String username) {
52+
@GetMapping("/api/commits/summer")
53+
public TotalCommitResponseDto getSummerSeasonCommits(@AuthenticationPrincipal CustomOAuth2User oAuth2User) {
54+
String username = oAuth2User.getName();
3555
int currentYear = LocalDateTime.now().getYear(); // ν˜„μž¬λŠ” ν…ŒμŠ€νŠΈμš©μœΌλ‘œ 2024 λŒ€μž…
3656
LocalDateTime since = LocalDateTime.of(2024, 6, 1, 0, 0);
3757
LocalDateTime until = LocalDateTime.of(2024, 8, 31, 23, 59, 59);
3858
return totalCommitService.getSeasonCommits(username, since, until);
3959
}
4060

4161
// 가을 μ‹œμ¦Œ(9/1 - 11/30)
42-
@GetMapping("/api/commits/{username}/fall")
43-
public TotalCommitResponseDto getFallSeasonCommits(@PathVariable String username) {
62+
@GetMapping("/api/commits/fall")
63+
public TotalCommitResponseDto getFallSeasonCommits(@AuthenticationPrincipal CustomOAuth2User oAuth2User) {
64+
String username = oAuth2User.getName();
4465
int currentYear = LocalDateTime.now().getYear(); // ν˜„μž¬λŠ” ν…ŒμŠ€νŠΈμš©μœΌλ‘œ 2024 λŒ€μž…
4566
LocalDateTime since = LocalDateTime.of(2024, 9, 1, 0, 0);
4667
LocalDateTime until = LocalDateTime.of(2024, 11, 30, 23, 59, 59);
4768
return totalCommitService.getSeasonCommits(username, since, until);
4869
}
4970

5071
// 겨울 μ‹œμ¦Œ(이전 년도 12/1 - λ‹€μŒ 년도 2/28)
51-
@GetMapping("/api/commits/{username}/winter")
52-
public TotalCommitResponseDto getWinterSeasonCommits(@PathVariable String username) {
72+
@GetMapping("/api/commits/winter")
73+
public TotalCommitResponseDto getWinterSeasonCommits(@AuthenticationPrincipal CustomOAuth2User oAuth2User) {
74+
String username = oAuth2User.getName();
5375
int currentYear = LocalDateTime.now().getYear(); // ν˜„μž¬λŠ” ν…ŒμŠ€νŠΈμš©μœΌλ‘œ 2024 λŒ€μž…
5476
LocalDateTime since = LocalDateTime.of(2024 - 1, 12, 1, 0, 0);
5577
LocalDateTime until = LocalDateTime.of(2024, 2, 1, 23, 59, 59)

0 commit comments

Comments
Β (0)