Skip to content
Open
Show file tree
Hide file tree
Changes from 28 commits
Commits
Show all changes
53 commits
Select commit Hold shift + click to select a range
6eb5796
add :: Rank.java
Kimhanju0210 Nov 11, 2024
1e8da19
add :: RankController.java
Kimhanju0210 Nov 11, 2024
7dce3ef
add :: RankResponse.java
Kimhanju0210 Nov 11, 2024
0ef14a4
add :: RankServiceImpl.java
Kimhanju0210 Nov 11, 2024
91ac7c2
add :: RankService.java
Kimhanju0210 Nov 11, 2024
210b0d0
add :: RedisConfig.java
Kimhanju0210 Nov 11, 2024
7855b49
add :: JwtService.java
Kimhanju0210 Nov 11, 2024
bc65f7a
add :: UserServiceImpl.java
Kimhanju0210 Nov 11, 2024
a2f9ec8
add :: UserService.java
Kimhanju0210 Nov 11, 2024
f274026
modify :: User.java
Kimhanju0210 Nov 11, 2024
4cce774
modify :: UserRepository.java
Kimhanju0210 Nov 11, 2024
07e3606
modify :: build.gradle
Kimhanju0210 Nov 11, 2024
a42a331
modify :: application.yml
Kimhanju0210 Nov 11, 2024
c748742
Merge branch '5-RankSystem' of https://github.com/Team-MindWay/Dormit…
Kimhanju0210 Nov 11, 2024
14e7af4
add :: GetTopRankingServiceImpl.java
Kimhanju0210 Nov 14, 2024
823fdf7
add :: GetTopRankingService.java
Kimhanju0210 Nov 14, 2024
2b1dd70
add :: GetRankingServiceImpl.java
Kimhanju0210 Nov 14, 2024
1f93210
add :: GetRankingService.java
Kimhanju0210 Nov 14, 2024
c2caf7c
add :: UpdateRankingServiceImpl.java
Kimhanju0210 Nov 14, 2024
2fc1e70
add :: UpdateRankingService.java
Kimhanju0210 Nov 14, 2024
6e642a9
modify :: RankController.java
Kimhanju0210 Nov 14, 2024
5854644
modify :: UserServiceImpl.java
Kimhanju0210 Nov 14, 2024
08478b2
delete :: RankServiceImpl.java
Kimhanju0210 Nov 14, 2024
6481c65
delete :: RankService.java
Kimhanju0210 Nov 14, 2024
35e0844
delete :: RedisConfig.java
Kimhanju0210 Nov 14, 2024
7e202be
modify :: GetRankingServiceImpl.java
Kimhanju0210 Nov 19, 2024
593a11e
modify :: GetTopRankingServiceImpl.java
Kimhanju0210 Nov 19, 2024
7581978
modify :: UpdateRankingServiceImpl.java
Kimhanju0210 Nov 19, 2024
ea0e18e
modify :: User.java
Kimhanju0210 Nov 21, 2024
994ac46
modify :: RankResponse.java
Kimhanju0210 Nov 21, 2024
039cbd7
Revert "modify :: User.java"
Kimhanju0210 Nov 21, 2024
e8c46cd
Revert "modify :: RankResponse.java"
Kimhanju0210 Nov 21, 2024
137867c
add :: AlreadExistsException.java
Kimhanju0210 Mar 5, 2025
9d0d536
modify :: User.java
Kimhanju0210 Mar 24, 2025
d20d357
modify :: UserRepository.java
Kimhanju0210 Mar 24, 2025
38a5611
modify :: UserServiceImpl.java
Kimhanju0210 Mar 24, 2025
cced1e3
add :: InvalidUserExeption.java
Kimhanju0210 Mar 24, 2025
2320115
modify :: NotFoundException.java
Kimhanju0210 Mar 24, 2025
760ee5a
modify :: Rank.java
Kimhanju0210 Mar 24, 2025
fcda490
modify :: GetRankingServiceImpl.java
Kimhanju0210 Mar 24, 2025
4ef693c
update :: GetTopRankingServiceImpl.java
Kimhanju0210 Mar 24, 2025
f273c54
modify :: UpdateRankingServiceImpl.java
Kimhanju0210 Mar 24, 2025
c9b7627
update :: RankController.java
Kimhanju0210 Mar 24, 2025
dd82968
modify :: application.yml
Kimhanju0210 Mar 24, 2025
6aab0e5
modify :: UserNotFoundException.java
Kimhanju0210 Mar 25, 2025
85db00e
modify :: UsernameNotFoundException.java
Kimhanju0210 Mar 25, 2025
22c8f80
modify :: UserServiceImpl.java
Kimhanju0210 Mar 25, 2025
3b16536
delete :: NotFoundException.java
Kimhanju0210 Mar 25, 2025
601722c
modify :: application.yml
Kimhanju0210 Apr 3, 2025
39b3095
modify :: UserServiceImpl.java
Kimhanju0210 Apr 3, 2025
3297aab
modify :: NotFoundException.java
Kimhanju0210 Apr 3, 2025
ea5b953
Merge remote-tracking branch 'origin/5-RankSystem' into 5-RankSystem
Kimhanju0210 Apr 3, 2025
a6517ef
modify :: application.yml
Kimhanju0210 Apr 3, 2025
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
2 changes: 2 additions & 0 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,8 @@ dependencies {

//redis
implementation ("org.springframework.boot:spring-boot-starter-data-redis")
implementation ("org.springframework.boot:spring-boot-starter-data-redis:2.3.1.RELEASE")


// aws
implementation("org.springframework.cloud:spring-cloud-starter-aws:2.2.6.RELEASE")
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package com.example.domaserver.domain.rank.entity;

import com.example.domaserver.domain.user.entity.User;
import jakarta.persistence.*;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;

@Entity
@Getter
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class Rank {

@Id
@GeneratedValue(strategy =GenerationType.IDENTITY)
private Long RankId;
private int PenaltyPoints;
private double RankScore;

@ManyToOne
@JoinColumn(name = "user_id")
private User user;

public Rank(Long rankId, Double rankScore) {
RankId = rankId;
RankScore = rankScore;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
package com.example.domaserver.domain.rank.presentation;


import com.example.domaserver.domain.rank.entity.Rank;
import com.example.domaserver.domain.rank.service.GetRankingService;
import com.example.domaserver.domain.rank.service.GetTopRankingService;
import com.example.domaserver.domain.rank.service.UpdateRankingService;
import com.example.domaserver.domain.user.entity.User;
import com.example.domaserver.domain.user.service.UserService;
import com.example.domaserver.global.security.jwt.JwtService;
import lombok.RequiredArgsConstructor;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestHeader;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;

@RequiredArgsConstructor
@RestController
@RequestMapping("/home")
public class RankController {

private final GetRankingService getRankingService;
private final GetTopRankingService getTopRankingService;
private final UpdateRankingService updateRankingService;
private final UserService userService;
private final JwtService jwtService;

@GetMapping("/rank")
public ResponseEntity<List<Rank>> getRanks() {
List<Rank> topRanks = getTopRankingService.getTopRanking(25);
return ResponseEntity.ok(topRanks);
}

@GetMapping("/my-rank")
public ResponseEntity<Long> getMyRank(@RequestHeader("Authorization") String token) {
User user = jwtService.getUserFromToken(token.substring(7));
Long rank = getRankingService.getRanking(user);
return ResponseEntity.ok(rank);
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package com.example.domaserver.domain.rank.presentation.dto.response;

import lombok.Builder;
import lombok.Getter;

import java.util.UUID;

@Builder
@Getter
public class RankResponse {
private UUID Id;
private String name;
private String profileImageUrl;
private int penaltyPoints;
private double RankScore;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package com.example.domaserver.domain.rank.service;

import com.example.domaserver.domain.user.entity.User;

public interface GetRankingService {
Long getRanking(User user);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package com.example.domaserver.domain.rank.service;

import com.example.domaserver.domain.rank.entity.Rank;

import java.util.List;

public interface GetTopRankingService {
List<Rank> getTopRanking(int topN);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package com.example.domaserver.domain.rank.service;

import com.example.domaserver.domain.rank.entity.Rank;

public interface UpdateRankingService {
void updateRanking(Rank rank);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package com.example.domaserver.domain.rank.service.impl;

import com.example.domaserver.domain.rank.service.GetRankingService;
import com.example.domaserver.domain.user.entity.User;
import com.example.domaserver.global.annotation.ServiceWithReadOnlyTransactional;
import lombok.RequiredArgsConstructor;
import org.springframework.data.redis.core.RedisTemplate;

@ServiceWithReadOnlyTransactional

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

get service는 ReadOnly 씁니다. 두개 붙일 필요 없이 ReadOnly만 남겨주세요

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

593a11e

수정했습니다!

@RequiredArgsConstructor
public class GetRankingServiceImpl implements GetRankingService {

private static final String GET_RANKING = "getRank";

private final RedisTemplate redisTemplate;

public Long getRanking(User user) {
Long rank = redisTemplate.opsForZSet().rank(GET_RANKING, user.getId());
return (rank != null) ? rank + 1 : null;
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
package com.example.domaserver.domain.rank.service.impl;

import com.example.domaserver.domain.rank.entity.Rank;
import com.example.domaserver.domain.rank.service.GetTopRankingService;
import com.example.domaserver.global.annotation.ServiceWithReadOnlyTransactional;
import lombok.RequiredArgsConstructor;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ZSetOperations;

import java.util.ArrayList;
import java.util.List;
import java.util.Set;

@ServiceWithReadOnlyTransactional

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

get service는 ReadOnly 씁니다. 두개 붙일 필요 없이 ReadOnly만 남겨주세요

@Kimhanju0210 Kimhanju0210 Nov 19, 2024

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

7e202be

수정했습니다!

@RequiredArgsConstructor
public class GetTopRankingServiceImpl implements GetTopRankingService {

private static final String GET_TOP_RANKING = "getTopRanking";

private final RedisTemplate redisTemplate;

public List<Rank> getTopRanking(int topN) {
Set<ZSetOperations.TypedTuple<Long>> rankedUsers =
redisTemplate.opsForZSet().reverseRange(GET_TOP_RANKING, 0, topN - 1);

List<Rank> userRanks = new ArrayList<>();
for (ZSetOperations.TypedTuple<Long> entry : rankedUsers) {
Long RankId = entry.getValue();
Double RankScore = entry.getScore();
userRanks.add(new Rank(RankId, RankScore));
}

return userRanks;
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package com.example.domaserver.domain.rank.service.impl;

import com.example.domaserver.domain.rank.entity.Rank;
import com.example.domaserver.domain.rank.service.UpdateRankingService;
import com.example.domaserver.global.annotation.ServiceWithTransaction;
import lombok.RequiredArgsConstructor;
import org.springframework.data.redis.core.RedisTemplate;


@ServiceWithTransaction
@RequiredArgsConstructor
public class UpdateRankingServiceImpl implements UpdateRankingService {

private static final String UPDATE_RANKING = "update ranking set rank=rank+1 where rank=?";

private final RedisTemplate redisTemplate;

public void updateRanking(Rank rank) {
redisTemplate.opsForSet().add(UPDATE_RANKING, rank.getUser().getId(), rank.getPenaltyPoints());
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,9 @@ public class User {
@Id
@GeneratedValue(generator = "UUID4")
private UUID id;

private String name;

private String email;
private int penaltyPoint;

@Embedded
private StudentNum studentNum;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,5 @@

public interface UserRepository extends JpaRepository<User, UUID> {
Optional<User> findByEmail(String email);
Optional<User> findByUsername(String Username);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package com.example.domaserver.domain.user.service;

import com.example.domaserver.domain.user.entity.User;

import java.util.UUID;

public interface UserService {
User findByUsername(String name);
User findById(UUID id);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package com.example.domaserver.domain.user.service.impl;

import com.example.domaserver.domain.user.entity.User;
import com.example.domaserver.domain.user.repository.UserRepository;
import com.example.domaserver.domain.user.service.UserService;
import com.example.domaserver.global.annotation.ServiceWithTransaction;
import lombok.RequiredArgsConstructor;
import org.springframework.security.core.userdetails.UsernameNotFoundException;

import java.util.UUID;

@RequiredArgsConstructor
@ServiceWithTransaction
public class UserServiceImpl implements UserService {

private final UserRepository userRepository;

@Override
public User findByUsername(String username) {
return userRepository.findByUsername(username)
.orElseThrow(() -> new UsernameNotFoundException("User not found with username: " + username));

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

custom exception을 만들어서 예외처리를 해보는건 어떨까요

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

6aab0e5

85db00e

수정했습니다!

}

@Override
public User findById(UUID id) {
return userRepository.findById(id)
.orElseThrow(() -> new UsernameNotFoundException("User not found with id: " + id));
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
package com.example.domaserver.global.security.jwt;


import com.example.domaserver.domain.user.entity.User;
import com.example.domaserver.domain.user.service.UserService;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.stereotype.Service;
import org.springframework.beans.factory.annotation.Value;

import java.util.Date;
import java.util.function.Function;

@Service
@Slf4j
public class JwtService {

private final UserService userService;

@Value("${jwt.secret}")
private String secretKey;

public JwtService(UserService userService) {
this.userService = userService;
}

public String extractUsername(String token) {
return extractClaim(token, Claims::getSubject);
}

public <T> T extractClaim(String token, Function<Claims, T> claimsResolver) {
final Claims claims = extractAllClaims(token);
return claimsResolver.apply(claims);
}

private Claims extractAllClaims(String token) {
return Jwts.parser()
.setSigningKey(secretKey)
.parseClaimsJws(token)
.getBody();
}

public boolean isTokenValid(String token, UserDetails userDetails) {
final String username = extractUsername(token);
return (username.equals(userDetails.getUsername()) && !isTokenExpired(token));
}

private boolean isTokenExpired(String token) {
return extractExpiration(token).before(new Date());
}

public Date extractExpiration(String token) {
return extractClaim(token, Claims::getExpiration);
}

public User getUserFromToken(String token) {
String username = extractUsername(token);
return userService.findByUsername(username);
}
}
8 changes: 6 additions & 2 deletions src/main/resources/application.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
server:
redis:
port: 6739
host: localhost

port: 8090
servlet:
context-path: /
Expand Down Expand Up @@ -33,9 +37,9 @@ spring:
port: ${REDIS_PORT}

jwt:
secret: ${JWT_SECRET}
secret: "your_secret_key_here"

gauth:
clientId: ${GAUTH_CLIENT}
clientSecret: ${GAUTH_SECRET}
redirectUri: ${GAUTH_REDIRECT_URI}
redirectUri: ${GAUTH_REDIRECT_URI}