Skip to content

Commit c241086

Browse files
authored
Merge pull request #57 from MEME-UMC/feat/#55
Feat/#55
2 parents 39f4c99 + eb5a157 commit c241086

File tree

21 files changed

+394
-112
lines changed

21 files changed

+394
-112
lines changed

.github/workflows/dev_ci_cd.yml

+7-4
Original file line numberDiff line numberDiff line change
@@ -2,19 +2,22 @@ name: MeMe CI/CD
22

33
on:
44
push:
5-
branches: ["develop", "main"]
5+
branches: ['develop']
66

77
jobs:
88
build:
99
runs-on: ubuntu-latest
1010
steps:
1111
- uses: actions/checkout@v4
12+
with:
13+
fetch-depth: 0
1214

1315
- name: Set up JDK 17
1416
uses: actions/setup-java@v3
1517
with:
1618
java-version: '17'
1719
distribution: "adopt"
20+
1821
- name: Set up QEMU
1922
uses: docker/setup-qemu-action@v3
2023

@@ -40,7 +43,7 @@ jobs:
4043
context: ./MEME-AUTH # MEME-AUTH 모듈의 경로
4144
push: true
4245
tags: ${{ vars.DOCKER_USERNAME }}/${{ vars.MEME_AUTH }}:latest
43-
platforms: linux/amd64,linux/arm64
46+
platforms: linux/arm64
4447

4548
# MEME-RESERVATION 모듈 빌드
4649
- name: Build MEME-RESERVATION with Gradle
@@ -55,7 +58,7 @@ jobs:
5558
context: ./MEME-RESERVATION # MEME-RESERVATION 모듈의 경로
5659
push: true
5760
tags: ${{ vars.DOCKER_USERNAME }}/${{ vars.MEME_RESERVATION }}:latest
58-
platforms: linux/amd64,linux/arm64
61+
platforms: linux/arm64
5962

6063
# MEME-RESERVATION 모듈 빌드
6164
- name: Build MEME-SERVICE with Gradle
@@ -70,7 +73,7 @@ jobs:
7073
context: ./MEME-SERVICE # MEME-RESERVATION 모듈의 경로
7174
push: true
7275
tags: ${{ vars.DOCKER_USERNAME }}/${{ vars.MEME_SERVICE }}:latest
73-
platforms: linux/amd64,linux/arm64
76+
platforms: linux/arm64
7477

7578
deploy:
7679
runs-on: ubuntu-latest

.gitignore

-1
Original file line numberDiff line numberDiff line change
@@ -36,5 +36,4 @@ out/
3636

3737
### VS Code ###
3838
.vscode/
39-
*/application.yml
4039
*.json

MEME-AUTH/build.gradle

+4-1
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@ dependencies {
1111

1212
// Spring Security
1313
implementation 'org.springframework.boot:spring-boot-starter-security'
14-
implementation 'org.springframework.boot:spring-boot-starter-security'
1514
testImplementation 'org.springframework.security:spring-security-test'
1615

1716
// Json Web Token
@@ -28,6 +27,10 @@ dependencies {
2827
// Embedded Redis
2928
implementation 'it.ozimov:embedded-redis:0.7.2'
3029

30+
// Spring Boot Actuator
31+
implementation 'org.springframework.boot:spring-boot-starter-actuator'
32+
33+
3134
runtimeOnly 'com.h2database:h2' // h2 추가
3235
}
3336

MEME-AUTH/src/main/java/org/meme/auth/config/SecurityConfig.java

+3-1
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
import org.springframework.context.annotation.Configuration;
1111
import org.springframework.security.authentication.AuthenticationManager;
1212
import org.springframework.security.authentication.dao.DaoAuthenticationProvider;
13+
import org.springframework.security.config.Customizer;
1314
import org.springframework.security.config.annotation.authentication.configuration.AuthenticationConfiguration;
1415
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
1516
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
@@ -18,6 +19,7 @@
1819
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
1920
import org.springframework.security.web.SecurityFilterChain;
2021
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
22+
import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer;
2123

2224
import static org.springframework.security.config.http.SessionCreationPolicy.STATELESS;
2325

@@ -56,7 +58,7 @@ public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Excepti
5658
.requestMatchers("/api/v1/auth/logout").permitAll()
5759
.requestMatchers("/api/v1/auth/withdraw").permitAll()
5860
.requestMatchers("/auth/**").permitAll()
59-
61+
.requestMatchers("/actuator/**").permitAll() // 모든 Actuator 엔드포인트 허용
6062
.requestMatchers("/api/v2/**").permitAll() // API version update
6163
.requestMatchers("/h2-console/**").permitAll() // H2 데이터베이스 경로 허용
6264
);

MEME-AUTH/src/main/java/org/meme/auth/config/SwaggerConfig.java

+2-1
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,8 @@ public OpenAPI MemeAPI() {
3232
.bearerFormat("JWT"));
3333

3434
return new OpenAPI()
35-
.addServersItem(new Server().url("/"))
35+
.addServersItem(new Server().url("/meme-auth")) // 운영 환경 추가
36+
.addServersItem(new Server().url("/")) // 로컬 환경 추가
3637
.info(info)
3738
.addSecurityItem(securityRequirement)
3839
.components(components);

MEME-AUTH/src/main/java/org/meme/auth/controller/AuthController.java

+2-1
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,8 @@
1919

2020
@Slf4j(topic = "MEME-AUTH")
2121
@RequiredArgsConstructor
22-
@RequestMapping("/api/v2")
2322
@RestController
23+
@RequestMapping("/api/v2") // 클래스 레벨 URL 매핑
2424
public class AuthController {
2525

2626
private final AuthService authService;
@@ -33,6 +33,7 @@ public class AuthController {
3333
*/
3434
@PostMapping("/join/social")
3535
public BaseResponseDto<AuthResponse.JoinDto> socialJoin(@RequestBody AuthRequest.UserJoinDto joinDto) throws AuthException {
36+
log.info("소셜 회원가입 요청: {}", joinDto);
3637
return SuccessResponse(SuccessStatus.USER_SIGNUP_SUCCESS, authService.socialJoin(joinDto));
3738
}
3839

MEME-AUTH/src/main/resources/application.yml

+18-1
Original file line numberDiff line numberDiff line change
@@ -42,4 +42,21 @@ springdoc:
4242
path: /auth/swagger-ui
4343
display-request-duration: true
4444
api-docs:
45-
path: /auth/docs
45+
path: /auth/docs
46+
47+
server:
48+
port: 8081
49+
50+
logging:
51+
level:
52+
org:
53+
springframework: DEBUG
54+
55+
management:
56+
endpoints:
57+
web:
58+
exposure:
59+
include: "*"
60+
endpoint:
61+
health:
62+
show-details: "always"
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
11
package org.meme.reservation.config;
22

3+
import io.swagger.v3.oas.models.Components;
34
import io.swagger.v3.oas.models.OpenAPI;
45
import io.swagger.v3.oas.models.info.Info;
6+
import io.swagger.v3.oas.models.security.SecurityRequirement;
7+
import io.swagger.v3.oas.models.security.SecurityScheme;
58
import io.swagger.v3.oas.models.servers.Server;
69
import org.springframework.context.annotation.Bean;
710
import org.springframework.context.annotation.Configuration;
@@ -15,22 +18,23 @@ public OpenAPI MemeAPI() {
1518
.description("MEME API 명세서")
1619
.version("2.0.0");
1720

18-
// String jwtSchemeName = "accessToken";
19-
// // API 요청헤더에 인증정보 포함
20-
// SecurityRequirement securityRequirement = new SecurityRequirement().addList(jwtSchemeName);
21-
//
22-
// // SecuritySchemes 등록
23-
// Components components = new Components()
24-
// .addSecuritySchemes(jwtSchemeName, new SecurityScheme()
25-
// .name(jwtSchemeName)
26-
// .type(SecurityScheme.Type.HTTP) // HTTP 방식
27-
// .scheme("bearer")
28-
// .bearerFormat("JWT"));
21+
String jwtSchemeName = "accessToken";
22+
// API 요청헤더에 인증정보 포함
23+
SecurityRequirement securityRequirement = new SecurityRequirement().addList(jwtSchemeName);
24+
25+
// SecuritySchemes 등록
26+
Components components = new Components()
27+
.addSecuritySchemes(jwtSchemeName, new SecurityScheme()
28+
.name(jwtSchemeName)
29+
.type(SecurityScheme.Type.HTTP) // HTTP 방식
30+
.scheme("bearer")
31+
.bearerFormat("JWT"));
2932

3033
return new OpenAPI()
34+
.addServersItem(new Server().url("/meme-reservation")) // 운영 환경 추가
3135
.addServersItem(new Server().url("/"))
32-
.info(info);
33-
// .addSecurityItem(securityRequirement)
34-
// .components(components);
36+
.info(info)
37+
.addSecurityItem(securityRequirement)
38+
.components(components);
3539
}
3640
}

MEME-RESERVATION/src/main/resources/application.yml

+9-2
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
spring:
22
datasource:
33
driver-class-name: com.mysql.cj.jdbc.Driver
4-
url: jdbc:mysql://localhost:3306/${DB_SCHEMA}?useSSL=false&useUnicode=true&characterEncoding=utf8&allowPublicKeyRetrieval=true
4+
url: ${SPRING_DATASOURCE_URL}
55
username: ${DB_USERNAME}
66
password: ${DB_PASSWORD}
77

@@ -22,6 +22,13 @@ spring:
2222
host: ${REDIS_URL}
2323
port: 6379
2424

25+
springdoc:
26+
swagger-ui:
27+
path: /reservation/swagger-ui
28+
display-request-duration: true
29+
api-docs:
30+
path: /reservation/docs
31+
2532
server:
26-
port: 8083
33+
port: 8082
2734

MEME-RESERVATION/src/test/java/org/meme/reservation/ReservationApplicationTests.java

+3-3
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,8 @@
66
@SpringBootTest
77
class ReservationApplicationTests {
88

9-
@Test
10-
void contextLoads() {
11-
}
9+
// @Test
10+
// void contextLoads() {
11+
// }
1212

1313
}

MEME-RESERVATION/src/test/java/org/meme/reservation/service/ReservationServiceTest.java

+54-54
Original file line numberDiff line numberDiff line change
@@ -39,58 +39,58 @@ class ReservationServiceTest {
3939
@MockBean
4040
private ReservationRepository reservationRepository;
4141

42-
@Test
43-
void 예약_성공() {
44-
// Given
45-
ReservationRequest.SaveDto request = new ReservationRequest.SaveDto();
46-
request.setTimes(Set.of("18:30", "19:00", "19:30"));
47-
48-
Model mockedModel = mock(Model.class);
49-
Portfolio mockedPortfolio = mock(Portfolio.class);
50-
51-
when(modelRepository.findById(any())).thenReturn(Optional.of(mockedModel));
52-
when(portfolioRepository.findById(1L)).thenReturn(Optional.of(mockedPortfolio));
53-
when(reservationRepository.save(any(Reservation.class))).thenReturn(new Reservation());
54-
55-
// When
56-
when(reservationRepository.findByPortfolioAndYearAndMonthAndDay(any(Portfolio.class), anyInt(), anyInt(), anyInt()))
57-
.thenReturn(Optional.empty()); // null 값 반환
58-
ReservationResponse.SuccessDto successDto = reservationService.makeReservation(request);
59-
60-
// Then
61-
Assertions.assertNotNull(successDto);
62-
}
63-
64-
@Test
65-
void 예약_실패() {
66-
// Given
67-
ReservationRequest.SaveDto request = new ReservationRequest.SaveDto();
68-
request.setTimes(Set.of("18:30", "19:00", "19:30"));
69-
70-
Model mockedModel = mock(Model.class);
71-
Portfolio mockedPortfolio = mock(Portfolio.class);
72-
73-
when(modelRepository.findById(any())).thenReturn(Optional.of(mockedModel));
74-
when(portfolioRepository.findById(1L)).thenReturn(Optional.of(mockedPortfolio));
75-
when(reservationRepository.save(any(Reservation.class))).thenReturn(new Reservation());
76-
77-
// When
78-
when(reservationRepository.findByPortfolioAndYearAndMonthAndDay(any(Portfolio.class), anyInt(), anyInt(), anyInt()))
79-
.thenReturn(Optional.of(getReservations())); // 예약 내역 반환
80-
81-
// Then
82-
Assertions.assertThrows(ReservationException.class,
83-
() -> reservationService.makeReservation(request));
84-
}
85-
86-
private List<Reservation> getReservations() {
87-
Reservation reservation1 = Reservation.builder()
88-
.times("18:00,18:30,19:00")
89-
.build();
90-
Reservation reservation2 = Reservation.builder()
91-
.times("21:00,21:30,22:00")
92-
.build();
93-
94-
return List.of(reservation1, reservation2);
95-
}
42+
// @Test
43+
// void 예약_성공() {
44+
// // Given
45+
// ReservationRequest.SaveDto request = new ReservationRequest.SaveDto();
46+
// request.setTimes(Set.of("18:30", "19:00", "19:30"));
47+
//
48+
// Model mockedModel = mock(Model.class);
49+
// Portfolio mockedPortfolio = mock(Portfolio.class);
50+
//
51+
// when(modelRepository.findById(any())).thenReturn(Optional.of(mockedModel));
52+
// when(portfolioRepository.findById(1L)).thenReturn(Optional.of(mockedPortfolio));
53+
// when(reservationRepository.save(any(Reservation.class))).thenReturn(new Reservation());
54+
//
55+
// // When
56+
// when(reservationRepository.findByPortfolioAndYearAndMonthAndDay(any(Portfolio.class), anyInt(), anyInt(), anyInt()))
57+
// .thenReturn(Optional.empty()); // null 값 반환
58+
// ReservationResponse.SuccessDto successDto = reservationService.makeReservation(request);
59+
//
60+
// // Then
61+
// Assertions.assertNotNull(successDto);
62+
// }
63+
//
64+
// @Test
65+
// void 예약_실패() {
66+
// // Given
67+
// ReservationRequest.SaveDto request = new ReservationRequest.SaveDto();
68+
// request.setTimes(Set.of("18:30", "19:00", "19:30"));
69+
//
70+
// Model mockedModel = mock(Model.class);
71+
// Portfolio mockedPortfolio = mock(Portfolio.class);
72+
//
73+
// when(modelRepository.findById(any())).thenReturn(Optional.of(mockedModel));
74+
// when(portfolioRepository.findById(1L)).thenReturn(Optional.of(mockedPortfolio));
75+
// when(reservationRepository.save(any(Reservation.class))).thenReturn(new Reservation());
76+
//
77+
// // When
78+
// when(reservationRepository.findByPortfolioAndYearAndMonthAndDay(any(Portfolio.class), anyInt(), anyInt(), anyInt()))
79+
// .thenReturn(Optional.of(getReservations())); // 예약 내역 반환
80+
//
81+
// // Then
82+
// Assertions.assertThrows(ReservationException.class,
83+
// () -> reservationService.makeReservation(request));
84+
// }
85+
//
86+
// private List<Reservation> getReservations() {
87+
// Reservation reservation1 = Reservation.builder()
88+
// .times("18:00,18:30,19:00")
89+
// .build();
90+
// Reservation reservation2 = Reservation.builder()
91+
// .times("21:00,21:30,22:00")
92+
// .build();
93+
//
94+
// return List.of(reservation1, reservation2);
95+
// }
9696
}

MEME-SERVICE/build.gradle

+3
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,9 @@ dependencies {
22
implementation 'org.springframework.boot:spring-boot-starter-web'
33
implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
44

5+
implementation 'org.springframework.kafka:spring-kafka'
6+
implementation 'com.fasterxml.jackson.datatype:jackson-datatype-jsr310'
7+
58
compileOnly 'org.projectlombok:lombok'
69
annotationProcessor 'org.projectlombok:lombok'
710
testImplementation platform('org.junit:junit-bom:5.9.1')

0 commit comments

Comments
 (0)