Skip to content

Commit 311773b

Browse files
authored
Merge pull request #645 from woowacourse-teams/dev
main v1.3.0 배포
2 parents de36841 + 5433090 commit 311773b

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

46 files changed

+759
-185
lines changed

.gitmodules

+4
Original file line numberDiff line numberDiff line change
@@ -6,3 +6,7 @@
66
path = s3proxy/src/main/resources/s3proxy-config
77
url = [email protected]:zzimkkong/s3proxy-config.git
88
branch = main
9+
[submodule "backend/src/main/resources/infra-appender"]
10+
path = backend/src/main/resources/infra-appender
11+
url = [email protected]:zzimkkong/infra-appender.git
12+
branch = main

backend/build.gradle

+2
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,8 @@ dependencies {
6868
// Logstash
6969
implementation 'net.logstash.logback:logstash-logback-encoder:6.6'
7070

71+
// Kafka Appender
72+
implementation 'com.github.danielwegener:logback-kafka-appender:0.2.0-RC2'
7173
}
7274

7375
test {

backend/docker/main/Dockerfile

+20
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
FROM ubuntu:18.04
2+
3+
LABEL email="[email protected]"
4+
LABEL name="sakjung"
5+
LABEL description="zzimkkong main application"
6+
7+
RUN apt-get -y update
8+
RUN apt-get install -y openjdk-11-jdk
9+
10+
# run application
11+
WORKDIR /home/ubuntu
12+
COPY build/libs/backend-0.0.1-SNAPSHOT.jar app.jar
13+
RUN mkdir zzimkkong && mkdir zzimkkong/tmp
14+
15+
EXPOSE 8080
16+
17+
# 빌드시 명령어에 옵션 추가: --build-arg CLUSTER_IP=<cluster ip>
18+
ENV CLUSTER_IP="IP"
19+
20+
ENTRYPOINT ["java", "-Ds3proxy.server-uri=http://${CLUSTER_IP}", "-Dspring.profiles.active=prod", "-jar", "app.jar", "--spring.config.location=classpath:config/application-prod.properties"]

backend/src/main/java/com/woowacourse/zzimkkong/config/SlackConfig.java

+9-2
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,15 @@
1212
@PropertySource("classpath:config/slack.properties")
1313
public class SlackConfig implements WebMvcConfigurer {
1414
@Bean
15-
@Profile("!test")
16-
public SlackUrl slackUrl(
15+
@Profile("prod")
16+
public SlackUrl slackUrlProd(
17+
@Value("${slack.webhook.prod}") final String prodUrl) {
18+
return new SlackUrl(prodUrl);
19+
}
20+
21+
@Bean
22+
@Profile({"local", "dev"})
23+
public SlackUrl slackUrlDev(
1724
@Value("${slack.webhook.local}") final String devUrl) {
1825
return new SlackUrl(devUrl);
1926
}

backend/src/main/java/com/woowacourse/zzimkkong/controller/GuestReservationController.java

+12-3
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,9 @@
22

33
import com.woowacourse.zzimkkong.config.logaspect.LogMethodExecutionTime;
44
import com.woowacourse.zzimkkong.dto.reservation.*;
5+
import com.woowacourse.zzimkkong.dto.slack.SlackResponse;
56
import com.woowacourse.zzimkkong.service.ReservationService;
7+
import com.woowacourse.zzimkkong.service.SlackService;
68
import com.woowacourse.zzimkkong.service.strategy.GuestReservationStrategy;
79
import org.springframework.format.annotation.DateTimeFormat;
810
import org.springframework.http.ResponseEntity;
@@ -18,10 +20,14 @@
1820
@RestController
1921
@RequestMapping("/api/guests/maps/{mapId}/spaces")
2022
public class GuestReservationController {
23+
private final SlackService slackService;
2124
private final ReservationService reservationService;
2225
private final GuestReservationStrategy guestReservationStrategy;
2326

24-
public GuestReservationController(final ReservationService reservationService) {
27+
public GuestReservationController(
28+
final SlackService slackService,
29+
final ReservationService reservationService) {
30+
this.slackService = slackService;
2531
this.reservationService = reservationService;
2632
this.guestReservationStrategy = new GuestReservationStrategy();
2733
}
@@ -36,6 +42,7 @@ public ResponseEntity<Void> create(
3642
spaceId,
3743
reservationCreateUpdateWithPasswordRequest);
3844
ReservationCreateResponse reservationCreateResponse = reservationService.saveReservation(reservationCreateDto, guestReservationStrategy);
45+
slackService.sendCreateMessage(reservationCreateResponse.getSlackResponse());
3946
return ResponseEntity
4047
.created(URI.create("/api/guests/maps/" + mapId + "/spaces/" + spaceId + "/reservations/" + reservationCreateResponse.getId()))
4148
.build();
@@ -92,7 +99,8 @@ public ResponseEntity<Void> update(
9299
spaceId,
93100
reservationId,
94101
reservationCreateUpdateWithPasswordRequest);
95-
reservationService.updateReservation(reservationUpdateDto, guestReservationStrategy);
102+
SlackResponse slackResponse = reservationService.updateReservation(reservationUpdateDto, guestReservationStrategy);
103+
slackService.sendUpdateMessage(slackResponse);
96104
return ResponseEntity.ok().build();
97105
}
98106

@@ -107,7 +115,8 @@ public ResponseEntity<Void> delete(
107115
spaceId,
108116
reservationId,
109117
reservationPasswordAuthenticationRequest);
110-
reservationService.deleteReservation(reservationAuthenticationDto, guestReservationStrategy);
118+
SlackResponse slackResponse = reservationService.deleteReservation(reservationAuthenticationDto, guestReservationStrategy);
119+
slackService.sendDeleteMessage(slackResponse);
111120
return ResponseEntity.noContent().build();
112121
}
113122
}

backend/src/main/java/com/woowacourse/zzimkkong/controller/ManagerReservationController.java

+2-1
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ public ResponseEntity<Void> create(
4747
reservationCreateUpdateWithPasswordRequest,
4848
loginEmailDto);
4949
ReservationCreateResponse reservationCreateResponse = reservationService.saveReservation(reservationCreateDto, managerReservationStrategy);
50+
slackService.sendCreateMessage(reservationCreateResponse.getSlackResponse());
5051
return ResponseEntity
5152
.created(URI.create("/api/managers/maps/" + mapId + "/spaces/" + spaceId + "/reservations/" + reservationCreateResponse.getId()))
5253
.build();
@@ -125,7 +126,7 @@ public ResponseEntity<Void> delete(
125126
reservationId,
126127
loginEmailDto);
127128
SlackResponse slackResponse = reservationService.deleteReservation(reservationAuthenticationDto, managerReservationStrategy);
128-
slackService.sendUpdateMessage(slackResponse);
129+
slackService.sendDeleteMessage(slackResponse);
129130
return ResponseEntity.noContent().build();
130131
}
131132
}
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,23 @@
11
package com.woowacourse.zzimkkong.dto.reservation;
22

33
import com.woowacourse.zzimkkong.domain.Reservation;
4+
import com.woowacourse.zzimkkong.dto.slack.SlackResponse;
45
import lombok.Getter;
56
import lombok.NoArgsConstructor;
67

78
@Getter
89
@NoArgsConstructor
910
public class ReservationCreateResponse {
1011
private Long id;
12+
private SlackResponse slackResponse;
1113

12-
private ReservationCreateResponse(final Long id) {
14+
private ReservationCreateResponse(final Long id, final SlackResponse slackResponse) {
1315
this.id = id;
16+
this.slackResponse = slackResponse;
1417
}
1518

1619
public static ReservationCreateResponse from(final Reservation reservation) {
17-
return new ReservationCreateResponse(reservation.getId());
20+
SlackResponse slackResponse = SlackResponse.from(reservation);
21+
return new ReservationCreateResponse(reservation.getId(), slackResponse);
1822
}
1923
}

backend/src/main/java/com/woowacourse/zzimkkong/dto/slack/Attachments.java

+15-3
Original file line numberDiff line numberDiff line change
@@ -10,20 +10,32 @@
1010
@NoArgsConstructor
1111
public class Attachments {
1212
private static final String COLOR = "#FF7515";
13-
private static final String TITLE_LINK = "https://zzimkkong.o-r.kr/";
13+
private static final String TITLE_LINK_MESSAGE = "예약링크 바로가기";
14+
private static final String TITLE_LINK = "https://zzimkkong.com";
1415

1516
private List<Attachment> messageBody;
1617

1718
private Attachments(final List<Attachment> messageBody) {
1819
this.messageBody = messageBody;
1920
}
2021

22+
public static Attachments createMessageFrom(final SlackResponse slackResponse) {
23+
Attachment attachment = Attachment.of(
24+
"🎉 예약 생성 알림 🎉",
25+
COLOR,
26+
"🎉 예약이 생성되었습니다.",
27+
TITLE_LINK_MESSAGE,
28+
TITLE_LINK,
29+
slackResponse);
30+
return Attachments.from(attachment);
31+
}
32+
2133
public static Attachments updateMessageFrom(final SlackResponse slackResponse) {
2234
Attachment attachment = Attachment.of(
2335
"✏️ 예약 수정 알림 ✏️",
2436
COLOR,
2537
"✏️ 예약이 수정되었습니다.",
26-
"변경된 예약내용",
38+
TITLE_LINK_MESSAGE,
2739
TITLE_LINK,
2840
slackResponse);
2941
return Attachments.from(attachment);
@@ -34,7 +46,7 @@ public static Attachments deleteMessageFrom(final SlackResponse slackResponse) {
3446
"🗑 예약 삭제 알림 🗑",
3547
COLOR,
3648
"🗑 예약이 삭제되었습니다.",
37-
"삭제된 예약내용",
49+
TITLE_LINK_MESSAGE,
3850
TITLE_LINK,
3951
slackResponse);
4052
return Attachments.from(attachment);

backend/src/main/java/com/woowacourse/zzimkkong/service/ReservationService.java

+2-2
Original file line numberDiff line numberDiff line change
@@ -172,7 +172,7 @@ public SlackResponse updateReservation(
172172

173173
reservation.update(updateReservation, space);
174174

175-
return reservationStrategy.createSlackResponse(reservation);
175+
return SlackResponse.from(reservation);
176176
}
177177

178178
public SlackResponse deleteReservation(
@@ -196,7 +196,7 @@ public SlackResponse deleteReservation(
196196
reservationStrategy.checkCorrectPassword(reservation, password);
197197

198198
reservations.delete(reservation);
199-
return reservationStrategy.createSlackResponse(reservation);
199+
return SlackResponse.from(reservation);
200200
}
201201

202202
private void validateTime(final ReservationCreateDto reservationCreateDto) {

backend/src/main/java/com/woowacourse/zzimkkong/service/SlackService.java

+12-8
Original file line numberDiff line numberDiff line change
@@ -15,27 +15,31 @@
1515
@Transactional(readOnly = true)
1616
public class SlackService {
1717
private final SlackUrl slackUrl;
18+
private final RestTemplate restTemplate;
19+
private final HttpHeaders headers;
1820

1921
public SlackService(final SlackUrl slackUrl) {
2022
this.slackUrl = slackUrl;
23+
restTemplate = new RestTemplate();
24+
headers = new HttpHeaders();
25+
headers.setContentType(MediaType.APPLICATION_JSON);
2126
}
2227

23-
public void sendUpdateMessage(SlackResponse slackResponse) {
24-
RestTemplate restTemplate = new RestTemplate();
25-
HttpHeaders headers = new HttpHeaders();
26-
headers.setContentType(MediaType.APPLICATION_JSON);
28+
public void sendCreateMessage(SlackResponse slackResponse) {
29+
Attachments attachments = Attachments.createMessageFrom(slackResponse);
30+
HttpEntity<String> requestEntity = new HttpEntity<>(attachments.toString(), headers);
31+
32+
restTemplate.exchange(slackUrl.getUrl(), HttpMethod.POST, requestEntity, String.class);
33+
}
2734

35+
public void sendUpdateMessage(SlackResponse slackResponse) {
2836
Attachments attachments = Attachments.updateMessageFrom(slackResponse);
2937
HttpEntity<String> requestEntity = new HttpEntity<>(attachments.toString(), headers);
3038

3139
restTemplate.exchange(slackUrl.getUrl(), HttpMethod.POST, requestEntity, String.class);
3240
}
3341

3442
public void sendDeleteMessage(SlackResponse slackResponse) {
35-
RestTemplate restTemplate = new RestTemplate();
36-
HttpHeaders headers = new HttpHeaders();
37-
headers.setContentType(MediaType.APPLICATION_JSON);
38-
3943
Attachments attachments = Attachments.deleteMessageFrom(slackResponse);
4044
HttpEntity<String> requestEntity = new HttpEntity<>(attachments.toString(), headers);
4145

backend/src/main/java/com/woowacourse/zzimkkong/service/strategy/GuestReservationStrategy.java

-6
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22

33
import com.woowacourse.zzimkkong.domain.Map;
44
import com.woowacourse.zzimkkong.domain.Reservation;
5-
import com.woowacourse.zzimkkong.dto.slack.SlackResponse;
65
import com.woowacourse.zzimkkong.exception.reservation.ReservationPasswordException;
76
import com.woowacourse.zzimkkong.repository.MemberRepository;
87

@@ -18,9 +17,4 @@ public void checkCorrectPassword(final Reservation reservation, final String pas
1817
throw new ReservationPasswordException();
1918
}
2019
}
21-
22-
@Override
23-
public SlackResponse createSlackResponse(final Reservation reservation) {
24-
return null;
25-
}
2620
}

backend/src/main/java/com/woowacourse/zzimkkong/service/strategy/ManagerReservationStrategy.java

-6
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33
import com.woowacourse.zzimkkong.domain.Map;
44
import com.woowacourse.zzimkkong.domain.Member;
55
import com.woowacourse.zzimkkong.domain.Reservation;
6-
import com.woowacourse.zzimkkong.dto.slack.SlackResponse;
76
import com.woowacourse.zzimkkong.exception.authorization.NoAuthorityOnMapException;
87
import com.woowacourse.zzimkkong.exception.member.NoSuchMemberException;
98
import com.woowacourse.zzimkkong.repository.MemberRepository;
@@ -21,9 +20,4 @@ public void validateManagerOfMap(final Map map, final MemberRepository members,
2120
public void checkCorrectPassword(final Reservation reservation, final String password) {
2221
// manager는 비밀번호 확인과정이 없으므로 생략
2322
}
24-
25-
@Override
26-
public SlackResponse createSlackResponse(final Reservation reservation) {
27-
return SlackResponse.from(reservation);
28-
}
2923
}

backend/src/main/java/com/woowacourse/zzimkkong/service/strategy/ReservationStrategy.java

-2
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,4 @@ public interface ReservationStrategy {
99
void validateManagerOfMap(final Map map, final MemberRepository members, final String loginEmail);
1010

1111
void checkCorrectPassword(final Reservation reservation, final String password);
12-
13-
SlackResponse createSlackResponse(final Reservation reservation);
1412
}

backend/src/main/resources/config

Submodule infra-appender added at 1a4ed48

backend/src/main/resources/logback-spring.xml

+5-6
Original file line numberDiff line numberDiff line change
@@ -19,21 +19,20 @@
1919

2020
<root level="INFO">
2121
<appender-ref ref="CONSOLE_APPENDER"/>
22-
2322
</root>
2423
</springProfile>
2524

2625
<springProfile name="dev">
2726
<include resource="appenders/console-appender.xml"/>
28-
<include resource="appenders/logstash-appender-dev.xml"/>
27+
<include resource="infra-appender/kafka-appender-dev.xml"/>
2928

3029
<include resource="appenders/file-appender-info.xml"/>
3130
<include resource="appenders/file-appender-error.xml"/>
3231
<include resource="appenders/file-appender-warn.xml"/>
3332

3433
<root level="INFO">
3534
<appender-ref ref="CONSOLE_APPENDER"/>
36-
<appender-ref ref="STASH"/>
35+
<appender-ref ref="KAFKA_APPENDER_DEV"/>
3736

3837
<appender-ref ref="FILE_APPENDER_INFO"/>
3938
<appender-ref ref="FILE_APPENDER_ERROR"/>
@@ -43,14 +42,14 @@
4342

4443
<springProfile name="prod">
4544
<include resource="appenders/console-appender.xml"/>
46-
<include resource="appenders/logstash-appender-prod.xml"/>
45+
<include resource="infra-appender/kafka-appender-prod.xml"/>
4746

4847
<include resource="appenders/file-appender-error.xml"/>
4948
<include resource="appenders/file-appender-warn.xml"/>
5049

51-
<root level="WARN">
50+
<root level="INFO">
5251
<appender-ref ref="CONSOLE_APPENDER"/>
53-
<appender-ref ref="STASH"/>
52+
<appender-ref ref="KAFKA_APPENDER_PROD"/>
5453

5554
<appender-ref ref="FILE_APPENDER_ERROR"/>
5655
<appender-ref ref="FILE_APPENDER_WARN"/>

backend/src/test/java/com/woowacourse/zzimkkong/controller/AdminControllerTest.java

+5
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
import com.woowacourse.zzimkkong.dto.space.SpaceFindDetailWithIdResponse;
1212
import com.woowacourse.zzimkkong.infrastructure.auth.AuthorizationExtractor;
1313
import com.woowacourse.zzimkkong.service.AdminService;
14+
import com.woowacourse.zzimkkong.service.SlackService;
1415
import io.restassured.RestAssured;
1516
import io.restassured.response.ExtractableResponse;
1617
import io.restassured.response.Response;
@@ -19,6 +20,7 @@
1920
import org.junit.jupiter.api.Test;
2021
import org.junit.jupiter.params.ParameterizedTest;
2122
import org.junit.jupiter.params.provider.CsvSource;
23+
import org.springframework.boot.test.mock.mockito.MockBean;
2224
import org.springframework.http.HttpStatus;
2325
import org.springframework.http.MediaType;
2426
import org.springframework.http.ResponseEntity;
@@ -34,6 +36,9 @@
3436
import static org.mockito.Mockito.mock;
3537

3638
class AdminControllerTest extends AcceptanceTest {
39+
@MockBean
40+
private SlackService slackService;
41+
3742
private static final Member POBI = new Member(memberSaveRequest.getEmail(), memberSaveRequest.getPassword(), memberSaveRequest.getOrganization());
3843
private static final Map LUTHER = new Map(LUTHER_NAME, MAP_DRAWING_DATA, MAP_IMAGE_URL, POBI);
3944
private static final Setting BE_SETTING = Setting.builder()

backend/src/test/java/com/woowacourse/zzimkkong/controller/GuestReservationControllerTest.java

+5
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,14 @@
22

33
import com.woowacourse.zzimkkong.domain.*;
44
import com.woowacourse.zzimkkong.dto.reservation.*;
5+
import com.woowacourse.zzimkkong.service.SlackService;
56
import io.restassured.RestAssured;
67
import io.restassured.response.ExtractableResponse;
78
import io.restassured.response.Response;
89
import org.junit.jupiter.api.BeforeEach;
910
import org.junit.jupiter.api.DisplayName;
1011
import org.junit.jupiter.api.Test;
12+
import org.springframework.boot.test.mock.mockito.MockBean;
1113
import org.springframework.http.HttpStatus;
1214
import org.springframework.http.MediaType;
1315

@@ -21,6 +23,9 @@
2123
import static org.springframework.restdocs.restassured3.RestAssuredRestDocumentation.document;
2224

2325
class GuestReservationControllerTest extends AcceptanceTest {
26+
@MockBean
27+
private SlackService slackService;
28+
2429
private ReservationCreateUpdateWithPasswordRequest reservationCreateUpdateWithPasswordRequest;
2530
private Reservation savedReservation;
2631
private String beReservationApi;

0 commit comments

Comments
 (0)