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

Gradle 멀티 모듈 구조 적용 #36

Merged
merged 30 commits into from
Feb 16, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
5ec47fc
fix: 루트 프로젝트 setting
BinarySstar Feb 5, 2025
e77aba4
refactor: build 전용 프로젝트 생성
BinarySstar Feb 6, 2025
b80fbab
refactor: 인증/인가 모듈 세분화
BinarySstar Feb 8, 2025
87e94e0
refactor: 인증/인가 모듈 세분화
BinarySstar Feb 8, 2025
f08edb0
refactor: 인증/인가 모듈 세분화
BinarySstar Feb 8, 2025
66d7c11
build: Security 모듈 의존성 추가
BinarySstar Feb 8, 2025
8a4c3bc
build: core 모듈 의존성 추가
BinarySstar Feb 9, 2025
80127d5
refactor: 멀티 모듈 구성
BinarySstar Feb 9, 2025
2365c92
refactor: 공통 모듈 구성
BinarySstar Feb 10, 2025
39b7bfb
build: app 모듈 의존
BinarySstar Feb 11, 2025
0a67cbc
build: domain 모듈 의존
BinarySstar Feb 11, 2025
e570ff5
build: infra 모듈 의존
BinarySstar Feb 11, 2025
3d74a4f
docs: api 모듈에 application.yml 구성
BinarySstar Feb 12, 2025
c0b0ac9
delete: domain 모듈 삭제
BinarySstar Feb 12, 2025
6e38b85
build: domain 모듈 삭제에 따른 dependencies 재구성
BinarySstar Feb 12, 2025
9ebc45a
feat: BaseTimeEntity 구현
BinarySstar Feb 12, 2025
e4cf2e6
refactor: 프로필 조회 API 리팩토링
BinarySstar Feb 12, 2025
7a9a591
refactor: Jwt 생성 API 리팩토링
BinarySstar Feb 12, 2025
f2b3354
refactor: main 클래스 api 모듈로 이전
BinarySstar Feb 12, 2025
d40819f
refactor: 프로필 조회 API 리팩토링
BinarySstar Feb 12, 2025
688c161
feat: Refresh Token 저장 로직 구현
BinarySstar Feb 14, 2025
9ca3ddf
feat: Refresh Token 도메인 클래스 구현
BinarySstar Feb 15, 2025
69cb2fa
feat: Refresh Token 저장 및 구현 완료
BinarySstar Feb 15, 2025
4b5289e
build: Refresh Token 저장을 위해 Redis 의존성 추가
BinarySstar Feb 15, 2025
40e2309
delete: 기존 모놀리식 구조 파일 삭제
BinarySstar Feb 16, 2025
bfb7a09
chore: 멀티 모듈 구성 완료
BinarySstar Feb 16, 2025
218e0e4
chore: 서브 모듈 구성
BinarySstar Feb 16, 2025
85a5dac
chore: 서브 모듈 구성
BinarySstar Feb 16, 2025
00e6d59
chore: 서브 모듈 구성
BinarySstar Feb 16, 2025
f495eae
chore: 배포 스크립트 수정
BinarySstar Feb 16, 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: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
HELP.md
.gradle
build/
.gradle
!gradle/wrapper/gradle-wrapper.jar
!**/src/main/**/build/
!**/src/test/**/build/
Expand Down
3 changes: 3 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
[submodule "api/src/main/resources/secrets"]
path = api/src/main/resources/secrets
url = https://github.com/BinarySstar/BinarySstar-shared-parking-service-kongju-private-repo.git
9 changes: 9 additions & 0 deletions api/build.gradle
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
dependencies {
implementation(project(":core:core-global"))
implementation(project(":core:core-security"))

implementation(project(":app"))
}

bootJar.enabled = true
jar.enabled = false
56 changes: 56 additions & 0 deletions api/src/main/java/univ/goormthon/kongju/auth/AuthController.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
package univ.goormthon.kongju.auth;

import lombok.RequiredArgsConstructor;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import univ.goormthon.kongju.auth.dto.TokenRequest;
import univ.goormthon.kongju.auth.dto.TokenResponse;
import univ.goormthon.kongju.client.provider.OAuth2UserInfoProvider;
import univ.goormthon.kongju.client.provider.OAuth2UserInfoProviderFactory;
import univ.goormthon.kongju.jwt.JwtProvider;
import univ.goormthon.kongju.member.domain.Member;
import univ.goormthon.kongju.member.service.MemberService;

import java.util.Map;

@RestController
@RequiredArgsConstructor
@RequestMapping("/api/v1/auth")
public class AuthController {

private final JwtProvider jwtProvider;
private final OAuth2UserInfoProviderFactory oAuth2UserInfoProviderFactory;
private final MemberService memberService;

@PostMapping
public ResponseEntity<TokenResponse> issueToken(@RequestParam String provider,
@RequestBody TokenRequest tokenRequest) {
OAuth2UserInfoProvider providerInstance = oAuth2UserInfoProviderFactory.getProvider(provider);
Map<String, Object> userInfo = providerInstance.getUserInfo(tokenRequest.accessToken());
Member member = memberService.getMember(userInfo);

return ResponseEntity.ok(TokenResponse.builder()
.accessToken(jwtProvider.issueAccessToken(member.getEmail()))
.refreshToken(jwtProvider.issueRefreshToken(member.getEmail()))
.build());
}

@PostMapping("/refresh")
public ResponseEntity<TokenResponse> refresh(@RequestBody TokenRequest tokenRequest) {
String refreshToken = tokenRequest.refreshToken();
if (!jwtProvider.isRefreshTokenValid(refreshToken)) {
return ResponseEntity.status(HttpStatus.UNAUTHORIZED).build();
}

String email = jwtProvider.getEmailFromToken(refreshToken);

// 기존 refresh token 만료
jwtProvider.invalidateRefreshToken(email);

return ResponseEntity.ok(TokenResponse.builder()
.accessToken(jwtProvider.issueAccessToken(email))
.refreshToken(jwtProvider.issueRefreshToken(email))
.build());
}
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package univ.goormthon.kongju.global.jwt.dto.request;
package univ.goormthon.kongju.auth.dto;

import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Builder;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package univ.goormthon.kongju.global.jwt.dto.response;
package univ.goormthon.kongju.auth.dto;

import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Builder;
Expand All @@ -8,4 +8,4 @@ public record TokenResponse(
@JsonProperty("access_token") String accessToken,
@JsonProperty("refresh_token") String refreshToken
) {
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package univ.goormthon.kongju.profile;

import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import univ.goormthon.kongju.jwt.MemberContext;
import univ.goormthon.kongju.member.domain.Member;
import univ.goormthon.kongju.member.utils.MemberFinder;
import univ.goormthon.kongju.profile.dto.ProfileResponse;

@RestController
@RequestMapping("/api/v1/profiles")
public class ProfileController {

private final MemberFinder memberFinder;

public ProfileController(MemberFinder memberFinder) {
this.memberFinder = memberFinder;
}

@GetMapping
public ResponseEntity<ProfileResponse> getProfile() {
String email = MemberContext.getCurrentMemberEmail();
Member member = memberFinder.findByEmail(email);
return ResponseEntity.ok(ProfileResponse.of(member));
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package univ.goormthon.kongju.profile.dto;

import lombok.Builder;
import univ.goormthon.kongju.member.domain.Member;

@Builder
public record ProfileResponse(
String nickname, String email, String profileImage
) {

public static ProfileResponse of(Member member) {
return ProfileResponse.builder()
.nickname(member.getNickname())
.email(member.getEmail())
.profileImage(member.getProfileImage())
.build();
}
}
15 changes: 15 additions & 0 deletions api/src/main/resources/application.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
spring:
config:
activate:
on-profile: local
import:
- classpath:secrets/application-common.yml
- classpath:secrets/application-local.yml
---
spring:
config:
activate:
on-profile: prod
import:
- classpath:secrets/application-common.yml
- classpath:secrets/application-prod.yml
1 change: 1 addition & 0 deletions api/src/main/resources/secrets
Submodule secrets added at 8f9a33
4 changes: 4 additions & 0 deletions app/build.gradle
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
dependencies {
implementation(project(":core:core-global"))
implementation(project(":infra"))
}
33 changes: 33 additions & 0 deletions app/src/main/java/univ/goormthon/kongju/member/domain/Member.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package univ.goormthon.kongju.member.domain;

import lombok.Builder;
import lombok.Getter;
import univ.goormthon.kongju.entity.MemberEntity;

@Getter
public class Member {

private Long id;
private Long kakaoId;
private String nickname;
private String email;
private String profileImage;

@Builder
public Member(Long id, Long kakaoId, String nickname, String email, String profileImage) {
this.id = id;
this.kakaoId = kakaoId;
this.nickname = nickname;
this.email = email;
this.profileImage = profileImage;
}

public static Member of(MemberEntity memberEntity) {
return Member.builder()
.id(memberEntity.getId())
.nickname(memberEntity.getNickname())
.email(memberEntity.getEmail())
.profileImage(memberEntity.getProfileImage())
.build();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package univ.goormthon.kongju.member.exception;

import univ.goormthon.kongju.exception.KongjuException;
import univ.goormthon.kongju.exception.dto.ErrorCode;

public class MemberNotFoundException extends KongjuException {
public MemberNotFoundException(ErrorCode errorCode) {
super(errorCode);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package univ.goormthon.kongju.member.service;

import org.springframework.stereotype.Service;
import univ.goormthon.kongju.member.domain.Member;
import univ.goormthon.kongju.member.utils.MemberFinder;
import univ.goormthon.kongju.member.utils.MemberRegistrant;

import java.util.Map;


@Service
public class MemberService {

private final MemberFinder memberFinder;
private final MemberRegistrant memberRegistrant;

public MemberService(MemberFinder memberFinder, MemberRegistrant memberRegistrant) {
this.memberFinder = memberFinder;
this.memberRegistrant = memberRegistrant;
}

public Member getMember(Map<String, Object> userInfo) {
String email = (String) userInfo.get("email");
if(!memberFinder.isExistByEmail(email)){
registerMember(userInfo);
}
return memberFinder.findByEmail(email);
}

private void registerMember(Map<String, Object> userInfo) {
memberRegistrant.register(userInfo);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package univ.goormthon.kongju.member.utils;

import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import univ.goormthon.kongju.entity.MemberEntity;
import univ.goormthon.kongju.exception.dto.ErrorCode;
import univ.goormthon.kongju.member.domain.Member;
import univ.goormthon.kongju.member.exception.MemberNotFoundException;
import univ.goormthon.kongju.repository.MemberRepository;

@Component
public class MemberFinder {

private final MemberRepository memberRepository;

public MemberFinder(MemberRepository memberRepository) {
this.memberRepository = memberRepository;
}

@Transactional(readOnly = true)
public Member findByEmail(String email) {
MemberEntity member = memberRepository.findByEmail(email)
.orElseThrow(() -> new MemberNotFoundException(ErrorCode.MEMBER_NOT_FOUND));
return Member.of(member);
}

@Transactional(readOnly = true)
public boolean isExistByEmail(String email) {
return memberRepository.existsByEmail(email);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package univ.goormthon.kongju.member.utils;

import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import univ.goormthon.kongju.entity.MemberEntity;
import univ.goormthon.kongju.member.domain.Member;
import univ.goormthon.kongju.repository.MemberRepository;

import java.util.Map;

@Component
public class MemberRegistrant {

private final MemberRepository memberRepository;

public MemberRegistrant(MemberRepository memberRepository) {
this.memberRepository = memberRepository;
}

@Transactional
public Member register(Map<String, Object> userInfo) {
MemberEntity memberEntity = MemberEntity.builder()
.email((String) userInfo.get("email"))
.nickname((String) userInfo.get("nickname"))
.profileImage((String) userInfo.get("profile_image"))
.build();

return Member.of(memberRepository.save(memberEntity));
}
}
63 changes: 21 additions & 42 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,6 @@ plugins {
id 'io.spring.dependency-management' version '1.1.6'
}

ext {
springCloudVersion = "2023.0.3"
}

group = 'univ.goormthon'
version = '0.0.1-SNAPSHOT'

java {
toolchain {
languageVersion = JavaLanguageVersion.of(17)
Expand All @@ -23,46 +16,32 @@ configurations {
}
}

repositories {
mavenCentral()
}

dependencies {
implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
implementation 'org.springframework.boot:spring-boot-starter-webflux'
implementation 'org.springframework.boot:spring-boot-starter-web'
implementation 'org.springframework.cloud:spring-cloud-starter-aws:2.2.6.RELEASE'
implementation 'org.springdoc:springdoc-openapi-starter-webmvc-ui:2.2.0'
implementation 'org.springframework.boot:spring-boot-starter-security'
implementation 'org.springframework.boot:spring-boot-starter-oauth2-resource-server'
implementation 'org.springframework.boot:spring-boot-starter-websocket'
testImplementation 'org.springframework.security:spring-security-test'

// JWT
implementation 'io.jsonwebtoken:jjwt-api:0.12.6'
runtimeOnly 'io.jsonwebtoken:jjwt-impl:0.12.6'
runtimeOnly 'io.jsonwebtoken:jjwt-jackson:0.12.6'
bootJar.enabled = false

compileOnly 'org.projectlombok:lombok'
developmentOnly 'org.springframework.boot:spring-boot-devtools'
allprojects {
group = 'univ.goormthon'
version = '0.0.1-SNAPSHOT'

runtimeOnly 'com.h2database:h2'
runtimeOnly 'com.mysql:mysql-connector-j'
repositories {
mavenCentral()
}
}

annotationProcessor 'org.projectlombok:lombok'
subprojects {
apply plugin: 'java'
apply plugin: 'java-library'
apply plugin: 'io.spring.dependency-management'
apply plugin: 'org.springframework.boot'

testImplementation 'org.springframework.boot:spring-boot-starter-test'
testImplementation 'io.projectreactor:reactor-test'
dependencies {
testImplementation 'org.springframework.boot:spring-boot-starter-test'

testRuntimeOnly 'org.junit.platform:junit-platform-launcher'
}

dependencyManagement {
imports {
mavenBom "org.springframework.cloud:spring-cloud-dependencies:$springCloudVersion"
compileOnly 'org.projectlombok:lombok'
annotationProcessor 'org.projectlombok:lombok'
testCompileOnly 'org.projectlombok:lombok'
testAnnotationProcessor 'org.projectlombok:lombok'
}
}

test {
useJUnitPlatform()
bootJar.enabled = false
jar.enabled = true
}
Empty file added core/build.gradle
Empty file.
Loading
Loading