From 6ab33da006244c006f3c1ea2bd8cd9096bcd327d Mon Sep 17 00:00:00 2001 From: hseong3243 Date: Mon, 25 Mar 2024 16:25:59 +0900 Subject: [PATCH] =?UTF-8?q?feat:=20=EB=8F=84=EB=A9=94=EC=9D=B8=20=EC=9D=B4?= =?UTF-8?q?=EB=B2=A4=ED=8A=B8=20=EB=A6=AC=EC=8A=A4=EB=84=88=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/link/service/LinkService.java | 4 +- .../link/service/event/CreateLinkEvent.java | 2 +- .../shoutlink/global/config/EventConfig.java | 7 + .../global/event/DomainEventListener.java | 21 +++ .../seong/shoutlink/base/DatabaseCleaner.java | 8 +- .../global/event/DomainEventListenerTest.java | 127 ++++++++++++++++++ src/test/resources/application.yml | 6 + 7 files changed, 166 insertions(+), 9 deletions(-) create mode 100644 src/main/java/com/seong/shoutlink/global/event/DomainEventListener.java create mode 100644 src/test/java/com/seong/shoutlink/global/event/DomainEventListenerTest.java diff --git a/src/main/java/com/seong/shoutlink/domain/link/service/LinkService.java b/src/main/java/com/seong/shoutlink/domain/link/service/LinkService.java index efa3189..f816e8c 100644 --- a/src/main/java/com/seong/shoutlink/domain/link/service/LinkService.java +++ b/src/main/java/com/seong/shoutlink/domain/link/service/LinkService.java @@ -45,7 +45,7 @@ public CreateLinkResponse createLink(CreateLinkCommand command) { Link link = new Link(command.url(), command.description()); LinkWithLinkBundle linkWithLinkBundle = new LinkWithLinkBundle(link, linkBundle); Long linkId = linkRepository.save(linkWithLinkBundle); - eventPublisher.publishEvent(new CreateLinkEvent(command.url())); + eventPublisher.publishEvent(new CreateLinkEvent(linkId, command.url())); return new CreateLinkResponse(linkId); } @@ -78,7 +78,7 @@ public CreateHubLinkResponse createHubLink(CreateHubLinkCommand command) { LinkBundle hubLinkBundle = getHubLinkBundle(command.linkBundleId(), hub); Link link = new Link(command.url(), command.description()); Long linkId = linkRepository.save(new LinkWithLinkBundle(link, hubLinkBundle)); - eventPublisher.publishEvent(new CreateLinkEvent(command.url())); + eventPublisher.publishEvent(new CreateLinkEvent(linkId, command.url())); return new CreateHubLinkResponse(linkId); } diff --git a/src/main/java/com/seong/shoutlink/domain/link/service/event/CreateLinkEvent.java b/src/main/java/com/seong/shoutlink/domain/link/service/event/CreateLinkEvent.java index 0f9f6ee..b03f114 100644 --- a/src/main/java/com/seong/shoutlink/domain/link/service/event/CreateLinkEvent.java +++ b/src/main/java/com/seong/shoutlink/domain/link/service/event/CreateLinkEvent.java @@ -2,6 +2,6 @@ import com.seong.shoutlink.domain.common.Event; -public record CreateLinkEvent(String url) implements Event { +public record CreateLinkEvent(Long linkId, String url) implements Event { } diff --git a/src/main/java/com/seong/shoutlink/global/config/EventConfig.java b/src/main/java/com/seong/shoutlink/global/config/EventConfig.java index f87cf5b..a42787e 100644 --- a/src/main/java/com/seong/shoutlink/global/config/EventConfig.java +++ b/src/main/java/com/seong/shoutlink/global/config/EventConfig.java @@ -1,7 +1,9 @@ package com.seong.shoutlink.global.config; import com.seong.shoutlink.domain.common.EventPublisher; +import com.seong.shoutlink.domain.domain.service.DomainService; import com.seong.shoutlink.domain.linkbundle.service.LinkBundleService; +import com.seong.shoutlink.global.event.DomainEventListener; import com.seong.shoutlink.global.event.LinkBundleEventListener; import com.seong.shoutlink.global.event.SpringEventPublisher; import org.springframework.context.ApplicationEventPublisher; @@ -20,4 +22,9 @@ public EventPublisher eventPublisher(ApplicationEventPublisher applicationEventP public LinkBundleEventListener springEventListener(LinkBundleService linkBundleService) { return new LinkBundleEventListener(linkBundleService); } + + @Bean + public DomainEventListener domainEventListener(DomainService domainService) { + return new DomainEventListener(domainService); + } } diff --git a/src/main/java/com/seong/shoutlink/global/event/DomainEventListener.java b/src/main/java/com/seong/shoutlink/global/event/DomainEventListener.java new file mode 100644 index 0000000..8ef9d81 --- /dev/null +++ b/src/main/java/com/seong/shoutlink/global/event/DomainEventListener.java @@ -0,0 +1,21 @@ +package com.seong.shoutlink.global.event; + +import com.seong.shoutlink.domain.domain.service.DomainService; +import com.seong.shoutlink.domain.domain.service.request.UpdateDomainCommand; +import com.seong.shoutlink.domain.link.service.event.CreateLinkEvent; +import lombok.RequiredArgsConstructor; +import org.springframework.transaction.annotation.Propagation; +import org.springframework.transaction.annotation.Transactional; +import org.springframework.transaction.event.TransactionalEventListener; + +@RequiredArgsConstructor +public class DomainEventListener { + + private final DomainService domainService; + + @TransactionalEventListener + @Transactional(propagation = Propagation.REQUIRES_NEW) + public void updateDomainInfo(CreateLinkEvent event) { + domainService.updateDomain(new UpdateDomainCommand(event.linkId(), event.url())); + } +} diff --git a/src/test/java/com/seong/shoutlink/base/DatabaseCleaner.java b/src/test/java/com/seong/shoutlink/base/DatabaseCleaner.java index 18d6ebe..65400bb 100644 --- a/src/test/java/com/seong/shoutlink/base/DatabaseCleaner.java +++ b/src/test/java/com/seong/shoutlink/base/DatabaseCleaner.java @@ -1,7 +1,6 @@ package com.seong.shoutlink.base; -import com.seong.shoutlink.domain.linkbundle.repository.HubLinkBundleEntity; -import com.seong.shoutlink.domain.linkbundle.repository.MemberLinkBundleEntity; +import jakarta.persistence.DiscriminatorValue; import jakarta.persistence.EntityManager; import jakarta.persistence.Table; import jakarta.persistence.metamodel.Type; @@ -22,10 +21,7 @@ public DatabaseCleaner(EntityManager em) { .getEntities() .stream() .map(Type::getJavaType) - .filter(j -> - !(j.isAssignableFrom(HubLinkBundleEntity.class) - || j.isAssignableFrom(MemberLinkBundleEntity.class)) - ) + .filter(j -> !j.isAnnotationPresent(DiscriminatorValue.class)) .map(javaType -> javaType.getAnnotation(Table.class)) .map(Table::name) .toList(); diff --git a/src/test/java/com/seong/shoutlink/global/event/DomainEventListenerTest.java b/src/test/java/com/seong/shoutlink/global/event/DomainEventListenerTest.java new file mode 100644 index 0000000..e3f7c65 --- /dev/null +++ b/src/test/java/com/seong/shoutlink/global/event/DomainEventListenerTest.java @@ -0,0 +1,127 @@ +package com.seong.shoutlink.global.event; + +import static org.assertj.core.api.Assertions.assertThat; + +import com.seong.shoutlink.base.BaseIntegrationTest; +import com.seong.shoutlink.domain.domain.Domain; +import com.seong.shoutlink.domain.domain.repository.DomainEntity; +import com.seong.shoutlink.domain.domain.service.DomainRepository; +import com.seong.shoutlink.domain.link.repository.LinkEntity; +import com.seong.shoutlink.domain.link.service.LinkService; +import com.seong.shoutlink.domain.link.service.request.CreateLinkCommand; +import com.seong.shoutlink.domain.link.service.response.CreateLinkResponse; +import com.seong.shoutlink.domain.linkbundle.LinkBundle; +import com.seong.shoutlink.domain.linkbundle.MemberLinkBundle; +import com.seong.shoutlink.domain.linkbundle.repository.LinkBundleEntity; +import com.seong.shoutlink.domain.linkbundle.service.LinkBundleRepository; +import com.seong.shoutlink.domain.member.Member; +import com.seong.shoutlink.domain.member.service.MemberRepository; +import com.seong.shoutlink.fixture.DomainFixture.DomainFixture; +import com.seong.shoutlink.fixture.LinkBundleFixture; +import com.seong.shoutlink.fixture.MemberFixture; +import jakarta.persistence.EntityManager; +import java.util.List; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.test.context.event.RecordApplicationEvents; + +@RecordApplicationEvents +class DomainEventListenerTest extends BaseIntegrationTest { + + @Autowired + private LinkService linkService; + + @Autowired + private MemberRepository memberRepository; + + @Autowired + private LinkBundleRepository linkBundleRepository; + + @Autowired + private DomainRepository domainRepository; + + @Autowired + private EntityManager em; + + @Nested + @DisplayName("createLinkEvent 수신 시") + class CreateLinkEventTest { + + @Test + @DisplayName("성공: 도메인 정보가 없으면 생성 됨") + void createDomainInfo() { + //given + Member member = MemberFixture.member(); + memberRepository.save(member); + LinkBundle linkBundle = LinkBundleFixture.linkBundle(); + MemberLinkBundle memberLinkBundle = new MemberLinkBundle(member, linkBundle); + linkBundleRepository.save(memberLinkBundle); + CreateLinkCommand command = new CreateLinkCommand(member.getMemberId(), + linkBundle.getLinkBundleId(), + "github.com/hseong3243", "내 깃허브"); + + List a = em.createQuery( + "select lb from LinkBundleEntity lb", LinkBundleEntity.class) + .getResultList(); + System.out.println(a.size()); + + //when + linkService.createLink(command); + + //then + List result = em.createQuery("select d from DomainEntity d", + DomainEntity.class) + .getResultList(); + assertThat(result).hasSize(1); + } + + @Test + @DisplayName("성공: 도메인 정보가 있으면 생성되지 않음") + void updateDomainInfo() { + //given + Member member = MemberFixture.member(); + memberRepository.save(member); + LinkBundle linkBundle = LinkBundleFixture.linkBundle(); + MemberLinkBundle memberLinkBundle = new MemberLinkBundle(member, linkBundle); + linkBundleRepository.save(memberLinkBundle); + Domain domain = DomainFixture.domain(); + domainRepository.save(domain); + CreateLinkCommand command = new CreateLinkCommand(member.getMemberId(), + linkBundle.getLinkBundleId(), + domain.getRootDomain(), "내 깃허브"); + + //when + linkService.createLink(command); + + //then + List result = em.createQuery("select d from DomainEntity d", + DomainEntity.class) + .getResultList(); + assertThat(result).hasSize(1); + } + + @Test + @DisplayName("성공: 링크 도메인 식별자가 업데이트 됨") + void updateLinkDomainId() { + //given + Member member = MemberFixture.member(); + memberRepository.save(member); + LinkBundle linkBundle = LinkBundleFixture.linkBundle(); + MemberLinkBundle memberLinkBundle = new MemberLinkBundle(member, linkBundle); + linkBundleRepository.save(memberLinkBundle); + Domain domain = DomainFixture.domain(); + CreateLinkCommand command = new CreateLinkCommand(member.getMemberId(), + linkBundle.getLinkBundleId(), + "github.com/hseong3243", "내 깃허브"); + + //when + CreateLinkResponse response = linkService.createLink(command); + + //then + LinkEntity linkEntity = em.find(LinkEntity.class, response.linkId()); + assertThat(linkEntity.getDomainId()).isNotNull(); + } + } +} \ No newline at end of file diff --git a/src/test/resources/application.yml b/src/test/resources/application.yml index 13360ee..3210e30 100644 --- a/src/test/resources/application.yml +++ b/src/test/resources/application.yml @@ -4,3 +4,9 @@ jwt: secret: bAM5hBSuhrVhI6aVvNPk1r9rR3n8Ar4Atest refresh-expiry-seconds: 18000 refresh-secret: cjOYckwZQhEqZOCZCCjCIG4W0HFPfSjMtest +spring: + jpa: + properties: + hibernate: + format_sql: true + show_sql: true