diff --git a/src/mooc/main/tv/codely/mooc/notification/application/like/SendPushToSubscribersOnVideoLiked.java b/src/mooc/main/tv/codely/mooc/notification/application/like/SendPushToSubscribersOnVideoLiked.java new file mode 100644 index 0000000..ee14dfc --- /dev/null +++ b/src/mooc/main/tv/codely/mooc/notification/application/like/SendPushToSubscribersOnVideoLiked.java @@ -0,0 +1,22 @@ +package tv.codely.mooc.notification.application.like; + +import tv.codely.mooc.video.domain.VideoLiked; +import tv.codely.shared.application.DomainEventSubscriber; + +public class SendPushToSubscribersOnVideoLiked implements DomainEventSubscriber { + @Override + public Class subscribedTo() { + return VideoLiked.class; + } + + @Override + public void consume(VideoLiked event) { + System.out.println( + String.format( + "Hey! User with ID <%s> liked video with title <%s>", + event.userId(), + event.title() + ) + ); + } +} diff --git a/src/mooc/main/tv/codely/mooc/shared/domain/user/UserId.java b/src/mooc/main/tv/codely/mooc/shared/domain/user/UserId.java new file mode 100644 index 0000000..b9fefa1 --- /dev/null +++ b/src/mooc/main/tv/codely/mooc/shared/domain/user/UserId.java @@ -0,0 +1,28 @@ +package tv.codely.mooc.shared.domain.user; + +public final class UserId { + private final String value; + + public UserId(final String value) { + this.value = value; + } + + public String value() { + return value; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + UserId that = (UserId) o; + + return value.equals(that.value); + } + + @Override + public int hashCode() { + return value.hashCode(); + } +} diff --git a/src/mooc/main/tv/codely/mooc/video/application/like/VideoLiker.java b/src/mooc/main/tv/codely/mooc/video/application/like/VideoLiker.java new file mode 100644 index 0000000..d783e32 --- /dev/null +++ b/src/mooc/main/tv/codely/mooc/video/application/like/VideoLiker.java @@ -0,0 +1,23 @@ +package tv.codely.mooc.video.application.like; + +import tv.codely.mooc.shared.domain.user.UserId; +import tv.codely.mooc.video.domain.VideoLike; +import tv.codely.mooc.video.domain.VideoTitle; +import tv.codely.shared.domain.EventBus; + +public final class VideoLiker { + private final EventBus eventBus; + + public VideoLiker(EventBus eventBus) { + this.eventBus = eventBus; + } + + public void like(String rawTitle, String rawUserId) { + final var title = new VideoTitle(rawTitle); + final var userId = new UserId(rawUserId); + + final var videoLike = VideoLike.like(title, userId); + + eventBus.publish(videoLike.pullDomainEvents()); + } +} diff --git a/src/mooc/main/tv/codely/mooc/video/domain/VideoLike.java b/src/mooc/main/tv/codely/mooc/video/domain/VideoLike.java new file mode 100644 index 0000000..fdff51f --- /dev/null +++ b/src/mooc/main/tv/codely/mooc/video/domain/VideoLike.java @@ -0,0 +1,25 @@ +package tv.codely.mooc.video.domain; + +import tv.codely.mooc.shared.domain.user.UserId; +import tv.codely.shared.domain.AggregateRoot; + +public class VideoLike extends AggregateRoot { + private final VideoTitle title; + private final UserId userId; + + private VideoLike(VideoTitle title, UserId userId) { + this.title = title; + this.userId = userId; + } + + public static VideoLike like(VideoTitle title, UserId userId) { + var videoLike = new VideoLike(title, userId); + + var videoLiked = new VideoLiked(title.value(), userId.value()); + + videoLike.record(videoLiked); + + return videoLike; + } + +} diff --git a/src/mooc/main/tv/codely/mooc/video/domain/VideoLiked.java b/src/mooc/main/tv/codely/mooc/video/domain/VideoLiked.java new file mode 100644 index 0000000..83e9292 --- /dev/null +++ b/src/mooc/main/tv/codely/mooc/video/domain/VideoLiked.java @@ -0,0 +1,45 @@ +package tv.codely.mooc.video.domain; + +import tv.codely.shared.domain.DomainEvent; + +public final class VideoLiked implements DomainEvent { + private static final String FULL_QUALIFIED_EVENT_NAME = "codelytv.video.video.event.1.video.liked"; + + private final String title; + private final String userId; + + public VideoLiked(String title, String userId) { + this.title = title; + this.userId = userId; + } + + public String fullQualifiedEventName() { + return FULL_QUALIFIED_EVENT_NAME; + } + + public String title() { + return title; + } + + public String userId() { + return userId; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + VideoLiked that = (VideoLiked) o; + + if (!title.equals(that.title)) return false; + return userId.equals(that.userId); + } + + @Override + public int hashCode() { + int result = title.hashCode(); + result = 31 * result + userId.hashCode(); + return result; + } +} diff --git a/src/mooc/main/tv/codely/mooc/video/infrastructure/VideoLikeCliController.java b/src/mooc/main/tv/codely/mooc/video/infrastructure/VideoLikeCliController.java new file mode 100644 index 0000000..460d2a6 --- /dev/null +++ b/src/mooc/main/tv/codely/mooc/video/infrastructure/VideoLikeCliController.java @@ -0,0 +1,24 @@ +package tv.codely.mooc.video.infrastructure; + +import tv.codely.mooc.notification.application.like.SendPushToSubscribersOnVideoLiked; +import tv.codely.mooc.video.application.like.VideoLiker; +import tv.codely.shared.application.DomainEventSubscriber; +import tv.codely.shared.domain.EventBus; +import tv.codely.shared.infrastructure.bus.ReactorEventBus; + +import java.util.Set; + +public class VideoLikeCliController { + public static void main(String[] args) { + final Set subscribers = Set.of( + new SendPushToSubscribersOnVideoLiked() + ); + final EventBus eventBus = new ReactorEventBus(subscribers); + final var videoLiker = new VideoLiker(eventBus); + + final var videoTitle = "\uD83C\uDF89 New YouTube.com/CodelyTV video title"; + final var userId = "06e8bb44-486c-41ec-8395-ead1288e5b37"; + + videoLiker.like(videoTitle, userId); + } +} diff --git a/src/mooc/test/tv/codely/mooc/video/application/like/VideoLikerShould.java b/src/mooc/test/tv/codely/mooc/video/application/like/VideoLikerShould.java new file mode 100644 index 0000000..6dbbfc8 --- /dev/null +++ b/src/mooc/test/tv/codely/mooc/video/application/like/VideoLikerShould.java @@ -0,0 +1,28 @@ +package tv.codely.mooc.video.application.like; + +import org.junit.jupiter.api.Test; +import tv.codely.mooc.video.domain.VideoLiked; +import tv.codely.shared.domain.EventBus; + +import java.util.List; + +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; + +final class VideoLikerShould { + @Test + void publish_the_video_liked_domain_event() { + final EventBus eventBus = mock(EventBus.class); + final var videoLiker = new VideoLiker(eventBus); + + final var videoTitle = "\uD83C\uDF89 New YouTube.com/CodelyTV video title"; + final var userId = "This should be the video description \uD83D\uDE42"; + + videoLiker.like(videoTitle, userId); + + final var expectedVideoLiked = new VideoLiked(videoTitle, userId); + + verify(eventBus).publish(List.of(expectedVideoLiked)); + } + +}