Skip to content

Commit

Permalink
Merge pull request #645 from woowacourse-teams/dev
Browse files Browse the repository at this point in the history
main v1.3.0 배포
  • Loading branch information
dusdn1702 authored Oct 13, 2021
2 parents de36841 + 5433090 commit 311773b
Show file tree
Hide file tree
Showing 46 changed files with 759 additions and 185 deletions.
4 changes: 4 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,7 @@
path = s3proxy/src/main/resources/s3proxy-config
url = [email protected]:zzimkkong/s3proxy-config.git
branch = main
[submodule "backend/src/main/resources/infra-appender"]
path = backend/src/main/resources/infra-appender
url = [email protected]:zzimkkong/infra-appender.git
branch = main
2 changes: 2 additions & 0 deletions backend/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,8 @@ dependencies {
// Logstash
implementation 'net.logstash.logback:logstash-logback-encoder:6.6'

// Kafka Appender
implementation 'com.github.danielwegener:logback-kafka-appender:0.2.0-RC2'
}

test {
Expand Down
20 changes: 20 additions & 0 deletions backend/docker/main/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
FROM ubuntu:18.04

LABEL email="[email protected]"
LABEL name="sakjung"
LABEL description="zzimkkong main application"

RUN apt-get -y update
RUN apt-get install -y openjdk-11-jdk

# run application
WORKDIR /home/ubuntu
COPY build/libs/backend-0.0.1-SNAPSHOT.jar app.jar
RUN mkdir zzimkkong && mkdir zzimkkong/tmp

EXPOSE 8080

# 빌드시 명령어에 옵션 추가: --build-arg CLUSTER_IP=<cluster ip>
ENV CLUSTER_IP="IP"

ENTRYPOINT ["java", "-Ds3proxy.server-uri=http://${CLUSTER_IP}", "-Dspring.profiles.active=prod", "-jar", "app.jar", "--spring.config.location=classpath:config/application-prod.properties"]
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,15 @@
@PropertySource("classpath:config/slack.properties")
public class SlackConfig implements WebMvcConfigurer {
@Bean
@Profile("!test")
public SlackUrl slackUrl(
@Profile("prod")
public SlackUrl slackUrlProd(
@Value("${slack.webhook.prod}") final String prodUrl) {
return new SlackUrl(prodUrl);
}

@Bean
@Profile({"local", "dev"})
public SlackUrl slackUrlDev(
@Value("${slack.webhook.local}") final String devUrl) {
return new SlackUrl(devUrl);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@

import com.woowacourse.zzimkkong.config.logaspect.LogMethodExecutionTime;
import com.woowacourse.zzimkkong.dto.reservation.*;
import com.woowacourse.zzimkkong.dto.slack.SlackResponse;
import com.woowacourse.zzimkkong.service.ReservationService;
import com.woowacourse.zzimkkong.service.SlackService;
import com.woowacourse.zzimkkong.service.strategy.GuestReservationStrategy;
import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.http.ResponseEntity;
Expand All @@ -18,10 +20,14 @@
@RestController
@RequestMapping("/api/guests/maps/{mapId}/spaces")
public class GuestReservationController {
private final SlackService slackService;
private final ReservationService reservationService;
private final GuestReservationStrategy guestReservationStrategy;

public GuestReservationController(final ReservationService reservationService) {
public GuestReservationController(
final SlackService slackService,
final ReservationService reservationService) {
this.slackService = slackService;
this.reservationService = reservationService;
this.guestReservationStrategy = new GuestReservationStrategy();
}
Expand All @@ -36,6 +42,7 @@ public ResponseEntity<Void> create(
spaceId,
reservationCreateUpdateWithPasswordRequest);
ReservationCreateResponse reservationCreateResponse = reservationService.saveReservation(reservationCreateDto, guestReservationStrategy);
slackService.sendCreateMessage(reservationCreateResponse.getSlackResponse());
return ResponseEntity
.created(URI.create("/api/guests/maps/" + mapId + "/spaces/" + spaceId + "/reservations/" + reservationCreateResponse.getId()))
.build();
Expand Down Expand Up @@ -92,7 +99,8 @@ public ResponseEntity<Void> update(
spaceId,
reservationId,
reservationCreateUpdateWithPasswordRequest);
reservationService.updateReservation(reservationUpdateDto, guestReservationStrategy);
SlackResponse slackResponse = reservationService.updateReservation(reservationUpdateDto, guestReservationStrategy);
slackService.sendUpdateMessage(slackResponse);
return ResponseEntity.ok().build();
}

Expand All @@ -107,7 +115,8 @@ public ResponseEntity<Void> delete(
spaceId,
reservationId,
reservationPasswordAuthenticationRequest);
reservationService.deleteReservation(reservationAuthenticationDto, guestReservationStrategy);
SlackResponse slackResponse = reservationService.deleteReservation(reservationAuthenticationDto, guestReservationStrategy);
slackService.sendDeleteMessage(slackResponse);
return ResponseEntity.noContent().build();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ public ResponseEntity<Void> create(
reservationCreateUpdateWithPasswordRequest,
loginEmailDto);
ReservationCreateResponse reservationCreateResponse = reservationService.saveReservation(reservationCreateDto, managerReservationStrategy);
slackService.sendCreateMessage(reservationCreateResponse.getSlackResponse());
return ResponseEntity
.created(URI.create("/api/managers/maps/" + mapId + "/spaces/" + spaceId + "/reservations/" + reservationCreateResponse.getId()))
.build();
Expand Down Expand Up @@ -125,7 +126,7 @@ public ResponseEntity<Void> delete(
reservationId,
loginEmailDto);
SlackResponse slackResponse = reservationService.deleteReservation(reservationAuthenticationDto, managerReservationStrategy);
slackService.sendUpdateMessage(slackResponse);
slackService.sendDeleteMessage(slackResponse);
return ResponseEntity.noContent().build();
}
}
Original file line number Diff line number Diff line change
@@ -1,19 +1,23 @@
package com.woowacourse.zzimkkong.dto.reservation;

import com.woowacourse.zzimkkong.domain.Reservation;
import com.woowacourse.zzimkkong.dto.slack.SlackResponse;
import lombok.Getter;
import lombok.NoArgsConstructor;

@Getter
@NoArgsConstructor
public class ReservationCreateResponse {
private Long id;
private SlackResponse slackResponse;

private ReservationCreateResponse(final Long id) {
private ReservationCreateResponse(final Long id, final SlackResponse slackResponse) {
this.id = id;
this.slackResponse = slackResponse;
}

public static ReservationCreateResponse from(final Reservation reservation) {
return new ReservationCreateResponse(reservation.getId());
SlackResponse slackResponse = SlackResponse.from(reservation);
return new ReservationCreateResponse(reservation.getId(), slackResponse);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,20 +10,32 @@
@NoArgsConstructor
public class Attachments {
private static final String COLOR = "#FF7515";
private static final String TITLE_LINK = "https://zzimkkong.o-r.kr/";
private static final String TITLE_LINK_MESSAGE = "예약링크 바로가기";
private static final String TITLE_LINK = "https://zzimkkong.com";

private List<Attachment> messageBody;

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

public static Attachments createMessageFrom(final SlackResponse slackResponse) {
Attachment attachment = Attachment.of(
"🎉 예약 생성 알림 🎉",
COLOR,
"🎉 예약이 생성되었습니다.",
TITLE_LINK_MESSAGE,
TITLE_LINK,
slackResponse);
return Attachments.from(attachment);
}

public static Attachments updateMessageFrom(final SlackResponse slackResponse) {
Attachment attachment = Attachment.of(
"✏️ 예약 수정 알림 ✏️",
COLOR,
"✏️ 예약이 수정되었습니다.",
"변경된 예약내용",
TITLE_LINK_MESSAGE,
TITLE_LINK,
slackResponse);
return Attachments.from(attachment);
Expand All @@ -34,7 +46,7 @@ public static Attachments deleteMessageFrom(final SlackResponse slackResponse) {
"🗑 예약 삭제 알림 🗑",
COLOR,
"🗑 예약이 삭제되었습니다.",
"삭제된 예약내용",
TITLE_LINK_MESSAGE,
TITLE_LINK,
slackResponse);
return Attachments.from(attachment);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -172,7 +172,7 @@ public SlackResponse updateReservation(

reservation.update(updateReservation, space);

return reservationStrategy.createSlackResponse(reservation);
return SlackResponse.from(reservation);
}

public SlackResponse deleteReservation(
Expand All @@ -196,7 +196,7 @@ public SlackResponse deleteReservation(
reservationStrategy.checkCorrectPassword(reservation, password);

reservations.delete(reservation);
return reservationStrategy.createSlackResponse(reservation);
return SlackResponse.from(reservation);
}

private void validateTime(final ReservationCreateDto reservationCreateDto) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,27 +15,31 @@
@Transactional(readOnly = true)
public class SlackService {
private final SlackUrl slackUrl;
private final RestTemplate restTemplate;
private final HttpHeaders headers;

public SlackService(final SlackUrl slackUrl) {
this.slackUrl = slackUrl;
restTemplate = new RestTemplate();
headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
}

public void sendUpdateMessage(SlackResponse slackResponse) {
RestTemplate restTemplate = new RestTemplate();
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
public void sendCreateMessage(SlackResponse slackResponse) {
Attachments attachments = Attachments.createMessageFrom(slackResponse);
HttpEntity<String> requestEntity = new HttpEntity<>(attachments.toString(), headers);

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

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

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

public void sendDeleteMessage(SlackResponse slackResponse) {
RestTemplate restTemplate = new RestTemplate();
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);

Attachments attachments = Attachments.deleteMessageFrom(slackResponse);
HttpEntity<String> requestEntity = new HttpEntity<>(attachments.toString(), headers);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@

import com.woowacourse.zzimkkong.domain.Map;
import com.woowacourse.zzimkkong.domain.Reservation;
import com.woowacourse.zzimkkong.dto.slack.SlackResponse;
import com.woowacourse.zzimkkong.exception.reservation.ReservationPasswordException;
import com.woowacourse.zzimkkong.repository.MemberRepository;

Expand All @@ -18,9 +17,4 @@ public void checkCorrectPassword(final Reservation reservation, final String pas
throw new ReservationPasswordException();
}
}

@Override
public SlackResponse createSlackResponse(final Reservation reservation) {
return null;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
import com.woowacourse.zzimkkong.domain.Map;
import com.woowacourse.zzimkkong.domain.Member;
import com.woowacourse.zzimkkong.domain.Reservation;
import com.woowacourse.zzimkkong.dto.slack.SlackResponse;
import com.woowacourse.zzimkkong.exception.authorization.NoAuthorityOnMapException;
import com.woowacourse.zzimkkong.exception.member.NoSuchMemberException;
import com.woowacourse.zzimkkong.repository.MemberRepository;
Expand All @@ -21,9 +20,4 @@ public void validateManagerOfMap(final Map map, final MemberRepository members,
public void checkCorrectPassword(final Reservation reservation, final String password) {
// manager는 비밀번호 확인과정이 없으므로 생략
}

@Override
public SlackResponse createSlackResponse(final Reservation reservation) {
return SlackResponse.from(reservation);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,4 @@ public interface ReservationStrategy {
void validateManagerOfMap(final Map map, final MemberRepository members, final String loginEmail);

void checkCorrectPassword(final Reservation reservation, final String password);

SlackResponse createSlackResponse(final Reservation reservation);
}
2 changes: 1 addition & 1 deletion backend/src/main/resources/config
1 change: 1 addition & 0 deletions backend/src/main/resources/infra-appender
Submodule infra-appender added at 1a4ed4
11 changes: 5 additions & 6 deletions backend/src/main/resources/logback-spring.xml
Original file line number Diff line number Diff line change
Expand Up @@ -19,21 +19,20 @@

<root level="INFO">
<appender-ref ref="CONSOLE_APPENDER"/>

</root>
</springProfile>

<springProfile name="dev">
<include resource="appenders/console-appender.xml"/>
<include resource="appenders/logstash-appender-dev.xml"/>
<include resource="infra-appender/kafka-appender-dev.xml"/>

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

<root level="INFO">
<appender-ref ref="CONSOLE_APPENDER"/>
<appender-ref ref="STASH"/>
<appender-ref ref="KAFKA_APPENDER_DEV"/>

<appender-ref ref="FILE_APPENDER_INFO"/>
<appender-ref ref="FILE_APPENDER_ERROR"/>
Expand All @@ -43,14 +42,14 @@

<springProfile name="prod">
<include resource="appenders/console-appender.xml"/>
<include resource="appenders/logstash-appender-prod.xml"/>
<include resource="infra-appender/kafka-appender-prod.xml"/>

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

<root level="WARN">
<root level="INFO">
<appender-ref ref="CONSOLE_APPENDER"/>
<appender-ref ref="STASH"/>
<appender-ref ref="KAFKA_APPENDER_PROD"/>

<appender-ref ref="FILE_APPENDER_ERROR"/>
<appender-ref ref="FILE_APPENDER_WARN"/>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
import com.woowacourse.zzimkkong.dto.space.SpaceFindDetailWithIdResponse;
import com.woowacourse.zzimkkong.infrastructure.auth.AuthorizationExtractor;
import com.woowacourse.zzimkkong.service.AdminService;
import com.woowacourse.zzimkkong.service.SlackService;
import io.restassured.RestAssured;
import io.restassured.response.ExtractableResponse;
import io.restassured.response.Response;
Expand All @@ -19,6 +20,7 @@
import org.junit.jupiter.api.Test;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.CsvSource;
import org.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
Expand All @@ -34,6 +36,9 @@
import static org.mockito.Mockito.mock;

class AdminControllerTest extends AcceptanceTest {
@MockBean
private SlackService slackService;

private static final Member POBI = new Member(memberSaveRequest.getEmail(), memberSaveRequest.getPassword(), memberSaveRequest.getOrganization());
private static final Map LUTHER = new Map(LUTHER_NAME, MAP_DRAWING_DATA, MAP_IMAGE_URL, POBI);
private static final Setting BE_SETTING = Setting.builder()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,14 @@

import com.woowacourse.zzimkkong.domain.*;
import com.woowacourse.zzimkkong.dto.reservation.*;
import com.woowacourse.zzimkkong.service.SlackService;
import io.restassured.RestAssured;
import io.restassured.response.ExtractableResponse;
import io.restassured.response.Response;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;

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

class GuestReservationControllerTest extends AcceptanceTest {
@MockBean
private SlackService slackService;

private ReservationCreateUpdateWithPasswordRequest reservationCreateUpdateWithPasswordRequest;
private Reservation savedReservation;
private String beReservationApi;
Expand Down
Loading

0 comments on commit 311773b

Please sign in to comment.