Skip to content

Commit

Permalink
Merge pull request #124 from gloddy-dev/feat/message-adapter
Browse files Browse the repository at this point in the history
[FEAT]: 기존 서버 Adapter 구현 및 AWS SNS Publisher 구축
  • Loading branch information
jihwan2da committed Nov 6, 2023
2 parents 5b31ad8 + 8db3791 commit 7829896
Show file tree
Hide file tree
Showing 21 changed files with 306 additions and 2 deletions.
2 changes: 2 additions & 0 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,8 @@ dependencies {

//AWS
implementation 'org.springframework.cloud:spring-cloud-starter-aws:2.2.6.RELEASE'
implementation platform("io.awspring.cloud:spring-cloud-aws-dependencies:3.0.0")
implementation 'io.awspring.cloud:spring-cloud-aws-starter-sns'

//swagger
implementation 'org.springdoc:springdoc-openapi-starter-webmvc-ui:2.1.0'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import com.gloddy.server.apply.domain.handler.ApplyQueryHandler;
import com.gloddy.server.apply.domain.service.*;
import com.gloddy.server.apply.domain.vo.Status;
import com.gloddy.server.apply.event.ApplyCreateEvent;
import com.gloddy.server.apply.event.producer.ApplyEventProducer;
import com.gloddy.server.auth.domain.User;
import com.gloddy.server.core.event.GroupParticipateEvent;
Expand All @@ -30,6 +31,7 @@ public class ApplyService {
private final GroupQueryHandler groupQueryHandler;
private final RejectedApplyCheckExecutor rejectedApplyCheckExecutor;
private final ApplyStatusUpdateExecutor applyStatusUpdateExecutor;
private final ApplyEventProducer applyEventProducer;

@Transactional
public ApplyResponse.Create createApply(Long userId, Long groupId, ApplyRequest.Create request) {
Expand All @@ -38,6 +40,7 @@ public ApplyResponse.Create createApply(Long userId, Long groupId, ApplyRequest.
Apply apply = applyCommandHandler.save(
group.createApply(user, request.getIntroduce(), request.getReason())
);
applyEventProducer.produceEvent(new ApplyCreateEvent(userId, groupId, apply.getId()));
return new ApplyResponse.Create(apply.getId());
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,13 @@
import com.gloddy.server.apply.domain.Apply;
import com.gloddy.server.apply.domain.handler.ApplyQueryHandler;
import com.gloddy.server.apply.domain.vo.Status;
import com.gloddy.server.apply.event.ApplyStatusUpdateEvent;
import com.gloddy.server.apply.event.producer.ApplyEventProducer;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Component;

import static com.gloddy.server.apply.domain.vo.Status.*;

@Component
@RequiredArgsConstructor
public class ApplyStatusUpdateExecutor {
Expand All @@ -27,5 +30,7 @@ public void execute(Long userId, Long applyId, Status status) {
} else {
throw new RuntimeException("Apply Status Invalid");
}

applyEventProducer.produceEvent(new ApplyStatusUpdateEvent(userId, apply.getGroup().getId(), applyId, status));
}
}
16 changes: 16 additions & 0 deletions src/main/java/com/gloddy/server/apply/event/ApplyCreateEvent.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package com.gloddy.server.apply.event;

import com.gloddy.server.core.event.Event;
import lombok.AccessLevel;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;

@NoArgsConstructor(access = AccessLevel.PROTECTED)
@AllArgsConstructor
@Getter
public class ApplyCreateEvent implements Event {
private Long userId;
private Long groupId;
private Long applyId;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package com.gloddy.server.apply.event;

import com.gloddy.server.apply.domain.vo.Status;
import com.gloddy.server.core.event.Event;
import lombok.AccessLevel;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;

@Getter
@NoArgsConstructor(access = AccessLevel.PROTECTED)
@AllArgsConstructor
public class ApplyStatusUpdateEvent implements Event {
private Long userId;
private Long groupId;
private Long applyId;
private Status status;
}
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ public void delete(Long userId, Long groupId) {
deleteGroupMemberVo(userId, groupId);
deleteGroupMember(userId, groupId);

groupMemberEventProducer.produceEvent(new GroupMemberLeaveEvent(userId));
groupMemberEventProducer.produceEvent(new GroupMemberLeaveEvent(userId, groupId));
}

private void deleteGroupMemberVo(Long userId, Long groupId) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,5 @@
@NoArgsConstructor(access = AccessLevel.PROTECTED)
public class GroupMemberLeaveEvent implements Event {
private Long userId;
private Long groupId;
}
4 changes: 4 additions & 0 deletions src/main/java/com/gloddy/server/messaging/AdapterEvent.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
package com.gloddy.server.messaging;

public interface AdapterEvent {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package com.gloddy.server.messaging;

import com.gloddy.server.messaging.adapter.apply.event.ApplyAdapterEvent;
import com.gloddy.server.messaging.adapter.group.event.GroupMemberAdapterEvent;

public interface MessagePublisher {
void publishApplyEvent(ApplyAdapterEvent event);
void publishGroupMemberEvent(GroupMemberAdapterEvent event);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package com.gloddy.server.messaging.adapter.apply.event;

import com.gloddy.server.messaging.AdapterEvent;
import lombok.AccessLevel;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;

@NoArgsConstructor(access = AccessLevel.PROTECTED)
@AllArgsConstructor
@Getter
public class ApplyAdapterEvent implements AdapterEvent {
private Long userId;
private Long groupId;
private Long applyId;
private ApplyEventType eventType;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package com.gloddy.server.messaging.adapter.apply.event;

import lombok.AllArgsConstructor;
import lombok.Getter;

@AllArgsConstructor
@Getter
public enum ApplyEventType {
APPLY_CREATE("지원서가 생성 되었을 때"),
APPLY_APPROVE("지원서가 승인 처리 되었을 때"),
APPLY_REFUSE("지원서가 거절 처리 되었을 때");

private final String description;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package com.gloddy.server.messaging.adapter.apply.handler;

import com.gloddy.server.apply.event.ApplyCreateEvent;
import com.gloddy.server.apply.event.ApplyStatusUpdateEvent;
import com.gloddy.server.messaging.MessagePublisher;
import com.gloddy.server.messaging.adapter.apply.event.ApplyAdapterEvent;
import com.gloddy.server.messaging.adapter.apply.mapper.ApplyEventMapper;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Component;
import org.springframework.transaction.event.TransactionPhase;
import org.springframework.transaction.event.TransactionalEventListener;

@Component
@RequiredArgsConstructor
public class ApplyAdapterEventHandler {

private final MessagePublisher messagePublisher;

@TransactionalEventListener(phase = TransactionPhase.AFTER_COMMIT)
public void handle(ApplyCreateEvent event) {
ApplyAdapterEvent adapterEvent = ApplyEventMapper.mapToApplyAdapterEventFrom(event);
messagePublisher.publishApplyEvent(adapterEvent);
}

@TransactionalEventListener(phase = TransactionPhase.AFTER_COMMIT)
public void handle(ApplyStatusUpdateEvent event) {
ApplyAdapterEvent adapterEvent = ApplyEventMapper.mapToApplyAdapterEventFrom(event);
messagePublisher.publishApplyEvent(adapterEvent);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
package com.gloddy.server.messaging.adapter.apply.mapper;

import com.gloddy.server.apply.domain.vo.Status;
import com.gloddy.server.apply.event.ApplyCreateEvent;
import com.gloddy.server.apply.event.ApplyStatusUpdateEvent;
import com.gloddy.server.messaging.adapter.apply.event.ApplyAdapterEvent;
import com.gloddy.server.messaging.adapter.apply.event.ApplyEventType;

public class ApplyEventMapper {

public static ApplyAdapterEvent mapToApplyAdapterEventFrom(ApplyCreateEvent applyCreateEvent) {
return new ApplyAdapterEvent(
applyCreateEvent.getUserId(),
applyCreateEvent.getGroupId(),
applyCreateEvent.getApplyId(),
ApplyEventType.APPLY_CREATE
);
}

public static ApplyAdapterEvent mapToApplyAdapterEventFrom(ApplyStatusUpdateEvent applyStatusUpdateEvent) {
return new ApplyAdapterEvent(
applyStatusUpdateEvent.getUserId(),
applyStatusUpdateEvent.getGroupId(),
applyStatusUpdateEvent.getApplyId(),
getApplyEventType(applyStatusUpdateEvent.getStatus())
);
}

private static ApplyEventType getApplyEventType(Status status) {
if (status.isApprove()) {
return ApplyEventType.APPLY_APPROVE;
} else if (status.isRefuse()) {
return ApplyEventType.APPLY_REFUSE;
} else {
throw new RuntimeException("invalid apply status");
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package com.gloddy.server.messaging.adapter.group.event;

import com.gloddy.server.messaging.AdapterEvent;
import lombok.AccessLevel;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;

@NoArgsConstructor(access = AccessLevel.PROTECTED)
@AllArgsConstructor
@Getter
public class GroupMemberAdapterEvent implements AdapterEvent {
private Long userId;
private Long groupId;
private GroupMemberEventType eventType;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package com.gloddy.server.messaging.adapter.group.event;

import lombok.AllArgsConstructor;
import lombok.Getter;

@AllArgsConstructor
@Getter
public enum GroupMemberEventType {
GROUP_MEMBER_LEAVE("그룹 멤버가 모임을 나갔을 때");

private final String description;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package com.gloddy.server.messaging.adapter.group.handler;

import com.gloddy.server.group_member.event.GroupMemberLeaveEvent;
import com.gloddy.server.messaging.MessagePublisher;
import com.gloddy.server.messaging.adapter.group.event.GroupMemberAdapterEvent;
import com.gloddy.server.messaging.adapter.group.event.GroupMemberEventType;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Component;
import org.springframework.transaction.event.TransactionPhase;
import org.springframework.transaction.event.TransactionalEventListener;

@Component
@RequiredArgsConstructor
public class GroupMemberAdapterEventHandler {
private final MessagePublisher messagePublisher;

@TransactionalEventListener(phase = TransactionPhase.AFTER_COMMIT)
public void handle(GroupMemberLeaveEvent event) {
GroupMemberAdapterEvent adapterEvent = new GroupMemberAdapterEvent(
event.getUserId(),
event.getGroupId(),
GroupMemberEventType.GROUP_MEMBER_LEAVE);

messagePublisher.publishGroupMemberEvent(adapterEvent);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package com.gloddy.server.messaging.sns.config;

import io.awspring.cloud.sns.core.TopicArnResolver;
import io.awspring.cloud.sns.core.TopicsListingTopicArnResolver;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import software.amazon.awssdk.services.sns.SnsClient;

@Configuration
@EnableConfigurationProperties(SnsProperties.class)
public class SnsConfig {

@Bean
public TopicArnResolver topicArnResolver(SnsClient snsClient) {
return new TopicsListingTopicArnResolver(snsClient);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package com.gloddy.server.messaging.sns.config;

import lombok.Getter;
import lombok.Setter;
import org.springframework.boot.context.properties.ConfigurationProperties;

@ConfigurationProperties("spring.cloud.event")
@Getter
@Setter
public class SnsProperties {
private String applyTopic;
private String groupMemberTopic;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
package com.gloddy.server.messaging.sns.publisher;

import com.gloddy.server.messaging.AdapterEvent;
import com.gloddy.server.messaging.MessagePublisher;
import com.gloddy.server.messaging.adapter.apply.event.ApplyAdapterEvent;
import com.gloddy.server.messaging.adapter.group.event.GroupMemberAdapterEvent;
import com.gloddy.server.messaging.sns.config.SnsProperties;
import io.awspring.cloud.sns.core.SnsTemplate;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.lang.Nullable;
import org.springframework.stereotype.Component;

@Component
@Slf4j
@RequiredArgsConstructor
public class SnsPublisher implements MessagePublisher {

private final SnsProperties snsProperties;
private final SnsTemplate snsTemplate;

@Override
public void publishApplyEvent(ApplyAdapterEvent event) {
send(snsProperties.getApplyTopic(), event, null);
}

@Override
public void publishGroupMemberEvent(GroupMemberAdapterEvent event) {
send(snsProperties.getGroupMemberTopic(), event, null);
}

private void send(String topicName, AdapterEvent event, @Nullable String subject) {
log.info("이벤트 발행 시작(AWS SNS)");
try {
snsTemplate.sendNotification(topicName, event, subject);
} catch (Exception e) {
log.error(e.getMessage());
}
log.info("이벤트 발행 완료(AWS SNS)");
}
}
12 changes: 11 additions & 1 deletion src/main/resources/application.yml
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,17 @@ spring:
max-file-size: ${MAX_FILE_SIZE}
max-request-size: ${MAX_REQUEST_SIZE}

cloud:
aws:
credentials:
access-key: ${AWS_ACCESS_KEY}
secret-key: ${AWS_SECRET_KEY}
region:
static: ap-northeast-2
event:
apply-topic: ${APPLY_TOPIC}
group-member-topic: ${GROUP_MEMBER_TOPIC}

logging:
level:
com.gloddy.server.authSms.infra: debug
Expand Down Expand Up @@ -79,4 +90,3 @@ springdoc:
swagger-ui:
url: /v3/api-docs
urls-primary-name: Gloddy

11 changes: 11 additions & 0 deletions src/test/resources/application.yml
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,17 @@ spring:
pathmatch:
matching-strategy: ant_path_matcher

cloud:
aws:
credentials:
access-key: dummy-key
secret-key: dummy-key
region:
static: ap-northeast-2
event:
apply-topic: dummy-apply-topic
group-member-topic: dummy-group-member-topic

jwt:
header: X-AUTH-TOKEN
secret: testJwtSecret-testJwtSecret-testJwtSecret-testJwtSecret-testJwtSecret-testJwtSecret
Expand Down

0 comments on commit 7829896

Please sign in to comment.