diff --git a/.gitignore b/.gitignore index 15bdab2..ac73e3f 100644 --- a/.gitignore +++ b/.gitignore @@ -3,3 +3,4 @@ *.iws *.iml *.ipr +target/ \ No newline at end of file diff --git a/src/main/java/tech/allegro/hexagon/articles/adapters/api/ArticleController.java b/src/main/java/tech/allegro/hexagon/articles/adapters/api/ArticleController.java deleted file mode 100644 index ba21be2..0000000 --- a/src/main/java/tech/allegro/hexagon/articles/adapters/api/ArticleController.java +++ /dev/null @@ -1,41 +0,0 @@ -package tech.allegro.hexagon.articles.adapters.api; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.PathVariable; -import org.springframework.web.bind.annotation.PostMapping; -import org.springframework.web.bind.annotation.RequestBody; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RestController; - -@RestController -@RequestMapping("articles") -class ArticleController { - - private final Logger log = LoggerFactory.getLogger(ArticleController.class); - - private final ArticleService service; - - ArticleController(final ArticleService service) { - this.service = service; - } - - @GetMapping("{articleId}") - ArticleResponse get(@PathVariable("articleId") final String articleId) { - log.info(">>> HTTP GET Request: retrieve an article with id: \"{}\"", articleId); - final ArticleResponse articleResponse = service.get(articleId); - log.info("<<< HTTP GET Response: article: \"{}\", successfully retrieved", articleResponse.title()); - return articleResponse; - } - - @PostMapping - ArticleIdResponse create(@RequestBody final ArticleRequest articleRequest) { - log.info(">>> HTTP POST Request: create an article: \"{}\"", articleRequest.title().value()); - final ArticleIdResponse articleIdResponse = service.create(articleRequest); - log.info("<<< HTTP POST Response: article with id: \"{}\", successfully created", articleIdResponse.id()); - return articleIdResponse; - } - - -} diff --git a/src/main/java/tech/allegro/hexagon/articles/adapters/api/ArticleEndpoint.java b/src/main/java/tech/allegro/hexagon/articles/adapters/api/ArticleEndpoint.java new file mode 100644 index 0000000..d0e1085 --- /dev/null +++ b/src/main/java/tech/allegro/hexagon/articles/adapters/api/ArticleEndpoint.java @@ -0,0 +1,30 @@ +package tech.allegro.hexagon.articles.adapters.api; + +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +@RestController +@RequestMapping("articles") +class ArticleEndpoint { + + private final ArticleFacade articles; + + ArticleEndpoint(ArticleFacade articles) { + this.articles = articles; + } + + @GetMapping("{articleId}") + ArticleResponse get(@PathVariable("articleId") final String articleId) { + return articles.get(articleId); + } + + @PostMapping + ArticleIdResponse create(@RequestBody final ArticleRequest articleRequest) { + return articles.create(articleRequest); + } + +} diff --git a/src/main/java/tech/allegro/hexagon/articles/adapters/api/ArticleFacade.java b/src/main/java/tech/allegro/hexagon/articles/adapters/api/ArticleFacade.java new file mode 100644 index 0000000..b81f066 --- /dev/null +++ b/src/main/java/tech/allegro/hexagon/articles/adapters/api/ArticleFacade.java @@ -0,0 +1,26 @@ +package tech.allegro.hexagon.articles.adapters.api; + +import org.springframework.stereotype.Component; +import tech.allegro.hexagon.articles.domain.model.Article; +import tech.allegro.hexagon.articles.domain.model.ArticleId; +import tech.allegro.hexagon.articles.domain.ports.ArticleService; + +@Component +class ArticleFacade { + + private final ArticleService articleService; + + ArticleFacade(final ArticleService articleService) { + this.articleService = articleService; + } + + ArticleResponse get(final String articleId) { + final Article article = articleService.get(ArticleId.of(articleId)); + return ArticleResponse.of(article); + } + + ArticleIdResponse create(final ArticleRequest articleRequest) { + final ArticleId articleId = articleService.create(articleRequest.authorId(), articleRequest.title(), articleRequest.content()); + return ArticleIdResponse.of(articleId); + } +} diff --git a/src/main/java/tech/allegro/hexagon/articles/adapters/api/ArticleIdResponse.java b/src/main/java/tech/allegro/hexagon/articles/adapters/api/ArticleIdResponse.java index 379569f..8623366 100644 --- a/src/main/java/tech/allegro/hexagon/articles/adapters/api/ArticleIdResponse.java +++ b/src/main/java/tech/allegro/hexagon/articles/adapters/api/ArticleIdResponse.java @@ -1,22 +1,23 @@ package tech.allegro.hexagon.articles.adapters.api; -import tech.allegro.hexagon.articles.domain.model.ArticleId; import com.fasterxml.jackson.annotation.JsonProperty; +import tech.allegro.hexagon.articles.domain.model.ArticleId; class ArticleIdResponse { + private final String id; private ArticleIdResponse(final String id) { this.id = id; } - @JsonProperty("id") - public String id() { - return id; - } - - public static ArticleIdResponse of(final ArticleId articleId) { + static ArticleIdResponse of(final ArticleId articleId) { return new ArticleIdResponse(articleId.value()); } + @JsonProperty("id") + String id() { + return id; + } + } diff --git a/src/main/java/tech/allegro/hexagon/articles/adapters/api/ArticleRequest.java b/src/main/java/tech/allegro/hexagon/articles/adapters/api/ArticleRequest.java index 5d21aa3..46a5885 100644 --- a/src/main/java/tech/allegro/hexagon/articles/adapters/api/ArticleRequest.java +++ b/src/main/java/tech/allegro/hexagon/articles/adapters/api/ArticleRequest.java @@ -1,9 +1,9 @@ package tech.allegro.hexagon.articles.adapters.api; +import com.fasterxml.jackson.annotation.JsonProperty; import tech.allegro.hexagon.articles.domain.model.AuthorId; import tech.allegro.hexagon.articles.domain.model.Content; import tech.allegro.hexagon.articles.domain.model.Title; -import com.fasterxml.jackson.annotation.JsonProperty; class ArticleRequest { private final String title; @@ -17,15 +17,15 @@ class ArticleRequest { } - public Title title() { + Title title() { return Title.of(title); } - public Content content() { + Content content() { return Content.of(content); } - public AuthorId authorId() { + AuthorId authorId() { return AuthorId.of(authorId); } diff --git a/src/main/java/tech/allegro/hexagon/articles/adapters/api/ArticleResponse.java b/src/main/java/tech/allegro/hexagon/articles/adapters/api/ArticleResponse.java index a464c7d..1ccf683 100644 --- a/src/main/java/tech/allegro/hexagon/articles/adapters/api/ArticleResponse.java +++ b/src/main/java/tech/allegro/hexagon/articles/adapters/api/ArticleResponse.java @@ -1,7 +1,7 @@ package tech.allegro.hexagon.articles.adapters.api; -import tech.allegro.hexagon.articles.domain.model.Article; import com.fasterxml.jackson.annotation.JsonProperty; +import tech.allegro.hexagon.articles.domain.model.Article; class ArticleResponse { private final String id; @@ -24,22 +24,22 @@ class ArticleResponse { } @JsonProperty("id") - public String id() { + String id() { return id; } @JsonProperty("title") - public String title() { + String title() { return title; } @JsonProperty("content") - public String content() { + String content() { return content; } @JsonProperty("authorName") - public String authorName() { + String authorName() { return authorName; } } diff --git a/src/main/java/tech/allegro/hexagon/articles/adapters/api/ArticleService.java b/src/main/java/tech/allegro/hexagon/articles/adapters/api/ArticleService.java deleted file mode 100644 index 46f83b9..0000000 --- a/src/main/java/tech/allegro/hexagon/articles/adapters/api/ArticleService.java +++ /dev/null @@ -1,24 +0,0 @@ -package tech.allegro.hexagon.articles.adapters.api; - -import tech.allegro.hexagon.articles.domain.ArticleFacade; -import tech.allegro.hexagon.articles.domain.model.ArticleId; -import org.springframework.stereotype.Component; - -@Component -class ArticleService { - - private final ArticleFacade articleFacade; - - ArticleService(final ArticleFacade articleFacade) { - this.articleFacade = articleFacade; - } - - ArticleResponse get(final String articleId) { - return ArticleResponse.of(articleFacade.get(ArticleId.of(articleId))); - } - - ArticleIdResponse create(final ArticleRequest articleRequest) { - final ArticleId articleId = articleFacade.create(articleRequest.authorId(), articleRequest.title(), articleRequest.content()); - return ArticleIdResponse.of(articleId); - } -} diff --git a/src/main/java/tech/allegro/hexagon/articles/adapters/articledb/ArticleDatabaseModel.java b/src/main/java/tech/allegro/hexagon/articles/adapters/articledb/ArticleDatabaseModel.java index d8559a2..2cd2fba 100644 --- a/src/main/java/tech/allegro/hexagon/articles/adapters/articledb/ArticleDatabaseModel.java +++ b/src/main/java/tech/allegro/hexagon/articles/adapters/articledb/ArticleDatabaseModel.java @@ -1,7 +1,125 @@ package tech.allegro.hexagon.articles.adapters.articledb; +import tech.allegro.hexagon.articles.domain.model.Article; +import tech.allegro.hexagon.articles.domain.model.ArticleId; +import tech.allegro.hexagon.articles.domain.model.Author; +import tech.allegro.hexagon.articles.domain.model.AuthorId; +import tech.allegro.hexagon.articles.domain.model.Content; +import tech.allegro.hexagon.articles.domain.model.PersonName; +import tech.allegro.hexagon.articles.domain.model.Title; + +import java.time.ZonedDateTime; +import java.util.UUID; + class ArticleDatabaseModel { - /** - * Database model implementation comes here - */ + + private final UUID id; + private final String title; + private final String content; + private final long version; + private final ZonedDateTime createdAt; + private final String authorId; + private final String authorName; + + private ArticleDatabaseModel(final UUID id, + final String title, + final String content, + final String authorId, + final long version, + final ZonedDateTime createdAt, + final String authorName) { + this.id = id; + this.title = title; + this.content = content; + this.authorId = authorId; + this.version = version; + this.createdAt = createdAt; + this.authorName = authorName; + } + + @Override + public String toString() { + return title; + } + + Article toDomain() { + return Article.article() + .withId(ArticleId.of(id.toString())) + .withAuthor(Author + .author() + .withId(AuthorId.of(authorId)) + .withName(PersonName.of(authorName)) + .build()) + .withTitle(Title.of(title)) + .withContent(Content.of(content)) + .build(); + } + + static ArticleDatabaseModel of(final Author author, final Title title, final Content content) { + return articleDatabaseModel() + .withId(UUID.randomUUID()) + .withVersion(0) + .withCreatedAt(ZonedDateTime.now()) + .withAuthorId(author.id().value()) + .withAuthorName(author.name().value()) + .withTitle(title.value()) + .withContent(content.value()) + .build(); + } + + static ArticleDatabaseModelBuilder articleDatabaseModel() { + return new ArticleDatabaseModelBuilder(); + } + + static final class ArticleDatabaseModelBuilder { + private UUID id; + private String title; + private String content; + private long version; + private ZonedDateTime createdAt; + private String authorId; + private String authorName; + + private ArticleDatabaseModelBuilder() { + } + + ArticleDatabaseModelBuilder withId(UUID id) { + this.id = id; + return this; + } + + ArticleDatabaseModelBuilder withTitle(String title) { + this.title = title; + return this; + } + + ArticleDatabaseModelBuilder withContent(String content) { + this.content = content; + return this; + } + + ArticleDatabaseModelBuilder withVersion(long version) { + this.version = version; + return this; + } + + ArticleDatabaseModelBuilder withCreatedAt(ZonedDateTime createdAt) { + this.createdAt = createdAt; + return this; + } + + ArticleDatabaseModelBuilder withAuthorId(String authorId) { + this.authorId = authorId; + return this; + } + + ArticleDatabaseModelBuilder withAuthorName(String authorName) { + this.authorName = authorName; + return this; + } + + ArticleDatabaseModel build() { + return new ArticleDatabaseModel(id, title, content, authorId, version, createdAt, authorName); + } + } } diff --git a/src/main/java/tech/allegro/hexagon/articles/adapters/articledb/DbArticleRepository.java b/src/main/java/tech/allegro/hexagon/articles/adapters/articledb/DbArticleRepository.java index 9f3f6d0..7eeb124 100644 --- a/src/main/java/tech/allegro/hexagon/articles/adapters/articledb/DbArticleRepository.java +++ b/src/main/java/tech/allegro/hexagon/articles/adapters/articledb/DbArticleRepository.java @@ -1,56 +1,42 @@ package tech.allegro.hexagon.articles.adapters.articledb; +import org.springframework.stereotype.Component; import tech.allegro.hexagon.articles.domain.model.Article; import tech.allegro.hexagon.articles.domain.model.ArticleId; import tech.allegro.hexagon.articles.domain.model.Author; -import tech.allegro.hexagon.articles.domain.model.AuthorId; import tech.allegro.hexagon.articles.domain.model.Content; -import tech.allegro.hexagon.articles.domain.model.PersonName; import tech.allegro.hexagon.articles.domain.model.Title; import tech.allegro.hexagon.articles.domain.ports.ArticleRepository; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.stereotype.Component; import java.util.UUID; +import static tech.allegro.hexagon.articles.adapters.articledb.ArticleDatabaseModel.articleDatabaseModel; +import static tech.allegro.hexagon.articles.adapters.articledb.ArticleDatabaseModel.of; + @Component class DbArticleRepository implements ArticleRepository { - private final Logger log = LoggerFactory.getLogger(DbArticleRepository.class); - - @Override public Article save(final Author author, final Title title, final Content content) { /** - * Database integration implementation using {@link ArticleDatabaseModel} comes here + * Database integration implementation comes here */ - final String articleId = UUID.randomUUID().toString(); - log.info("Article: \"{}\" persisted", title.value()); - return Article.article() - .withId(ArticleId.of(articleId)) - .withAuthor(author) - .withTitle(title) - .withContent(content) - .build(); + final ArticleDatabaseModel entity = of(author, title, content); + return entity.toDomain(); } @Override public Article get(final ArticleId id) { /** - * Database integration implementation using {@link ArticleDatabaseModel} comes here + * Database integration implementation comes here */ - final Title title = Title.of("Hexagonal Architecture"); - log.info("Article \"{}\" fetched", title.value()); - return Article.article() - .withId(id) - .withAuthor(Author - .author() - .withId(AuthorId.of(UUID.randomUUID().toString())) - .withName(PersonName.of("William Shakespeare")) - .build()) - .withTitle(title) - .withContent(Content.of("Lorem ipsum")) + final ArticleDatabaseModel entity = articleDatabaseModel() + .withId(UUID.fromString(id.value())) + .withAuthorName("William Shakespeare") + .withAuthorId("928467") + .withTitle("Hexagonal Architecture") + .withContent("Lorem ipsum") .build(); + return entity.toDomain(); } } diff --git a/src/main/java/tech/allegro/hexagon/articles/adapters/authorservice/AuthorExternalModel.java b/src/main/java/tech/allegro/hexagon/articles/adapters/authorservice/AuthorExternalModel.java index 8d5782b..29dbdd7 100644 --- a/src/main/java/tech/allegro/hexagon/articles/adapters/authorservice/AuthorExternalModel.java +++ b/src/main/java/tech/allegro/hexagon/articles/adapters/authorservice/AuthorExternalModel.java @@ -1,7 +1,65 @@ package tech.allegro.hexagon.articles.adapters.authorservice; +import tech.allegro.hexagon.articles.domain.model.Author; +import tech.allegro.hexagon.articles.domain.model.AuthorId; +import tech.allegro.hexagon.articles.domain.model.PersonName; + class AuthorExternalModel { - /** - * External author service model implementation comes here - */ + private final long id; + private final String firstName; + private final String lastName; + + private AuthorExternalModel(final long id, final String firstName, final String lastName) { + this.id = id; + this.firstName = firstName; + this.lastName = lastName; + } + + Author toDomain() { + return Author.author() + .withId(AuthorId.of(String.valueOf(id))) + .withName(PersonName.of(fullName())) + .build(); + } + + private String fullName() { + return String.format("%s %s", firstName, lastName); + } + + @Override + public String toString() { + return fullName(); + } + + static AuthorExternalModelBuilder authorExternalModel() { + return new AuthorExternalModelBuilder(); + } + + static final class AuthorExternalModelBuilder { + private long id; + private String firstName; + private String lastName; + + private AuthorExternalModelBuilder() { + } + + AuthorExternalModelBuilder withId(long id) { + this.id = id; + return this; + } + + AuthorExternalModelBuilder withFirstName(String firstName) { + this.firstName = firstName; + return this; + } + + AuthorExternalModelBuilder withLastName(String lastName) { + this.lastName = lastName; + return this; + } + + AuthorExternalModel build() { + return new AuthorExternalModel(id, firstName, lastName); + } + } } diff --git a/src/main/java/tech/allegro/hexagon/articles/adapters/authorservice/ExternalServiceClientAuthorRepository.java b/src/main/java/tech/allegro/hexagon/articles/adapters/authorservice/ExternalServiceClientAuthorRepository.java index 3a3912c..3d42462 100644 --- a/src/main/java/tech/allegro/hexagon/articles/adapters/authorservice/ExternalServiceClientAuthorRepository.java +++ b/src/main/java/tech/allegro/hexagon/articles/adapters/authorservice/ExternalServiceClientAuthorRepository.java @@ -1,27 +1,26 @@ package tech.allegro.hexagon.articles.adapters.authorservice; +import org.springframework.stereotype.Component; import tech.allegro.hexagon.articles.domain.model.Author; import tech.allegro.hexagon.articles.domain.model.AuthorId; -import tech.allegro.hexagon.articles.domain.model.PersonName; import tech.allegro.hexagon.articles.domain.ports.AuthorRepository; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.stereotype.Component; + +import static tech.allegro.hexagon.articles.adapters.authorservice.AuthorExternalModel.authorExternalModel; @Component class ExternalServiceClientAuthorRepository implements AuthorRepository { - private final Logger log = LoggerFactory.getLogger(ExternalServiceClientAuthorRepository.class); + @Override public Author get(final AuthorId authorId) { /** * external author service integration implementation comes here */ - log.info("Author: \"William Shakespeare\" fetched", authorId.value()); - return Author - .author() - .withId(authorId) - .withName(PersonName.of("William Shakespeare")) + final AuthorExternalModel author = authorExternalModel() + .withId(928467) + .withFirstName("William") + .withLastName("Shakespeare") .build(); + return author.toDomain(); } } diff --git a/src/main/java/tech/allegro/hexagon/articles/adapters/config/ArticleConfig.java b/src/main/java/tech/allegro/hexagon/articles/adapters/config/ArticleConfig.java deleted file mode 100644 index 91e58a1..0000000 --- a/src/main/java/tech/allegro/hexagon/articles/adapters/config/ArticleConfig.java +++ /dev/null @@ -1,26 +0,0 @@ -package tech.allegro.hexagon.articles.adapters.config; - -import tech.allegro.hexagon.articles.domain.ArticleFacade; -import tech.allegro.hexagon.articles.domain.ports.ArticleAuthorNotifier; -import tech.allegro.hexagon.articles.domain.ports.ArticleEventPublisher; -import tech.allegro.hexagon.articles.domain.ports.ArticleRepository; -import tech.allegro.hexagon.articles.domain.ports.AuthorRepository; -import tech.allegro.hexagon.articles.domain.ports.SocialMediaPublisher; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; - -import java.util.List; - -@Configuration -class ArticleConfig { - - @Bean - ArticleFacade articleFacade(final ArticleRepository articleRepository, - final AuthorRepository authorRepository, - final ArticleEventPublisher eventPublisher, - final List socialMediaPublishers, - final List articleAuthorNotifiers) { - return new ArticleFacade(eventPublisher, articleRepository, authorRepository, socialMediaPublishers, articleAuthorNotifiers); - } - -} diff --git a/src/main/java/tech/allegro/hexagon/articles/adapters/eventbus/ArticleCreatedEvent.java b/src/main/java/tech/allegro/hexagon/articles/adapters/eventbus/ArticleCreatedEvent.java deleted file mode 100644 index f901d26..0000000 --- a/src/main/java/tech/allegro/hexagon/articles/adapters/eventbus/ArticleCreatedEvent.java +++ /dev/null @@ -1,7 +0,0 @@ -package tech.allegro.hexagon.articles.adapters.eventbus; - -class ArticleCreatedEvent { - /** - * Message broker model implementation comes here - */ -} diff --git a/src/main/java/tech/allegro/hexagon/articles/adapters/eventbus/ArticleRetrievedEvent.java b/src/main/java/tech/allegro/hexagon/articles/adapters/eventbus/ArticleRetrievedEvent.java deleted file mode 100644 index 68b33a2..0000000 --- a/src/main/java/tech/allegro/hexagon/articles/adapters/eventbus/ArticleRetrievedEvent.java +++ /dev/null @@ -1,7 +0,0 @@ -package tech.allegro.hexagon.articles.adapters.eventbus; - -class ArticleRetrievedEvent { - /** - * Message broker model implementation comes here - */ -} diff --git a/src/main/java/tech/allegro/hexagon/articles/adapters/eventbus/MessageBrokerArticleEventPublisher.java b/src/main/java/tech/allegro/hexagon/articles/adapters/eventbus/MessageBrokerArticleEventPublisher.java deleted file mode 100644 index 21adb64..0000000 --- a/src/main/java/tech/allegro/hexagon/articles/adapters/eventbus/MessageBrokerArticleEventPublisher.java +++ /dev/null @@ -1,29 +0,0 @@ -package tech.allegro.hexagon.articles.adapters.eventbus; - -import tech.allegro.hexagon.articles.domain.model.Article; -import tech.allegro.hexagon.articles.domain.ports.ArticleEventPublisher; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.stereotype.Component; - -@Component -class MessageBrokerArticleEventPublisher implements ArticleEventPublisher { - - private final Logger log = LoggerFactory.getLogger(MessageBrokerArticleEventPublisher.class); - - @Override - public void publishArticleCreationEvent(final Article article) { - /** - * message broker integration implementation using {@link ArticleCreatedEvent} comes here - */ - log.info("Article: \"{}\" creation event published on event bus", article.title().value()); - } - - @Override - public void publishArticleRetrievalEvent(final Article article) { - /** - * message broker integration implementation using {@link ArticleRetrievedEvent} comes here - */ - log.info("Article: \"{}\" retrieval event published on event bus", article.title().value()); - } -} diff --git a/src/main/java/tech/allegro/hexagon/articles/adapters/messagebroker/ArticleCreatedMessage.java b/src/main/java/tech/allegro/hexagon/articles/adapters/messagebroker/ArticleCreatedMessage.java new file mode 100644 index 0000000..938d037 --- /dev/null +++ b/src/main/java/tech/allegro/hexagon/articles/adapters/messagebroker/ArticleCreatedMessage.java @@ -0,0 +1,25 @@ +package tech.allegro.hexagon.articles.adapters.messagebroker; + +import tech.allegro.hexagon.articles.domain.model.Article; + +import java.time.ZonedDateTime; + +class ArticleCreatedMessage { + + private final Article article; + private final ZonedDateTime sentAt; + + private ArticleCreatedMessage(final Article article, final ZonedDateTime sentAt) { + this.article = article; + this.sentAt = sentAt; + } + + static ArticleCreatedMessage of(Article article) { + return new ArticleCreatedMessage(article, ZonedDateTime.now()); + } + + @Override + public String toString() { + return String.format("\"Article >>%s<< created\"", article.title().value()); + } +} diff --git a/src/main/java/tech/allegro/hexagon/articles/adapters/messagebroker/ArticleRetrievedMessage.java b/src/main/java/tech/allegro/hexagon/articles/adapters/messagebroker/ArticleRetrievedMessage.java new file mode 100644 index 0000000..4536304 --- /dev/null +++ b/src/main/java/tech/allegro/hexagon/articles/adapters/messagebroker/ArticleRetrievedMessage.java @@ -0,0 +1,26 @@ +package tech.allegro.hexagon.articles.adapters.messagebroker; + +import tech.allegro.hexagon.articles.domain.model.Article; + +import java.time.ZonedDateTime; + +class ArticleRetrievedMessage { + + private final Article article; + + private final ZonedDateTime sentAt; + + private ArticleRetrievedMessage(final Article article, final ZonedDateTime sentAt) { + this.article = article; + this.sentAt = sentAt; + } + + static ArticleRetrievedMessage of(Article article) { + return new ArticleRetrievedMessage(article, ZonedDateTime.now()); + } + + @Override + public String toString() { + return String.format("\"Article >>%s<< retrieved\"", article.title().value()); + } +} diff --git a/src/main/java/tech/allegro/hexagon/articles/adapters/messagebroker/MessageBrokerArticleMessageSender.java b/src/main/java/tech/allegro/hexagon/articles/adapters/messagebroker/MessageBrokerArticleMessageSender.java new file mode 100644 index 0000000..213b669 --- /dev/null +++ b/src/main/java/tech/allegro/hexagon/articles/adapters/messagebroker/MessageBrokerArticleMessageSender.java @@ -0,0 +1,25 @@ +package tech.allegro.hexagon.articles.adapters.messagebroker; + +import org.springframework.stereotype.Component; +import tech.allegro.hexagon.articles.domain.model.Article; +import tech.allegro.hexagon.articles.domain.ports.ArticleMessageSender; + +@Component +class MessageBrokerArticleMessageSender implements ArticleMessageSender { + + @Override + public void sendMessageForCreated(final Article article) { + /** + * message broker integration implementation comes here + */ + ArticleCreatedMessage.of(article); + } + + @Override + public void sendMessageForRetrieved(final Article article) { + /** + * message broker integration implementation comes here + */ + ArticleRetrievedMessage.of(article); + } +} diff --git a/src/main/java/tech/allegro/hexagon/articles/adapters/notifications/ArticleAuthorMailNotifier.java b/src/main/java/tech/allegro/hexagon/articles/adapters/notifications/ArticleAuthorMailNotifier.java deleted file mode 100644 index 19c5892..0000000 --- a/src/main/java/tech/allegro/hexagon/articles/adapters/notifications/ArticleAuthorMailNotifier.java +++ /dev/null @@ -1,21 +0,0 @@ -package tech.allegro.hexagon.articles.adapters.notifications; - -import tech.allegro.hexagon.articles.domain.model.Article; -import tech.allegro.hexagon.articles.domain.ports.ArticleAuthorNotifier; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.stereotype.Component; - -@Component -class ArticleAuthorMailNotifier implements ArticleAuthorNotifier { - - private final Logger log = LoggerFactory.getLogger(ArticleAuthorMailNotifier.class); - - @Override - public void notifyAboutArticleCreation(final Article article) { - /** - * mail system integration implementation using {@link ArticleMailModel} comes here - */ - log.info("Mail sent to author: \"{}\"", article.author().name()); - } -} diff --git a/src/main/java/tech/allegro/hexagon/articles/adapters/notifications/ArticleAuthorSmsNotifier.java b/src/main/java/tech/allegro/hexagon/articles/adapters/notifications/ArticleAuthorSmsNotifier.java deleted file mode 100644 index 8589430..0000000 --- a/src/main/java/tech/allegro/hexagon/articles/adapters/notifications/ArticleAuthorSmsNotifier.java +++ /dev/null @@ -1,21 +0,0 @@ -package tech.allegro.hexagon.articles.adapters.notifications; - -import tech.allegro.hexagon.articles.domain.model.Article; -import tech.allegro.hexagon.articles.domain.ports.ArticleAuthorNotifier; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.stereotype.Component; - -@Component -class ArticleAuthorSmsNotifier implements ArticleAuthorNotifier { - - private final Logger log = LoggerFactory.getLogger(ArticleAuthorSmsNotifier.class); - - @Override - public void notifyAboutArticleCreation(final Article article) { - /** - * sms system integration implementation using {@link ArticleSmsModel}comes here - */ - log.info("SMS sent to author: \"{}\"", article.author().name()); - } -} diff --git a/src/main/java/tech/allegro/hexagon/articles/adapters/notifications/ArticleMailModel.java b/src/main/java/tech/allegro/hexagon/articles/adapters/notifications/ArticleMailModel.java index 7bdbd90..cdf10d7 100644 --- a/src/main/java/tech/allegro/hexagon/articles/adapters/notifications/ArticleMailModel.java +++ b/src/main/java/tech/allegro/hexagon/articles/adapters/notifications/ArticleMailModel.java @@ -1,7 +1,32 @@ package tech.allegro.hexagon.articles.adapters.notifications; +import tech.allegro.hexagon.articles.domain.model.Article; + class ArticleMailModel { - /** - * Mail model implementation comes here - */ + + private static final String SUBJECT = "You have successfully published: >>%s<<"; + private static final String CONTENT = "Check if everything is correct: >>%s<<"; + + private final String recipientId; + private final String subject; + private final String content; + + private ArticleMailModel(final String recipientId, + final String subject, + final String content) { + this.recipientId = recipientId; + this.subject = subject; + this.content = content; + } + + static ArticleMailModel of(final Article article) { + return new ArticleMailModel(article.author().name().value(), + String.format(SUBJECT, article.title().value()), + String.format(CONTENT, article.content().value())); + } + + @Override + public String toString() { + return subject; + } } diff --git a/src/main/java/tech/allegro/hexagon/articles/adapters/notifications/ArticleSmsModel.java b/src/main/java/tech/allegro/hexagon/articles/adapters/notifications/ArticleSmsModel.java index de35fd6..694a861 100644 --- a/src/main/java/tech/allegro/hexagon/articles/adapters/notifications/ArticleSmsModel.java +++ b/src/main/java/tech/allegro/hexagon/articles/adapters/notifications/ArticleSmsModel.java @@ -1,7 +1,27 @@ package tech.allegro.hexagon.articles.adapters.notifications; +import tech.allegro.hexagon.articles.domain.model.Article; + class ArticleSmsModel { - /** - * Sms model implementation comes here - */ + + public static final String CONTENT = "Please check your email. We have sent you publication details of the article: >>%s<<"; + private final String recipientId; + private final String text; + + private ArticleSmsModel(final String recipientId, final String text) { + this.recipientId = recipientId; + this.text = text; + } + + public static ArticleSmsModel of(Article article) { + return new ArticleSmsModel( + article.author().name().value(), + String.format(CONTENT, article.title().value())); + + } + + @Override + public String toString() { + return text; + } } diff --git a/src/main/java/tech/allegro/hexagon/articles/adapters/notifications/AuthorMailNotifier.java b/src/main/java/tech/allegro/hexagon/articles/adapters/notifications/AuthorMailNotifier.java new file mode 100644 index 0000000..51a15c4 --- /dev/null +++ b/src/main/java/tech/allegro/hexagon/articles/adapters/notifications/AuthorMailNotifier.java @@ -0,0 +1,17 @@ +package tech.allegro.hexagon.articles.adapters.notifications; + +import org.springframework.stereotype.Component; +import tech.allegro.hexagon.articles.domain.model.Article; +import tech.allegro.hexagon.articles.domain.ports.AuthorNotifier; + +@Component +class AuthorMailNotifier implements AuthorNotifier { + + @Override + public void notifyAboutCreationOf(final Article article) { + /** + * Mail system integration implementation comes here + */ + ArticleMailModel.of(article); + } +} diff --git a/src/main/java/tech/allegro/hexagon/articles/adapters/notifications/AuthorSmsNotifier.java b/src/main/java/tech/allegro/hexagon/articles/adapters/notifications/AuthorSmsNotifier.java new file mode 100644 index 0000000..3836758 --- /dev/null +++ b/src/main/java/tech/allegro/hexagon/articles/adapters/notifications/AuthorSmsNotifier.java @@ -0,0 +1,17 @@ +package tech.allegro.hexagon.articles.adapters.notifications; + +import org.springframework.stereotype.Component; +import tech.allegro.hexagon.articles.domain.model.Article; +import tech.allegro.hexagon.articles.domain.ports.AuthorNotifier; + +@Component +class AuthorSmsNotifier implements AuthorNotifier { + + @Override + public void notifyAboutCreationOf(final Article article) { + /** + * SMS system integration implementation comes here + */ + ArticleSmsModel.of(article); + } +} diff --git a/src/main/java/tech/allegro/hexagon/articles/adapters/socialmedia/ArticleTwitterModel.java b/src/main/java/tech/allegro/hexagon/articles/adapters/socialmedia/ArticleTwitterModel.java index 3d4a174..66665fd 100644 --- a/src/main/java/tech/allegro/hexagon/articles/adapters/socialmedia/ArticleTwitterModel.java +++ b/src/main/java/tech/allegro/hexagon/articles/adapters/socialmedia/ArticleTwitterModel.java @@ -1,7 +1,28 @@ package tech.allegro.hexagon.articles.adapters.socialmedia; +import tech.allegro.hexagon.articles.domain.model.Article; + class ArticleTwitterModel { - /** - * twitter implementation comes here - */ + + public static final String TWEET = "Check out the new article >>%s<< by %s"; + private final String twitterAccountId; + private final String tweet; + + private ArticleTwitterModel(final String twitterAccountId, final String tweet) { + this.twitterAccountId = twitterAccountId; + this.tweet = tweet; + } + + static ArticleTwitterModel of(Article article) { + final String title = article + .title() + .value(); + final String twitterId = article.author().name().value(); + return new ArticleTwitterModel(twitterId, String.format(TWEET, title, twitterId)); + } + + @Override + public String toString() { + return tweet; + } } diff --git a/src/main/java/tech/allegro/hexagon/articles/adapters/socialmedia/TwitterArticlePublisher.java b/src/main/java/tech/allegro/hexagon/articles/adapters/socialmedia/TwitterArticlePublisher.java index c678fb7..6168f8c 100644 --- a/src/main/java/tech/allegro/hexagon/articles/adapters/socialmedia/TwitterArticlePublisher.java +++ b/src/main/java/tech/allegro/hexagon/articles/adapters/socialmedia/TwitterArticlePublisher.java @@ -1,22 +1,21 @@ package tech.allegro.hexagon.articles.adapters.socialmedia; +import org.springframework.stereotype.Component; import tech.allegro.hexagon.articles.domain.model.Article; import tech.allegro.hexagon.articles.domain.ports.SocialMediaPublisher; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.stereotype.Component; @Component class TwitterArticlePublisher implements SocialMediaPublisher { - private final Logger log = LoggerFactory.getLogger(TwitterArticlePublisher.class); + private final TwitterClient twitterClient; + TwitterArticlePublisher(final TwitterClient twitterClient) { + this.twitterClient = twitterClient; + } @Override public void publish(final Article article) { - /** - * social media integration implementation using {@link TwitterModel} comes here - */ - log.info("Article: \"{}\" published on twitter", article.title().value()); + final ArticleTwitterModel articleTweet = ArticleTwitterModel.of(article); + twitterClient.tweet(articleTweet); } } diff --git a/src/main/java/tech/allegro/hexagon/articles/adapters/socialmedia/TwitterClient.java b/src/main/java/tech/allegro/hexagon/articles/adapters/socialmedia/TwitterClient.java new file mode 100644 index 0000000..48c3379 --- /dev/null +++ b/src/main/java/tech/allegro/hexagon/articles/adapters/socialmedia/TwitterClient.java @@ -0,0 +1,12 @@ +package tech.allegro.hexagon.articles.adapters.socialmedia; + +import org.springframework.stereotype.Component; + +@Component +class TwitterClient { + void tweet(final ArticleTwitterModel articleTweet) { + /** + * social media integration implementation comes here + */ + } +} diff --git a/src/main/java/tech/allegro/hexagon/articles/config/ArticleConfig.java b/src/main/java/tech/allegro/hexagon/articles/config/ArticleConfig.java new file mode 100644 index 0000000..493dadc --- /dev/null +++ b/src/main/java/tech/allegro/hexagon/articles/config/ArticleConfig.java @@ -0,0 +1,38 @@ +package tech.allegro.hexagon.articles.config; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import tech.allegro.hexagon.articles.domain.ArticlePublisher; +import tech.allegro.hexagon.articles.domain.ports.ArticleMessageSender; +import tech.allegro.hexagon.articles.domain.ports.ArticleRepository; +import tech.allegro.hexagon.articles.domain.ports.ArticleService; +import tech.allegro.hexagon.articles.domain.ports.AuthorNotifier; +import tech.allegro.hexagon.articles.domain.ports.AuthorRepository; +import tech.allegro.hexagon.articles.domain.ports.SocialMediaPublisher; + +import java.util.List; + +@Configuration +class ArticleConfig { + + @Bean + ArticlePublisher articleEventPublisher(final ArticleMessageSender eventPublisher, + final List socialMediaPublishers, + final List articleAuthorNotifiers) { + return new ArticlePublisher(eventPublisher, + socialMediaPublishers, + articleAuthorNotifiers); + } + + @Bean + ArticleService articleService(final ArticleRepository articleRepository, + final AuthorRepository authorRepository, + final ArticlePublisher articleEventPublisher + ) { + return new ArticleService( + articleRepository, + authorRepository, + articleEventPublisher); + } + +} diff --git a/src/main/java/tech/allegro/hexagon/articles/domain/ArticleFacade.java b/src/main/java/tech/allegro/hexagon/articles/domain/ArticleFacade.java deleted file mode 100644 index c366b57..0000000 --- a/src/main/java/tech/allegro/hexagon/articles/domain/ArticleFacade.java +++ /dev/null @@ -1,47 +0,0 @@ -package tech.allegro.hexagon.articles.domain; - -import tech.allegro.hexagon.articles.domain.model.Article; -import tech.allegro.hexagon.articles.domain.model.ArticleId; -import tech.allegro.hexagon.articles.domain.model.Author; -import tech.allegro.hexagon.articles.domain.model.AuthorId; -import tech.allegro.hexagon.articles.domain.model.Content; -import tech.allegro.hexagon.articles.domain.model.Title; -import tech.allegro.hexagon.articles.domain.ports.ArticleAuthorNotifier; -import tech.allegro.hexagon.articles.domain.ports.ArticleEventPublisher; -import tech.allegro.hexagon.articles.domain.ports.ArticleRepository; -import tech.allegro.hexagon.articles.domain.ports.AuthorRepository; -import tech.allegro.hexagon.articles.domain.ports.SocialMediaPublisher; - -import java.util.List; - -public class ArticleFacade { - - private final ArticleEventPublisher eventPublisher; - private final ArticleRepository articleRepository; - private final AuthorRepository authorRepository; - private final List socialMediaPublishers; - private final List articleAuthorNotifiers; - - public ArticleFacade(final ArticleEventPublisher eventPublisher, final ArticleRepository articleRepository, final AuthorRepository authorRepository, final List socialMediaPublishers, final List articleAuthorNotifiers) { - this.eventPublisher = eventPublisher; - this.articleRepository = articleRepository; - this.authorRepository = authorRepository; - this.socialMediaPublishers = socialMediaPublishers; - this.articleAuthorNotifiers = articleAuthorNotifiers; - } - - public ArticleId create(final AuthorId authorId, final Title title, final Content content) { - final Author author = authorRepository.get(authorId); - final Article article = articleRepository.save(author, title, content); - eventPublisher.publishArticleCreationEvent(article); - socialMediaPublishers.forEach(socialMediaPublisher -> socialMediaPublisher.publish(article)); - articleAuthorNotifiers.forEach(articleAuthorNotifier -> articleAuthorNotifier.notifyAboutArticleCreation(article)); - return article.id(); - } - - public Article get(final ArticleId id) { - final Article article = articleRepository.get(id); - eventPublisher.publishArticleRetrievalEvent(article); - return article; - } -} diff --git a/src/main/java/tech/allegro/hexagon/articles/domain/ArticlePublisher.java b/src/main/java/tech/allegro/hexagon/articles/domain/ArticlePublisher.java new file mode 100644 index 0000000..1b47c4c --- /dev/null +++ b/src/main/java/tech/allegro/hexagon/articles/domain/ArticlePublisher.java @@ -0,0 +1,32 @@ +package tech.allegro.hexagon.articles.domain; + +import tech.allegro.hexagon.articles.domain.model.Article; +import tech.allegro.hexagon.articles.domain.ports.ArticleMessageSender; +import tech.allegro.hexagon.articles.domain.ports.AuthorNotifier; +import tech.allegro.hexagon.articles.domain.ports.SocialMediaPublisher; + +import java.util.List; + +public class ArticlePublisher { + private final ArticleMessageSender messageSender; + private final List socialMediaPublishers; + private final List articleAuthorNotifiers; + + public ArticlePublisher(final ArticleMessageSender messageSender, + final List socialMediaPublishers, + final List articleAuthorNotifiers) { + this.messageSender = messageSender; + this.socialMediaPublishers = socialMediaPublishers; + this.articleAuthorNotifiers = articleAuthorNotifiers; + } + + public void publishCreationOf(final Article article) { + messageSender.sendMessageForCreated(article); + socialMediaPublishers.forEach(socialMediaPublisher -> socialMediaPublisher.publish(article)); + articleAuthorNotifiers.forEach(articleAuthorNotifier -> articleAuthorNotifier.notifyAboutCreationOf(article)); + } + + public void publishRetrievalOf(final Article article) { + messageSender.sendMessageForRetrieved(article); + } +} diff --git a/src/main/java/tech/allegro/hexagon/articles/domain/model/Article.java b/src/main/java/tech/allegro/hexagon/articles/domain/model/Article.java index 13f322b..e51dfcb 100644 --- a/src/main/java/tech/allegro/hexagon/articles/domain/model/Article.java +++ b/src/main/java/tech/allegro/hexagon/articles/domain/model/Article.java @@ -1,12 +1,12 @@ package tech.allegro.hexagon.articles.domain.model; public class Article { + private final ArticleId id; private final Title title; private final Content content; private final Author author; - private Article(final ArticleId id, final Title title, final Content content, final Author author) { this.id = id; this.title = title; @@ -14,6 +14,16 @@ public class Article { this.author = author; } + public void validateEligibilityForPublication() { + verifyForPlagiarism(); + validateTitleLength(); + validateContentLength(); + checkPunctuation(); + checkGrammar(); + checkStyle(); + //TODO: these methods are just placeholders with empty implementation + } + public ArticleId id() { return id; } @@ -30,6 +40,24 @@ public class Article { return author; } + private void checkGrammar() { + } + + private void checkStyle() { + } + + private void checkPunctuation() { + } + + private void verifyForPlagiarism() { + } + + private void validateContentLength() { + } + + private void validateTitleLength() { + } + public static ArticleBuilder article() { return new ArticleBuilder(); } diff --git a/src/main/java/tech/allegro/hexagon/articles/domain/model/Author.java b/src/main/java/tech/allegro/hexagon/articles/domain/model/Author.java index 8af731b..7a322ae 100644 --- a/src/main/java/tech/allegro/hexagon/articles/domain/model/Author.java +++ b/src/main/java/tech/allegro/hexagon/articles/domain/model/Author.java @@ -5,7 +5,7 @@ public class Author { private final PersonName name; - public Author(final AuthorId id, final PersonName name) { + private Author(final AuthorId id, final PersonName name) { this.id = id; this.name = name; } @@ -18,6 +18,10 @@ public class Author { return name; } + public AuthorId id() { + return id; + } + public static final class AuthorBuilder { private AuthorId id; private PersonName name; diff --git a/src/main/java/tech/allegro/hexagon/articles/domain/ports/ArticleEventPublisher.java b/src/main/java/tech/allegro/hexagon/articles/domain/ports/ArticleEventPublisher.java deleted file mode 100644 index dd7d546..0000000 --- a/src/main/java/tech/allegro/hexagon/articles/domain/ports/ArticleEventPublisher.java +++ /dev/null @@ -1,11 +0,0 @@ -package tech.allegro.hexagon.articles.domain.ports; - -import tech.allegro.hexagon.articles.domain.model.Article; - -public interface ArticleEventPublisher { - - void publishArticleCreationEvent(Article article); - - void publishArticleRetrievalEvent(Article article); - -} diff --git a/src/main/java/tech/allegro/hexagon/articles/domain/ports/ArticleMessageSender.java b/src/main/java/tech/allegro/hexagon/articles/domain/ports/ArticleMessageSender.java new file mode 100644 index 0000000..315e597 --- /dev/null +++ b/src/main/java/tech/allegro/hexagon/articles/domain/ports/ArticleMessageSender.java @@ -0,0 +1,11 @@ +package tech.allegro.hexagon.articles.domain.ports; + +import tech.allegro.hexagon.articles.domain.model.Article; + +public interface ArticleMessageSender { + + void sendMessageForCreated(Article article); + + void sendMessageForRetrieved(Article article); + +} diff --git a/src/main/java/tech/allegro/hexagon/articles/domain/ports/ArticleService.java b/src/main/java/tech/allegro/hexagon/articles/domain/ports/ArticleService.java new file mode 100644 index 0000000..8647954 --- /dev/null +++ b/src/main/java/tech/allegro/hexagon/articles/domain/ports/ArticleService.java @@ -0,0 +1,41 @@ +package tech.allegro.hexagon.articles.domain.ports; + +import tech.allegro.hexagon.articles.domain.ArticlePublisher; +import tech.allegro.hexagon.articles.domain.model.Article; +import tech.allegro.hexagon.articles.domain.model.ArticleId; +import tech.allegro.hexagon.articles.domain.model.Author; +import tech.allegro.hexagon.articles.domain.model.AuthorId; +import tech.allegro.hexagon.articles.domain.model.Content; +import tech.allegro.hexagon.articles.domain.model.Title; + +public final class ArticleService { + + private final ArticleRepository articleRepository; + private final AuthorRepository authorRepository; + private final ArticlePublisher eventPublisher; + + + public ArticleService(final ArticleRepository articleRepository, + final AuthorRepository authorRepository, + final ArticlePublisher eventPublisher) { + this.articleRepository = articleRepository; + this.authorRepository = authorRepository; + this.eventPublisher = eventPublisher; + } + + public ArticleId create(final AuthorId authorId, final Title title, final Content content) { + final Author author = authorRepository.get(authorId); + final Article article = articleRepository.save(author, title, content); + + article.validateEligibilityForPublication(); + + eventPublisher.publishCreationOf(article); + return article.id(); + } + + public Article get(final ArticleId id) { + final Article article = articleRepository.get(id); + eventPublisher.publishRetrievalOf(article); + return article; + } +} diff --git a/src/main/java/tech/allegro/hexagon/articles/domain/ports/ArticleAuthorNotifier.java b/src/main/java/tech/allegro/hexagon/articles/domain/ports/AuthorNotifier.java similarity index 55% rename from src/main/java/tech/allegro/hexagon/articles/domain/ports/ArticleAuthorNotifier.java rename to src/main/java/tech/allegro/hexagon/articles/domain/ports/AuthorNotifier.java index e5e0102..646ecf8 100644 --- a/src/main/java/tech/allegro/hexagon/articles/domain/ports/ArticleAuthorNotifier.java +++ b/src/main/java/tech/allegro/hexagon/articles/domain/ports/AuthorNotifier.java @@ -2,8 +2,8 @@ package tech.allegro.hexagon.articles.domain.ports; import tech.allegro.hexagon.articles.domain.model.Article; -public interface ArticleAuthorNotifier { +public interface AuthorNotifier { - void notifyAboutArticleCreation(Article article); + void notifyAboutCreationOf(Article article); } diff --git a/target/classes/META-INF/hexagonal-architecture-example.kotlin_module b/target/classes/META-INF/hexagonal-architecture-example.kotlin_module deleted file mode 100644 index a49347a..0000000 Binary files a/target/classes/META-INF/hexagonal-architecture-example.kotlin_module and /dev/null differ diff --git a/target/classes/tech/allegro/hexagon/HexagonalArchitectureExampleApplication.class b/target/classes/tech/allegro/hexagon/HexagonalArchitectureExampleApplication.class deleted file mode 100644 index b345df0..0000000 Binary files a/target/classes/tech/allegro/hexagon/HexagonalArchitectureExampleApplication.class and /dev/null differ diff --git a/target/classes/tech/allegro/hexagon/articles/adapters/api/ArticleController.class b/target/classes/tech/allegro/hexagon/articles/adapters/api/ArticleController.class deleted file mode 100644 index cf6d0fd..0000000 Binary files a/target/classes/tech/allegro/hexagon/articles/adapters/api/ArticleController.class and /dev/null differ diff --git a/target/classes/tech/allegro/hexagon/articles/adapters/api/ArticleIdResponse.class b/target/classes/tech/allegro/hexagon/articles/adapters/api/ArticleIdResponse.class deleted file mode 100644 index 96ba684..0000000 Binary files a/target/classes/tech/allegro/hexagon/articles/adapters/api/ArticleIdResponse.class and /dev/null differ diff --git a/target/classes/tech/allegro/hexagon/articles/adapters/api/ArticleRequest.class b/target/classes/tech/allegro/hexagon/articles/adapters/api/ArticleRequest.class deleted file mode 100644 index 8c48a0f..0000000 Binary files a/target/classes/tech/allegro/hexagon/articles/adapters/api/ArticleRequest.class and /dev/null differ diff --git a/target/classes/tech/allegro/hexagon/articles/adapters/api/ArticleResponse.class b/target/classes/tech/allegro/hexagon/articles/adapters/api/ArticleResponse.class deleted file mode 100644 index 779221a..0000000 Binary files a/target/classes/tech/allegro/hexagon/articles/adapters/api/ArticleResponse.class and /dev/null differ diff --git a/target/classes/tech/allegro/hexagon/articles/adapters/api/ArticleService.class b/target/classes/tech/allegro/hexagon/articles/adapters/api/ArticleService.class deleted file mode 100644 index 50b31df..0000000 Binary files a/target/classes/tech/allegro/hexagon/articles/adapters/api/ArticleService.class and /dev/null differ diff --git a/target/classes/tech/allegro/hexagon/articles/adapters/authorservice/AuthorExternalModel.class b/target/classes/tech/allegro/hexagon/articles/adapters/authorservice/AuthorExternalModel.class deleted file mode 100644 index e160b4d..0000000 Binary files a/target/classes/tech/allegro/hexagon/articles/adapters/authorservice/AuthorExternalModel.class and /dev/null differ diff --git a/target/classes/tech/allegro/hexagon/articles/adapters/authorservice/ExternalServiceClientAuthorRepository.class b/target/classes/tech/allegro/hexagon/articles/adapters/authorservice/ExternalServiceClientAuthorRepository.class deleted file mode 100644 index 3240ac3..0000000 Binary files a/target/classes/tech/allegro/hexagon/articles/adapters/authorservice/ExternalServiceClientAuthorRepository.class and /dev/null differ diff --git a/target/classes/tech/allegro/hexagon/articles/adapters/config/ArticleConfig.class b/target/classes/tech/allegro/hexagon/articles/adapters/config/ArticleConfig.class deleted file mode 100644 index 99ead3c..0000000 Binary files a/target/classes/tech/allegro/hexagon/articles/adapters/config/ArticleConfig.class and /dev/null differ diff --git a/target/classes/tech/allegro/hexagon/articles/adapters/events/ArticleCreatedEvent.class b/target/classes/tech/allegro/hexagon/articles/adapters/events/ArticleCreatedEvent.class deleted file mode 100644 index 2188e65..0000000 Binary files a/target/classes/tech/allegro/hexagon/articles/adapters/events/ArticleCreatedEvent.class and /dev/null differ diff --git a/target/classes/tech/allegro/hexagon/articles/adapters/events/ArticleRetrievedEvent.class b/target/classes/tech/allegro/hexagon/articles/adapters/events/ArticleRetrievedEvent.class deleted file mode 100644 index 8af0758..0000000 Binary files a/target/classes/tech/allegro/hexagon/articles/adapters/events/ArticleRetrievedEvent.class and /dev/null differ diff --git a/target/classes/tech/allegro/hexagon/articles/adapters/events/MessageBrokerArticleEventPublisher.class b/target/classes/tech/allegro/hexagon/articles/adapters/events/MessageBrokerArticleEventPublisher.class deleted file mode 100644 index f8fbb94..0000000 Binary files a/target/classes/tech/allegro/hexagon/articles/adapters/events/MessageBrokerArticleEventPublisher.class and /dev/null differ diff --git a/target/classes/tech/allegro/hexagon/articles/adapters/notifications/ArticleAuthorMailNotifier.class b/target/classes/tech/allegro/hexagon/articles/adapters/notifications/ArticleAuthorMailNotifier.class deleted file mode 100644 index 2903420..0000000 Binary files a/target/classes/tech/allegro/hexagon/articles/adapters/notifications/ArticleAuthorMailNotifier.class and /dev/null differ diff --git a/target/classes/tech/allegro/hexagon/articles/adapters/notifications/ArticleAuthorSmsNotifier.class b/target/classes/tech/allegro/hexagon/articles/adapters/notifications/ArticleAuthorSmsNotifier.class deleted file mode 100644 index 3d556b1..0000000 Binary files a/target/classes/tech/allegro/hexagon/articles/adapters/notifications/ArticleAuthorSmsNotifier.class and /dev/null differ diff --git a/target/classes/tech/allegro/hexagon/articles/adapters/notifications/ArticleMailModel.class b/target/classes/tech/allegro/hexagon/articles/adapters/notifications/ArticleMailModel.class deleted file mode 100644 index 38355b1..0000000 Binary files a/target/classes/tech/allegro/hexagon/articles/adapters/notifications/ArticleMailModel.class and /dev/null differ diff --git a/target/classes/tech/allegro/hexagon/articles/adapters/notifications/ArticleSmsModel.class b/target/classes/tech/allegro/hexagon/articles/adapters/notifications/ArticleSmsModel.class deleted file mode 100644 index 0035520..0000000 Binary files a/target/classes/tech/allegro/hexagon/articles/adapters/notifications/ArticleSmsModel.class and /dev/null differ diff --git a/target/classes/tech/allegro/hexagon/articles/adapters/persistence/ArticleDatabaseModel.class b/target/classes/tech/allegro/hexagon/articles/adapters/persistence/ArticleDatabaseModel.class deleted file mode 100644 index 6192af7..0000000 Binary files a/target/classes/tech/allegro/hexagon/articles/adapters/persistence/ArticleDatabaseModel.class and /dev/null differ diff --git a/target/classes/tech/allegro/hexagon/articles/adapters/persistence/DbArticleRepository.class b/target/classes/tech/allegro/hexagon/articles/adapters/persistence/DbArticleRepository.class deleted file mode 100644 index c5994e4..0000000 Binary files a/target/classes/tech/allegro/hexagon/articles/adapters/persistence/DbArticleRepository.class and /dev/null differ diff --git a/target/classes/tech/allegro/hexagon/articles/adapters/twitter/ArticleTwitterModel.class b/target/classes/tech/allegro/hexagon/articles/adapters/twitter/ArticleTwitterModel.class deleted file mode 100644 index e54826a..0000000 Binary files a/target/classes/tech/allegro/hexagon/articles/adapters/twitter/ArticleTwitterModel.class and /dev/null differ diff --git a/target/classes/tech/allegro/hexagon/articles/adapters/twitter/TwitterArticlePublisher.class b/target/classes/tech/allegro/hexagon/articles/adapters/twitter/TwitterArticlePublisher.class deleted file mode 100644 index 8be0717..0000000 Binary files a/target/classes/tech/allegro/hexagon/articles/adapters/twitter/TwitterArticlePublisher.class and /dev/null differ diff --git a/target/classes/tech/allegro/hexagon/articles/domain/ArticleFacade.class b/target/classes/tech/allegro/hexagon/articles/domain/ArticleFacade.class deleted file mode 100644 index a8e076a..0000000 Binary files a/target/classes/tech/allegro/hexagon/articles/domain/ArticleFacade.class and /dev/null differ diff --git a/target/classes/tech/allegro/hexagon/articles/domain/model/Article$ArticleBuilder.class b/target/classes/tech/allegro/hexagon/articles/domain/model/Article$ArticleBuilder.class deleted file mode 100644 index 5f61800..0000000 Binary files a/target/classes/tech/allegro/hexagon/articles/domain/model/Article$ArticleBuilder.class and /dev/null differ diff --git a/target/classes/tech/allegro/hexagon/articles/domain/model/Article.class b/target/classes/tech/allegro/hexagon/articles/domain/model/Article.class deleted file mode 100644 index 46a60b2..0000000 Binary files a/target/classes/tech/allegro/hexagon/articles/domain/model/Article.class and /dev/null differ diff --git a/target/classes/tech/allegro/hexagon/articles/domain/model/ArticleId.class b/target/classes/tech/allegro/hexagon/articles/domain/model/ArticleId.class deleted file mode 100644 index 5fe8972..0000000 Binary files a/target/classes/tech/allegro/hexagon/articles/domain/model/ArticleId.class and /dev/null differ diff --git a/target/classes/tech/allegro/hexagon/articles/domain/model/Author$AuthorBuilder.class b/target/classes/tech/allegro/hexagon/articles/domain/model/Author$AuthorBuilder.class deleted file mode 100644 index 0276613..0000000 Binary files a/target/classes/tech/allegro/hexagon/articles/domain/model/Author$AuthorBuilder.class and /dev/null differ diff --git a/target/classes/tech/allegro/hexagon/articles/domain/model/Author.class b/target/classes/tech/allegro/hexagon/articles/domain/model/Author.class deleted file mode 100644 index 2f4e8a8..0000000 Binary files a/target/classes/tech/allegro/hexagon/articles/domain/model/Author.class and /dev/null differ diff --git a/target/classes/tech/allegro/hexagon/articles/domain/model/AuthorId.class b/target/classes/tech/allegro/hexagon/articles/domain/model/AuthorId.class deleted file mode 100644 index 7801cb1..0000000 Binary files a/target/classes/tech/allegro/hexagon/articles/domain/model/AuthorId.class and /dev/null differ diff --git a/target/classes/tech/allegro/hexagon/articles/domain/model/Content.class b/target/classes/tech/allegro/hexagon/articles/domain/model/Content.class deleted file mode 100644 index 6ea737d..0000000 Binary files a/target/classes/tech/allegro/hexagon/articles/domain/model/Content.class and /dev/null differ diff --git a/target/classes/tech/allegro/hexagon/articles/domain/model/PersonName.class b/target/classes/tech/allegro/hexagon/articles/domain/model/PersonName.class deleted file mode 100644 index f0809a6..0000000 Binary files a/target/classes/tech/allegro/hexagon/articles/domain/model/PersonName.class and /dev/null differ diff --git a/target/classes/tech/allegro/hexagon/articles/domain/model/Title.class b/target/classes/tech/allegro/hexagon/articles/domain/model/Title.class deleted file mode 100644 index 7fe0550..0000000 Binary files a/target/classes/tech/allegro/hexagon/articles/domain/model/Title.class and /dev/null differ diff --git a/target/classes/tech/allegro/hexagon/articles/domain/ports/ArticleAuthorNotifier.class b/target/classes/tech/allegro/hexagon/articles/domain/ports/ArticleAuthorNotifier.class deleted file mode 100644 index a5c6ae9..0000000 Binary files a/target/classes/tech/allegro/hexagon/articles/domain/ports/ArticleAuthorNotifier.class and /dev/null differ diff --git a/target/classes/tech/allegro/hexagon/articles/domain/ports/ArticleEventPublisher.class b/target/classes/tech/allegro/hexagon/articles/domain/ports/ArticleEventPublisher.class deleted file mode 100644 index 7ee9def..0000000 Binary files a/target/classes/tech/allegro/hexagon/articles/domain/ports/ArticleEventPublisher.class and /dev/null differ diff --git a/target/classes/tech/allegro/hexagon/articles/domain/ports/ArticleRepository.class b/target/classes/tech/allegro/hexagon/articles/domain/ports/ArticleRepository.class deleted file mode 100644 index 9e05795..0000000 Binary files a/target/classes/tech/allegro/hexagon/articles/domain/ports/ArticleRepository.class and /dev/null differ diff --git a/target/classes/tech/allegro/hexagon/articles/domain/ports/AuthorRepository.class b/target/classes/tech/allegro/hexagon/articles/domain/ports/AuthorRepository.class deleted file mode 100644 index 63b3f3a..0000000 Binary files a/target/classes/tech/allegro/hexagon/articles/domain/ports/AuthorRepository.class and /dev/null differ diff --git a/target/classes/tech/allegro/hexagon/articles/domain/ports/SocialMediaPublisher.class b/target/classes/tech/allegro/hexagon/articles/domain/ports/SocialMediaPublisher.class deleted file mode 100644 index d0fe161..0000000 Binary files a/target/classes/tech/allegro/hexagon/articles/domain/ports/SocialMediaPublisher.class and /dev/null differ