From 8756dbab80405537181882c28f33acfacf1758f6 Mon Sep 17 00:00:00 2001 From: Pavel Vetokhin Date: Wed, 11 Oct 2023 22:04:26 +0300 Subject: [PATCH 01/10] Bring client impl to description --- .../bezmen/interior/construction/App.java | 27 ++++--- .../interior/core/SepulkaServiceImpl.java | 13 ++-- .../interior/messaging/SepulkaClientImpl.java | 19 +++-- .../springmvc/SepulkaController.java | 15 +--- .../construction/SepulkaClientBeans.java | 18 ++--- .../interior/messaging/SepulkaClientIT.java | 15 ++-- docs/pipeline.adoc | 45 +++--------- docs/solution.adoc | 69 ++++++++++++++++-- docs/solution/domain.png | Bin 0 -> 33264 bytes docs/solution/domain.puml | 59 +++++++++++++++ docs/toolchain.adoc | 24 ++++++ .../exterior/messaging/SepulkaClient.java | 2 +- .../messaging/SepulkaRegisterSliceEg.java | 6 ++ .../messaging/SepulkaRegisteredSliceEg.java | 6 ++ .../bezmen/interior/core/SepulkaService.java | 3 +- .../interior/core/SepulkaSliceMapper.java | 3 + .../messaging/BezmenClientJavaHttp.java | 22 ++---- .../messaging/SepulkaClientSpringWeb.java | 14 ++-- .../bezmen/registration/SepulkaTest.java | 12 ++- 19 files changed, 239 insertions(+), 133 deletions(-) create mode 100644 docs/solution/domain.png create mode 100644 docs/solution/domain.puml create mode 100644 docs/toolchain.adoc diff --git a/apps/sepuling/src/main/java/smecalculus/bezmen/interior/construction/App.java b/apps/sepuling/src/main/java/smecalculus/bezmen/interior/construction/App.java index 10b134bb..4ab51325 100644 --- a/apps/sepuling/src/main/java/smecalculus/bezmen/interior/construction/App.java +++ b/apps/sepuling/src/main/java/smecalculus/bezmen/interior/construction/App.java @@ -38,9 +38,8 @@ public static void main(String[] args) { @Bean @ConditionalOnMessageMappingModes(SPRING_MVC) - SepulkaController sepulkaControllerSpringMvc( - EdgeValidator validator, SepulkaClient client, SepulkaMsgMapper mapper) { - return new SepulkaController(validator, client, mapper); + SepulkaController sepulkaControllerSpringMvc(SepulkaClient client) { + return new SepulkaController(client); } @Bean @@ -49,18 +48,23 @@ SepulkaMsgMapper sepulkaMsgMapper() { } @Bean - SepulkaClient sepulkaClient(SepulkaService service, SepulkaSliceMapper mapper) { - return new SepulkaClientImpl(service, mapper); + SepulkaClient sepulkaClient(EdgeValidator validator, SepulkaMsgMapper mapper, SepulkaService service) { + return new SepulkaClientImpl(validator, mapper, service); } @Bean - SepulkaService sepulkaService(SepulkaDao sepulkaDao) { - return new SepulkaServiceImpl(sepulkaDao); + SepulkaSliceMapper sepulkaSliceMapper() { + return new SepulkaSliceMapperImpl(); } @Bean - SepulkaSliceMapper sepulkaSliceMapper() { - return new SepulkaSliceMapperImpl(); + SepulkaService sepulkaService(SepulkaSliceMapper mapper, SepulkaDao dao) { + return new SepulkaServiceImpl(mapper, dao); + } + + @Bean + SepulkaRecMapper sepulkaRecMapper() { + return new SepulkaRecMapperImpl(); } @Bean @@ -74,9 +78,4 @@ SepulkaDaoSpringData sepulkaDaoSpringData(SepulkaRecMapper mapper, SepulkaReposi SepulkaDaoMyBatis sepulkaDaoMyBatis(SepulkaRecMapper recMapper, SepulkaSqlMapper sqlMapper) { return new SepulkaDaoMyBatis(recMapper, sqlMapper); } - - @Bean - SepulkaRecMapper sepulkaRecMapper() { - return new SepulkaRecMapperImpl(); - } } diff --git a/apps/sepuling/src/main/java/smecalculus/bezmen/interior/core/SepulkaServiceImpl.java b/apps/sepuling/src/main/java/smecalculus/bezmen/interior/core/SepulkaServiceImpl.java index e0e2fe90..368bdf62 100644 --- a/apps/sepuling/src/main/java/smecalculus/bezmen/interior/core/SepulkaServiceImpl.java +++ b/apps/sepuling/src/main/java/smecalculus/bezmen/interior/core/SepulkaServiceImpl.java @@ -5,18 +5,21 @@ import java.util.List; import lombok.NonNull; import smecalculus.bezmen.exterior.messaging.SepulkaRegisterSlice; +import smecalculus.bezmen.exterior.messaging.SepulkaRegisteredSlice; import smecalculus.bezmen.interior.storage.SepulkaDao; -public record SepulkaServiceImpl(@NonNull SepulkaDao sepulkaDao) implements SepulkaService { +public record SepulkaServiceImpl(@NonNull SepulkaSliceMapper mapper, @NonNull SepulkaDao dao) + implements SepulkaService { @Override - public Sepulka register(SepulkaRegisterSlice slice) { - Sepulka sepulka = Sepulka.builder().id(randomUUID()).name(slice.name()).build(); - return sepulkaDao.save(sepulka); + public SepulkaRegisteredSlice register(SepulkaRegisterSlice request) { + var sepulkaCreated = mapper.toDomain(request).id(randomUUID()).build(); + var sepulkaSaved = dao.save(sepulkaCreated); + return mapper.toSlice(sepulkaSaved); } @Override public List getSepulkas() { - return sepulkaDao.getSepulkas(); + return dao.getSepulkas(); } } diff --git a/apps/sepuling/src/main/java/smecalculus/bezmen/interior/messaging/SepulkaClientImpl.java b/apps/sepuling/src/main/java/smecalculus/bezmen/interior/messaging/SepulkaClientImpl.java index 50ec3109..fc8c6b23 100644 --- a/apps/sepuling/src/main/java/smecalculus/bezmen/interior/messaging/SepulkaClientImpl.java +++ b/apps/sepuling/src/main/java/smecalculus/bezmen/interior/messaging/SepulkaClientImpl.java @@ -2,18 +2,21 @@ import lombok.NonNull; import smecalculus.bezmen.exterior.messaging.SepulkaClient; -import smecalculus.bezmen.exterior.messaging.SepulkaRegisterSlice; -import smecalculus.bezmen.exterior.messaging.SepulkaRegisteredSlice; -import smecalculus.bezmen.interior.core.Sepulka; +import smecalculus.bezmen.exterior.messaging.SepulkaMsgMapper; +import smecalculus.bezmen.exterior.messaging.SepulkaRegisterSliceMsg; +import smecalculus.bezmen.exterior.messaging.SepulkaRegisteredSliceMsg; import smecalculus.bezmen.interior.core.SepulkaService; -import smecalculus.bezmen.interior.core.SepulkaSliceMapper; +import smecalculus.bezmen.interior.validation.EdgeValidator; -public record SepulkaClientImpl(@NonNull SepulkaService service, @NonNull SepulkaSliceMapper mapper) +public record SepulkaClientImpl( + @NonNull EdgeValidator validator, @NonNull SepulkaMsgMapper mapper, @NonNull SepulkaService service) implements SepulkaClient { @Override - public SepulkaRegisteredSlice register(SepulkaRegisterSlice request) { - Sepulka sepulka = service.register(request); - return mapper.toSlice(sepulka); + public SepulkaRegisteredSliceMsg register(SepulkaRegisterSliceMsg sliceMsg) { + validator.validate(sliceMsg); + var registerSlice = mapper.toDomain(sliceMsg); + var registeredSlice = service.register(registerSlice); + return mapper.toMsg(registeredSlice); } } diff --git a/apps/sepuling/src/main/java/smecalculus/bezmen/interior/messaging/springmvc/SepulkaController.java b/apps/sepuling/src/main/java/smecalculus/bezmen/interior/messaging/springmvc/SepulkaController.java index f8335cc8..49d9cc23 100644 --- a/apps/sepuling/src/main/java/smecalculus/bezmen/interior/messaging/springmvc/SepulkaController.java +++ b/apps/sepuling/src/main/java/smecalculus/bezmen/interior/messaging/springmvc/SepulkaController.java @@ -8,23 +8,16 @@ import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import smecalculus.bezmen.exterior.messaging.SepulkaClient; -import smecalculus.bezmen.exterior.messaging.SepulkaMsgMapper; -import smecalculus.bezmen.exterior.messaging.SepulkaRegisterSlice; import smecalculus.bezmen.exterior.messaging.SepulkaRegisterSliceMsg; -import smecalculus.bezmen.exterior.messaging.SepulkaRegisteredSlice; import smecalculus.bezmen.exterior.messaging.SepulkaRegisteredSliceMsg; -import smecalculus.bezmen.interior.validation.EdgeValidator; @RestController @RequestMapping("sepulkas") -public record SepulkaController( - @NonNull EdgeValidator validator, @NonNull SepulkaClient client, @NonNull SepulkaMsgMapper mapper) { +public record SepulkaController(@NonNull SepulkaClient client) { @PostMapping - ResponseEntity register(@RequestBody SepulkaRegisterSliceMsg sliceMsg) { - validator.validate(sliceMsg); - SepulkaRegisterSlice requestSlice = mapper.toDomain(sliceMsg); - SepulkaRegisteredSlice responseSlice = client.register(requestSlice); - return ResponseEntity.status(HttpStatus.CREATED).body(mapper.toMsg(responseSlice)); + ResponseEntity register(@RequestBody SepulkaRegisterSliceMsg registerSliceMsg) { + var registeredSliceMsg = client.register(registerSliceMsg); + return ResponseEntity.status(HttpStatus.CREATED).body(registeredSliceMsg); } } diff --git a/apps/sepuling/src/test/java/smecalculus/bezmen/interior/construction/SepulkaClientBeans.java b/apps/sepuling/src/test/java/smecalculus/bezmen/interior/construction/SepulkaClientBeans.java index b9fb24e3..d84dc367 100644 --- a/apps/sepuling/src/test/java/smecalculus/bezmen/interior/construction/SepulkaClientBeans.java +++ b/apps/sepuling/src/test/java/smecalculus/bezmen/interior/construction/SepulkaClientBeans.java @@ -5,14 +5,10 @@ import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Import; -import org.springframework.test.web.reactive.server.WebTestClient; import org.springframework.test.web.servlet.client.MockMvcWebTestClient; import smecalculus.bezmen.exterior.messaging.SepulkaClient; -import smecalculus.bezmen.exterior.messaging.SepulkaMsgMapper; import smecalculus.bezmen.exterior.messaging.SepulkaMsgMapperImpl; import smecalculus.bezmen.interior.core.SepulkaService; -import smecalculus.bezmen.interior.core.SepulkaSliceMapper; -import smecalculus.bezmen.interior.core.SepulkaSliceMapperImpl; import smecalculus.bezmen.interior.messaging.SepulkaClientImpl; import smecalculus.bezmen.interior.messaging.SepulkaClientSpringWeb; import smecalculus.bezmen.interior.messaging.springmvc.SepulkaController; @@ -28,17 +24,15 @@ public SepulkaService sepulkaService() { } @Bean - SepulkaClient internalClient(SepulkaService service) { - SepulkaSliceMapper mapper = new SepulkaSliceMapperImpl(); - return new SepulkaClientImpl(service, mapper); + SepulkaClient internalClient(EdgeValidator validator, SepulkaService service) { + var mapper = new SepulkaMsgMapperImpl(); + return new SepulkaClientImpl(validator, mapper, service); } @Bean - SepulkaClient externalClient(EdgeValidator validator, SepulkaClient internalClient) { - SepulkaMsgMapper mapper = new SepulkaMsgMapperImpl(); - WebTestClient client = MockMvcWebTestClient.bindToController( - new SepulkaController(validator, internalClient, mapper)) + SepulkaClient externalClient(SepulkaClient internalClient) { + var client = MockMvcWebTestClient.bindToController(new SepulkaController(internalClient)) .build(); - return new SepulkaClientSpringWeb(client, mapper); + return new SepulkaClientSpringWeb(client); } } diff --git a/apps/sepuling/src/test/java/smecalculus/bezmen/interior/messaging/SepulkaClientIT.java b/apps/sepuling/src/test/java/smecalculus/bezmen/interior/messaging/SepulkaClientIT.java index dc1b77f4..dada14fb 100644 --- a/apps/sepuling/src/test/java/smecalculus/bezmen/interior/messaging/SepulkaClientIT.java +++ b/apps/sepuling/src/test/java/smecalculus/bezmen/interior/messaging/SepulkaClientIT.java @@ -3,9 +3,9 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.when; -import static smecalculus.bezmen.exterior.messaging.SepulkaRegisterSliceEg.Pojos.sepulkaRegisterSlice; +import static smecalculus.bezmen.exterior.messaging.SepulkaRegisterSliceEg.Pojos.sepulkaRegisterSliceMsg; import static smecalculus.bezmen.exterior.messaging.SepulkaRegisteredSliceEg.Pojos.sepulkaRegisteredSlice; -import static smecalculus.bezmen.interior.core.SepulkaEg.Pojos.sepulka; +import static smecalculus.bezmen.exterior.messaging.SepulkaRegisteredSliceEg.Pojos.sepulkaRegisteredSliceMsg; import java.util.UUID; import org.junit.jupiter.api.Test; @@ -15,7 +15,6 @@ import org.springframework.test.context.junit.jupiter.SpringExtension; import smecalculus.bezmen.exterior.messaging.SepulkaClient; import smecalculus.bezmen.exterior.messaging.SepulkaRegisterSlice; -import smecalculus.bezmen.exterior.messaging.SepulkaRegisteredSlice; import smecalculus.bezmen.interior.construction.SepulkaClientBeans; import smecalculus.bezmen.interior.core.SepulkaService; @@ -32,15 +31,15 @@ abstract class SepulkaClientIT { @Test void shouldRegisterSepulka() { // given - UUID id = UUID.randomUUID(); + var id = UUID.randomUUID(); // and - SepulkaRegisterSlice request = sepulkaRegisterSlice(); + var request = sepulkaRegisterSliceMsg(); // and - when(serviceMock.register(any(SepulkaRegisterSlice.class))).thenReturn(sepulka(id)); + when(serviceMock.register(any(SepulkaRegisterSlice.class))).thenReturn(sepulkaRegisteredSlice(id)); // and - SepulkaRegisteredSlice expectedResponse = sepulkaRegisteredSlice(id); + var expectedResponse = sepulkaRegisteredSliceMsg(id); // when - SepulkaRegisteredSlice actualResponse = externalClient.register(request); + var actualResponse = externalClient.register(request); // then assertThat(actualResponse) .usingRecursiveComparison() diff --git a/docs/pipeline.adoc b/docs/pipeline.adoc index 1df78f70..9f15e742 100644 --- a/docs/pipeline.adoc +++ b/docs/pipeline.adoc @@ -1,30 +1,12 @@ -= Конвейер += Конвейер (Pipeline) -== Ключевые принципы +Система, реализуемая для внедренцев. -Сущности первого класса:: -Решение (solution) - система, реализуемая для клиентов. Конвейер (pipeline) - система, реализуемая для внедренцев. Инструментарий (toolchain) - система, реализуемая для разработчиков. - -Единый инструментарий для локальной разработки и непрерывной интеграции:: -Семантика интерфейса подразумевает набор предопределенных абстракций, артефакты которых последовательно конструируются в ходе сборки. Перед началом конструирования выполняются обязательные проверки. Примеры абстракций: кодовая база (codebase), бинарники (binaries), образы (images), стеки (stacks) и другие. - -Контентная адресация (aka идентификация по содержимому):: -Контентная адресация (content addressability) делает конструирование *идемпотентным*. Для директорий с исходным кодом вычисляются их контентные идентификаторы (CID's). Затем вычисляются корневые идентификаторы решения и конвейера. Таким образом формируется 2 небольших дерева Меркла, хеши которых подставляются в качестве тегов/классификаторов артефактов соответствующих абстракций. Артефакт конструируется, только когда его контентный идентификатор меняется. - -Множественность окружений и назначений:: -Решение/инструментарий используется клиентами/разработчиками в разных окружениях (envs) для разных назначений (usages). Ключевые окружения/назначения именуются и проверяются в рамках непрерывной интеграции. Устаревшие окружения/назначения снимаются с поддержки. - -Тесты! Тесты! Тесты!:: -Тестирование - один из самых важных (или даже самый важный) аспектов разработки! При тестировании проверяется поведение целевого объекта в различных ситуациях. В зависимости от подхода к подготовке зависимостей целевого объекта тесты можно подразделить на 3 категории. -Модульные тесты (unit tests)::: -Все зависимости целевого объекта глушатся (stub) или мокируются (mock). -Интеграционные тесты (integration tests)::: -Все зависимости глушатся/мокируются кроме одной (иногда нескольких), которая честно конструируется. -Сквозные тесты (end-to-end tests)::: -Все зависимости честно конструируются. - -Роботизированная асинхронная заливка (merge):: +.Ключевые принципы +**** +Роботизированная заливка изменений:: Позволяет избежать ошибок/конкуренции и, как следствие, неоправданных потерь на загруженных ветках (например, main). +**** == Непрерывная интеграция (CI) @@ -39,15 +21,15 @@ ==== В пределах разумного (sanity) -Запускаем анализ зависимостей, линтинг, статический анализ, компиляцию, модульные тесты, собираем и публикуем бинарники. +Запускаем анализ зависимостей, линтинг, компиляцию, прогоняем модульные тесты и собираем бинарники. ==== Убедительная (convincing) -Все перечисленное ранее. Плюс запускаем интеграционные тесты, анализируем покрытие, собираем и публикуем образы. +Все перечисленное ранее. Плюс прогоняем интеграционные тесты, анализируем покрытие, публикуем бинарники, собираем и публикуем образы. ==== За пределами сомнений (beyond doubt) -Все перечисленное ранее. Плюс запускаем сквозные тесты, собираем и публикуем стеки. +Все перечисленное ранее. Плюс собираем стеки, прогоняем сквозные тесты, публикуем стеки. === Проверка инструментария @@ -59,7 +41,7 @@ ==== За пределами сомнений (beyond doubt) -Запускаем проверку работы всего инструментария. +Запускаем проверку работы всего инструментария и публикуем стеки. == Частые вопросы (FAQ) @@ -67,13 +49,6 @@ Почему обязательными статусными проверками назначены тестовые отчеты, а не тестовые джобы?:: Это дает свободу выбора структуры джобов, т.к. в различных планах сборки она может быть разной. -== Консольный интерфейс (CLI) - - ansible-playbook .yaml - == Todo . Релизная сборка -. Параллелизация модульных тестов -. Построение дерева хешей (взглянуть критически) -. Поддержка нескольких версий Java diff --git a/docs/solution.adoc b/docs/solution.adoc index 287a6cbe..3ae652e0 100644 --- a/docs/solution.adoc +++ b/docs/solution.adoc @@ -1,8 +1,46 @@ -= Решение += Решение (Solution) -== Обмен сообщениями +Система, реализуемая для клиентов. -Принимаем/отправляем сообщения в рамках некоторого протокола, отображая их в доменные объекты. +.Ключевые принципы +**** +Множественность окружений и назначений:: +Решение используется клиентами в различных окружениях (envs) и для различных назначений (usages). Ключевые окружения/назначения явно выделяются и проверяются в рамках непрерывной интеграции. Устаревшие окружения/назначения снимаются с поддержки. + +Тесты! Тесты! Тесты!:: +Тестирование - один из самых важных (или даже самый важный) аспектов разработки! При тестировании проверяется поведение целевого объекта в различных ситуациях. В зависимости от подхода к подготовке зависимостей целевого объекта тесты можно подразделить на 3 категории. +Модульные тесты (unit tests)::: +Все зависимости целевого объекта глушатся (stub) или мокируются (mock). +Интеграционные тесты (integration tests)::: +Все зависимости глушатся/мокируются кроме одной (иногда нескольких), которая честно конструируется. +Сквозные тесты (end-to-end tests)::: +Все зависимости честно конструируются. +**** + +== Конфигурирование (Configuration) + +Читаем конфигурационные параметры (props) в рамках некоторого протокола, отображая их в объекты предметной области. + +// [discrete] +=== Протоколы (Protocols) + +==== FileSystem + +Протокол FileSystem + +=== Отображения (Mappings) + +==== SpringConfig + +Подробнее https://docs.spring.io/spring-boot/docs/current/reference/html/features.html#features.external-config + +==== LightbendConfig + +Подробнее https://lightbend.github.io/config + +== Обмен сообщениями (Messaging) + +Принимаем/отправляем сообщения (messages) в рамках некоторого протокола, отображая их в объекты предметной области. === Протоколы @@ -18,7 +56,7 @@ NOTE: Обычно используются стандартные проток Протокол JMX -=== Отображения +=== Отображения (Mappings) NOTE: Шаблон проектирования `Message Mapping`. @@ -30,11 +68,11 @@ NOTE: Шаблон проектирования `Message Mapping`. Подробнее https://docs.spring.io/spring-boot/docs/current/reference/html/actuator.html -== Хранение состояния +== Хранение состояния (Storage) -Запоминаем/вспоминаем состояние в рамках некоторого протокола, отображая его в доменные объекты. +Запоминаем/вспоминаем состояние (state) в рамках некоторого протокола, отображая его в объекты предметной области. -=== Протоколы +=== Протоколы (Protocols) NOTE: Обычно используются кастомные протоколы, реже - стандартные. @@ -42,7 +80,7 @@ NOTE: Обычно используются кастомные протокол Кастомный протокол PostgreSQL -=== Отображения +=== Отображения (Mappings) NOTE: Шаблон проектирования `Object-Relational Mapping`. @@ -53,3 +91,18 @@ NOTE: Шаблон проектирования `Object-Relational Mapping`. ==== SpringData Подробнее https://docs.spring.io/spring-data/jdbc/docs/current/reference/html + +== Ядро (Core) + +image::solution/domain.png[] + +=== Клиенты (Clients) + +Интерфейсы клиентов являются `портами` в терминах clean/onion/hexagonal архитектуры. +Имплементации клиентов являются `адаптерами` в терминах onion/hexagonal архитектуры и `use case интеракторами` в терминах clean архитектуры. + +=== Мапперы (Mappers) + +=== Сервисы (Services) + +=== Модели (Models) diff --git a/docs/solution/domain.png b/docs/solution/domain.png new file mode 100644 index 0000000000000000000000000000000000000000..cf5313ac53a770643261bfaeee16249e9e095d4b GIT binary patch literal 33264 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 I;u!XS00o4$1ONa4 literal 0 HcmV?d00001 diff --git a/docs/solution/domain.puml b/docs/solution/domain.puml new file mode 100644 index 00000000..5adf6773 --- /dev/null +++ b/docs/solution/domain.puml @@ -0,0 +1,59 @@ +@startuml +hide stereotype + +skinparam nodesep 50 +skinparam ranksep 50 + +skinparam file { + BackgroundColor<> Transparent + BorderColor<> Transparent +} + +show <> stereotype +show <> stereotype + +file "request" as requestIn <> +interface Client as clientIn <> +component Client as adapterIn <> +component Mapper as mapperIn +component Service as service +component Mapper as mapper +interface Client as clientOut <> +component Client as adapterOut <> +component Mapper as mapperOut +file "request" as requestOut <> + +requestIn - clientIn +clientIn -> adapterIn +adapterIn --> mapperIn: Serde\nModel +adapterIn <-- mapperIn: Domain\nModel +adapterIn -> service +service --> mapper: Slice\nModel +service <-- mapper: Entity\nModel +service - clientOut +clientOut -> adapterOut +adapterOut --> mapperOut: Domain\nModel +adapterOut <-- mapperOut: Serde\nModel +adapterOut -> requestOut + +file "response" as responseIn <> +component Client as adapterOut2 <> +interface Client as clientOut2 <> +component Service as service2 +component Client as adapterIn2 <> +interface Client as clientIn2 <> +file "response" as responseOut <> + +adapterOut2 <- responseIn +mapperOut --> adapterOut2: Domain\nModel +mapperOut <-- adapterOut2: Serde\nModel +clientOut2 - adapterOut2 +service2 <- clientOut2 +mapper --> service2: Slice\nModel +mapper <-- service2: Entity\nModel +adapterIn2 <- service2 +mapperIn --> adapterIn2: Serde\nModel +mapperIn <-- adapterIn2: Domain\nModel +clientIn2 - adapterIn2 +responseOut <- clientIn2 +@enduml diff --git a/docs/toolchain.adoc b/docs/toolchain.adoc new file mode 100644 index 00000000..2acfb842 --- /dev/null +++ b/docs/toolchain.adoc @@ -0,0 +1,24 @@ += Инструментарий (Toolchain) + +Система, реализуемая для разработчиков. + +.Ключевые принципы +**** +Единая обвязка для локальной разработки и непрерывной интеграции:: +Семантика обвязки подразумевает набор предопределенных абстракций, артефакты которых последовательно конструируются в ходе сборки. Перед началом конструирования выполняются обязательные проверки. Примеры абстракций: кодовая база (codebase), бинарники (binaries), образы (images), стеки (stacks) и другие. + +Контентная адресация (aka идентификация по содержимому):: +Контентная адресация (content addressability) делает конструирование артефактов *идемпотентным*. Для директорий с исходным кодом вычисляются их контентные идентификаторы (CID's). Затем вычисляются корневые идентификаторы решения и инструментария. Таким образом формируется 2 небольших дерева Меркла, хеши которых подставляются в качестве тегов/классификаторов артефактов соответствующих абстракций. Артефакт реконструируется, только когда его контентный идентификатор изменился. + +Множественность окружений и назначений:: +Инструментарий используется разработчиками в различных окружениях (envs) и для различных назначений (usages). Ключевые окружения/назначения явно выделяются и проверяются в рамках непрерывной интеграции. Устаревшие окружения/назначения снимаются с поддержки. +**** + +== Консольный интерфейс (CLI) + + ansible-playbook .yaml + +== Todo + +. Параллелизация модульных тестов +. Построение дерева хешей (взглянуть критически) diff --git a/libs/abstraction/src/main/java/smecalculus/bezmen/exterior/messaging/SepulkaClient.java b/libs/abstraction/src/main/java/smecalculus/bezmen/exterior/messaging/SepulkaClient.java index 10c3d74d..299e6a61 100644 --- a/libs/abstraction/src/main/java/smecalculus/bezmen/exterior/messaging/SepulkaClient.java +++ b/libs/abstraction/src/main/java/smecalculus/bezmen/exterior/messaging/SepulkaClient.java @@ -1,5 +1,5 @@ package smecalculus.bezmen.exterior.messaging; public interface SepulkaClient { - SepulkaRegisteredSlice register(SepulkaRegisterSlice request); + SepulkaRegisteredSliceMsg register(SepulkaRegisterSliceMsg request); } diff --git a/libs/abstraction/src/main/java/smecalculus/bezmen/exterior/messaging/SepulkaRegisterSliceEg.java b/libs/abstraction/src/main/java/smecalculus/bezmen/exterior/messaging/SepulkaRegisterSliceEg.java index ea5ec87b..ffe324cb 100644 --- a/libs/abstraction/src/main/java/smecalculus/bezmen/exterior/messaging/SepulkaRegisterSliceEg.java +++ b/libs/abstraction/src/main/java/smecalculus/bezmen/exterior/messaging/SepulkaRegisterSliceEg.java @@ -7,5 +7,11 @@ public static class Pojos { public static SepulkaRegisterSlice sepulkaRegisterSlice() { return new SepulkaRegisterSlice(NAME); } + + public static SepulkaRegisterSliceMsg sepulkaRegisterSliceMsg() { + var msg = new SepulkaRegisterSliceMsg(); + msg.setName(NAME); + return msg; + } } } diff --git a/libs/abstraction/src/main/java/smecalculus/bezmen/exterior/messaging/SepulkaRegisteredSliceEg.java b/libs/abstraction/src/main/java/smecalculus/bezmen/exterior/messaging/SepulkaRegisteredSliceEg.java index a741c9da..401a8cb7 100644 --- a/libs/abstraction/src/main/java/smecalculus/bezmen/exterior/messaging/SepulkaRegisteredSliceEg.java +++ b/libs/abstraction/src/main/java/smecalculus/bezmen/exterior/messaging/SepulkaRegisteredSliceEg.java @@ -12,5 +12,11 @@ public static SepulkaRegisteredSlice sepulkaRegisteredSlice() { public static SepulkaRegisteredSlice sepulkaRegisteredSlice(UUID id) { return new SepulkaRegisteredSlice(id); } + + public static SepulkaRegisteredSliceMsg sepulkaRegisteredSliceMsg(UUID id) { + var sliceMsg = new SepulkaRegisteredSliceMsg(); + sliceMsg.setId(id.toString()); + return sliceMsg; + } } } diff --git a/libs/abstraction/src/main/java/smecalculus/bezmen/interior/core/SepulkaService.java b/libs/abstraction/src/main/java/smecalculus/bezmen/interior/core/SepulkaService.java index 4b0c3eea..64352b8f 100644 --- a/libs/abstraction/src/main/java/smecalculus/bezmen/interior/core/SepulkaService.java +++ b/libs/abstraction/src/main/java/smecalculus/bezmen/interior/core/SepulkaService.java @@ -2,9 +2,10 @@ import java.util.List; import smecalculus.bezmen.exterior.messaging.SepulkaRegisterSlice; +import smecalculus.bezmen.exterior.messaging.SepulkaRegisteredSlice; public interface SepulkaService { - Sepulka register(SepulkaRegisterSlice slice); + SepulkaRegisteredSlice register(SepulkaRegisterSlice slice); List getSepulkas(); } diff --git a/libs/abstraction/src/main/java/smecalculus/bezmen/interior/core/SepulkaSliceMapper.java b/libs/abstraction/src/main/java/smecalculus/bezmen/interior/core/SepulkaSliceMapper.java index d23f6e89..057648dd 100644 --- a/libs/abstraction/src/main/java/smecalculus/bezmen/interior/core/SepulkaSliceMapper.java +++ b/libs/abstraction/src/main/java/smecalculus/bezmen/interior/core/SepulkaSliceMapper.java @@ -1,9 +1,12 @@ package smecalculus.bezmen.interior.core; import org.mapstruct.Mapper; +import smecalculus.bezmen.exterior.messaging.SepulkaRegisterSlice; import smecalculus.bezmen.exterior.messaging.SepulkaRegisteredSlice; @Mapper public interface SepulkaSliceMapper { + Sepulka.Builder toDomain(SepulkaRegisterSlice slice); + SepulkaRegisteredSlice toSlice(Sepulka sepulka); } diff --git a/libs/messaging/src/main/java/smecalculus/bezmen/exterior/messaging/BezmenClientJavaHttp.java b/libs/messaging/src/main/java/smecalculus/bezmen/exterior/messaging/BezmenClientJavaHttp.java index 2b6cd0f5..da4121fd 100644 --- a/libs/messaging/src/main/java/smecalculus/bezmen/exterior/messaging/BezmenClientJavaHttp.java +++ b/libs/messaging/src/main/java/smecalculus/bezmen/exterior/messaging/BezmenClientJavaHttp.java @@ -7,29 +7,23 @@ import java.net.http.HttpClient; import java.net.http.HttpRequest; import java.net.http.HttpRequest.BodyPublishers; -import java.net.http.HttpResponse; import java.net.http.HttpResponse.BodyHandlers; import lombok.NonNull; -public record BezmenClientJavaHttp( - @NonNull SepulkaMsgMapper msgMapper, @NonNull ObjectMapper jsonMapper, @NonNull HttpClient client) - implements BezmenClient { +public record BezmenClientJavaHttp(@NonNull ObjectMapper mapper, @NonNull HttpClient client) implements BezmenClient { @Override - public SepulkaRegisteredSlice register(SepulkaRegisterSlice request) { + public SepulkaRegisteredSliceMsg register(SepulkaRegisterSliceMsg request) { try { - SepulkaRegisterSliceMsg requestMsg = msgMapper.toMsg(request); - String requestJson = jsonMapper.writeValueAsString(requestMsg); - HttpRequest httpRequest = HttpRequest.newBuilder() + var requestJson = mapper.writeValueAsString(request); + var httpRequest = HttpRequest.newBuilder() .uri(URI.create("http://localhost:8080/sepulkas")) .POST(BodyPublishers.ofString(requestJson)) .header("Content-Type", "application/json") .header("Accept", "application/json") .build(); - HttpResponse responseHttp = client.send(httpRequest, BodyHandlers.ofString()); - SepulkaRegisteredSliceMsg responseMsg = - jsonMapper.readValue(responseHttp.body(), SepulkaRegisteredSliceMsg.class); - return msgMapper.toDomain(responseMsg); + var httpResponse = client.send(httpRequest, BodyHandlers.ofString()); + return mapper.readValue(httpResponse.body(), SepulkaRegisteredSliceMsg.class); } catch (JsonProcessingException e) { throw new RuntimeException(e); } catch (IOException | InterruptedException e) { @@ -40,11 +34,11 @@ public SepulkaRegisteredSlice register(SepulkaRegisterSlice request) { @Override public boolean isReady() { try { - HttpRequest httpRequest = HttpRequest.newBuilder() + var httpRequest = HttpRequest.newBuilder() .uri(URI.create("http://localhost:8080/actuator/health")) .GET() .build(); - HttpResponse httpResponse = client.send(httpRequest, BodyHandlers.discarding()); + var httpResponse = client.send(httpRequest, BodyHandlers.discarding()); return httpResponse.statusCode() == 200; } catch (IOException | InterruptedException e) { throw new RuntimeException(e); diff --git a/libs/testing/src/main/java/smecalculus/bezmen/interior/messaging/SepulkaClientSpringWeb.java b/libs/testing/src/main/java/smecalculus/bezmen/interior/messaging/SepulkaClientSpringWeb.java index ea8e6d13..b2017784 100644 --- a/libs/testing/src/main/java/smecalculus/bezmen/interior/messaging/SepulkaClientSpringWeb.java +++ b/libs/testing/src/main/java/smecalculus/bezmen/interior/messaging/SepulkaClientSpringWeb.java @@ -4,25 +4,21 @@ import org.springframework.http.MediaType; import org.springframework.test.web.reactive.server.WebTestClient; import smecalculus.bezmen.exterior.messaging.SepulkaClient; -import smecalculus.bezmen.exterior.messaging.SepulkaMsgMapper; -import smecalculus.bezmen.exterior.messaging.SepulkaRegisterSlice; -import smecalculus.bezmen.exterior.messaging.SepulkaRegisteredSlice; +import smecalculus.bezmen.exterior.messaging.SepulkaRegisterSliceMsg; import smecalculus.bezmen.exterior.messaging.SepulkaRegisteredSliceMsg; -public record SepulkaClientSpringWeb(@NonNull WebTestClient client, @NonNull SepulkaMsgMapper mapper) - implements SepulkaClient { +public record SepulkaClientSpringWeb(@NonNull WebTestClient client) implements SepulkaClient { @Override - public SepulkaRegisteredSlice register(SepulkaRegisterSlice request) { - SepulkaRegisteredSliceMsg responseMsg = client.post() + public SepulkaRegisteredSliceMsg register(SepulkaRegisterSliceMsg request) { + return client.post() .uri("/sepulkas") .contentType(MediaType.APPLICATION_JSON) .accept(MediaType.APPLICATION_JSON) - .bodyValue(mapper.toMsg(request)) + .bodyValue(request) .exchange() .expectBody(SepulkaRegisteredSliceMsg.class) .returnResult() .getResponseBody(); - return mapper.toDomain(responseMsg); } } diff --git a/tests/e2e/src/test/java/smecalculus/bezmen/registration/SepulkaTest.java b/tests/e2e/src/test/java/smecalculus/bezmen/registration/SepulkaTest.java index 7a0c20b2..14686da1 100644 --- a/tests/e2e/src/test/java/smecalculus/bezmen/registration/SepulkaTest.java +++ b/tests/e2e/src/test/java/smecalculus/bezmen/registration/SepulkaTest.java @@ -3,7 +3,8 @@ import static java.time.Duration.ofSeconds; import static org.assertj.core.api.Assertions.assertThat; import static org.awaitility.Awaitility.await; -import static smecalculus.bezmen.exterior.messaging.SepulkaRegisterSliceEg.Pojos.sepulkaRegisterSlice; +import static smecalculus.bezmen.exterior.messaging.SepulkaRegisterSliceEg.Pojos.sepulkaRegisterSliceMsg; +import static smecalculus.bezmen.exterior.messaging.SepulkaRegisteredSliceEg.Pojos.sepulkaRegisteredSlice; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Tag; @@ -15,9 +16,6 @@ import org.springframework.test.context.junit.jupiter.SpringExtension; import smecalculus.bezmen.StandBeans; import smecalculus.bezmen.exterior.messaging.BezmenClient; -import smecalculus.bezmen.exterior.messaging.SepulkaRegisterSlice; -import smecalculus.bezmen.exterior.messaging.SepulkaRegisteredSlice; -import smecalculus.bezmen.exterior.messaging.SepulkaRegisteredSliceEg; @ExtendWith(SpringExtension.class) @ContextConfiguration(classes = StandBeans.class) @@ -35,11 +33,11 @@ void beforeAll() { @Tag("smoke") void shouldRegisterSepulka() { // given - SepulkaRegisterSlice request = sepulkaRegisterSlice(); + var request = sepulkaRegisterSliceMsg(); // and - SepulkaRegisteredSlice expectedResponse = SepulkaRegisteredSliceEg.Pojos.sepulkaRegisteredSlice(); + var expectedResponse = sepulkaRegisteredSlice(); // when - SepulkaRegisteredSlice actualResponse = bezmenClient.register(request); + var actualResponse = bezmenClient.register(request); // then assertThat(actualResponse) .usingRecursiveComparison() From 56c05cf1783cf45c9e1fba64ce91465c11b8f667 Mon Sep 17 00:00:00 2001 From: Pavel Vetokhin Date: Wed, 11 Oct 2023 22:20:04 +0300 Subject: [PATCH 02/10] Record to class --- .../bezmen/interior/core/SepulkaServiceImpl.java | 11 +++++++++-- .../interior/messaging/SepulkaClientImpl.java | 15 ++++++++++++--- .../messaging/springmvc/SepulkaController.java | 7 ++++++- .../interior/storage/SepulkaDaoMyBatis.java | 11 +++++++++-- .../interior/storage/SepulkaDaoSpringData.java | 11 +++++++++-- .../ConfigKeeperLightbendConfig.java | 8 +++++++- .../configuration/ConfigKeeperSpringConfig.java | 8 +++++++- .../EdgeValidatorHibernateValidator.java | 7 ++++++- .../exterior/messaging/BezmenClientJavaHttp.java | 10 +++++++++- .../messaging/SepulkaClientSpringWeb.java | 7 ++++++- 10 files changed, 80 insertions(+), 15 deletions(-) diff --git a/apps/sepuling/src/main/java/smecalculus/bezmen/interior/core/SepulkaServiceImpl.java b/apps/sepuling/src/main/java/smecalculus/bezmen/interior/core/SepulkaServiceImpl.java index 368bdf62..fffce3ab 100644 --- a/apps/sepuling/src/main/java/smecalculus/bezmen/interior/core/SepulkaServiceImpl.java +++ b/apps/sepuling/src/main/java/smecalculus/bezmen/interior/core/SepulkaServiceImpl.java @@ -4,12 +4,19 @@ import java.util.List; import lombok.NonNull; +import lombok.RequiredArgsConstructor; import smecalculus.bezmen.exterior.messaging.SepulkaRegisterSlice; import smecalculus.bezmen.exterior.messaging.SepulkaRegisteredSlice; import smecalculus.bezmen.interior.storage.SepulkaDao; -public record SepulkaServiceImpl(@NonNull SepulkaSliceMapper mapper, @NonNull SepulkaDao dao) - implements SepulkaService { +@RequiredArgsConstructor +public class SepulkaServiceImpl implements SepulkaService { + + @NonNull + private SepulkaSliceMapper mapper; + + @NonNull + private SepulkaDao dao; @Override public SepulkaRegisteredSlice register(SepulkaRegisterSlice request) { diff --git a/apps/sepuling/src/main/java/smecalculus/bezmen/interior/messaging/SepulkaClientImpl.java b/apps/sepuling/src/main/java/smecalculus/bezmen/interior/messaging/SepulkaClientImpl.java index fc8c6b23..c37a3e74 100644 --- a/apps/sepuling/src/main/java/smecalculus/bezmen/interior/messaging/SepulkaClientImpl.java +++ b/apps/sepuling/src/main/java/smecalculus/bezmen/interior/messaging/SepulkaClientImpl.java @@ -1,6 +1,7 @@ package smecalculus.bezmen.interior.messaging; import lombok.NonNull; +import lombok.RequiredArgsConstructor; import smecalculus.bezmen.exterior.messaging.SepulkaClient; import smecalculus.bezmen.exterior.messaging.SepulkaMsgMapper; import smecalculus.bezmen.exterior.messaging.SepulkaRegisterSliceMsg; @@ -8,9 +9,17 @@ import smecalculus.bezmen.interior.core.SepulkaService; import smecalculus.bezmen.interior.validation.EdgeValidator; -public record SepulkaClientImpl( - @NonNull EdgeValidator validator, @NonNull SepulkaMsgMapper mapper, @NonNull SepulkaService service) - implements SepulkaClient { +@RequiredArgsConstructor +public class SepulkaClientImpl implements SepulkaClient { + + @NonNull + private EdgeValidator validator; + + @NonNull + private SepulkaMsgMapper mapper; + + @NonNull + private SepulkaService service; @Override public SepulkaRegisteredSliceMsg register(SepulkaRegisterSliceMsg sliceMsg) { diff --git a/apps/sepuling/src/main/java/smecalculus/bezmen/interior/messaging/springmvc/SepulkaController.java b/apps/sepuling/src/main/java/smecalculus/bezmen/interior/messaging/springmvc/SepulkaController.java index 49d9cc23..fb1e3ff9 100644 --- a/apps/sepuling/src/main/java/smecalculus/bezmen/interior/messaging/springmvc/SepulkaController.java +++ b/apps/sepuling/src/main/java/smecalculus/bezmen/interior/messaging/springmvc/SepulkaController.java @@ -1,6 +1,7 @@ package smecalculus.bezmen.interior.messaging.springmvc; import lombok.NonNull; +import lombok.RequiredArgsConstructor; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.PostMapping; @@ -13,7 +14,11 @@ @RestController @RequestMapping("sepulkas") -public record SepulkaController(@NonNull SepulkaClient client) { +@RequiredArgsConstructor +public class SepulkaController { + + @NonNull + private SepulkaClient client; @PostMapping ResponseEntity register(@RequestBody SepulkaRegisterSliceMsg registerSliceMsg) { diff --git a/apps/sepuling/src/main/java/smecalculus/bezmen/interior/storage/SepulkaDaoMyBatis.java b/apps/sepuling/src/main/java/smecalculus/bezmen/interior/storage/SepulkaDaoMyBatis.java index da937ef8..16823440 100644 --- a/apps/sepuling/src/main/java/smecalculus/bezmen/interior/storage/SepulkaDaoMyBatis.java +++ b/apps/sepuling/src/main/java/smecalculus/bezmen/interior/storage/SepulkaDaoMyBatis.java @@ -5,11 +5,18 @@ import java.util.List; import java.util.UUID; import lombok.NonNull; +import lombok.RequiredArgsConstructor; import smecalculus.bezmen.interior.core.Sepulka; import smecalculus.bezmen.interior.storage.mybatis.SepulkaSqlMapper; -public record SepulkaDaoMyBatis(@NonNull SepulkaRecMapper recMapper, @NonNull SepulkaSqlMapper sqlMapper) - implements SepulkaDao { +@RequiredArgsConstructor +public class SepulkaDaoMyBatis implements SepulkaDao { + + @NonNull + private SepulkaRecMapper recMapper; + + @NonNull + private SepulkaSqlMapper sqlMapper; @Override public Sepulka getById(@NonNull UUID id) { diff --git a/apps/sepuling/src/main/java/smecalculus/bezmen/interior/storage/SepulkaDaoSpringData.java b/apps/sepuling/src/main/java/smecalculus/bezmen/interior/storage/SepulkaDaoSpringData.java index 960049ee..8f3b7cc5 100644 --- a/apps/sepuling/src/main/java/smecalculus/bezmen/interior/storage/SepulkaDaoSpringData.java +++ b/apps/sepuling/src/main/java/smecalculus/bezmen/interior/storage/SepulkaDaoSpringData.java @@ -6,11 +6,18 @@ import java.util.List; import java.util.UUID; import lombok.NonNull; +import lombok.RequiredArgsConstructor; import smecalculus.bezmen.interior.core.Sepulka; import smecalculus.bezmen.interior.storage.springdata.SepulkaRepository; -public record SepulkaDaoSpringData(@NonNull SepulkaRecMapper mapper, @NonNull SepulkaRepository repository) - implements SepulkaDao { +@RequiredArgsConstructor +public class SepulkaDaoSpringData implements SepulkaDao { + + @NonNull + private SepulkaRecMapper mapper; + + @NonNull + private SepulkaRepository repository; @Override public Sepulka getById(@NonNull UUID id) { diff --git a/libs/essentials/src/main/java/smecalculus/bezmen/interior/configuration/ConfigKeeperLightbendConfig.java b/libs/essentials/src/main/java/smecalculus/bezmen/interior/configuration/ConfigKeeperLightbendConfig.java index c0acde9d..893b9fc0 100644 --- a/libs/essentials/src/main/java/smecalculus/bezmen/interior/configuration/ConfigKeeperLightbendConfig.java +++ b/libs/essentials/src/main/java/smecalculus/bezmen/interior/configuration/ConfigKeeperLightbendConfig.java @@ -2,8 +2,14 @@ import com.typesafe.config.Config; import com.typesafe.config.ConfigBeanFactory; +import lombok.NonNull; +import lombok.RequiredArgsConstructor; -public record ConfigKeeperLightbendConfig(Config config) implements ConfigKeeper { +@RequiredArgsConstructor +public class ConfigKeeperLightbendConfig implements ConfigKeeper { + + @NonNull + private Config config; @Override public T read(String key, Class type) { diff --git a/libs/essentials/src/main/java/smecalculus/bezmen/interior/configuration/ConfigKeeperSpringConfig.java b/libs/essentials/src/main/java/smecalculus/bezmen/interior/configuration/ConfigKeeperSpringConfig.java index fbdaf8f5..ed746c3d 100644 --- a/libs/essentials/src/main/java/smecalculus/bezmen/interior/configuration/ConfigKeeperSpringConfig.java +++ b/libs/essentials/src/main/java/smecalculus/bezmen/interior/configuration/ConfigKeeperSpringConfig.java @@ -1,9 +1,15 @@ package smecalculus.bezmen.interior.configuration; +import lombok.NonNull; +import lombok.RequiredArgsConstructor; import org.springframework.boot.context.properties.bind.Binder; import org.springframework.core.env.Environment; -public record ConfigKeeperSpringConfig(Environment environment) implements ConfigKeeper { +@RequiredArgsConstructor +public class ConfigKeeperSpringConfig implements ConfigKeeper { + + @NonNull + private Environment environment; @Override public T read(String key, Class type) { diff --git a/libs/essentials/src/main/java/smecalculus/bezmen/interior/validation/EdgeValidatorHibernateValidator.java b/libs/essentials/src/main/java/smecalculus/bezmen/interior/validation/EdgeValidatorHibernateValidator.java index 94ff26ac..4563e422 100644 --- a/libs/essentials/src/main/java/smecalculus/bezmen/interior/validation/EdgeValidatorHibernateValidator.java +++ b/libs/essentials/src/main/java/smecalculus/bezmen/interior/validation/EdgeValidatorHibernateValidator.java @@ -5,8 +5,13 @@ import jakarta.validation.Validator; import java.util.Set; import lombok.NonNull; +import lombok.RequiredArgsConstructor; -public record EdgeValidatorHibernateValidator(@NonNull Validator validator) implements EdgeValidator { +@RequiredArgsConstructor +public class EdgeValidatorHibernateValidator implements EdgeValidator { + + @NonNull + private Validator validator; @Override public void validate(T object, Class... groups) { diff --git a/libs/messaging/src/main/java/smecalculus/bezmen/exterior/messaging/BezmenClientJavaHttp.java b/libs/messaging/src/main/java/smecalculus/bezmen/exterior/messaging/BezmenClientJavaHttp.java index da4121fd..15c15e7f 100644 --- a/libs/messaging/src/main/java/smecalculus/bezmen/exterior/messaging/BezmenClientJavaHttp.java +++ b/libs/messaging/src/main/java/smecalculus/bezmen/exterior/messaging/BezmenClientJavaHttp.java @@ -9,8 +9,16 @@ import java.net.http.HttpRequest.BodyPublishers; import java.net.http.HttpResponse.BodyHandlers; import lombok.NonNull; +import lombok.RequiredArgsConstructor; -public record BezmenClientJavaHttp(@NonNull ObjectMapper mapper, @NonNull HttpClient client) implements BezmenClient { +@RequiredArgsConstructor +public class BezmenClientJavaHttp implements BezmenClient { + + @NonNull + private ObjectMapper mapper; + + @NonNull + private HttpClient client; @Override public SepulkaRegisteredSliceMsg register(SepulkaRegisterSliceMsg request) { diff --git a/libs/testing/src/main/java/smecalculus/bezmen/interior/messaging/SepulkaClientSpringWeb.java b/libs/testing/src/main/java/smecalculus/bezmen/interior/messaging/SepulkaClientSpringWeb.java index b2017784..3088d3cd 100644 --- a/libs/testing/src/main/java/smecalculus/bezmen/interior/messaging/SepulkaClientSpringWeb.java +++ b/libs/testing/src/main/java/smecalculus/bezmen/interior/messaging/SepulkaClientSpringWeb.java @@ -1,13 +1,18 @@ package smecalculus.bezmen.interior.messaging; import lombok.NonNull; +import lombok.RequiredArgsConstructor; import org.springframework.http.MediaType; import org.springframework.test.web.reactive.server.WebTestClient; import smecalculus.bezmen.exterior.messaging.SepulkaClient; import smecalculus.bezmen.exterior.messaging.SepulkaRegisterSliceMsg; import smecalculus.bezmen.exterior.messaging.SepulkaRegisteredSliceMsg; -public record SepulkaClientSpringWeb(@NonNull WebTestClient client) implements SepulkaClient { +@RequiredArgsConstructor +public class SepulkaClientSpringWeb implements SepulkaClient { + + @NonNull + private WebTestClient client; @Override public SepulkaRegisteredSliceMsg register(SepulkaRegisterSliceMsg request) { From f06717ef03cd1eff52781aa5225f6bd10c2f926d Mon Sep 17 00:00:00 2001 From: Pavel Vetokhin Date: Thu, 12 Oct 2023 08:27:01 +0300 Subject: [PATCH 03/10] Client and servers --- docs/solution.adoc | 41 ++++++++++++------ docs/solution/core.png | Bin 0 -> 34154 bytes docs/solution/{domain.puml => core.puml} | 51 ++++++++++++----------- docs/solution/domain.png | Bin 33264 -> 0 bytes 4 files changed, 55 insertions(+), 37 deletions(-) create mode 100644 docs/solution/core.png rename docs/solution/{domain.puml => core.puml} (51%) delete mode 100644 docs/solution/domain.png diff --git a/docs/solution.adoc b/docs/solution.adoc index 3ae652e0..ad585e08 100644 --- a/docs/solution.adoc +++ b/docs/solution.adoc @@ -8,7 +8,7 @@ Решение используется клиентами в различных окружениях (envs) и для различных назначений (usages). Ключевые окружения/назначения явно выделяются и проверяются в рамках непрерывной интеграции. Устаревшие окружения/назначения снимаются с поддержки. Тесты! Тесты! Тесты!:: -Тестирование - один из самых важных (или даже самый важный) аспектов разработки! При тестировании проверяется поведение целевого объекта в различных ситуациях. В зависимости от подхода к подготовке зависимостей целевого объекта тесты можно подразделить на 3 категории. +Тестирование - один из важных или даже самый важный аспект разработки! При тестировании проверяется поведение целевого объекта в различных ситуациях. В зависимости от подхода к подготовке зависимостей целевого объекта тесты можно подразделить на 3 категории. Модульные тесты (unit tests)::: Все зависимости целевого объекта глушатся (stub) или мокируются (mock). Интеграционные тесты (integration tests)::: @@ -19,9 +19,8 @@ == Конфигурирование (Configuration) -Читаем конфигурационные параметры (props) в рамках некоторого протокола, отображая их в объекты предметной области. +Читаем конфигурационные параметры (props) в рамках некоторого протокола, отображая их в объекты пограничных моделей. -// [discrete] === Протоколы (Protocols) ==== FileSystem @@ -40,7 +39,7 @@ == Обмен сообщениями (Messaging) -Принимаем/отправляем сообщения (messages) в рамках некоторого протокола, отображая их в объекты предметной области. +Принимаем/отправляем сообщения (messages) в рамках некоторого протокола, отображая их в объекты пограничных моделей. === Протоколы @@ -70,7 +69,7 @@ NOTE: Шаблон проектирования `Message Mapping`. == Хранение состояния (Storage) -Запоминаем/вспоминаем состояние (state) в рамках некоторого протокола, отображая его в объекты предметной области. +Запоминаем/вспоминаем состояние (state) в рамках некоторого протокола, отображая его в объекты пограничных моделей. === Протоколы (Protocols) @@ -94,15 +93,33 @@ NOTE: Шаблон проектирования `Object-Relational Mapping`. == Ядро (Core) -image::solution/domain.png[] +image::solution/core.png[] -=== Клиенты (Clients) +=== Клиенты и серверы (clients & servers) -Интерфейсы клиентов являются `портами` в терминах clean/onion/hexagonal архитектуры. -Имплементации клиентов являются `адаптерами` в терминах onion/hexagonal архитектуры и `use case интеракторами` в терминах clean архитектуры. +[%autowidth] +|=== +2.+| ^|Hexagonal ^| Onion ^| Clean -=== Мапперы (Mappers) +.2+h|Client +h|Interface +2.+^|Port +|Use case input port -=== Сервисы (Services) +h|Impl +2.+^|Adapter +|Use case interactor -=== Модели (Models) +.2+h|Server +h|Interface +2.+^|Port +|Use case output port + +h|Impl +2.+^|Adapter +|Use case interactor +|=== + +=== Модели и мапперы (models & mappers) + +=== Сервисы (services) diff --git a/docs/solution/core.png b/docs/solution/core.png new file mode 100644 index 0000000000000000000000000000000000000000..744290f69efc64ac5f191f069128ab7c35a4d01d GIT binary patch literal 34154 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 Xl-%n5cG`f80)LqpS{mHba}NJsM-s+4 literal 0 HcmV?d00001 diff --git a/docs/solution/domain.puml b/docs/solution/core.puml similarity index 51% rename from docs/solution/domain.puml rename to docs/solution/core.puml index 5adf6773..7ddc4a9d 100644 --- a/docs/solution/domain.puml +++ b/docs/solution/core.puml @@ -12,48 +12,49 @@ skinparam file { show <> stereotype show <> stereotype -file "request" as requestIn <> -interface Client as clientIn <> -component Client as adapterIn <> component Mapper as mapperIn -component Service as service component Mapper as mapper -interface Client as clientOut <> -component Client as adapterOut <> component Mapper as mapperOut + +file "request" as requestIn <> +interface Client as portIn1 <> +component Client as adapterIn1 <> +component Service as service1 +interface Server as portOut1 <> +component Server as adapterOut1 <> file "request" as requestOut <> -requestIn - clientIn -clientIn -> adapterIn -adapterIn --> mapperIn: Serde\nModel -adapterIn <-- mapperIn: Domain\nModel -adapterIn -> service -service --> mapper: Slice\nModel -service <-- mapper: Entity\nModel -service - clientOut -clientOut -> adapterOut -adapterOut --> mapperOut: Domain\nModel -adapterOut <-- mapperOut: Serde\nModel -adapterOut -> requestOut +requestIn - portIn1 +portIn1 -> adapterIn1 +adapterIn1 --> mapperIn: Serde\nModel +adapterIn1 <-- mapperIn: Domain\nModel +adapterIn1 -> service1 +service1 --> mapper: Slice\nModel +service1 <-- mapper: Entity\nModel +service1 - portOut1 +portOut1 -> adapterOut1 +adapterOut1 --> mapperOut: Domain\nModel +adapterOut1 <-- mapperOut: Serde\nModel +adapterOut1 -> requestOut file "response" as responseIn <> -component Client as adapterOut2 <> -interface Client as clientOut2 <> +component Server as adapterOut2 <> +interface Server as portOut2 <> component Service as service2 component Client as adapterIn2 <> -interface Client as clientIn2 <> +interface Client as portIn2 <> file "response" as responseOut <> adapterOut2 <- responseIn mapperOut --> adapterOut2: Domain\nModel mapperOut <-- adapterOut2: Serde\nModel -clientOut2 - adapterOut2 -service2 <- clientOut2 +portOut2 - adapterOut2 +service2 <- portOut2 mapper --> service2: Slice\nModel mapper <-- service2: Entity\nModel adapterIn2 <- service2 mapperIn --> adapterIn2: Serde\nModel mapperIn <-- adapterIn2: Domain\nModel -clientIn2 - adapterIn2 -responseOut <- clientIn2 +portIn2 - adapterIn2 +responseOut <- portIn2 @enduml diff --git a/docs/solution/domain.png b/docs/solution/domain.png deleted file mode 100644 index cf5313ac53a770643261bfaeee16249e9e095d4b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 33264 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 I;u!XS00o4$1ONa4 From f6f682c0247f4fd72899b097585c57bae4b18ecc Mon Sep 17 00:00:00 2001 From: Pavel Vetokhin Date: Thu, 12 Oct 2023 08:31:06 +0300 Subject: [PATCH 04/10] Table formatting --- docs/solution.adoc | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/docs/solution.adoc b/docs/solution.adoc index ad585e08..4c6d3956 100644 --- a/docs/solution.adoc +++ b/docs/solution.adoc @@ -97,26 +97,27 @@ image::solution/core.png[] === Клиенты и серверы (clients & servers) +[%noheader] [%autowidth] |=== -2.+| ^|Hexagonal ^| Onion ^| Clean +2.+| ^s|Hexagonal ^s| Onion ^s| Clean -.2+h|Client -h|Interface -2.+^|Port +.2+s|Client +s|Interface +2.+|Port |Use case input port -h|Impl -2.+^|Adapter +s|Impl +2.+|Adapter |Use case interactor -.2+h|Server -h|Interface -2.+^|Port +.2+s|Server +s|Interface +2.+|Port |Use case output port -h|Impl -2.+^|Adapter +s|Impl +2.+|Adapter |Use case interactor |=== From 95e44dba795ba1fa53a894bc86376feeef76c7b7 Mon Sep 17 00:00:00 2001 From: Pavel Vetokhin Date: Thu, 12 Oct 2023 08:33:47 +0300 Subject: [PATCH 05/10] Table formatting 2 --- docs/solution.adoc | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/docs/solution.adoc b/docs/solution.adoc index 4c6d3956..dbc2e8f8 100644 --- a/docs/solution.adoc +++ b/docs/solution.adoc @@ -97,27 +97,26 @@ image::solution/core.png[] === Клиенты и серверы (clients & servers) -[%noheader] [%autowidth] |=== -2.+| ^s|Hexagonal ^s| Onion ^s| Clean +2.+| ^|Hexagonal & Onion ^| Clean .2+s|Client s|Interface -2.+|Port +|Port |Use case input port s|Impl -2.+|Adapter +|Adapter |Use case interactor .2+s|Server s|Interface -2.+|Port +|Port |Use case output port s|Impl -2.+|Adapter +|Adapter |Use case interactor |=== From eb3f1716a6cdb6bf9863ccef2d6fe8e12473820e Mon Sep 17 00:00:00 2001 From: Pavel Vetokhin Date: Thu, 12 Oct 2023 08:54:38 +0300 Subject: [PATCH 06/10] A bit about models and services --- docs/solution.adoc | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/docs/solution.adoc b/docs/solution.adoc index dbc2e8f8..e434a63b 100644 --- a/docs/solution.adoc +++ b/docs/solution.adoc @@ -69,7 +69,7 @@ NOTE: Шаблон проектирования `Message Mapping`. == Хранение состояния (Storage) -Запоминаем/вспоминаем состояние (state) в рамках некоторого протокола, отображая его в объекты пограничных моделей. +Сохраняем/извлекаем состояние (state) в рамках некоторого протокола, отображая его в объекты пограничных моделей. === Протоколы (Protocols) @@ -95,8 +95,19 @@ NOTE: Шаблон проектирования `Object-Relational Mapping`. image::solution/core.png[] +=== Модели и мапперы (models & mappers) + +Модели делим по двум основаниям: + +. Предметные против пограничных +. Сущности против срезов + === Клиенты и серверы (clients & servers) +Клиент принимает и возвращает пограничную модель. Сервер - предметную. + +[caption=] +.Сопоставление с популярными архитектурами [%autowidth] |=== 2.+| ^|Hexagonal & Onion ^| Clean @@ -120,6 +131,6 @@ s|Impl |Use case interactor |=== -=== Модели и мапперы (models & mappers) - === Сервисы (services) + +Инкапсулируют операции над сущностями предметной области. Принимают и возвращают срезы. \ No newline at end of file From 39ec374ba1fd324a4baa967568c17b38d739f8b5 Mon Sep 17 00:00:00 2001 From: Pavel Vetokhin Date: Thu, 12 Oct 2023 08:56:58 +0300 Subject: [PATCH 07/10] Discrete headers --- docs/solution.adoc | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/docs/solution.adoc b/docs/solution.adoc index e434a63b..dc491eb3 100644 --- a/docs/solution.adoc +++ b/docs/solution.adoc @@ -97,7 +97,8 @@ image::solution/core.png[] === Модели и мапперы (models & mappers) -Модели делим по двум основаниям: +[discrete] +====== Модели делим по двум основаниям . Предметные против пограничных . Сущности против срезов @@ -106,8 +107,8 @@ image::solution/core.png[] Клиент принимает и возвращает пограничную модель. Сервер - предметную. -[caption=] -.Сопоставление с популярными архитектурами +[discrete] +====== Сопоставление с популярными архитектурами [%autowidth] |=== 2.+| ^|Hexagonal & Onion ^| Clean From c9bfd297838f3e5fbef8f0bc22d9ab6844b6cb1d Mon Sep 17 00:00:00 2001 From: Pavel Vetokhin Date: Sat, 14 Oct 2023 09:41:53 +0300 Subject: [PATCH 08/10] Move client code to separate modules --- apps/sepuling/Dockerfile | 2 +- apps/sepuling/pom.xml | 1 - .../{interior => }/construction/App.java | 42 +++++++------- .../core/SepulkaServiceImpl.java | 8 +-- .../interior/messaging/SepulkaClientImpl.java | 31 ----------- .../bezmen/messaging/SepulkaClientImpl.java | 27 +++++++++ .../springmvc/SepulkaController.java | 14 ++--- .../{interior => }/storage/SepulkaDao.java | 4 +- .../storage/SepulkaDaoMyBatis.java | 6 +- .../storage/SepulkaDaoSpringData.java | 6 +- .../{interior => }/storage/SepulkaRec.java | 2 +- .../storage/SepulkaRecMapper.java | 4 +- .../storage/mybatis/SepulkaSqlMapper.java | 4 +- .../storage/springdata/SepulkaRepository.java | 4 +- .../construction/SepulkaClientBeans.java | 16 +++--- .../construction/SepulkaDaoBeans.java | 28 +++++----- .../messaging/SepulkaClientIT.java | 21 ++++--- .../messaging/SepulkaClientSpringWebIT.java | 2 +- .../{interior => }/storage/SepulkaDaoIT.java | 8 +-- .../storage/SepulkaDaoMyBatisPostgresIT.java | 6 +- .../storage/SepulkaDaoMyBatisTest.java | 2 +- .../SepulkaDaoSpringDataPostgresIT.java | 6 +- docs/solution.adoc | 8 +-- docs/solution/core.png | Bin 34154 -> 34299 bytes docs/solution/core.puml | 8 +-- docs/toolchain.adoc | 2 +- libs/abstraction-client/pom.xml | 40 ++++++++++++++ .../bezmen}/messaging/BezmenClient.java | 2 +- .../bezmen}/messaging/SepulingClient.java | 2 +- .../bezmen/messaging/SepulkaClient.java | 5 ++ .../bezmen/messaging/SepulkaNewRequestEg.java | 14 +++++ .../messaging/SepulkaNewRequestMsg.java | 11 ++++ .../messaging/SepulkaNewResponseEg.java | 19 +++++++ .../messaging/SepulkaNewResponseMsg.java | 11 ++++ libs/abstraction/pom.xml | 35 +----------- .../configuration/ConfigKeeper.java | 2 +- .../bezmen/{interior => }/core/Sepulka.java | 5 +- .../bezmen/{interior => }/core/SepulkaEg.java | 2 +- .../bezmen/core/SepulkaNewRequest.java | 8 +++ .../bezmen/core/SepulkaNewRequestEg.java | 11 ++++ .../bezmen/core/SepulkaNewResponse.java | 9 +++ .../bezmen/core/SepulkaNewResponseEg.java | 16 ++++++ .../bezmen/core/SepulkaService.java | 9 +++ .../bezmen/core/SepulkaSliceMapper.java | 10 ++++ .../exterior/messaging/SepulkaClient.java | 5 -- .../exterior/messaging/SepulkaMsgMapper.java | 14 ----- .../messaging/SepulkaRegisterSlice.java | 5 -- .../messaging/SepulkaRegisterSliceEg.java | 17 ------ .../messaging/SepulkaRegisterSliceMsg.java | 8 --- .../messaging/SepulkaRegisteredSlice.java | 6 -- .../messaging/SepulkaRegisteredSliceEg.java | 22 -------- .../messaging/SepulkaRegisteredSliceMsg.java | 8 --- .../bezmen/interior/core/SepulkaService.java | 11 ---- .../interior/core/SepulkaSliceMapper.java | 12 ---- .../validation/EdgeValidator.java | 2 +- .../ConfigKeeperLightbendConfig.java | 2 +- .../ConfigKeeperSpringConfig.java | 2 +- .../configuration/ConfigMappingMode.java | 2 +- .../configuration/ConfigProtocolMode.java | 2 +- .../ConditionalOnConfigMappingMode.java | 4 +- .../ConditionalOnConfigProtocolMode.java | 4 +- .../construction/ConfigBeans.java | 12 ++-- .../ConfigMappingModeCondition.java | 4 +- .../ConfigProtocolModeCondition.java | 4 +- .../construction/ValidationBeans.java | 6 +- .../EdgeValidatorHibernateValidator.java | 2 +- .../validation/ValueOfEnum.java | 2 +- .../validation/ValueOfEnumValidator.java | 2 +- libs/messaging-client/pom.xml | 52 ++++++++++++++++++ .../messaging/BezmenClientJavaHttp.java | 6 +- .../src/main/resources/messaging.properties | 2 + .../src/main/resources/reference.conf | 10 ++++ .../src/test/resources/logback-test.xml | 11 ++++ libs/messaging/README.adoc | 1 - libs/messaging/pom.xml | 35 ++---------- .../configuration/MessageMappingMode.java | 2 +- .../configuration/MessageMappingProps.java | 2 +- .../configuration/MessageMappingPropsCfg.java | 4 +- .../configuration/MessageMappingPropsEg.java | 2 +- .../configuration/MessagingCfgMapper.java | 2 +- .../configuration/MessagingProps.java | 2 +- .../configuration/MessagingPropsCfg.java | 2 +- .../configuration/MessagingPropsEg.java | 6 +- .../configuration/MessagingProtocolMode.java | 2 +- .../configuration/MessagingProtocolProps.java | 2 +- .../MessagingProtocolPropsCfg.java | 4 +- .../MessagingProtocolPropsEg.java | 4 +- .../ConditionalOnMessageMappingModes.java | 4 +- .../ConditionalOnMessagingProtocolModes.java | 4 +- .../MappingSpringJmxManagementBeans.java | 10 ++++ .../MappingSpringWebManagementBeans.java | 11 ++-- .../MappingSpringWebMvcBeans.java | 6 +- .../MessageMappingModeCondition.java | 6 +- .../construction/MessagingBeans.java | 2 +- .../construction/MessagingConfigBeans.java | 14 ++--- .../MessagingProtocolModeCondition.java | 6 +- .../construction/ProtocolHttpBeans.java | 4 +- .../construction/ProtocolJmxBeans.java | 7 +-- .../MappingSpringJmxManagementBeans.java | 11 ---- .../bezmen/messaging/SepulkaMsgMapper.java | 14 +++++ .../construction/MessagingConfigBeansIT.java | 6 +- ...MessagingConfigBeansLightbendConfigIT.java | 2 +- .../MessagingConfigBeansSpringConfigIT.java | 2 +- libs/pom.xml | 8 +-- .../{interior => }/configuration/H2Props.java | 2 +- .../configuration/H2PropsCfg.java | 2 +- .../configuration/PostgresProps.java | 2 +- .../configuration/PostgresPropsCfg.java | 2 +- .../configuration/StateMappingMode.java | 2 +- .../configuration/StateMappingProps.java | 2 +- .../configuration/StateMappingPropsCfg.java | 4 +- .../configuration/StateMappingPropsEg.java | 4 +- .../configuration/StorageCfgMapper.java | 2 +- .../configuration/StorageProps.java | 2 +- .../configuration/StoragePropsCfg.java | 2 +- .../configuration/StoragePropsEg.java | 10 ++-- .../configuration/StorageProtocolMode.java | 2 +- .../configuration/StorageProtocolProps.java | 2 +- .../StorageProtocolPropsCfg.java | 4 +- .../configuration/StorageProtocolPropsEg.java | 2 +- .../ConditionalOnStateMappingMode.java | 4 +- .../construction/MappingMyBatisBeans.java | 6 +- .../construction/MappingSpringDataBeans.java | 10 ++-- .../StateMappingModeCondition.java | 6 +- .../construction/StorageBeans.java | 10 ++-- .../construction/StorageConfigBeans.java | 14 ++--- .../construction/StorageConfigBeansIT.java | 6 +- .../StorageConfigBeansLightbendConfigIT.java | 2 +- .../StorageConfigBeansSpringConfigIT.java | 2 +- .../construction/StorageConfigBeansTest.java | 14 ++--- libs/testing/pom.xml | 3 +- .../construction/TestingBeans.java | 2 +- .../messaging/SepulkaClientSpringWeb.java | 9 +-- .../testing/ShardingExtension.java | 2 +- .../org.junit.jupiter.api.extension.Extension | 2 +- tests/e2e/pom.xml | 3 +- .../java/smecalculus/bezmen/StandBeans.java | 9 +-- .../bezmen/registration/SepulkaTest.java | 10 ++-- 138 files changed, 564 insertions(+), 495 deletions(-) rename apps/sepuling/src/main/java/smecalculus/bezmen/{interior => }/construction/App.java (57%) rename apps/sepuling/src/main/java/smecalculus/bezmen/{interior => }/core/SepulkaServiceImpl.java (66%) delete mode 100644 apps/sepuling/src/main/java/smecalculus/bezmen/interior/messaging/SepulkaClientImpl.java create mode 100644 apps/sepuling/src/main/java/smecalculus/bezmen/messaging/SepulkaClientImpl.java rename apps/sepuling/src/main/java/smecalculus/bezmen/{interior => }/messaging/springmvc/SepulkaController.java (58%) rename apps/sepuling/src/main/java/smecalculus/bezmen/{interior => }/storage/SepulkaDao.java (65%) rename apps/sepuling/src/main/java/smecalculus/bezmen/{interior => }/storage/SepulkaDaoMyBatis.java (83%) rename apps/sepuling/src/main/java/smecalculus/bezmen/{interior => }/storage/SepulkaDaoSpringData.java (85%) rename apps/sepuling/src/main/java/smecalculus/bezmen/{interior => }/storage/SepulkaRec.java (87%) rename apps/sepuling/src/main/java/smecalculus/bezmen/{interior => }/storage/SepulkaRecMapper.java (63%) rename apps/sepuling/src/main/java/smecalculus/bezmen/{interior => }/storage/mybatis/SepulkaSqlMapper.java (83%) rename apps/sepuling/src/main/java/smecalculus/bezmen/{interior => }/storage/springdata/SepulkaRepository.java (56%) rename apps/sepuling/src/test/java/smecalculus/bezmen/{interior => }/construction/SepulkaClientBeans.java (65%) rename apps/sepuling/src/test/java/smecalculus/bezmen/{interior => }/construction/SepulkaDaoBeans.java (75%) rename apps/sepuling/src/test/java/smecalculus/bezmen/{interior => }/messaging/SepulkaClientIT.java (57%) rename apps/sepuling/src/test/java/smecalculus/bezmen/{interior => }/messaging/SepulkaClientSpringWebIT.java (58%) rename apps/sepuling/src/test/java/smecalculus/bezmen/{interior => }/storage/SepulkaDaoIT.java (81%) rename apps/sepuling/src/test/java/smecalculus/bezmen/{interior => }/storage/SepulkaDaoMyBatisPostgresIT.java (56%) rename apps/sepuling/src/test/java/smecalculus/bezmen/{interior => }/storage/SepulkaDaoMyBatisTest.java (68%) rename apps/sepuling/src/test/java/smecalculus/bezmen/{interior => }/storage/SepulkaDaoSpringDataPostgresIT.java (56%) create mode 100644 libs/abstraction-client/pom.xml rename libs/{abstraction/src/main/java/smecalculus/bezmen/exterior => abstraction-client/src/main/java/smecalculus/bezmen}/messaging/BezmenClient.java (54%) rename libs/{abstraction/src/main/java/smecalculus/bezmen/exterior => abstraction-client/src/main/java/smecalculus/bezmen}/messaging/SepulingClient.java (61%) create mode 100644 libs/abstraction-client/src/main/java/smecalculus/bezmen/messaging/SepulkaClient.java create mode 100644 libs/abstraction-client/src/main/java/smecalculus/bezmen/messaging/SepulkaNewRequestEg.java create mode 100644 libs/abstraction-client/src/main/java/smecalculus/bezmen/messaging/SepulkaNewRequestMsg.java create mode 100644 libs/abstraction-client/src/main/java/smecalculus/bezmen/messaging/SepulkaNewResponseEg.java create mode 100644 libs/abstraction-client/src/main/java/smecalculus/bezmen/messaging/SepulkaNewResponseMsg.java rename libs/abstraction/src/main/java/smecalculus/bezmen/{interior => }/configuration/ConfigKeeper.java (60%) rename libs/abstraction/src/main/java/smecalculus/bezmen/{interior => }/core/Sepulka.java (69%) rename libs/abstraction/src/main/java/smecalculus/bezmen/{interior => }/core/SepulkaEg.java (93%) create mode 100644 libs/abstraction/src/main/java/smecalculus/bezmen/core/SepulkaNewRequest.java create mode 100644 libs/abstraction/src/main/java/smecalculus/bezmen/core/SepulkaNewRequestEg.java create mode 100644 libs/abstraction/src/main/java/smecalculus/bezmen/core/SepulkaNewResponse.java create mode 100644 libs/abstraction/src/main/java/smecalculus/bezmen/core/SepulkaNewResponseEg.java create mode 100644 libs/abstraction/src/main/java/smecalculus/bezmen/core/SepulkaService.java create mode 100644 libs/abstraction/src/main/java/smecalculus/bezmen/core/SepulkaSliceMapper.java delete mode 100644 libs/abstraction/src/main/java/smecalculus/bezmen/exterior/messaging/SepulkaClient.java delete mode 100644 libs/abstraction/src/main/java/smecalculus/bezmen/exterior/messaging/SepulkaMsgMapper.java delete mode 100644 libs/abstraction/src/main/java/smecalculus/bezmen/exterior/messaging/SepulkaRegisterSlice.java delete mode 100644 libs/abstraction/src/main/java/smecalculus/bezmen/exterior/messaging/SepulkaRegisterSliceEg.java delete mode 100644 libs/abstraction/src/main/java/smecalculus/bezmen/exterior/messaging/SepulkaRegisterSliceMsg.java delete mode 100644 libs/abstraction/src/main/java/smecalculus/bezmen/exterior/messaging/SepulkaRegisteredSlice.java delete mode 100644 libs/abstraction/src/main/java/smecalculus/bezmen/exterior/messaging/SepulkaRegisteredSliceEg.java delete mode 100644 libs/abstraction/src/main/java/smecalculus/bezmen/exterior/messaging/SepulkaRegisteredSliceMsg.java delete mode 100644 libs/abstraction/src/main/java/smecalculus/bezmen/interior/core/SepulkaService.java delete mode 100644 libs/abstraction/src/main/java/smecalculus/bezmen/interior/core/SepulkaSliceMapper.java rename libs/abstraction/src/main/java/smecalculus/bezmen/{interior => }/validation/EdgeValidator.java (64%) rename libs/essentials/src/main/java/smecalculus/bezmen/{interior => }/configuration/ConfigKeeperLightbendConfig.java (89%) rename libs/essentials/src/main/java/smecalculus/bezmen/{interior => }/configuration/ConfigKeeperSpringConfig.java (90%) rename libs/essentials/src/main/java/smecalculus/bezmen/{interior => }/configuration/ConfigMappingMode.java (59%) rename libs/essentials/src/main/java/smecalculus/bezmen/{interior => }/configuration/ConfigProtocolMode.java (50%) rename libs/essentials/src/main/java/smecalculus/bezmen/{interior => }/construction/ConditionalOnConfigMappingMode.java (78%) rename libs/essentials/src/main/java/smecalculus/bezmen/{interior => }/construction/ConditionalOnConfigProtocolMode.java (78%) rename libs/essentials/src/main/java/smecalculus/bezmen/{interior => }/construction/ConfigBeans.java (67%) rename libs/essentials/src/main/java/smecalculus/bezmen/{interior => }/construction/ConfigMappingModeCondition.java (89%) rename libs/essentials/src/main/java/smecalculus/bezmen/{interior => }/construction/ConfigProtocolModeCondition.java (89%) rename libs/essentials/src/main/java/smecalculus/bezmen/{interior => }/construction/ValidationBeans.java (72%) rename libs/essentials/src/main/java/smecalculus/bezmen/{interior => }/validation/EdgeValidatorHibernateValidator.java (93%) rename libs/essentials/src/main/java/smecalculus/bezmen/{interior => }/validation/ValueOfEnum.java (93%) rename libs/essentials/src/main/java/smecalculus/bezmen/{interior => }/validation/ValueOfEnumValidator.java (95%) create mode 100644 libs/messaging-client/pom.xml rename libs/{messaging/src/main/java/smecalculus/bezmen/exterior => messaging-client/src/main/java/smecalculus/bezmen}/messaging/BezmenClientJavaHttp.java (92%) create mode 100644 libs/messaging-client/src/main/resources/messaging.properties create mode 100644 libs/messaging-client/src/main/resources/reference.conf create mode 100644 libs/messaging-client/src/test/resources/logback-test.xml delete mode 100644 libs/messaging/README.adoc rename libs/messaging/src/main/java/smecalculus/bezmen/{interior => }/configuration/MessageMappingMode.java (59%) rename libs/messaging/src/main/java/smecalculus/bezmen/{interior => }/configuration/MessageMappingProps.java (76%) rename libs/messaging/src/main/java/smecalculus/bezmen/{interior => }/configuration/MessageMappingPropsCfg.java (71%) rename libs/messaging/src/main/java/smecalculus/bezmen/{interior => }/configuration/MessageMappingPropsEg.java (85%) rename libs/messaging/src/main/java/smecalculus/bezmen/{interior => }/configuration/MessagingCfgMapper.java (94%) rename libs/messaging/src/main/java/smecalculus/bezmen/{interior => }/configuration/MessagingProps.java (78%) rename libs/messaging/src/main/java/smecalculus/bezmen/{interior => }/configuration/MessagingPropsCfg.java (80%) rename libs/messaging/src/main/java/smecalculus/bezmen/{interior => }/configuration/MessagingPropsEg.java (54%) rename libs/messaging/src/main/java/smecalculus/bezmen/{interior => }/configuration/MessagingProtocolMode.java (52%) rename libs/messaging/src/main/java/smecalculus/bezmen/{interior => }/configuration/MessagingProtocolProps.java (76%) rename libs/messaging/src/main/java/smecalculus/bezmen/{interior => }/configuration/MessagingProtocolPropsCfg.java (71%) rename libs/messaging/src/main/java/smecalculus/bezmen/{interior => }/configuration/MessagingProtocolPropsEg.java (67%) rename libs/messaging/src/main/java/smecalculus/bezmen/{interior => }/construction/ConditionalOnMessageMappingModes.java (78%) rename libs/messaging/src/main/java/smecalculus/bezmen/{interior => }/construction/ConditionalOnMessagingProtocolModes.java (78%) create mode 100644 libs/messaging/src/main/java/smecalculus/bezmen/construction/MappingSpringJmxManagementBeans.java rename libs/messaging/src/main/java/smecalculus/bezmen/{interior => }/construction/MappingSpringWebManagementBeans.java (74%) rename libs/messaging/src/main/java/smecalculus/bezmen/{interior => }/construction/MappingSpringWebMvcBeans.java (65%) rename libs/messaging/src/main/java/smecalculus/bezmen/{interior => }/construction/MessageMappingModeCondition.java (86%) rename libs/messaging/src/main/java/smecalculus/bezmen/{interior => }/construction/MessagingBeans.java (89%) rename libs/messaging/src/main/java/smecalculus/bezmen/{interior => }/construction/MessagingConfigBeans.java (66%) rename libs/messaging/src/main/java/smecalculus/bezmen/{interior => }/construction/MessagingProtocolModeCondition.java (86%) rename libs/messaging/src/main/java/smecalculus/bezmen/{interior => }/construction/ProtocolHttpBeans.java (82%) rename libs/messaging/src/main/java/smecalculus/bezmen/{interior => }/construction/ProtocolJmxBeans.java (65%) delete mode 100644 libs/messaging/src/main/java/smecalculus/bezmen/interior/construction/MappingSpringJmxManagementBeans.java create mode 100644 libs/messaging/src/main/java/smecalculus/bezmen/messaging/SepulkaMsgMapper.java rename libs/messaging/src/test/java/smecalculus/bezmen/{interior => }/construction/MessagingConfigBeansIT.java (79%) rename libs/messaging/src/test/java/smecalculus/bezmen/{interior => }/construction/MessagingConfigBeansLightbendConfigIT.java (81%) rename libs/messaging/src/test/java/smecalculus/bezmen/{interior => }/construction/MessagingConfigBeansSpringConfigIT.java (81%) rename libs/storage/src/main/java/smecalculus/bezmen/{interior => }/configuration/H2Props.java (79%) rename libs/storage/src/main/java/smecalculus/bezmen/{interior => }/configuration/H2PropsCfg.java (80%) rename libs/storage/src/main/java/smecalculus/bezmen/{interior => }/configuration/PostgresProps.java (80%) rename libs/storage/src/main/java/smecalculus/bezmen/{interior => }/configuration/PostgresPropsCfg.java (83%) rename libs/storage/src/main/java/smecalculus/bezmen/{interior => }/configuration/StateMappingMode.java (55%) rename libs/storage/src/main/java/smecalculus/bezmen/{interior => }/configuration/StateMappingProps.java (66%) rename libs/storage/src/main/java/smecalculus/bezmen/{interior => }/configuration/StateMappingPropsCfg.java (54%) rename libs/storage/src/main/java/smecalculus/bezmen/{interior => }/configuration/StateMappingPropsEg.java (78%) rename libs/storage/src/main/java/smecalculus/bezmen/{interior => }/configuration/StorageCfgMapper.java (94%) rename libs/storage/src/main/java/smecalculus/bezmen/{interior => }/configuration/StorageProps.java (77%) rename libs/storage/src/main/java/smecalculus/bezmen/{interior => }/configuration/StoragePropsCfg.java (80%) rename libs/storage/src/main/java/smecalculus/bezmen/{interior => }/configuration/StoragePropsEg.java (58%) rename libs/storage/src/main/java/smecalculus/bezmen/{interior => }/configuration/StorageProtocolMode.java (53%) rename libs/storage/src/main/java/smecalculus/bezmen/{interior => }/configuration/StorageProtocolProps.java (79%) rename libs/storage/src/main/java/smecalculus/bezmen/{interior => }/configuration/StorageProtocolPropsCfg.java (69%) rename libs/storage/src/main/java/smecalculus/bezmen/{interior => }/configuration/StorageProtocolPropsEg.java (95%) rename libs/storage/src/main/java/smecalculus/bezmen/{interior => }/construction/ConditionalOnStateMappingMode.java (78%) rename libs/storage/src/main/java/smecalculus/bezmen/{interior => }/construction/MappingMyBatisBeans.java (76%) rename libs/storage/src/main/java/smecalculus/bezmen/{interior => }/construction/MappingSpringDataBeans.java (81%) rename libs/storage/src/main/java/smecalculus/bezmen/{interior => }/construction/StateMappingModeCondition.java (84%) rename libs/storage/src/main/java/smecalculus/bezmen/{interior => }/construction/StorageBeans.java (83%) rename libs/storage/src/main/java/smecalculus/bezmen/{interior => }/construction/StorageConfigBeans.java (66%) rename libs/storage/src/test/java/smecalculus/bezmen/{interior => }/construction/StorageConfigBeansIT.java (79%) rename libs/storage/src/test/java/smecalculus/bezmen/{interior => }/construction/StorageConfigBeansLightbendConfigIT.java (81%) rename libs/storage/src/test/java/smecalculus/bezmen/{interior => }/construction/StorageConfigBeansSpringConfigIT.java (80%) rename libs/storage/src/test/java/smecalculus/bezmen/{interior => }/construction/StorageConfigBeansTest.java (67%) rename libs/testing/src/main/java/smecalculus/bezmen/{interior => }/construction/TestingBeans.java (93%) rename libs/testing/src/main/java/smecalculus/bezmen/{interior => }/messaging/SepulkaClientSpringWeb.java (61%) rename libs/testing/src/main/java/smecalculus/bezmen/{interior => }/testing/ShardingExtension.java (96%) diff --git a/apps/sepuling/Dockerfile b/apps/sepuling/Dockerfile index 04e95771..8604baea 100644 --- a/apps/sepuling/Dockerfile +++ b/apps/sepuling/Dockerfile @@ -7,5 +7,5 @@ COPY sepuling*.jar app.jar ENTRYPOINT [ \ "java", "-cp", "app.jar:libs/*", \ "-Dconfig.file=application.conf", \ - "smecalculus.bezmen.interior.construction.App" \ + "smecalculus.bezmen.construction.App" \ ] diff --git a/apps/sepuling/pom.xml b/apps/sepuling/pom.xml index cdda54e9..2e83c563 100644 --- a/apps/sepuling/pom.xml +++ b/apps/sepuling/pom.xml @@ -25,7 +25,6 @@ ${project.groupId} storage - ${project.groupId} testing diff --git a/apps/sepuling/src/main/java/smecalculus/bezmen/interior/construction/App.java b/apps/sepuling/src/main/java/smecalculus/bezmen/construction/App.java similarity index 57% rename from apps/sepuling/src/main/java/smecalculus/bezmen/interior/construction/App.java rename to apps/sepuling/src/main/java/smecalculus/bezmen/construction/App.java index 4ab51325..9aa3c617 100644 --- a/apps/sepuling/src/main/java/smecalculus/bezmen/interior/construction/App.java +++ b/apps/sepuling/src/main/java/smecalculus/bezmen/construction/App.java @@ -1,31 +1,31 @@ -package smecalculus.bezmen.interior.construction; +package smecalculus.bezmen.construction; -import static smecalculus.bezmen.interior.configuration.MessageMappingMode.SPRING_MVC; -import static smecalculus.bezmen.interior.configuration.StateMappingMode.MY_BATIS; -import static smecalculus.bezmen.interior.configuration.StateMappingMode.SPRING_DATA; +import static smecalculus.bezmen.configuration.MessageMappingMode.SPRING_MVC; +import static smecalculus.bezmen.configuration.StateMappingMode.MY_BATIS; +import static smecalculus.bezmen.configuration.StateMappingMode.SPRING_DATA; import org.springframework.boot.SpringApplication; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Import; import org.springframework.context.annotation.PropertySource; -import smecalculus.bezmen.exterior.messaging.SepulkaClient; -import smecalculus.bezmen.exterior.messaging.SepulkaMsgMapper; -import smecalculus.bezmen.exterior.messaging.SepulkaMsgMapperImpl; -import smecalculus.bezmen.interior.core.SepulkaService; -import smecalculus.bezmen.interior.core.SepulkaServiceImpl; -import smecalculus.bezmen.interior.core.SepulkaSliceMapper; -import smecalculus.bezmen.interior.core.SepulkaSliceMapperImpl; -import smecalculus.bezmen.interior.messaging.SepulkaClientImpl; -import smecalculus.bezmen.interior.messaging.springmvc.SepulkaController; -import smecalculus.bezmen.interior.storage.SepulkaDao; -import smecalculus.bezmen.interior.storage.SepulkaDaoMyBatis; -import smecalculus.bezmen.interior.storage.SepulkaDaoSpringData; -import smecalculus.bezmen.interior.storage.SepulkaRecMapper; -import smecalculus.bezmen.interior.storage.SepulkaRecMapperImpl; -import smecalculus.bezmen.interior.storage.mybatis.SepulkaSqlMapper; -import smecalculus.bezmen.interior.storage.springdata.SepulkaRepository; -import smecalculus.bezmen.interior.validation.EdgeValidator; +import smecalculus.bezmen.core.SepulkaService; +import smecalculus.bezmen.core.SepulkaServiceImpl; +import smecalculus.bezmen.core.SepulkaSliceMapper; +import smecalculus.bezmen.core.SepulkaSliceMapperImpl; +import smecalculus.bezmen.messaging.SepulkaClient; +import smecalculus.bezmen.messaging.SepulkaClientImpl; +import smecalculus.bezmen.messaging.SepulkaMsgMapper; +import smecalculus.bezmen.messaging.SepulkaMsgMapperImpl; +import smecalculus.bezmen.messaging.springmvc.SepulkaController; +import smecalculus.bezmen.storage.SepulkaDao; +import smecalculus.bezmen.storage.SepulkaDaoMyBatis; +import smecalculus.bezmen.storage.SepulkaDaoSpringData; +import smecalculus.bezmen.storage.SepulkaRecMapper; +import smecalculus.bezmen.storage.SepulkaRecMapperImpl; +import smecalculus.bezmen.storage.mybatis.SepulkaSqlMapper; +import smecalculus.bezmen.storage.springdata.SepulkaRepository; +import smecalculus.bezmen.validation.EdgeValidator; @Import({ValidationBeans.class, ConfigBeans.class, MessagingBeans.class, StorageBeans.class}) @PropertySource("classpath:application.properties") diff --git a/apps/sepuling/src/main/java/smecalculus/bezmen/interior/core/SepulkaServiceImpl.java b/apps/sepuling/src/main/java/smecalculus/bezmen/core/SepulkaServiceImpl.java similarity index 66% rename from apps/sepuling/src/main/java/smecalculus/bezmen/interior/core/SepulkaServiceImpl.java rename to apps/sepuling/src/main/java/smecalculus/bezmen/core/SepulkaServiceImpl.java index fffce3ab..3b31ceb0 100644 --- a/apps/sepuling/src/main/java/smecalculus/bezmen/interior/core/SepulkaServiceImpl.java +++ b/apps/sepuling/src/main/java/smecalculus/bezmen/core/SepulkaServiceImpl.java @@ -1,13 +1,11 @@ -package smecalculus.bezmen.interior.core; +package smecalculus.bezmen.core; import static java.util.UUID.randomUUID; import java.util.List; import lombok.NonNull; import lombok.RequiredArgsConstructor; -import smecalculus.bezmen.exterior.messaging.SepulkaRegisterSlice; -import smecalculus.bezmen.exterior.messaging.SepulkaRegisteredSlice; -import smecalculus.bezmen.interior.storage.SepulkaDao; +import smecalculus.bezmen.storage.SepulkaDao; @RequiredArgsConstructor public class SepulkaServiceImpl implements SepulkaService { @@ -19,7 +17,7 @@ public class SepulkaServiceImpl implements SepulkaService { private SepulkaDao dao; @Override - public SepulkaRegisteredSlice register(SepulkaRegisterSlice request) { + public SepulkaNewResponse register(SepulkaNewRequest request) { var sepulkaCreated = mapper.toDomain(request).id(randomUUID()).build(); var sepulkaSaved = dao.save(sepulkaCreated); return mapper.toSlice(sepulkaSaved); diff --git a/apps/sepuling/src/main/java/smecalculus/bezmen/interior/messaging/SepulkaClientImpl.java b/apps/sepuling/src/main/java/smecalculus/bezmen/interior/messaging/SepulkaClientImpl.java deleted file mode 100644 index c37a3e74..00000000 --- a/apps/sepuling/src/main/java/smecalculus/bezmen/interior/messaging/SepulkaClientImpl.java +++ /dev/null @@ -1,31 +0,0 @@ -package smecalculus.bezmen.interior.messaging; - -import lombok.NonNull; -import lombok.RequiredArgsConstructor; -import smecalculus.bezmen.exterior.messaging.SepulkaClient; -import smecalculus.bezmen.exterior.messaging.SepulkaMsgMapper; -import smecalculus.bezmen.exterior.messaging.SepulkaRegisterSliceMsg; -import smecalculus.bezmen.exterior.messaging.SepulkaRegisteredSliceMsg; -import smecalculus.bezmen.interior.core.SepulkaService; -import smecalculus.bezmen.interior.validation.EdgeValidator; - -@RequiredArgsConstructor -public class SepulkaClientImpl implements SepulkaClient { - - @NonNull - private EdgeValidator validator; - - @NonNull - private SepulkaMsgMapper mapper; - - @NonNull - private SepulkaService service; - - @Override - public SepulkaRegisteredSliceMsg register(SepulkaRegisterSliceMsg sliceMsg) { - validator.validate(sliceMsg); - var registerSlice = mapper.toDomain(sliceMsg); - var registeredSlice = service.register(registerSlice); - return mapper.toMsg(registeredSlice); - } -} diff --git a/apps/sepuling/src/main/java/smecalculus/bezmen/messaging/SepulkaClientImpl.java b/apps/sepuling/src/main/java/smecalculus/bezmen/messaging/SepulkaClientImpl.java new file mode 100644 index 00000000..bd2ae3c8 --- /dev/null +++ b/apps/sepuling/src/main/java/smecalculus/bezmen/messaging/SepulkaClientImpl.java @@ -0,0 +1,27 @@ +package smecalculus.bezmen.messaging; + +import lombok.NonNull; +import lombok.RequiredArgsConstructor; +import smecalculus.bezmen.core.SepulkaService; +import smecalculus.bezmen.validation.EdgeValidator; + +@RequiredArgsConstructor +public class SepulkaClientImpl implements SepulkaClient { + + @NonNull + private EdgeValidator validator; + + @NonNull + private SepulkaMsgMapper mapper; + + @NonNull + private SepulkaService service; + + @Override + public SepulkaNewResponseMsg register(SepulkaNewRequestMsg requestMsg) { + validator.validate(requestMsg); + var request = mapper.toDomain(requestMsg); + var response = service.register(request); + return mapper.toMsg(response); + } +} diff --git a/apps/sepuling/src/main/java/smecalculus/bezmen/interior/messaging/springmvc/SepulkaController.java b/apps/sepuling/src/main/java/smecalculus/bezmen/messaging/springmvc/SepulkaController.java similarity index 58% rename from apps/sepuling/src/main/java/smecalculus/bezmen/interior/messaging/springmvc/SepulkaController.java rename to apps/sepuling/src/main/java/smecalculus/bezmen/messaging/springmvc/SepulkaController.java index fb1e3ff9..edfb6da3 100644 --- a/apps/sepuling/src/main/java/smecalculus/bezmen/interior/messaging/springmvc/SepulkaController.java +++ b/apps/sepuling/src/main/java/smecalculus/bezmen/messaging/springmvc/SepulkaController.java @@ -1,4 +1,4 @@ -package smecalculus.bezmen.interior.messaging.springmvc; +package smecalculus.bezmen.messaging.springmvc; import lombok.NonNull; import lombok.RequiredArgsConstructor; @@ -8,9 +8,9 @@ import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; -import smecalculus.bezmen.exterior.messaging.SepulkaClient; -import smecalculus.bezmen.exterior.messaging.SepulkaRegisterSliceMsg; -import smecalculus.bezmen.exterior.messaging.SepulkaRegisteredSliceMsg; +import smecalculus.bezmen.messaging.SepulkaClient; +import smecalculus.bezmen.messaging.SepulkaNewRequestMsg; +import smecalculus.bezmen.messaging.SepulkaNewResponseMsg; @RestController @RequestMapping("sepulkas") @@ -21,8 +21,8 @@ public class SepulkaController { private SepulkaClient client; @PostMapping - ResponseEntity register(@RequestBody SepulkaRegisterSliceMsg registerSliceMsg) { - var registeredSliceMsg = client.register(registerSliceMsg); - return ResponseEntity.status(HttpStatus.CREATED).body(registeredSliceMsg); + ResponseEntity register(@RequestBody SepulkaNewRequestMsg requestMsg) { + var responseMsg = client.register(requestMsg); + return ResponseEntity.status(HttpStatus.CREATED).body(responseMsg); } } diff --git a/apps/sepuling/src/main/java/smecalculus/bezmen/interior/storage/SepulkaDao.java b/apps/sepuling/src/main/java/smecalculus/bezmen/storage/SepulkaDao.java similarity index 65% rename from apps/sepuling/src/main/java/smecalculus/bezmen/interior/storage/SepulkaDao.java rename to apps/sepuling/src/main/java/smecalculus/bezmen/storage/SepulkaDao.java index e0423d41..32a13ccb 100644 --- a/apps/sepuling/src/main/java/smecalculus/bezmen/interior/storage/SepulkaDao.java +++ b/apps/sepuling/src/main/java/smecalculus/bezmen/storage/SepulkaDao.java @@ -1,8 +1,8 @@ -package smecalculus.bezmen.interior.storage; +package smecalculus.bezmen.storage; import java.util.List; import java.util.UUID; -import smecalculus.bezmen.interior.core.Sepulka; +import smecalculus.bezmen.core.Sepulka; public interface SepulkaDao { diff --git a/apps/sepuling/src/main/java/smecalculus/bezmen/interior/storage/SepulkaDaoMyBatis.java b/apps/sepuling/src/main/java/smecalculus/bezmen/storage/SepulkaDaoMyBatis.java similarity index 83% rename from apps/sepuling/src/main/java/smecalculus/bezmen/interior/storage/SepulkaDaoMyBatis.java rename to apps/sepuling/src/main/java/smecalculus/bezmen/storage/SepulkaDaoMyBatis.java index 16823440..d4b47889 100644 --- a/apps/sepuling/src/main/java/smecalculus/bezmen/interior/storage/SepulkaDaoMyBatis.java +++ b/apps/sepuling/src/main/java/smecalculus/bezmen/storage/SepulkaDaoMyBatis.java @@ -1,4 +1,4 @@ -package smecalculus.bezmen.interior.storage; +package smecalculus.bezmen.storage; import static java.util.stream.Collectors.toList; @@ -6,8 +6,8 @@ import java.util.UUID; import lombok.NonNull; import lombok.RequiredArgsConstructor; -import smecalculus.bezmen.interior.core.Sepulka; -import smecalculus.bezmen.interior.storage.mybatis.SepulkaSqlMapper; +import smecalculus.bezmen.core.Sepulka; +import smecalculus.bezmen.storage.mybatis.SepulkaSqlMapper; @RequiredArgsConstructor public class SepulkaDaoMyBatis implements SepulkaDao { diff --git a/apps/sepuling/src/main/java/smecalculus/bezmen/interior/storage/SepulkaDaoSpringData.java b/apps/sepuling/src/main/java/smecalculus/bezmen/storage/SepulkaDaoSpringData.java similarity index 85% rename from apps/sepuling/src/main/java/smecalculus/bezmen/interior/storage/SepulkaDaoSpringData.java rename to apps/sepuling/src/main/java/smecalculus/bezmen/storage/SepulkaDaoSpringData.java index 8f3b7cc5..fef83ba2 100644 --- a/apps/sepuling/src/main/java/smecalculus/bezmen/interior/storage/SepulkaDaoSpringData.java +++ b/apps/sepuling/src/main/java/smecalculus/bezmen/storage/SepulkaDaoSpringData.java @@ -1,4 +1,4 @@ -package smecalculus.bezmen.interior.storage; +package smecalculus.bezmen.storage; import static java.util.stream.Collectors.toList; import static java.util.stream.StreamSupport.stream; @@ -7,8 +7,8 @@ import java.util.UUID; import lombok.NonNull; import lombok.RequiredArgsConstructor; -import smecalculus.bezmen.interior.core.Sepulka; -import smecalculus.bezmen.interior.storage.springdata.SepulkaRepository; +import smecalculus.bezmen.core.Sepulka; +import smecalculus.bezmen.storage.springdata.SepulkaRepository; @RequiredArgsConstructor public class SepulkaDaoSpringData implements SepulkaDao { diff --git a/apps/sepuling/src/main/java/smecalculus/bezmen/interior/storage/SepulkaRec.java b/apps/sepuling/src/main/java/smecalculus/bezmen/storage/SepulkaRec.java similarity index 87% rename from apps/sepuling/src/main/java/smecalculus/bezmen/interior/storage/SepulkaRec.java rename to apps/sepuling/src/main/java/smecalculus/bezmen/storage/SepulkaRec.java index 29c2e7c9..9a2400e1 100644 --- a/apps/sepuling/src/main/java/smecalculus/bezmen/interior/storage/SepulkaRec.java +++ b/apps/sepuling/src/main/java/smecalculus/bezmen/storage/SepulkaRec.java @@ -1,4 +1,4 @@ -package smecalculus.bezmen.interior.storage; +package smecalculus.bezmen.storage; import lombok.Data; import org.springframework.data.annotation.Id; diff --git a/apps/sepuling/src/main/java/smecalculus/bezmen/interior/storage/SepulkaRecMapper.java b/apps/sepuling/src/main/java/smecalculus/bezmen/storage/SepulkaRecMapper.java similarity index 63% rename from apps/sepuling/src/main/java/smecalculus/bezmen/interior/storage/SepulkaRecMapper.java rename to apps/sepuling/src/main/java/smecalculus/bezmen/storage/SepulkaRecMapper.java index 7ffcb90d..3bc8ccf1 100644 --- a/apps/sepuling/src/main/java/smecalculus/bezmen/interior/storage/SepulkaRecMapper.java +++ b/apps/sepuling/src/main/java/smecalculus/bezmen/storage/SepulkaRecMapper.java @@ -1,7 +1,7 @@ -package smecalculus.bezmen.interior.storage; +package smecalculus.bezmen.storage; import org.mapstruct.Mapper; -import smecalculus.bezmen.interior.core.Sepulka; +import smecalculus.bezmen.core.Sepulka; @Mapper public interface SepulkaRecMapper { diff --git a/apps/sepuling/src/main/java/smecalculus/bezmen/interior/storage/mybatis/SepulkaSqlMapper.java b/apps/sepuling/src/main/java/smecalculus/bezmen/storage/mybatis/SepulkaSqlMapper.java similarity index 83% rename from apps/sepuling/src/main/java/smecalculus/bezmen/interior/storage/mybatis/SepulkaSqlMapper.java rename to apps/sepuling/src/main/java/smecalculus/bezmen/storage/mybatis/SepulkaSqlMapper.java index 809b23dc..d617ecc4 100644 --- a/apps/sepuling/src/main/java/smecalculus/bezmen/interior/storage/mybatis/SepulkaSqlMapper.java +++ b/apps/sepuling/src/main/java/smecalculus/bezmen/storage/mybatis/SepulkaSqlMapper.java @@ -1,11 +1,11 @@ -package smecalculus.bezmen.interior.storage.mybatis; +package smecalculus.bezmen.storage.mybatis; import java.util.List; import java.util.Optional; import org.apache.ibatis.annotations.Insert; import org.apache.ibatis.annotations.Param; import org.apache.ibatis.annotations.Select; -import smecalculus.bezmen.interior.storage.SepulkaRec; +import smecalculus.bezmen.storage.SepulkaRec; public interface SepulkaSqlMapper { diff --git a/apps/sepuling/src/main/java/smecalculus/bezmen/interior/storage/springdata/SepulkaRepository.java b/apps/sepuling/src/main/java/smecalculus/bezmen/storage/springdata/SepulkaRepository.java similarity index 56% rename from apps/sepuling/src/main/java/smecalculus/bezmen/interior/storage/springdata/SepulkaRepository.java rename to apps/sepuling/src/main/java/smecalculus/bezmen/storage/springdata/SepulkaRepository.java index 98412922..947734b8 100644 --- a/apps/sepuling/src/main/java/smecalculus/bezmen/interior/storage/springdata/SepulkaRepository.java +++ b/apps/sepuling/src/main/java/smecalculus/bezmen/storage/springdata/SepulkaRepository.java @@ -1,6 +1,6 @@ -package smecalculus.bezmen.interior.storage.springdata; +package smecalculus.bezmen.storage.springdata; import org.springframework.data.repository.CrudRepository; -import smecalculus.bezmen.interior.storage.SepulkaRec; +import smecalculus.bezmen.storage.SepulkaRec; public interface SepulkaRepository extends CrudRepository {} diff --git a/apps/sepuling/src/test/java/smecalculus/bezmen/interior/construction/SepulkaClientBeans.java b/apps/sepuling/src/test/java/smecalculus/bezmen/construction/SepulkaClientBeans.java similarity index 65% rename from apps/sepuling/src/test/java/smecalculus/bezmen/interior/construction/SepulkaClientBeans.java rename to apps/sepuling/src/test/java/smecalculus/bezmen/construction/SepulkaClientBeans.java index d84dc367..b19ba583 100644 --- a/apps/sepuling/src/test/java/smecalculus/bezmen/interior/construction/SepulkaClientBeans.java +++ b/apps/sepuling/src/test/java/smecalculus/bezmen/construction/SepulkaClientBeans.java @@ -1,4 +1,4 @@ -package smecalculus.bezmen.interior.construction; +package smecalculus.bezmen.construction; import static org.mockito.Mockito.mock; @@ -6,13 +6,13 @@ import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Import; import org.springframework.test.web.servlet.client.MockMvcWebTestClient; -import smecalculus.bezmen.exterior.messaging.SepulkaClient; -import smecalculus.bezmen.exterior.messaging.SepulkaMsgMapperImpl; -import smecalculus.bezmen.interior.core.SepulkaService; -import smecalculus.bezmen.interior.messaging.SepulkaClientImpl; -import smecalculus.bezmen.interior.messaging.SepulkaClientSpringWeb; -import smecalculus.bezmen.interior.messaging.springmvc.SepulkaController; -import smecalculus.bezmen.interior.validation.EdgeValidator; +import smecalculus.bezmen.core.SepulkaService; +import smecalculus.bezmen.messaging.SepulkaClient; +import smecalculus.bezmen.messaging.SepulkaClientImpl; +import smecalculus.bezmen.messaging.SepulkaClientSpringWeb; +import smecalculus.bezmen.messaging.SepulkaMsgMapperImpl; +import smecalculus.bezmen.messaging.springmvc.SepulkaController; +import smecalculus.bezmen.validation.EdgeValidator; @Import(ValidationBeans.class) @Configuration(proxyBeanMethods = false) diff --git a/apps/sepuling/src/test/java/smecalculus/bezmen/interior/construction/SepulkaDaoBeans.java b/apps/sepuling/src/test/java/smecalculus/bezmen/construction/SepulkaDaoBeans.java similarity index 75% rename from apps/sepuling/src/test/java/smecalculus/bezmen/interior/construction/SepulkaDaoBeans.java rename to apps/sepuling/src/test/java/smecalculus/bezmen/construction/SepulkaDaoBeans.java index c5f22d1b..74305fd5 100644 --- a/apps/sepuling/src/test/java/smecalculus/bezmen/interior/construction/SepulkaDaoBeans.java +++ b/apps/sepuling/src/test/java/smecalculus/bezmen/construction/SepulkaDaoBeans.java @@ -1,9 +1,9 @@ -package smecalculus.bezmen.interior.construction; +package smecalculus.bezmen.construction; import static java.util.stream.Collectors.joining; -import static smecalculus.bezmen.interior.configuration.StateMappingMode.MY_BATIS; -import static smecalculus.bezmen.interior.configuration.StateMappingMode.SPRING_DATA; -import static smecalculus.bezmen.interior.configuration.StorageProtocolMode.POSTGRES; +import static smecalculus.bezmen.configuration.StateMappingMode.MY_BATIS; +import static smecalculus.bezmen.configuration.StateMappingMode.SPRING_DATA; +import static smecalculus.bezmen.configuration.StorageProtocolMode.POSTGRES; import java.util.Collection; import java.util.List; @@ -13,16 +13,16 @@ import org.springframework.context.annotation.Configuration; import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseBuilder; import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseType; -import smecalculus.bezmen.interior.configuration.StateMappingProps; -import smecalculus.bezmen.interior.configuration.StorageProps; -import smecalculus.bezmen.interior.configuration.StorageProtocolProps; -import smecalculus.bezmen.interior.storage.SepulkaDao; -import smecalculus.bezmen.interior.storage.SepulkaDaoMyBatis; -import smecalculus.bezmen.interior.storage.SepulkaDaoSpringData; -import smecalculus.bezmen.interior.storage.SepulkaRecMapper; -import smecalculus.bezmen.interior.storage.SepulkaRecMapperImpl; -import smecalculus.bezmen.interior.storage.mybatis.SepulkaSqlMapper; -import smecalculus.bezmen.interior.storage.springdata.SepulkaRepository; +import smecalculus.bezmen.configuration.StateMappingProps; +import smecalculus.bezmen.configuration.StorageProps; +import smecalculus.bezmen.configuration.StorageProtocolProps; +import smecalculus.bezmen.storage.SepulkaDao; +import smecalculus.bezmen.storage.SepulkaDaoMyBatis; +import smecalculus.bezmen.storage.SepulkaDaoSpringData; +import smecalculus.bezmen.storage.SepulkaRecMapper; +import smecalculus.bezmen.storage.SepulkaRecMapperImpl; +import smecalculus.bezmen.storage.mybatis.SepulkaSqlMapper; +import smecalculus.bezmen.storage.springdata.SepulkaRepository; @Configuration(proxyBeanMethods = false) public class SepulkaDaoBeans { diff --git a/apps/sepuling/src/test/java/smecalculus/bezmen/interior/messaging/SepulkaClientIT.java b/apps/sepuling/src/test/java/smecalculus/bezmen/messaging/SepulkaClientIT.java similarity index 57% rename from apps/sepuling/src/test/java/smecalculus/bezmen/interior/messaging/SepulkaClientIT.java rename to apps/sepuling/src/test/java/smecalculus/bezmen/messaging/SepulkaClientIT.java index dada14fb..3b96ad32 100644 --- a/apps/sepuling/src/test/java/smecalculus/bezmen/interior/messaging/SepulkaClientIT.java +++ b/apps/sepuling/src/test/java/smecalculus/bezmen/messaging/SepulkaClientIT.java @@ -1,11 +1,11 @@ -package smecalculus.bezmen.interior.messaging; +package smecalculus.bezmen.messaging; import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.when; -import static smecalculus.bezmen.exterior.messaging.SepulkaRegisterSliceEg.Pojos.sepulkaRegisterSliceMsg; -import static smecalculus.bezmen.exterior.messaging.SepulkaRegisteredSliceEg.Pojos.sepulkaRegisteredSlice; -import static smecalculus.bezmen.exterior.messaging.SepulkaRegisteredSliceEg.Pojos.sepulkaRegisteredSliceMsg; +import static smecalculus.bezmen.core.SepulkaNewResponseEg.Pojos.sepulkaNewResponse; +import static smecalculus.bezmen.messaging.SepulkaNewRequestEg.Pojos.sepulkaNewRequestMsg; +import static smecalculus.bezmen.messaging.SepulkaNewResponseEg.Pojos.sepulkaNewResponseMsg; import java.util.UUID; import org.junit.jupiter.api.Test; @@ -13,10 +13,9 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit.jupiter.SpringExtension; -import smecalculus.bezmen.exterior.messaging.SepulkaClient; -import smecalculus.bezmen.exterior.messaging.SepulkaRegisterSlice; -import smecalculus.bezmen.interior.construction.SepulkaClientBeans; -import smecalculus.bezmen.interior.core.SepulkaService; +import smecalculus.bezmen.construction.SepulkaClientBeans; +import smecalculus.bezmen.core.SepulkaNewRequest; +import smecalculus.bezmen.core.SepulkaService; @ExtendWith(SpringExtension.class) @ContextConfiguration(classes = SepulkaClientBeans.class) @@ -33,11 +32,11 @@ void shouldRegisterSepulka() { // given var id = UUID.randomUUID(); // and - var request = sepulkaRegisterSliceMsg(); + var request = sepulkaNewRequestMsg(); // and - when(serviceMock.register(any(SepulkaRegisterSlice.class))).thenReturn(sepulkaRegisteredSlice(id)); + when(serviceMock.register(any(SepulkaNewRequest.class))).thenReturn(sepulkaNewResponse(id)); // and - var expectedResponse = sepulkaRegisteredSliceMsg(id); + var expectedResponse = sepulkaNewResponseMsg(id); // when var actualResponse = externalClient.register(request); // then diff --git a/apps/sepuling/src/test/java/smecalculus/bezmen/interior/messaging/SepulkaClientSpringWebIT.java b/apps/sepuling/src/test/java/smecalculus/bezmen/messaging/SepulkaClientSpringWebIT.java similarity index 58% rename from apps/sepuling/src/test/java/smecalculus/bezmen/interior/messaging/SepulkaClientSpringWebIT.java rename to apps/sepuling/src/test/java/smecalculus/bezmen/messaging/SepulkaClientSpringWebIT.java index cbe16901..0859ae5b 100644 --- a/apps/sepuling/src/test/java/smecalculus/bezmen/interior/messaging/SepulkaClientSpringWebIT.java +++ b/apps/sepuling/src/test/java/smecalculus/bezmen/messaging/SepulkaClientSpringWebIT.java @@ -1,3 +1,3 @@ -package smecalculus.bezmen.interior.messaging; +package smecalculus.bezmen.messaging; public class SepulkaClientSpringWebIT extends SepulkaClientIT {} diff --git a/apps/sepuling/src/test/java/smecalculus/bezmen/interior/storage/SepulkaDaoIT.java b/apps/sepuling/src/test/java/smecalculus/bezmen/storage/SepulkaDaoIT.java similarity index 81% rename from apps/sepuling/src/test/java/smecalculus/bezmen/interior/storage/SepulkaDaoIT.java rename to apps/sepuling/src/test/java/smecalculus/bezmen/storage/SepulkaDaoIT.java index ad5f227e..607d1cda 100644 --- a/apps/sepuling/src/test/java/smecalculus/bezmen/interior/storage/SepulkaDaoIT.java +++ b/apps/sepuling/src/test/java/smecalculus/bezmen/storage/SepulkaDaoIT.java @@ -1,7 +1,7 @@ -package smecalculus.bezmen.interior.storage; +package smecalculus.bezmen.storage; import static org.assertj.core.api.Assertions.assertThat; -import static smecalculus.bezmen.interior.core.SepulkaEg.Pojos.sepulka; +import static smecalculus.bezmen.core.SepulkaEg.Pojos.sepulka; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; @@ -9,8 +9,8 @@ import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.jdbc.Sql; import org.springframework.test.context.junit.jupiter.SpringExtension; -import smecalculus.bezmen.interior.construction.SepulkaDaoBeans; -import smecalculus.bezmen.interior.core.Sepulka; +import smecalculus.bezmen.construction.SepulkaDaoBeans; +import smecalculus.bezmen.core.Sepulka; @ExtendWith(SpringExtension.class) @ContextConfiguration(classes = SepulkaDaoBeans.class) diff --git a/apps/sepuling/src/test/java/smecalculus/bezmen/interior/storage/SepulkaDaoMyBatisPostgresIT.java b/apps/sepuling/src/test/java/smecalculus/bezmen/storage/SepulkaDaoMyBatisPostgresIT.java similarity index 56% rename from apps/sepuling/src/test/java/smecalculus/bezmen/interior/storage/SepulkaDaoMyBatisPostgresIT.java rename to apps/sepuling/src/test/java/smecalculus/bezmen/storage/SepulkaDaoMyBatisPostgresIT.java index 9c37e9a2..31aac61e 100644 --- a/apps/sepuling/src/test/java/smecalculus/bezmen/interior/storage/SepulkaDaoMyBatisPostgresIT.java +++ b/apps/sepuling/src/test/java/smecalculus/bezmen/storage/SepulkaDaoMyBatisPostgresIT.java @@ -1,8 +1,8 @@ -package smecalculus.bezmen.interior.storage; +package smecalculus.bezmen.storage; import org.springframework.test.context.ContextConfiguration; -import smecalculus.bezmen.interior.construction.MappingMyBatisBeans; -import smecalculus.bezmen.interior.construction.SepulkaDaoBeans; +import smecalculus.bezmen.construction.MappingMyBatisBeans; +import smecalculus.bezmen.construction.SepulkaDaoBeans; @ContextConfiguration(classes = {SepulkaDaoBeans.MyBatisPostgres.class, MappingMyBatisBeans.class}) public class SepulkaDaoMyBatisPostgresIT extends SepulkaDaoIT {} diff --git a/apps/sepuling/src/test/java/smecalculus/bezmen/interior/storage/SepulkaDaoMyBatisTest.java b/apps/sepuling/src/test/java/smecalculus/bezmen/storage/SepulkaDaoMyBatisTest.java similarity index 68% rename from apps/sepuling/src/test/java/smecalculus/bezmen/interior/storage/SepulkaDaoMyBatisTest.java rename to apps/sepuling/src/test/java/smecalculus/bezmen/storage/SepulkaDaoMyBatisTest.java index 81707ecf..3536c60f 100644 --- a/apps/sepuling/src/test/java/smecalculus/bezmen/interior/storage/SepulkaDaoMyBatisTest.java +++ b/apps/sepuling/src/test/java/smecalculus/bezmen/storage/SepulkaDaoMyBatisTest.java @@ -1,4 +1,4 @@ -package smecalculus.bezmen.interior.storage; +package smecalculus.bezmen.storage; import org.junit.jupiter.api.Test; diff --git a/apps/sepuling/src/test/java/smecalculus/bezmen/interior/storage/SepulkaDaoSpringDataPostgresIT.java b/apps/sepuling/src/test/java/smecalculus/bezmen/storage/SepulkaDaoSpringDataPostgresIT.java similarity index 56% rename from apps/sepuling/src/test/java/smecalculus/bezmen/interior/storage/SepulkaDaoSpringDataPostgresIT.java rename to apps/sepuling/src/test/java/smecalculus/bezmen/storage/SepulkaDaoSpringDataPostgresIT.java index df0668f1..386a603a 100644 --- a/apps/sepuling/src/test/java/smecalculus/bezmen/interior/storage/SepulkaDaoSpringDataPostgresIT.java +++ b/apps/sepuling/src/test/java/smecalculus/bezmen/storage/SepulkaDaoSpringDataPostgresIT.java @@ -1,8 +1,8 @@ -package smecalculus.bezmen.interior.storage; +package smecalculus.bezmen.storage; import org.springframework.test.context.ContextConfiguration; -import smecalculus.bezmen.interior.construction.MappingSpringDataBeans; -import smecalculus.bezmen.interior.construction.SepulkaDaoBeans; +import smecalculus.bezmen.construction.MappingSpringDataBeans; +import smecalculus.bezmen.construction.SepulkaDaoBeans; @ContextConfiguration(classes = {SepulkaDaoBeans.SpringDataPostgres.class, MappingSpringDataBeans.class}) public class SepulkaDaoSpringDataPostgresIT extends SepulkaDaoIT {} diff --git a/docs/solution.adoc b/docs/solution.adoc index dc491eb3..e2437769 100644 --- a/docs/solution.adoc +++ b/docs/solution.adoc @@ -5,7 +5,7 @@ .Ключевые принципы **** Множественность окружений и назначений:: -Решение используется клиентами в различных окружениях (envs) и для различных назначений (usages). Ключевые окружения/назначения явно выделяются и проверяются в рамках непрерывной интеграции. Устаревшие окружения/назначения снимаются с поддержки. +Решение используется клиентами в различных окружениях (envs) и для различных назначений (usages). Ключевые окружения/назначения явно выделяются и проверяются в рамках непрерывной интеграции, устаревшие - снимаются с поддержки. Тесты! Тесты! Тесты!:: Тестирование - один из важных или даже самый важный аспект разработки! При тестировании проверяется поведение целевого объекта в различных ситуациях. В зависимости от подхода к подготовке зависимостей целевого объекта тесты можно подразделить на 3 категории. @@ -100,8 +100,8 @@ image::solution/core.png[] [discrete] ====== Модели делим по двум основаниям -. Предметные против пограничных -. Сущности против срезов +. Предметные (domain) против пограничных (edge) +. Сущности (entities) против срезов (slices) === Клиенты и серверы (clients & servers) @@ -134,4 +134,4 @@ s|Impl === Сервисы (services) -Инкапсулируют операции над сущностями предметной области. Принимают и возвращают срезы. \ No newline at end of file +Инкапсулируют операции над сущностями предметной области. Принимают и возвращают срезы. diff --git a/docs/solution/core.png b/docs/solution/core.png index 744290f69efc64ac5f191f069128ab7c35a4d01d..5819227de90a8dbb326440febda05a29bbea7ee8 100644 GIT binary patch literal 34299 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 LvF06hyO93@K9u#g literal 34154 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 Xl-%n5cG`f80)LqpS{mHba}NJsM-s+4 diff --git a/docs/solution/core.puml b/docs/solution/core.puml index 7ddc4a9d..1e5472e8 100644 --- a/docs/solution/core.puml +++ b/docs/solution/core.puml @@ -26,7 +26,7 @@ file "request" as requestOut <> requestIn - portIn1 portIn1 -> adapterIn1 -adapterIn1 --> mapperIn: Serde\nModel +adapterIn1 --> mapperIn: Edge\nModel adapterIn1 <-- mapperIn: Domain\nModel adapterIn1 -> service1 service1 --> mapper: Slice\nModel @@ -34,7 +34,7 @@ service1 <-- mapper: Entity\nModel service1 - portOut1 portOut1 -> adapterOut1 adapterOut1 --> mapperOut: Domain\nModel -adapterOut1 <-- mapperOut: Serde\nModel +adapterOut1 <-- mapperOut: Edge\nModel adapterOut1 -> requestOut file "response" as responseIn <> @@ -47,13 +47,13 @@ file "response" as responseOut <> adapterOut2 <- responseIn mapperOut --> adapterOut2: Domain\nModel -mapperOut <-- adapterOut2: Serde\nModel +mapperOut <-- adapterOut2: Edge\nModel portOut2 - adapterOut2 service2 <- portOut2 mapper --> service2: Slice\nModel mapper <-- service2: Entity\nModel adapterIn2 <- service2 -mapperIn --> adapterIn2: Serde\nModel +mapperIn --> adapterIn2: Edge\nModel mapperIn <-- adapterIn2: Domain\nModel portIn2 - adapterIn2 responseOut <- portIn2 diff --git a/docs/toolchain.adoc b/docs/toolchain.adoc index 2acfb842..52cf6de0 100644 --- a/docs/toolchain.adoc +++ b/docs/toolchain.adoc @@ -11,7 +11,7 @@ Контентная адресация (content addressability) делает конструирование артефактов *идемпотентным*. Для директорий с исходным кодом вычисляются их контентные идентификаторы (CID's). Затем вычисляются корневые идентификаторы решения и инструментария. Таким образом формируется 2 небольших дерева Меркла, хеши которых подставляются в качестве тегов/классификаторов артефактов соответствующих абстракций. Артефакт реконструируется, только когда его контентный идентификатор изменился. Множественность окружений и назначений:: -Инструментарий используется разработчиками в различных окружениях (envs) и для различных назначений (usages). Ключевые окружения/назначения явно выделяются и проверяются в рамках непрерывной интеграции. Устаревшие окружения/назначения снимаются с поддержки. +Инструментарий используется разработчиками в различных окружениях (envs) и для различных назначений (usages). Ключевые окружения/назначения явно выделяются и проверяются в рамках непрерывной интеграции, устаревшие - снимаются с поддержки. **** == Консольный интерфейс (CLI) diff --git a/libs/abstraction-client/pom.xml b/libs/abstraction-client/pom.xml new file mode 100644 index 00000000..c37ca8bb --- /dev/null +++ b/libs/abstraction-client/pom.xml @@ -0,0 +1,40 @@ + + + 4.0.0 + + + smecalculus.bezmen + libs + ${revision} + + + abstraction-client + + + + jakarta.validation + jakarta.validation-api + + + + + + + org.apache.maven.plugins + maven-install-plugin + + false + + + + org.apache.maven.plugins + maven-deploy-plugin + + false + + + + + diff --git a/libs/abstraction/src/main/java/smecalculus/bezmen/exterior/messaging/BezmenClient.java b/libs/abstraction-client/src/main/java/smecalculus/bezmen/messaging/BezmenClient.java similarity index 54% rename from libs/abstraction/src/main/java/smecalculus/bezmen/exterior/messaging/BezmenClient.java rename to libs/abstraction-client/src/main/java/smecalculus/bezmen/messaging/BezmenClient.java index 2d9d4965..4100b815 100644 --- a/libs/abstraction/src/main/java/smecalculus/bezmen/exterior/messaging/BezmenClient.java +++ b/libs/abstraction-client/src/main/java/smecalculus/bezmen/messaging/BezmenClient.java @@ -1,3 +1,3 @@ -package smecalculus.bezmen.exterior.messaging; +package smecalculus.bezmen.messaging; public interface BezmenClient extends SepulingClient {} diff --git a/libs/abstraction/src/main/java/smecalculus/bezmen/exterior/messaging/SepulingClient.java b/libs/abstraction-client/src/main/java/smecalculus/bezmen/messaging/SepulingClient.java similarity index 61% rename from libs/abstraction/src/main/java/smecalculus/bezmen/exterior/messaging/SepulingClient.java rename to libs/abstraction-client/src/main/java/smecalculus/bezmen/messaging/SepulingClient.java index aeae9568..cd4aeaae 100644 --- a/libs/abstraction/src/main/java/smecalculus/bezmen/exterior/messaging/SepulingClient.java +++ b/libs/abstraction-client/src/main/java/smecalculus/bezmen/messaging/SepulingClient.java @@ -1,4 +1,4 @@ -package smecalculus.bezmen.exterior.messaging; +package smecalculus.bezmen.messaging; interface SepulingClient extends SepulkaClient { boolean isReady(); diff --git a/libs/abstraction-client/src/main/java/smecalculus/bezmen/messaging/SepulkaClient.java b/libs/abstraction-client/src/main/java/smecalculus/bezmen/messaging/SepulkaClient.java new file mode 100644 index 00000000..ba4d002e --- /dev/null +++ b/libs/abstraction-client/src/main/java/smecalculus/bezmen/messaging/SepulkaClient.java @@ -0,0 +1,5 @@ +package smecalculus.bezmen.messaging; + +public interface SepulkaClient { + SepulkaNewResponseMsg register(SepulkaNewRequestMsg request); +} diff --git a/libs/abstraction-client/src/main/java/smecalculus/bezmen/messaging/SepulkaNewRequestEg.java b/libs/abstraction-client/src/main/java/smecalculus/bezmen/messaging/SepulkaNewRequestEg.java new file mode 100644 index 00000000..a16727c2 --- /dev/null +++ b/libs/abstraction-client/src/main/java/smecalculus/bezmen/messaging/SepulkaNewRequestEg.java @@ -0,0 +1,14 @@ +package smecalculus.bezmen.messaging; + +public class SepulkaNewRequestEg { + public static final String NAME = "foo"; + + public static class Pojos { + + public static SepulkaNewRequestMsg sepulkaNewRequestMsg() { + var requestMsg = new SepulkaNewRequestMsg(); + requestMsg.setName(NAME); + return requestMsg; + } + } +} diff --git a/libs/abstraction-client/src/main/java/smecalculus/bezmen/messaging/SepulkaNewRequestMsg.java b/libs/abstraction-client/src/main/java/smecalculus/bezmen/messaging/SepulkaNewRequestMsg.java new file mode 100644 index 00000000..8fac608e --- /dev/null +++ b/libs/abstraction-client/src/main/java/smecalculus/bezmen/messaging/SepulkaNewRequestMsg.java @@ -0,0 +1,11 @@ +package smecalculus.bezmen.messaging; + +import lombok.Data; + +/** + * Model: edge slice + */ +@Data +public class SepulkaNewRequestMsg { + private String name; +} diff --git a/libs/abstraction-client/src/main/java/smecalculus/bezmen/messaging/SepulkaNewResponseEg.java b/libs/abstraction-client/src/main/java/smecalculus/bezmen/messaging/SepulkaNewResponseEg.java new file mode 100644 index 00000000..26666cb9 --- /dev/null +++ b/libs/abstraction-client/src/main/java/smecalculus/bezmen/messaging/SepulkaNewResponseEg.java @@ -0,0 +1,19 @@ +package smecalculus.bezmen.messaging; + +import java.util.UUID; + +public class SepulkaNewResponseEg { + + public static class Pojos { + + public static SepulkaNewResponseMsg sepulkaNewResponseMsg() { + return sepulkaNewResponseMsg(UUID.randomUUID()); + } + + public static SepulkaNewResponseMsg sepulkaNewResponseMsg(UUID id) { + var responseMsg = new SepulkaNewResponseMsg(); + responseMsg.setId(id.toString()); + return responseMsg; + } + } +} diff --git a/libs/abstraction-client/src/main/java/smecalculus/bezmen/messaging/SepulkaNewResponseMsg.java b/libs/abstraction-client/src/main/java/smecalculus/bezmen/messaging/SepulkaNewResponseMsg.java new file mode 100644 index 00000000..1c6230cd --- /dev/null +++ b/libs/abstraction-client/src/main/java/smecalculus/bezmen/messaging/SepulkaNewResponseMsg.java @@ -0,0 +1,11 @@ +package smecalculus.bezmen.messaging; + +import lombok.Data; + +/** + * Model: edge slice + */ +@Data +public class SepulkaNewResponseMsg { + private String id; +} diff --git a/libs/abstraction/pom.xml b/libs/abstraction/pom.xml index 4ee857bf..7958be14 100644 --- a/libs/abstraction/pom.xml +++ b/libs/abstraction/pom.xml @@ -14,39 +14,8 @@ - jakarta.validation - jakarta.validation-api + ${project.groupId} + abstraction-client - - - - - org.apache.maven.plugins - maven-jar-plugin - - - exterior-jar - - jar - - - - - - org.apache.maven.plugins - maven-install-plugin - - false - - - - org.apache.maven.plugins - maven-deploy-plugin - - false - - - - diff --git a/libs/abstraction/src/main/java/smecalculus/bezmen/interior/configuration/ConfigKeeper.java b/libs/abstraction/src/main/java/smecalculus/bezmen/configuration/ConfigKeeper.java similarity index 60% rename from libs/abstraction/src/main/java/smecalculus/bezmen/interior/configuration/ConfigKeeper.java rename to libs/abstraction/src/main/java/smecalculus/bezmen/configuration/ConfigKeeper.java index 5685767f..cdb202e1 100644 --- a/libs/abstraction/src/main/java/smecalculus/bezmen/interior/configuration/ConfigKeeper.java +++ b/libs/abstraction/src/main/java/smecalculus/bezmen/configuration/ConfigKeeper.java @@ -1,4 +1,4 @@ -package smecalculus.bezmen.interior.configuration; +package smecalculus.bezmen.configuration; public interface ConfigKeeper { T read(String key, Class type); diff --git a/libs/abstraction/src/main/java/smecalculus/bezmen/interior/core/Sepulka.java b/libs/abstraction/src/main/java/smecalculus/bezmen/core/Sepulka.java similarity index 69% rename from libs/abstraction/src/main/java/smecalculus/bezmen/interior/core/Sepulka.java rename to libs/abstraction/src/main/java/smecalculus/bezmen/core/Sepulka.java index 5ec9e640..d94844a1 100644 --- a/libs/abstraction/src/main/java/smecalculus/bezmen/interior/core/Sepulka.java +++ b/libs/abstraction/src/main/java/smecalculus/bezmen/core/Sepulka.java @@ -1,8 +1,11 @@ -package smecalculus.bezmen.interior.core; +package smecalculus.bezmen.core; import java.util.UUID; import lombok.Builder; import lombok.NonNull; +/** + * Model: domain entity + */ @Builder public record Sepulka(@NonNull UUID id, @NonNull String name) {} diff --git a/libs/abstraction/src/main/java/smecalculus/bezmen/interior/core/SepulkaEg.java b/libs/abstraction/src/main/java/smecalculus/bezmen/core/SepulkaEg.java similarity index 93% rename from libs/abstraction/src/main/java/smecalculus/bezmen/interior/core/SepulkaEg.java rename to libs/abstraction/src/main/java/smecalculus/bezmen/core/SepulkaEg.java index 694e30b1..ae853ae8 100644 --- a/libs/abstraction/src/main/java/smecalculus/bezmen/interior/core/SepulkaEg.java +++ b/libs/abstraction/src/main/java/smecalculus/bezmen/core/SepulkaEg.java @@ -1,4 +1,4 @@ -package smecalculus.bezmen.interior.core; +package smecalculus.bezmen.core; import java.util.UUID; diff --git a/libs/abstraction/src/main/java/smecalculus/bezmen/core/SepulkaNewRequest.java b/libs/abstraction/src/main/java/smecalculus/bezmen/core/SepulkaNewRequest.java new file mode 100644 index 00000000..2ea5a065 --- /dev/null +++ b/libs/abstraction/src/main/java/smecalculus/bezmen/core/SepulkaNewRequest.java @@ -0,0 +1,8 @@ +package smecalculus.bezmen.core; + +import lombok.NonNull; + +/** + * Model: domain slice + */ +public record SepulkaNewRequest(@NonNull String name) {} diff --git a/libs/abstraction/src/main/java/smecalculus/bezmen/core/SepulkaNewRequestEg.java b/libs/abstraction/src/main/java/smecalculus/bezmen/core/SepulkaNewRequestEg.java new file mode 100644 index 00000000..3e35eb81 --- /dev/null +++ b/libs/abstraction/src/main/java/smecalculus/bezmen/core/SepulkaNewRequestEg.java @@ -0,0 +1,11 @@ +package smecalculus.bezmen.core; + +public class SepulkaNewRequestEg { + public static final String NAME = "foo"; + + public static class Pojos { + public static SepulkaNewRequest sepulkaNewRequest() { + return new SepulkaNewRequest(NAME); + } + } +} diff --git a/libs/abstraction/src/main/java/smecalculus/bezmen/core/SepulkaNewResponse.java b/libs/abstraction/src/main/java/smecalculus/bezmen/core/SepulkaNewResponse.java new file mode 100644 index 00000000..a1ef8115 --- /dev/null +++ b/libs/abstraction/src/main/java/smecalculus/bezmen/core/SepulkaNewResponse.java @@ -0,0 +1,9 @@ +package smecalculus.bezmen.core; + +import java.util.UUID; +import lombok.NonNull; + +/** + * Model: domain slice + */ +public record SepulkaNewResponse(@NonNull UUID id) {} diff --git a/libs/abstraction/src/main/java/smecalculus/bezmen/core/SepulkaNewResponseEg.java b/libs/abstraction/src/main/java/smecalculus/bezmen/core/SepulkaNewResponseEg.java new file mode 100644 index 00000000..d6f53462 --- /dev/null +++ b/libs/abstraction/src/main/java/smecalculus/bezmen/core/SepulkaNewResponseEg.java @@ -0,0 +1,16 @@ +package smecalculus.bezmen.core; + +import java.util.UUID; + +public class SepulkaNewResponseEg { + + public static class Pojos { + public static SepulkaNewResponse sepulkaNewResponse() { + return sepulkaNewResponse(UUID.randomUUID()); + } + + public static SepulkaNewResponse sepulkaNewResponse(UUID id) { + return new SepulkaNewResponse(id); + } + } +} diff --git a/libs/abstraction/src/main/java/smecalculus/bezmen/core/SepulkaService.java b/libs/abstraction/src/main/java/smecalculus/bezmen/core/SepulkaService.java new file mode 100644 index 00000000..d28e2c56 --- /dev/null +++ b/libs/abstraction/src/main/java/smecalculus/bezmen/core/SepulkaService.java @@ -0,0 +1,9 @@ +package smecalculus.bezmen.core; + +import java.util.List; + +public interface SepulkaService { + SepulkaNewResponse register(SepulkaNewRequest request); + + List getSepulkas(); +} diff --git a/libs/abstraction/src/main/java/smecalculus/bezmen/core/SepulkaSliceMapper.java b/libs/abstraction/src/main/java/smecalculus/bezmen/core/SepulkaSliceMapper.java new file mode 100644 index 00000000..278f2dd4 --- /dev/null +++ b/libs/abstraction/src/main/java/smecalculus/bezmen/core/SepulkaSliceMapper.java @@ -0,0 +1,10 @@ +package smecalculus.bezmen.core; + +import org.mapstruct.Mapper; + +@Mapper +public interface SepulkaSliceMapper { + Sepulka.Builder toDomain(SepulkaNewRequest request); + + SepulkaNewResponse toSlice(Sepulka sepulka); +} diff --git a/libs/abstraction/src/main/java/smecalculus/bezmen/exterior/messaging/SepulkaClient.java b/libs/abstraction/src/main/java/smecalculus/bezmen/exterior/messaging/SepulkaClient.java deleted file mode 100644 index 299e6a61..00000000 --- a/libs/abstraction/src/main/java/smecalculus/bezmen/exterior/messaging/SepulkaClient.java +++ /dev/null @@ -1,5 +0,0 @@ -package smecalculus.bezmen.exterior.messaging; - -public interface SepulkaClient { - SepulkaRegisteredSliceMsg register(SepulkaRegisterSliceMsg request); -} diff --git a/libs/abstraction/src/main/java/smecalculus/bezmen/exterior/messaging/SepulkaMsgMapper.java b/libs/abstraction/src/main/java/smecalculus/bezmen/exterior/messaging/SepulkaMsgMapper.java deleted file mode 100644 index 5785b301..00000000 --- a/libs/abstraction/src/main/java/smecalculus/bezmen/exterior/messaging/SepulkaMsgMapper.java +++ /dev/null @@ -1,14 +0,0 @@ -package smecalculus.bezmen.exterior.messaging; - -import org.mapstruct.Mapper; - -@Mapper -public interface SepulkaMsgMapper { - SepulkaRegisterSliceMsg toMsg(SepulkaRegisterSlice slice); - - SepulkaRegisterSlice toDomain(SepulkaRegisterSliceMsg sliceMsg); - - SepulkaRegisteredSliceMsg toMsg(SepulkaRegisteredSlice slice); - - SepulkaRegisteredSlice toDomain(SepulkaRegisteredSliceMsg sliceMsg); -} diff --git a/libs/abstraction/src/main/java/smecalculus/bezmen/exterior/messaging/SepulkaRegisterSlice.java b/libs/abstraction/src/main/java/smecalculus/bezmen/exterior/messaging/SepulkaRegisterSlice.java deleted file mode 100644 index 57fa7db6..00000000 --- a/libs/abstraction/src/main/java/smecalculus/bezmen/exterior/messaging/SepulkaRegisterSlice.java +++ /dev/null @@ -1,5 +0,0 @@ -package smecalculus.bezmen.exterior.messaging; - -import lombok.NonNull; - -public record SepulkaRegisterSlice(@NonNull String name) {} diff --git a/libs/abstraction/src/main/java/smecalculus/bezmen/exterior/messaging/SepulkaRegisterSliceEg.java b/libs/abstraction/src/main/java/smecalculus/bezmen/exterior/messaging/SepulkaRegisterSliceEg.java deleted file mode 100644 index ffe324cb..00000000 --- a/libs/abstraction/src/main/java/smecalculus/bezmen/exterior/messaging/SepulkaRegisterSliceEg.java +++ /dev/null @@ -1,17 +0,0 @@ -package smecalculus.bezmen.exterior.messaging; - -public class SepulkaRegisterSliceEg { - public static final String NAME = "foo"; - - public static class Pojos { - public static SepulkaRegisterSlice sepulkaRegisterSlice() { - return new SepulkaRegisterSlice(NAME); - } - - public static SepulkaRegisterSliceMsg sepulkaRegisterSliceMsg() { - var msg = new SepulkaRegisterSliceMsg(); - msg.setName(NAME); - return msg; - } - } -} diff --git a/libs/abstraction/src/main/java/smecalculus/bezmen/exterior/messaging/SepulkaRegisterSliceMsg.java b/libs/abstraction/src/main/java/smecalculus/bezmen/exterior/messaging/SepulkaRegisterSliceMsg.java deleted file mode 100644 index dea4ba85..00000000 --- a/libs/abstraction/src/main/java/smecalculus/bezmen/exterior/messaging/SepulkaRegisterSliceMsg.java +++ /dev/null @@ -1,8 +0,0 @@ -package smecalculus.bezmen.exterior.messaging; - -import lombok.Data; - -@Data -public class SepulkaRegisterSliceMsg { - private String name; -} diff --git a/libs/abstraction/src/main/java/smecalculus/bezmen/exterior/messaging/SepulkaRegisteredSlice.java b/libs/abstraction/src/main/java/smecalculus/bezmen/exterior/messaging/SepulkaRegisteredSlice.java deleted file mode 100644 index d781bb13..00000000 --- a/libs/abstraction/src/main/java/smecalculus/bezmen/exterior/messaging/SepulkaRegisteredSlice.java +++ /dev/null @@ -1,6 +0,0 @@ -package smecalculus.bezmen.exterior.messaging; - -import java.util.UUID; -import lombok.NonNull; - -public record SepulkaRegisteredSlice(@NonNull UUID id) {} diff --git a/libs/abstraction/src/main/java/smecalculus/bezmen/exterior/messaging/SepulkaRegisteredSliceEg.java b/libs/abstraction/src/main/java/smecalculus/bezmen/exterior/messaging/SepulkaRegisteredSliceEg.java deleted file mode 100644 index 401a8cb7..00000000 --- a/libs/abstraction/src/main/java/smecalculus/bezmen/exterior/messaging/SepulkaRegisteredSliceEg.java +++ /dev/null @@ -1,22 +0,0 @@ -package smecalculus.bezmen.exterior.messaging; - -import java.util.UUID; - -public class SepulkaRegisteredSliceEg { - - public static class Pojos { - public static SepulkaRegisteredSlice sepulkaRegisteredSlice() { - return new SepulkaRegisteredSlice(UUID.randomUUID()); - } - - public static SepulkaRegisteredSlice sepulkaRegisteredSlice(UUID id) { - return new SepulkaRegisteredSlice(id); - } - - public static SepulkaRegisteredSliceMsg sepulkaRegisteredSliceMsg(UUID id) { - var sliceMsg = new SepulkaRegisteredSliceMsg(); - sliceMsg.setId(id.toString()); - return sliceMsg; - } - } -} diff --git a/libs/abstraction/src/main/java/smecalculus/bezmen/exterior/messaging/SepulkaRegisteredSliceMsg.java b/libs/abstraction/src/main/java/smecalculus/bezmen/exterior/messaging/SepulkaRegisteredSliceMsg.java deleted file mode 100644 index a67e2ded..00000000 --- a/libs/abstraction/src/main/java/smecalculus/bezmen/exterior/messaging/SepulkaRegisteredSliceMsg.java +++ /dev/null @@ -1,8 +0,0 @@ -package smecalculus.bezmen.exterior.messaging; - -import lombok.Data; - -@Data -public class SepulkaRegisteredSliceMsg { - private String id; -} diff --git a/libs/abstraction/src/main/java/smecalculus/bezmen/interior/core/SepulkaService.java b/libs/abstraction/src/main/java/smecalculus/bezmen/interior/core/SepulkaService.java deleted file mode 100644 index 64352b8f..00000000 --- a/libs/abstraction/src/main/java/smecalculus/bezmen/interior/core/SepulkaService.java +++ /dev/null @@ -1,11 +0,0 @@ -package smecalculus.bezmen.interior.core; - -import java.util.List; -import smecalculus.bezmen.exterior.messaging.SepulkaRegisterSlice; -import smecalculus.bezmen.exterior.messaging.SepulkaRegisteredSlice; - -public interface SepulkaService { - SepulkaRegisteredSlice register(SepulkaRegisterSlice slice); - - List getSepulkas(); -} diff --git a/libs/abstraction/src/main/java/smecalculus/bezmen/interior/core/SepulkaSliceMapper.java b/libs/abstraction/src/main/java/smecalculus/bezmen/interior/core/SepulkaSliceMapper.java deleted file mode 100644 index 057648dd..00000000 --- a/libs/abstraction/src/main/java/smecalculus/bezmen/interior/core/SepulkaSliceMapper.java +++ /dev/null @@ -1,12 +0,0 @@ -package smecalculus.bezmen.interior.core; - -import org.mapstruct.Mapper; -import smecalculus.bezmen.exterior.messaging.SepulkaRegisterSlice; -import smecalculus.bezmen.exterior.messaging.SepulkaRegisteredSlice; - -@Mapper -public interface SepulkaSliceMapper { - Sepulka.Builder toDomain(SepulkaRegisterSlice slice); - - SepulkaRegisteredSlice toSlice(Sepulka sepulka); -} diff --git a/libs/abstraction/src/main/java/smecalculus/bezmen/interior/validation/EdgeValidator.java b/libs/abstraction/src/main/java/smecalculus/bezmen/validation/EdgeValidator.java similarity index 64% rename from libs/abstraction/src/main/java/smecalculus/bezmen/interior/validation/EdgeValidator.java rename to libs/abstraction/src/main/java/smecalculus/bezmen/validation/EdgeValidator.java index 97d3c45c..eff4e408 100644 --- a/libs/abstraction/src/main/java/smecalculus/bezmen/interior/validation/EdgeValidator.java +++ b/libs/abstraction/src/main/java/smecalculus/bezmen/validation/EdgeValidator.java @@ -1,4 +1,4 @@ -package smecalculus.bezmen.interior.validation; +package smecalculus.bezmen.validation; public interface EdgeValidator { void validate(T object, Class... groups); diff --git a/libs/essentials/src/main/java/smecalculus/bezmen/interior/configuration/ConfigKeeperLightbendConfig.java b/libs/essentials/src/main/java/smecalculus/bezmen/configuration/ConfigKeeperLightbendConfig.java similarity index 89% rename from libs/essentials/src/main/java/smecalculus/bezmen/interior/configuration/ConfigKeeperLightbendConfig.java rename to libs/essentials/src/main/java/smecalculus/bezmen/configuration/ConfigKeeperLightbendConfig.java index 893b9fc0..3a69e722 100644 --- a/libs/essentials/src/main/java/smecalculus/bezmen/interior/configuration/ConfigKeeperLightbendConfig.java +++ b/libs/essentials/src/main/java/smecalculus/bezmen/configuration/ConfigKeeperLightbendConfig.java @@ -1,4 +1,4 @@ -package smecalculus.bezmen.interior.configuration; +package smecalculus.bezmen.configuration; import com.typesafe.config.Config; import com.typesafe.config.ConfigBeanFactory; diff --git a/libs/essentials/src/main/java/smecalculus/bezmen/interior/configuration/ConfigKeeperSpringConfig.java b/libs/essentials/src/main/java/smecalculus/bezmen/configuration/ConfigKeeperSpringConfig.java similarity index 90% rename from libs/essentials/src/main/java/smecalculus/bezmen/interior/configuration/ConfigKeeperSpringConfig.java rename to libs/essentials/src/main/java/smecalculus/bezmen/configuration/ConfigKeeperSpringConfig.java index ed746c3d..1c3feed6 100644 --- a/libs/essentials/src/main/java/smecalculus/bezmen/interior/configuration/ConfigKeeperSpringConfig.java +++ b/libs/essentials/src/main/java/smecalculus/bezmen/configuration/ConfigKeeperSpringConfig.java @@ -1,4 +1,4 @@ -package smecalculus.bezmen.interior.configuration; +package smecalculus.bezmen.configuration; import lombok.NonNull; import lombok.RequiredArgsConstructor; diff --git a/libs/essentials/src/main/java/smecalculus/bezmen/interior/configuration/ConfigMappingMode.java b/libs/essentials/src/main/java/smecalculus/bezmen/configuration/ConfigMappingMode.java similarity index 59% rename from libs/essentials/src/main/java/smecalculus/bezmen/interior/configuration/ConfigMappingMode.java rename to libs/essentials/src/main/java/smecalculus/bezmen/configuration/ConfigMappingMode.java index 99712b9c..6b93eca4 100644 --- a/libs/essentials/src/main/java/smecalculus/bezmen/interior/configuration/ConfigMappingMode.java +++ b/libs/essentials/src/main/java/smecalculus/bezmen/configuration/ConfigMappingMode.java @@ -1,4 +1,4 @@ -package smecalculus.bezmen.interior.configuration; +package smecalculus.bezmen.configuration; public enum ConfigMappingMode { LIGHTBEND_CONFIG, diff --git a/libs/essentials/src/main/java/smecalculus/bezmen/interior/configuration/ConfigProtocolMode.java b/libs/essentials/src/main/java/smecalculus/bezmen/configuration/ConfigProtocolMode.java similarity index 50% rename from libs/essentials/src/main/java/smecalculus/bezmen/interior/configuration/ConfigProtocolMode.java rename to libs/essentials/src/main/java/smecalculus/bezmen/configuration/ConfigProtocolMode.java index a1acfbee..086768aa 100644 --- a/libs/essentials/src/main/java/smecalculus/bezmen/interior/configuration/ConfigProtocolMode.java +++ b/libs/essentials/src/main/java/smecalculus/bezmen/configuration/ConfigProtocolMode.java @@ -1,4 +1,4 @@ -package smecalculus.bezmen.interior.configuration; +package smecalculus.bezmen.configuration; public enum ConfigProtocolMode { FILE_SYSTEM diff --git a/libs/essentials/src/main/java/smecalculus/bezmen/interior/construction/ConditionalOnConfigMappingMode.java b/libs/essentials/src/main/java/smecalculus/bezmen/construction/ConditionalOnConfigMappingMode.java similarity index 78% rename from libs/essentials/src/main/java/smecalculus/bezmen/interior/construction/ConditionalOnConfigMappingMode.java rename to libs/essentials/src/main/java/smecalculus/bezmen/construction/ConditionalOnConfigMappingMode.java index 42d49162..d92a2be1 100644 --- a/libs/essentials/src/main/java/smecalculus/bezmen/interior/construction/ConditionalOnConfigMappingMode.java +++ b/libs/essentials/src/main/java/smecalculus/bezmen/construction/ConditionalOnConfigMappingMode.java @@ -1,11 +1,11 @@ -package smecalculus.bezmen.interior.construction; +package smecalculus.bezmen.construction; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; import org.springframework.context.annotation.Conditional; -import smecalculus.bezmen.interior.configuration.ConfigMappingMode; +import smecalculus.bezmen.configuration.ConfigMappingMode; @Target({ElementType.TYPE, ElementType.METHOD}) @Retention(RetentionPolicy.RUNTIME) diff --git a/libs/essentials/src/main/java/smecalculus/bezmen/interior/construction/ConditionalOnConfigProtocolMode.java b/libs/essentials/src/main/java/smecalculus/bezmen/construction/ConditionalOnConfigProtocolMode.java similarity index 78% rename from libs/essentials/src/main/java/smecalculus/bezmen/interior/construction/ConditionalOnConfigProtocolMode.java rename to libs/essentials/src/main/java/smecalculus/bezmen/construction/ConditionalOnConfigProtocolMode.java index 2e414d90..ef188f0a 100644 --- a/libs/essentials/src/main/java/smecalculus/bezmen/interior/construction/ConditionalOnConfigProtocolMode.java +++ b/libs/essentials/src/main/java/smecalculus/bezmen/construction/ConditionalOnConfigProtocolMode.java @@ -1,11 +1,11 @@ -package smecalculus.bezmen.interior.construction; +package smecalculus.bezmen.construction; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; import org.springframework.context.annotation.Conditional; -import smecalculus.bezmen.interior.configuration.ConfigProtocolMode; +import smecalculus.bezmen.configuration.ConfigProtocolMode; @Target({ElementType.TYPE, ElementType.METHOD}) @Retention(RetentionPolicy.RUNTIME) diff --git a/libs/essentials/src/main/java/smecalculus/bezmen/interior/construction/ConfigBeans.java b/libs/essentials/src/main/java/smecalculus/bezmen/construction/ConfigBeans.java similarity index 67% rename from libs/essentials/src/main/java/smecalculus/bezmen/interior/construction/ConfigBeans.java rename to libs/essentials/src/main/java/smecalculus/bezmen/construction/ConfigBeans.java index f0cbd216..8e90b345 100644 --- a/libs/essentials/src/main/java/smecalculus/bezmen/interior/construction/ConfigBeans.java +++ b/libs/essentials/src/main/java/smecalculus/bezmen/construction/ConfigBeans.java @@ -1,14 +1,14 @@ -package smecalculus.bezmen.interior.construction; +package smecalculus.bezmen.construction; import com.typesafe.config.ConfigFactory; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.core.env.Environment; -import smecalculus.bezmen.interior.configuration.ConfigKeeper; -import smecalculus.bezmen.interior.configuration.ConfigKeeperLightbendConfig; -import smecalculus.bezmen.interior.configuration.ConfigKeeperSpringConfig; -import smecalculus.bezmen.interior.configuration.ConfigMappingMode; -import smecalculus.bezmen.interior.configuration.ConfigProtocolMode; +import smecalculus.bezmen.configuration.ConfigKeeper; +import smecalculus.bezmen.configuration.ConfigKeeperLightbendConfig; +import smecalculus.bezmen.configuration.ConfigKeeperSpringConfig; +import smecalculus.bezmen.configuration.ConfigMappingMode; +import smecalculus.bezmen.configuration.ConfigProtocolMode; @Configuration(proxyBeanMethods = false) public class ConfigBeans { diff --git a/libs/essentials/src/main/java/smecalculus/bezmen/interior/construction/ConfigMappingModeCondition.java b/libs/essentials/src/main/java/smecalculus/bezmen/construction/ConfigMappingModeCondition.java similarity index 89% rename from libs/essentials/src/main/java/smecalculus/bezmen/interior/construction/ConfigMappingModeCondition.java rename to libs/essentials/src/main/java/smecalculus/bezmen/construction/ConfigMappingModeCondition.java index 486b77bd..a205f333 100644 --- a/libs/essentials/src/main/java/smecalculus/bezmen/interior/construction/ConfigMappingModeCondition.java +++ b/libs/essentials/src/main/java/smecalculus/bezmen/construction/ConfigMappingModeCondition.java @@ -1,4 +1,4 @@ -package smecalculus.bezmen.interior.construction; +package smecalculus.bezmen.construction; import static org.springframework.context.annotation.ConfigurationCondition.ConfigurationPhase.REGISTER_BEAN; @@ -6,7 +6,7 @@ import org.springframework.context.annotation.ConditionContext; import org.springframework.context.annotation.ConfigurationCondition; import org.springframework.core.type.AnnotatedTypeMetadata; -import smecalculus.bezmen.interior.configuration.ConfigMappingMode; +import smecalculus.bezmen.configuration.ConfigMappingMode; class ConfigMappingModeCondition implements ConfigurationCondition { diff --git a/libs/essentials/src/main/java/smecalculus/bezmen/interior/construction/ConfigProtocolModeCondition.java b/libs/essentials/src/main/java/smecalculus/bezmen/construction/ConfigProtocolModeCondition.java similarity index 89% rename from libs/essentials/src/main/java/smecalculus/bezmen/interior/construction/ConfigProtocolModeCondition.java rename to libs/essentials/src/main/java/smecalculus/bezmen/construction/ConfigProtocolModeCondition.java index 6d44dc83..0d8f0a8a 100644 --- a/libs/essentials/src/main/java/smecalculus/bezmen/interior/construction/ConfigProtocolModeCondition.java +++ b/libs/essentials/src/main/java/smecalculus/bezmen/construction/ConfigProtocolModeCondition.java @@ -1,4 +1,4 @@ -package smecalculus.bezmen.interior.construction; +package smecalculus.bezmen.construction; import static org.springframework.context.annotation.ConfigurationCondition.ConfigurationPhase.REGISTER_BEAN; @@ -6,7 +6,7 @@ import org.springframework.context.annotation.ConditionContext; import org.springframework.context.annotation.ConfigurationCondition; import org.springframework.core.type.AnnotatedTypeMetadata; -import smecalculus.bezmen.interior.configuration.ConfigProtocolMode; +import smecalculus.bezmen.configuration.ConfigProtocolMode; class ConfigProtocolModeCondition implements ConfigurationCondition { diff --git a/libs/essentials/src/main/java/smecalculus/bezmen/interior/construction/ValidationBeans.java b/libs/essentials/src/main/java/smecalculus/bezmen/construction/ValidationBeans.java similarity index 72% rename from libs/essentials/src/main/java/smecalculus/bezmen/interior/construction/ValidationBeans.java rename to libs/essentials/src/main/java/smecalculus/bezmen/construction/ValidationBeans.java index cda8fdee..baf32469 100644 --- a/libs/essentials/src/main/java/smecalculus/bezmen/interior/construction/ValidationBeans.java +++ b/libs/essentials/src/main/java/smecalculus/bezmen/construction/ValidationBeans.java @@ -1,11 +1,11 @@ -package smecalculus.bezmen.interior.construction; +package smecalculus.bezmen.construction; import jakarta.validation.Validation; import jakarta.validation.ValidatorFactory; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; -import smecalculus.bezmen.interior.validation.EdgeValidator; -import smecalculus.bezmen.interior.validation.EdgeValidatorHibernateValidator; +import smecalculus.bezmen.validation.EdgeValidator; +import smecalculus.bezmen.validation.EdgeValidatorHibernateValidator; @Configuration(proxyBeanMethods = false) public class ValidationBeans { diff --git a/libs/essentials/src/main/java/smecalculus/bezmen/interior/validation/EdgeValidatorHibernateValidator.java b/libs/essentials/src/main/java/smecalculus/bezmen/validation/EdgeValidatorHibernateValidator.java similarity index 93% rename from libs/essentials/src/main/java/smecalculus/bezmen/interior/validation/EdgeValidatorHibernateValidator.java rename to libs/essentials/src/main/java/smecalculus/bezmen/validation/EdgeValidatorHibernateValidator.java index 4563e422..9749f8fa 100644 --- a/libs/essentials/src/main/java/smecalculus/bezmen/interior/validation/EdgeValidatorHibernateValidator.java +++ b/libs/essentials/src/main/java/smecalculus/bezmen/validation/EdgeValidatorHibernateValidator.java @@ -1,4 +1,4 @@ -package smecalculus.bezmen.interior.validation; +package smecalculus.bezmen.validation; import jakarta.validation.ConstraintViolation; import jakarta.validation.ConstraintViolationException; diff --git a/libs/essentials/src/main/java/smecalculus/bezmen/interior/validation/ValueOfEnum.java b/libs/essentials/src/main/java/smecalculus/bezmen/validation/ValueOfEnum.java similarity index 93% rename from libs/essentials/src/main/java/smecalculus/bezmen/interior/validation/ValueOfEnum.java rename to libs/essentials/src/main/java/smecalculus/bezmen/validation/ValueOfEnum.java index 53d870b6..b9d0a614 100644 --- a/libs/essentials/src/main/java/smecalculus/bezmen/interior/validation/ValueOfEnum.java +++ b/libs/essentials/src/main/java/smecalculus/bezmen/validation/ValueOfEnum.java @@ -1,4 +1,4 @@ -package smecalculus.bezmen.interior.validation; +package smecalculus.bezmen.validation; import static java.lang.annotation.ElementType.FIELD; import static java.lang.annotation.ElementType.TYPE_USE; diff --git a/libs/essentials/src/main/java/smecalculus/bezmen/interior/validation/ValueOfEnumValidator.java b/libs/essentials/src/main/java/smecalculus/bezmen/validation/ValueOfEnumValidator.java similarity index 95% rename from libs/essentials/src/main/java/smecalculus/bezmen/interior/validation/ValueOfEnumValidator.java rename to libs/essentials/src/main/java/smecalculus/bezmen/validation/ValueOfEnumValidator.java index 6f765595..bff80fd6 100644 --- a/libs/essentials/src/main/java/smecalculus/bezmen/interior/validation/ValueOfEnumValidator.java +++ b/libs/essentials/src/main/java/smecalculus/bezmen/validation/ValueOfEnumValidator.java @@ -1,4 +1,4 @@ -package smecalculus.bezmen.interior.validation; +package smecalculus.bezmen.validation; import static java.lang.String.format; import static java.util.stream.Collectors.toSet; diff --git a/libs/messaging-client/pom.xml b/libs/messaging-client/pom.xml new file mode 100644 index 00000000..5ad195e8 --- /dev/null +++ b/libs/messaging-client/pom.xml @@ -0,0 +1,52 @@ + + + 4.0.0 + + + smecalculus.bezmen + libs + ${revision} + + + messaging-client + + + + + ${project.groupId} + abstraction-client + + + + com.fasterxml.jackson.core + jackson-databind + + + + ${project.groupId} + testing + test + + + + + + + org.apache.maven.plugins + maven-install-plugin + + false + + + + org.apache.maven.plugins + maven-deploy-plugin + + false + + + + + diff --git a/libs/messaging/src/main/java/smecalculus/bezmen/exterior/messaging/BezmenClientJavaHttp.java b/libs/messaging-client/src/main/java/smecalculus/bezmen/messaging/BezmenClientJavaHttp.java similarity index 92% rename from libs/messaging/src/main/java/smecalculus/bezmen/exterior/messaging/BezmenClientJavaHttp.java rename to libs/messaging-client/src/main/java/smecalculus/bezmen/messaging/BezmenClientJavaHttp.java index 15c15e7f..9cbfed2d 100644 --- a/libs/messaging/src/main/java/smecalculus/bezmen/exterior/messaging/BezmenClientJavaHttp.java +++ b/libs/messaging-client/src/main/java/smecalculus/bezmen/messaging/BezmenClientJavaHttp.java @@ -1,4 +1,4 @@ -package smecalculus.bezmen.exterior.messaging; +package smecalculus.bezmen.messaging; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; @@ -21,7 +21,7 @@ public class BezmenClientJavaHttp implements BezmenClient { private HttpClient client; @Override - public SepulkaRegisteredSliceMsg register(SepulkaRegisterSliceMsg request) { + public SepulkaNewResponseMsg register(SepulkaNewRequestMsg request) { try { var requestJson = mapper.writeValueAsString(request); var httpRequest = HttpRequest.newBuilder() @@ -31,7 +31,7 @@ public SepulkaRegisteredSliceMsg register(SepulkaRegisterSliceMsg request) { .header("Accept", "application/json") .build(); var httpResponse = client.send(httpRequest, BodyHandlers.ofString()); - return mapper.readValue(httpResponse.body(), SepulkaRegisteredSliceMsg.class); + return mapper.readValue(httpResponse.body(), SepulkaNewResponseMsg.class); } catch (JsonProcessingException e) { throw new RuntimeException(e); } catch (IOException | InterruptedException e) { diff --git a/libs/messaging-client/src/main/resources/messaging.properties b/libs/messaging-client/src/main/resources/messaging.properties new file mode 100644 index 00000000..4cec1140 --- /dev/null +++ b/libs/messaging-client/src/main/resources/messaging.properties @@ -0,0 +1,2 @@ +bezmen.messaging.protocol.modes[0]=http +bezmen.messaging.mapping.modes[0]=spring_mvc diff --git a/libs/messaging-client/src/main/resources/reference.conf b/libs/messaging-client/src/main/resources/reference.conf new file mode 100644 index 00000000..6504a9e6 --- /dev/null +++ b/libs/messaging-client/src/main/resources/reference.conf @@ -0,0 +1,10 @@ +bezmen { + messaging { + protocol { + modes = [http] + } + mapping { + modes = [spring_mvc] + } + } +} diff --git a/libs/messaging-client/src/test/resources/logback-test.xml b/libs/messaging-client/src/test/resources/logback-test.xml new file mode 100644 index 00000000..885aa3cb --- /dev/null +++ b/libs/messaging-client/src/test/resources/logback-test.xml @@ -0,0 +1,11 @@ + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + diff --git a/libs/messaging/README.adoc b/libs/messaging/README.adoc deleted file mode 100644 index a248c019..00000000 --- a/libs/messaging/README.adoc +++ /dev/null @@ -1 +0,0 @@ -= Обмен сообщениями diff --git a/libs/messaging/pom.xml b/libs/messaging/pom.xml index 0b1c758f..7962a394 100644 --- a/libs/messaging/pom.xml +++ b/libs/messaging/pom.xml @@ -14,6 +14,10 @@ + + ${project.groupId} + messaging-client + ${project.groupId} essentials @@ -66,35 +70,4 @@ test - - - - - org.apache.maven.plugins - maven-jar-plugin - - - exterior-jar - - jar - - - - - - org.apache.maven.plugins - maven-install-plugin - - false - - - - org.apache.maven.plugins - maven-deploy-plugin - - false - - - - diff --git a/libs/messaging/src/main/java/smecalculus/bezmen/interior/configuration/MessageMappingMode.java b/libs/messaging/src/main/java/smecalculus/bezmen/configuration/MessageMappingMode.java similarity index 59% rename from libs/messaging/src/main/java/smecalculus/bezmen/interior/configuration/MessageMappingMode.java rename to libs/messaging/src/main/java/smecalculus/bezmen/configuration/MessageMappingMode.java index 9e66c6b2..4adfba89 100644 --- a/libs/messaging/src/main/java/smecalculus/bezmen/interior/configuration/MessageMappingMode.java +++ b/libs/messaging/src/main/java/smecalculus/bezmen/configuration/MessageMappingMode.java @@ -1,4 +1,4 @@ -package smecalculus.bezmen.interior.configuration; +package smecalculus.bezmen.configuration; public enum MessageMappingMode { SPRING_MVC, diff --git a/libs/messaging/src/main/java/smecalculus/bezmen/interior/configuration/MessageMappingProps.java b/libs/messaging/src/main/java/smecalculus/bezmen/configuration/MessageMappingProps.java similarity index 76% rename from libs/messaging/src/main/java/smecalculus/bezmen/interior/configuration/MessageMappingProps.java rename to libs/messaging/src/main/java/smecalculus/bezmen/configuration/MessageMappingProps.java index fd338bf7..70d91764 100644 --- a/libs/messaging/src/main/java/smecalculus/bezmen/interior/configuration/MessageMappingProps.java +++ b/libs/messaging/src/main/java/smecalculus/bezmen/configuration/MessageMappingProps.java @@ -1,4 +1,4 @@ -package smecalculus.bezmen.interior.configuration; +package smecalculus.bezmen.configuration; import java.util.Set; import lombok.Builder; diff --git a/libs/messaging/src/main/java/smecalculus/bezmen/interior/configuration/MessageMappingPropsCfg.java b/libs/messaging/src/main/java/smecalculus/bezmen/configuration/MessageMappingPropsCfg.java similarity index 71% rename from libs/messaging/src/main/java/smecalculus/bezmen/interior/configuration/MessageMappingPropsCfg.java rename to libs/messaging/src/main/java/smecalculus/bezmen/configuration/MessageMappingPropsCfg.java index 856c4b17..b2045650 100644 --- a/libs/messaging/src/main/java/smecalculus/bezmen/interior/configuration/MessageMappingPropsCfg.java +++ b/libs/messaging/src/main/java/smecalculus/bezmen/configuration/MessageMappingPropsCfg.java @@ -1,10 +1,10 @@ -package smecalculus.bezmen.interior.configuration; +package smecalculus.bezmen.configuration; import jakarta.validation.constraints.NotNull; import jakarta.validation.constraints.Size; import java.util.Set; import lombok.Data; -import smecalculus.bezmen.interior.validation.ValueOfEnum; +import smecalculus.bezmen.validation.ValueOfEnum; @Data public class MessageMappingPropsCfg { diff --git a/libs/messaging/src/main/java/smecalculus/bezmen/interior/configuration/MessageMappingPropsEg.java b/libs/messaging/src/main/java/smecalculus/bezmen/configuration/MessageMappingPropsEg.java similarity index 85% rename from libs/messaging/src/main/java/smecalculus/bezmen/interior/configuration/MessageMappingPropsEg.java rename to libs/messaging/src/main/java/smecalculus/bezmen/configuration/MessageMappingPropsEg.java index 9c91b0bd..3faffea8 100644 --- a/libs/messaging/src/main/java/smecalculus/bezmen/interior/configuration/MessageMappingPropsEg.java +++ b/libs/messaging/src/main/java/smecalculus/bezmen/configuration/MessageMappingPropsEg.java @@ -1,4 +1,4 @@ -package smecalculus.bezmen.interior.configuration; +package smecalculus.bezmen.configuration; import java.util.Set; diff --git a/libs/messaging/src/main/java/smecalculus/bezmen/interior/configuration/MessagingCfgMapper.java b/libs/messaging/src/main/java/smecalculus/bezmen/configuration/MessagingCfgMapper.java similarity index 94% rename from libs/messaging/src/main/java/smecalculus/bezmen/interior/configuration/MessagingCfgMapper.java rename to libs/messaging/src/main/java/smecalculus/bezmen/configuration/MessagingCfgMapper.java index ae2b526a..2cd35b05 100644 --- a/libs/messaging/src/main/java/smecalculus/bezmen/interior/configuration/MessagingCfgMapper.java +++ b/libs/messaging/src/main/java/smecalculus/bezmen/configuration/MessagingCfgMapper.java @@ -1,4 +1,4 @@ -package smecalculus.bezmen.interior.configuration; +package smecalculus.bezmen.configuration; import org.mapstruct.Mapper; import org.mapstruct.Mapping; diff --git a/libs/messaging/src/main/java/smecalculus/bezmen/interior/configuration/MessagingProps.java b/libs/messaging/src/main/java/smecalculus/bezmen/configuration/MessagingProps.java similarity index 78% rename from libs/messaging/src/main/java/smecalculus/bezmen/interior/configuration/MessagingProps.java rename to libs/messaging/src/main/java/smecalculus/bezmen/configuration/MessagingProps.java index 8ed8dac0..37f710b9 100644 --- a/libs/messaging/src/main/java/smecalculus/bezmen/interior/configuration/MessagingProps.java +++ b/libs/messaging/src/main/java/smecalculus/bezmen/configuration/MessagingProps.java @@ -1,4 +1,4 @@ -package smecalculus.bezmen.interior.configuration; +package smecalculus.bezmen.configuration; import lombok.Builder; import lombok.NonNull; diff --git a/libs/messaging/src/main/java/smecalculus/bezmen/interior/configuration/MessagingPropsCfg.java b/libs/messaging/src/main/java/smecalculus/bezmen/configuration/MessagingPropsCfg.java similarity index 80% rename from libs/messaging/src/main/java/smecalculus/bezmen/interior/configuration/MessagingPropsCfg.java rename to libs/messaging/src/main/java/smecalculus/bezmen/configuration/MessagingPropsCfg.java index 96f9f77a..917e19c3 100644 --- a/libs/messaging/src/main/java/smecalculus/bezmen/interior/configuration/MessagingPropsCfg.java +++ b/libs/messaging/src/main/java/smecalculus/bezmen/configuration/MessagingPropsCfg.java @@ -1,4 +1,4 @@ -package smecalculus.bezmen.interior.configuration; +package smecalculus.bezmen.configuration; import jakarta.validation.constraints.NotNull; import lombok.Data; diff --git a/libs/messaging/src/main/java/smecalculus/bezmen/interior/configuration/MessagingPropsEg.java b/libs/messaging/src/main/java/smecalculus/bezmen/configuration/MessagingPropsEg.java similarity index 54% rename from libs/messaging/src/main/java/smecalculus/bezmen/interior/configuration/MessagingPropsEg.java rename to libs/messaging/src/main/java/smecalculus/bezmen/configuration/MessagingPropsEg.java index af301bac..44e0ef20 100644 --- a/libs/messaging/src/main/java/smecalculus/bezmen/interior/configuration/MessagingPropsEg.java +++ b/libs/messaging/src/main/java/smecalculus/bezmen/configuration/MessagingPropsEg.java @@ -1,7 +1,7 @@ -package smecalculus.bezmen.interior.configuration; +package smecalculus.bezmen.configuration; -import static smecalculus.bezmen.interior.configuration.MessageMappingPropsEg.Builders.messageMappingProps; -import static smecalculus.bezmen.interior.configuration.MessagingProtocolPropsEg.Builders.messagingProtocolProps; +import static smecalculus.bezmen.configuration.MessageMappingPropsEg.Builders.messageMappingProps; +import static smecalculus.bezmen.configuration.MessagingProtocolPropsEg.Builders.messagingProtocolProps; public class MessagingPropsEg { public static class Builders { diff --git a/libs/messaging/src/main/java/smecalculus/bezmen/interior/configuration/MessagingProtocolMode.java b/libs/messaging/src/main/java/smecalculus/bezmen/configuration/MessagingProtocolMode.java similarity index 52% rename from libs/messaging/src/main/java/smecalculus/bezmen/interior/configuration/MessagingProtocolMode.java rename to libs/messaging/src/main/java/smecalculus/bezmen/configuration/MessagingProtocolMode.java index bd7ea7c4..81021b0c 100644 --- a/libs/messaging/src/main/java/smecalculus/bezmen/interior/configuration/MessagingProtocolMode.java +++ b/libs/messaging/src/main/java/smecalculus/bezmen/configuration/MessagingProtocolMode.java @@ -1,4 +1,4 @@ -package smecalculus.bezmen.interior.configuration; +package smecalculus.bezmen.configuration; public enum MessagingProtocolMode { HTTP, diff --git a/libs/messaging/src/main/java/smecalculus/bezmen/interior/configuration/MessagingProtocolProps.java b/libs/messaging/src/main/java/smecalculus/bezmen/configuration/MessagingProtocolProps.java similarity index 76% rename from libs/messaging/src/main/java/smecalculus/bezmen/interior/configuration/MessagingProtocolProps.java rename to libs/messaging/src/main/java/smecalculus/bezmen/configuration/MessagingProtocolProps.java index d99a89e9..7df3ce65 100644 --- a/libs/messaging/src/main/java/smecalculus/bezmen/interior/configuration/MessagingProtocolProps.java +++ b/libs/messaging/src/main/java/smecalculus/bezmen/configuration/MessagingProtocolProps.java @@ -1,4 +1,4 @@ -package smecalculus.bezmen.interior.configuration; +package smecalculus.bezmen.configuration; import java.util.Set; import lombok.Builder; diff --git a/libs/messaging/src/main/java/smecalculus/bezmen/interior/configuration/MessagingProtocolPropsCfg.java b/libs/messaging/src/main/java/smecalculus/bezmen/configuration/MessagingProtocolPropsCfg.java similarity index 71% rename from libs/messaging/src/main/java/smecalculus/bezmen/interior/configuration/MessagingProtocolPropsCfg.java rename to libs/messaging/src/main/java/smecalculus/bezmen/configuration/MessagingProtocolPropsCfg.java index b8721650..522501b3 100644 --- a/libs/messaging/src/main/java/smecalculus/bezmen/interior/configuration/MessagingProtocolPropsCfg.java +++ b/libs/messaging/src/main/java/smecalculus/bezmen/configuration/MessagingProtocolPropsCfg.java @@ -1,10 +1,10 @@ -package smecalculus.bezmen.interior.configuration; +package smecalculus.bezmen.configuration; import jakarta.validation.constraints.NotNull; import jakarta.validation.constraints.Size; import java.util.Set; import lombok.Data; -import smecalculus.bezmen.interior.validation.ValueOfEnum; +import smecalculus.bezmen.validation.ValueOfEnum; @Data public class MessagingProtocolPropsCfg { diff --git a/libs/messaging/src/main/java/smecalculus/bezmen/interior/configuration/MessagingProtocolPropsEg.java b/libs/messaging/src/main/java/smecalculus/bezmen/configuration/MessagingProtocolPropsEg.java similarity index 67% rename from libs/messaging/src/main/java/smecalculus/bezmen/interior/configuration/MessagingProtocolPropsEg.java rename to libs/messaging/src/main/java/smecalculus/bezmen/configuration/MessagingProtocolPropsEg.java index f120e02f..13829818 100644 --- a/libs/messaging/src/main/java/smecalculus/bezmen/interior/configuration/MessagingProtocolPropsEg.java +++ b/libs/messaging/src/main/java/smecalculus/bezmen/configuration/MessagingProtocolPropsEg.java @@ -1,6 +1,6 @@ -package smecalculus.bezmen.interior.configuration; +package smecalculus.bezmen.configuration; -import static smecalculus.bezmen.interior.configuration.MessagingProtocolMode.HTTP; +import static smecalculus.bezmen.configuration.MessagingProtocolMode.HTTP; import java.util.Set; diff --git a/libs/messaging/src/main/java/smecalculus/bezmen/interior/construction/ConditionalOnMessageMappingModes.java b/libs/messaging/src/main/java/smecalculus/bezmen/construction/ConditionalOnMessageMappingModes.java similarity index 78% rename from libs/messaging/src/main/java/smecalculus/bezmen/interior/construction/ConditionalOnMessageMappingModes.java rename to libs/messaging/src/main/java/smecalculus/bezmen/construction/ConditionalOnMessageMappingModes.java index abb8dede..64cea4dc 100644 --- a/libs/messaging/src/main/java/smecalculus/bezmen/interior/construction/ConditionalOnMessageMappingModes.java +++ b/libs/messaging/src/main/java/smecalculus/bezmen/construction/ConditionalOnMessageMappingModes.java @@ -1,11 +1,11 @@ -package smecalculus.bezmen.interior.construction; +package smecalculus.bezmen.construction; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; import org.springframework.context.annotation.Conditional; -import smecalculus.bezmen.interior.configuration.MessageMappingMode; +import smecalculus.bezmen.configuration.MessageMappingMode; @Target({ElementType.TYPE, ElementType.METHOD}) @Retention(RetentionPolicy.RUNTIME) diff --git a/libs/messaging/src/main/java/smecalculus/bezmen/interior/construction/ConditionalOnMessagingProtocolModes.java b/libs/messaging/src/main/java/smecalculus/bezmen/construction/ConditionalOnMessagingProtocolModes.java similarity index 78% rename from libs/messaging/src/main/java/smecalculus/bezmen/interior/construction/ConditionalOnMessagingProtocolModes.java rename to libs/messaging/src/main/java/smecalculus/bezmen/construction/ConditionalOnMessagingProtocolModes.java index 40c1a98e..df59ac98 100644 --- a/libs/messaging/src/main/java/smecalculus/bezmen/interior/construction/ConditionalOnMessagingProtocolModes.java +++ b/libs/messaging/src/main/java/smecalculus/bezmen/construction/ConditionalOnMessagingProtocolModes.java @@ -1,11 +1,11 @@ -package smecalculus.bezmen.interior.construction; +package smecalculus.bezmen.construction; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; import org.springframework.context.annotation.Conditional; -import smecalculus.bezmen.interior.configuration.MessagingProtocolMode; +import smecalculus.bezmen.configuration.MessagingProtocolMode; @Target({ElementType.TYPE, ElementType.METHOD}) @Retention(RetentionPolicy.RUNTIME) diff --git a/libs/messaging/src/main/java/smecalculus/bezmen/construction/MappingSpringJmxManagementBeans.java b/libs/messaging/src/main/java/smecalculus/bezmen/construction/MappingSpringJmxManagementBeans.java new file mode 100644 index 00000000..d8d71019 --- /dev/null +++ b/libs/messaging/src/main/java/smecalculus/bezmen/construction/MappingSpringJmxManagementBeans.java @@ -0,0 +1,10 @@ +package smecalculus.bezmen.construction; + +import org.springframework.context.annotation.Configuration; +import smecalculus.bezmen.configuration.MessageMappingMode; +import smecalculus.bezmen.configuration.MessagingProtocolMode; + +@ConditionalOnMessagingProtocolModes(MessagingProtocolMode.JMX) +@ConditionalOnMessageMappingModes(MessageMappingMode.SPRING_MANAGEMENT) +@Configuration(proxyBeanMethods = false) +public class MappingSpringJmxManagementBeans {} diff --git a/libs/messaging/src/main/java/smecalculus/bezmen/interior/construction/MappingSpringWebManagementBeans.java b/libs/messaging/src/main/java/smecalculus/bezmen/construction/MappingSpringWebManagementBeans.java similarity index 74% rename from libs/messaging/src/main/java/smecalculus/bezmen/interior/construction/MappingSpringWebManagementBeans.java rename to libs/messaging/src/main/java/smecalculus/bezmen/construction/MappingSpringWebManagementBeans.java index ceb19839..87165215 100644 --- a/libs/messaging/src/main/java/smecalculus/bezmen/interior/construction/MappingSpringWebManagementBeans.java +++ b/libs/messaging/src/main/java/smecalculus/bezmen/construction/MappingSpringWebManagementBeans.java @@ -1,7 +1,4 @@ -package smecalculus.bezmen.interior.construction; - -import static smecalculus.bezmen.interior.configuration.MessageMappingMode.SPRING_MANAGEMENT; -import static smecalculus.bezmen.interior.configuration.MessagingProtocolMode.HTTP; +package smecalculus.bezmen.construction; import org.springframework.boot.actuate.autoconfigure.endpoint.EndpointAutoConfiguration; import org.springframework.boot.actuate.autoconfigure.endpoint.web.WebEndpointAutoConfiguration; @@ -10,9 +7,11 @@ import org.springframework.boot.actuate.autoconfigure.web.servlet.ServletManagementContextAutoConfiguration; import org.springframework.boot.autoconfigure.ImportAutoConfiguration; import org.springframework.context.annotation.Configuration; +import smecalculus.bezmen.configuration.MessageMappingMode; +import smecalculus.bezmen.configuration.MessagingProtocolMode; -@ConditionalOnMessagingProtocolModes(HTTP) -@ConditionalOnMessageMappingModes(SPRING_MANAGEMENT) +@ConditionalOnMessagingProtocolModes(MessagingProtocolMode.HTTP) +@ConditionalOnMessageMappingModes(MessageMappingMode.SPRING_MANAGEMENT) @ImportAutoConfiguration({ ManagementContextAutoConfiguration.class, ServletManagementContextAutoConfiguration.class, diff --git a/libs/messaging/src/main/java/smecalculus/bezmen/interior/construction/MappingSpringWebMvcBeans.java b/libs/messaging/src/main/java/smecalculus/bezmen/construction/MappingSpringWebMvcBeans.java similarity index 65% rename from libs/messaging/src/main/java/smecalculus/bezmen/interior/construction/MappingSpringWebMvcBeans.java rename to libs/messaging/src/main/java/smecalculus/bezmen/construction/MappingSpringWebMvcBeans.java index 8781a0df..10ebf9b7 100644 --- a/libs/messaging/src/main/java/smecalculus/bezmen/interior/construction/MappingSpringWebMvcBeans.java +++ b/libs/messaging/src/main/java/smecalculus/bezmen/construction/MappingSpringWebMvcBeans.java @@ -1,9 +1,9 @@ -package smecalculus.bezmen.interior.construction; +package smecalculus.bezmen.construction; import org.springframework.context.annotation.Configuration; import org.springframework.web.servlet.config.annotation.EnableWebMvc; -import smecalculus.bezmen.interior.configuration.MessageMappingMode; -import smecalculus.bezmen.interior.configuration.MessagingProtocolMode; +import smecalculus.bezmen.configuration.MessageMappingMode; +import smecalculus.bezmen.configuration.MessagingProtocolMode; @ConditionalOnMessagingProtocolModes(MessagingProtocolMode.HTTP) @ConditionalOnMessageMappingModes(MessageMappingMode.SPRING_MVC) diff --git a/libs/messaging/src/main/java/smecalculus/bezmen/interior/construction/MessageMappingModeCondition.java b/libs/messaging/src/main/java/smecalculus/bezmen/construction/MessageMappingModeCondition.java similarity index 86% rename from libs/messaging/src/main/java/smecalculus/bezmen/interior/construction/MessageMappingModeCondition.java rename to libs/messaging/src/main/java/smecalculus/bezmen/construction/MessageMappingModeCondition.java index 351f2735..0722e131 100644 --- a/libs/messaging/src/main/java/smecalculus/bezmen/interior/construction/MessageMappingModeCondition.java +++ b/libs/messaging/src/main/java/smecalculus/bezmen/construction/MessageMappingModeCondition.java @@ -1,4 +1,4 @@ -package smecalculus.bezmen.interior.construction; +package smecalculus.bezmen.construction; import static org.springframework.context.annotation.ConfigurationCondition.ConfigurationPhase.REGISTER_BEAN; @@ -8,8 +8,8 @@ import org.springframework.context.annotation.ConditionContext; import org.springframework.context.annotation.ConfigurationCondition; import org.springframework.core.type.AnnotatedTypeMetadata; -import smecalculus.bezmen.interior.configuration.MessageMappingMode; -import smecalculus.bezmen.interior.configuration.MessagingProps; +import smecalculus.bezmen.configuration.MessageMappingMode; +import smecalculus.bezmen.configuration.MessagingProps; class MessageMappingModeCondition implements ConfigurationCondition { diff --git a/libs/messaging/src/main/java/smecalculus/bezmen/interior/construction/MessagingBeans.java b/libs/messaging/src/main/java/smecalculus/bezmen/construction/MessagingBeans.java similarity index 89% rename from libs/messaging/src/main/java/smecalculus/bezmen/interior/construction/MessagingBeans.java rename to libs/messaging/src/main/java/smecalculus/bezmen/construction/MessagingBeans.java index a47647ef..60865bad 100644 --- a/libs/messaging/src/main/java/smecalculus/bezmen/interior/construction/MessagingBeans.java +++ b/libs/messaging/src/main/java/smecalculus/bezmen/construction/MessagingBeans.java @@ -1,4 +1,4 @@ -package smecalculus.bezmen.interior.construction; +package smecalculus.bezmen.construction; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Import; diff --git a/libs/messaging/src/main/java/smecalculus/bezmen/interior/construction/MessagingConfigBeans.java b/libs/messaging/src/main/java/smecalculus/bezmen/construction/MessagingConfigBeans.java similarity index 66% rename from libs/messaging/src/main/java/smecalculus/bezmen/interior/construction/MessagingConfigBeans.java rename to libs/messaging/src/main/java/smecalculus/bezmen/construction/MessagingConfigBeans.java index da63c8b3..cd190ca5 100644 --- a/libs/messaging/src/main/java/smecalculus/bezmen/interior/construction/MessagingConfigBeans.java +++ b/libs/messaging/src/main/java/smecalculus/bezmen/construction/MessagingConfigBeans.java @@ -1,16 +1,16 @@ -package smecalculus.bezmen.interior.construction; +package smecalculus.bezmen.construction; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.PropertySource; -import smecalculus.bezmen.interior.configuration.ConfigKeeper; -import smecalculus.bezmen.interior.configuration.MessagingCfgMapper; -import smecalculus.bezmen.interior.configuration.MessagingCfgMapperImpl; -import smecalculus.bezmen.interior.configuration.MessagingProps; -import smecalculus.bezmen.interior.configuration.MessagingPropsCfg; -import smecalculus.bezmen.interior.validation.EdgeValidator; +import smecalculus.bezmen.configuration.ConfigKeeper; +import smecalculus.bezmen.configuration.MessagingCfgMapper; +import smecalculus.bezmen.configuration.MessagingCfgMapperImpl; +import smecalculus.bezmen.configuration.MessagingProps; +import smecalculus.bezmen.configuration.MessagingPropsCfg; +import smecalculus.bezmen.validation.EdgeValidator; @PropertySource("classpath:messaging.properties") @Configuration(proxyBeanMethods = false) diff --git a/libs/messaging/src/main/java/smecalculus/bezmen/interior/construction/MessagingProtocolModeCondition.java b/libs/messaging/src/main/java/smecalculus/bezmen/construction/MessagingProtocolModeCondition.java similarity index 86% rename from libs/messaging/src/main/java/smecalculus/bezmen/interior/construction/MessagingProtocolModeCondition.java rename to libs/messaging/src/main/java/smecalculus/bezmen/construction/MessagingProtocolModeCondition.java index 6b1b2302..29192529 100644 --- a/libs/messaging/src/main/java/smecalculus/bezmen/interior/construction/MessagingProtocolModeCondition.java +++ b/libs/messaging/src/main/java/smecalculus/bezmen/construction/MessagingProtocolModeCondition.java @@ -1,4 +1,4 @@ -package smecalculus.bezmen.interior.construction; +package smecalculus.bezmen.construction; import static org.springframework.context.annotation.ConfigurationCondition.ConfigurationPhase.REGISTER_BEAN; @@ -8,8 +8,8 @@ import org.springframework.context.annotation.ConditionContext; import org.springframework.context.annotation.ConfigurationCondition; import org.springframework.core.type.AnnotatedTypeMetadata; -import smecalculus.bezmen.interior.configuration.MessagingProps; -import smecalculus.bezmen.interior.configuration.MessagingProtocolMode; +import smecalculus.bezmen.configuration.MessagingProps; +import smecalculus.bezmen.configuration.MessagingProtocolMode; class MessagingProtocolModeCondition implements ConfigurationCondition { diff --git a/libs/messaging/src/main/java/smecalculus/bezmen/interior/construction/ProtocolHttpBeans.java b/libs/messaging/src/main/java/smecalculus/bezmen/construction/ProtocolHttpBeans.java similarity index 82% rename from libs/messaging/src/main/java/smecalculus/bezmen/interior/construction/ProtocolHttpBeans.java rename to libs/messaging/src/main/java/smecalculus/bezmen/construction/ProtocolHttpBeans.java index ae51efd0..e0c3a3f2 100644 --- a/libs/messaging/src/main/java/smecalculus/bezmen/interior/construction/ProtocolHttpBeans.java +++ b/libs/messaging/src/main/java/smecalculus/bezmen/construction/ProtocolHttpBeans.java @@ -1,10 +1,10 @@ -package smecalculus.bezmen.interior.construction; +package smecalculus.bezmen.construction; import org.springframework.boot.autoconfigure.ImportAutoConfiguration; import org.springframework.boot.autoconfigure.web.servlet.DispatcherServletAutoConfiguration; import org.springframework.boot.autoconfigure.web.servlet.ServletWebServerFactoryAutoConfiguration; import org.springframework.context.annotation.Configuration; -import smecalculus.bezmen.interior.configuration.MessagingProtocolMode; +import smecalculus.bezmen.configuration.MessagingProtocolMode; @ConditionalOnMessagingProtocolModes(MessagingProtocolMode.HTTP) @ImportAutoConfiguration({ServletWebServerFactoryAutoConfiguration.class, DispatcherServletAutoConfiguration.class}) diff --git a/libs/messaging/src/main/java/smecalculus/bezmen/interior/construction/ProtocolJmxBeans.java b/libs/messaging/src/main/java/smecalculus/bezmen/construction/ProtocolJmxBeans.java similarity index 65% rename from libs/messaging/src/main/java/smecalculus/bezmen/interior/construction/ProtocolJmxBeans.java rename to libs/messaging/src/main/java/smecalculus/bezmen/construction/ProtocolJmxBeans.java index c4cf2de8..dc21c4dd 100644 --- a/libs/messaging/src/main/java/smecalculus/bezmen/interior/construction/ProtocolJmxBeans.java +++ b/libs/messaging/src/main/java/smecalculus/bezmen/construction/ProtocolJmxBeans.java @@ -1,12 +1,11 @@ -package smecalculus.bezmen.interior.construction; - -import static smecalculus.bezmen.interior.configuration.MessagingProtocolMode.JMX; +package smecalculus.bezmen.construction; import org.springframework.boot.autoconfigure.ImportAutoConfiguration; import org.springframework.boot.autoconfigure.jmx.JmxAutoConfiguration; import org.springframework.context.annotation.Configuration; +import smecalculus.bezmen.configuration.MessagingProtocolMode; -@ConditionalOnMessagingProtocolModes(JMX) +@ConditionalOnMessagingProtocolModes(MessagingProtocolMode.JMX) @ImportAutoConfiguration({JmxAutoConfiguration.class}) @Configuration(proxyBeanMethods = false) public class ProtocolJmxBeans {} diff --git a/libs/messaging/src/main/java/smecalculus/bezmen/interior/construction/MappingSpringJmxManagementBeans.java b/libs/messaging/src/main/java/smecalculus/bezmen/interior/construction/MappingSpringJmxManagementBeans.java deleted file mode 100644 index 5d982015..00000000 --- a/libs/messaging/src/main/java/smecalculus/bezmen/interior/construction/MappingSpringJmxManagementBeans.java +++ /dev/null @@ -1,11 +0,0 @@ -package smecalculus.bezmen.interior.construction; - -import static smecalculus.bezmen.interior.configuration.MessageMappingMode.SPRING_MANAGEMENT; -import static smecalculus.bezmen.interior.configuration.MessagingProtocolMode.JMX; - -import org.springframework.context.annotation.Configuration; - -@ConditionalOnMessagingProtocolModes(JMX) -@ConditionalOnMessageMappingModes(SPRING_MANAGEMENT) -@Configuration(proxyBeanMethods = false) -public class MappingSpringJmxManagementBeans {} diff --git a/libs/messaging/src/main/java/smecalculus/bezmen/messaging/SepulkaMsgMapper.java b/libs/messaging/src/main/java/smecalculus/bezmen/messaging/SepulkaMsgMapper.java new file mode 100644 index 00000000..0299c734 --- /dev/null +++ b/libs/messaging/src/main/java/smecalculus/bezmen/messaging/SepulkaMsgMapper.java @@ -0,0 +1,14 @@ +package smecalculus.bezmen.messaging; + +import org.mapstruct.Mapper; +import smecalculus.bezmen.core.SepulkaNewRequest; +import smecalculus.bezmen.core.SepulkaNewResponse; + +@Mapper +public interface SepulkaMsgMapper { + SepulkaNewRequest toDomain(SepulkaNewRequestMsg requestMsg); + + SepulkaNewResponseMsg toMsg(SepulkaNewResponse response); + + SepulkaNewResponse toDomain(SepulkaNewResponseMsg responseMsg); +} diff --git a/libs/messaging/src/test/java/smecalculus/bezmen/interior/construction/MessagingConfigBeansIT.java b/libs/messaging/src/test/java/smecalculus/bezmen/construction/MessagingConfigBeansIT.java similarity index 79% rename from libs/messaging/src/test/java/smecalculus/bezmen/interior/construction/MessagingConfigBeansIT.java rename to libs/messaging/src/test/java/smecalculus/bezmen/construction/MessagingConfigBeansIT.java index b771b298..19dbbb29 100644 --- a/libs/messaging/src/test/java/smecalculus/bezmen/interior/construction/MessagingConfigBeansIT.java +++ b/libs/messaging/src/test/java/smecalculus/bezmen/construction/MessagingConfigBeansIT.java @@ -1,14 +1,14 @@ -package smecalculus.bezmen.interior.construction; +package smecalculus.bezmen.construction; import static org.assertj.core.api.Assertions.assertThat; -import static smecalculus.bezmen.interior.configuration.MessagingPropsEg.Builders.messagingProps; +import static smecalculus.bezmen.configuration.MessagingPropsEg.Builders.messagingProps; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit.jupiter.SpringExtension; -import smecalculus.bezmen.interior.configuration.MessagingProps; +import smecalculus.bezmen.configuration.MessagingProps; @ExtendWith(SpringExtension.class) @ContextConfiguration(classes = {MessagingConfigBeans.class, ConfigBeans.class, ValidationBeans.class}) diff --git a/libs/messaging/src/test/java/smecalculus/bezmen/interior/construction/MessagingConfigBeansLightbendConfigIT.java b/libs/messaging/src/test/java/smecalculus/bezmen/construction/MessagingConfigBeansLightbendConfigIT.java similarity index 81% rename from libs/messaging/src/test/java/smecalculus/bezmen/interior/construction/MessagingConfigBeansLightbendConfigIT.java rename to libs/messaging/src/test/java/smecalculus/bezmen/construction/MessagingConfigBeansLightbendConfigIT.java index 24ffe9d4..5e8b69f1 100644 --- a/libs/messaging/src/test/java/smecalculus/bezmen/interior/construction/MessagingConfigBeansLightbendConfigIT.java +++ b/libs/messaging/src/test/java/smecalculus/bezmen/construction/MessagingConfigBeansLightbendConfigIT.java @@ -1,4 +1,4 @@ -package smecalculus.bezmen.interior.construction; +package smecalculus.bezmen.construction; import org.springframework.test.context.TestPropertySource; diff --git a/libs/messaging/src/test/java/smecalculus/bezmen/interior/construction/MessagingConfigBeansSpringConfigIT.java b/libs/messaging/src/test/java/smecalculus/bezmen/construction/MessagingConfigBeansSpringConfigIT.java similarity index 81% rename from libs/messaging/src/test/java/smecalculus/bezmen/interior/construction/MessagingConfigBeansSpringConfigIT.java rename to libs/messaging/src/test/java/smecalculus/bezmen/construction/MessagingConfigBeansSpringConfigIT.java index 36b53175..668b3e3f 100644 --- a/libs/messaging/src/test/java/smecalculus/bezmen/interior/construction/MessagingConfigBeansSpringConfigIT.java +++ b/libs/messaging/src/test/java/smecalculus/bezmen/construction/MessagingConfigBeansSpringConfigIT.java @@ -1,4 +1,4 @@ -package smecalculus.bezmen.interior.construction; +package smecalculus.bezmen.construction; import org.springframework.test.context.TestPropertySource; diff --git a/libs/pom.xml b/libs/pom.xml index 5f8686ed..d30dfa14 100644 --- a/libs/pom.xml +++ b/libs/pom.xml @@ -11,8 +11,10 @@ ${revision} + abstraction-client abstraction essentials + messaging-client messaging storage testing @@ -57,14 +59,13 @@ ${project.groupId} - abstraction + abstraction-client ${project.version} ${project.groupId} abstraction ${project.version} - client ${project.groupId} @@ -73,14 +74,13 @@ ${project.groupId} - messaging + messaging-client ${project.version} ${project.groupId} messaging ${project.version} - client ${project.groupId} diff --git a/libs/storage/src/main/java/smecalculus/bezmen/interior/configuration/H2Props.java b/libs/storage/src/main/java/smecalculus/bezmen/configuration/H2Props.java similarity index 79% rename from libs/storage/src/main/java/smecalculus/bezmen/interior/configuration/H2Props.java rename to libs/storage/src/main/java/smecalculus/bezmen/configuration/H2Props.java index f5febf82..a16d6945 100644 --- a/libs/storage/src/main/java/smecalculus/bezmen/interior/configuration/H2Props.java +++ b/libs/storage/src/main/java/smecalculus/bezmen/configuration/H2Props.java @@ -1,4 +1,4 @@ -package smecalculus.bezmen.interior.configuration; +package smecalculus.bezmen.configuration; import lombok.Builder; import lombok.NonNull; diff --git a/libs/storage/src/main/java/smecalculus/bezmen/interior/configuration/H2PropsCfg.java b/libs/storage/src/main/java/smecalculus/bezmen/configuration/H2PropsCfg.java similarity index 80% rename from libs/storage/src/main/java/smecalculus/bezmen/interior/configuration/H2PropsCfg.java rename to libs/storage/src/main/java/smecalculus/bezmen/configuration/H2PropsCfg.java index 3c5226c6..f7eaf189 100644 --- a/libs/storage/src/main/java/smecalculus/bezmen/interior/configuration/H2PropsCfg.java +++ b/libs/storage/src/main/java/smecalculus/bezmen/configuration/H2PropsCfg.java @@ -1,4 +1,4 @@ -package smecalculus.bezmen.interior.configuration; +package smecalculus.bezmen.configuration; import jakarta.validation.constraints.NotBlank; import lombok.Data; diff --git a/libs/storage/src/main/java/smecalculus/bezmen/interior/configuration/PostgresProps.java b/libs/storage/src/main/java/smecalculus/bezmen/configuration/PostgresProps.java similarity index 80% rename from libs/storage/src/main/java/smecalculus/bezmen/interior/configuration/PostgresProps.java rename to libs/storage/src/main/java/smecalculus/bezmen/configuration/PostgresProps.java index c2c734c6..b80f1901 100644 --- a/libs/storage/src/main/java/smecalculus/bezmen/interior/configuration/PostgresProps.java +++ b/libs/storage/src/main/java/smecalculus/bezmen/configuration/PostgresProps.java @@ -1,4 +1,4 @@ -package smecalculus.bezmen.interior.configuration; +package smecalculus.bezmen.configuration; import lombok.Builder; import lombok.NonNull; diff --git a/libs/storage/src/main/java/smecalculus/bezmen/interior/configuration/PostgresPropsCfg.java b/libs/storage/src/main/java/smecalculus/bezmen/configuration/PostgresPropsCfg.java similarity index 83% rename from libs/storage/src/main/java/smecalculus/bezmen/interior/configuration/PostgresPropsCfg.java rename to libs/storage/src/main/java/smecalculus/bezmen/configuration/PostgresPropsCfg.java index 880d99ea..d0839893 100644 --- a/libs/storage/src/main/java/smecalculus/bezmen/interior/configuration/PostgresPropsCfg.java +++ b/libs/storage/src/main/java/smecalculus/bezmen/configuration/PostgresPropsCfg.java @@ -1,4 +1,4 @@ -package smecalculus.bezmen.interior.configuration; +package smecalculus.bezmen.configuration; import jakarta.validation.constraints.NotBlank; import lombok.Data; diff --git a/libs/storage/src/main/java/smecalculus/bezmen/interior/configuration/StateMappingMode.java b/libs/storage/src/main/java/smecalculus/bezmen/configuration/StateMappingMode.java similarity index 55% rename from libs/storage/src/main/java/smecalculus/bezmen/interior/configuration/StateMappingMode.java rename to libs/storage/src/main/java/smecalculus/bezmen/configuration/StateMappingMode.java index afbd1bd2..40335f1a 100644 --- a/libs/storage/src/main/java/smecalculus/bezmen/interior/configuration/StateMappingMode.java +++ b/libs/storage/src/main/java/smecalculus/bezmen/configuration/StateMappingMode.java @@ -1,4 +1,4 @@ -package smecalculus.bezmen.interior.configuration; +package smecalculus.bezmen.configuration; public enum StateMappingMode { SPRING_DATA, diff --git a/libs/storage/src/main/java/smecalculus/bezmen/interior/configuration/StateMappingProps.java b/libs/storage/src/main/java/smecalculus/bezmen/configuration/StateMappingProps.java similarity index 66% rename from libs/storage/src/main/java/smecalculus/bezmen/interior/configuration/StateMappingProps.java rename to libs/storage/src/main/java/smecalculus/bezmen/configuration/StateMappingProps.java index 2034f72b..f8010d0c 100644 --- a/libs/storage/src/main/java/smecalculus/bezmen/interior/configuration/StateMappingProps.java +++ b/libs/storage/src/main/java/smecalculus/bezmen/configuration/StateMappingProps.java @@ -1,4 +1,4 @@ -package smecalculus.bezmen.interior.configuration; +package smecalculus.bezmen.configuration; import lombok.Builder; diff --git a/libs/storage/src/main/java/smecalculus/bezmen/interior/configuration/StateMappingPropsCfg.java b/libs/storage/src/main/java/smecalculus/bezmen/configuration/StateMappingPropsCfg.java similarity index 54% rename from libs/storage/src/main/java/smecalculus/bezmen/interior/configuration/StateMappingPropsCfg.java rename to libs/storage/src/main/java/smecalculus/bezmen/configuration/StateMappingPropsCfg.java index 692aa719..dfd890f0 100644 --- a/libs/storage/src/main/java/smecalculus/bezmen/interior/configuration/StateMappingPropsCfg.java +++ b/libs/storage/src/main/java/smecalculus/bezmen/configuration/StateMappingPropsCfg.java @@ -1,7 +1,7 @@ -package smecalculus.bezmen.interior.configuration; +package smecalculus.bezmen.configuration; import lombok.Data; -import smecalculus.bezmen.interior.validation.ValueOfEnum; +import smecalculus.bezmen.validation.ValueOfEnum; @Data public class StateMappingPropsCfg { diff --git a/libs/storage/src/main/java/smecalculus/bezmen/interior/configuration/StateMappingPropsEg.java b/libs/storage/src/main/java/smecalculus/bezmen/configuration/StateMappingPropsEg.java similarity index 78% rename from libs/storage/src/main/java/smecalculus/bezmen/interior/configuration/StateMappingPropsEg.java rename to libs/storage/src/main/java/smecalculus/bezmen/configuration/StateMappingPropsEg.java index db6ce4ce..c7bb4c25 100644 --- a/libs/storage/src/main/java/smecalculus/bezmen/interior/configuration/StateMappingPropsEg.java +++ b/libs/storage/src/main/java/smecalculus/bezmen/configuration/StateMappingPropsEg.java @@ -1,6 +1,6 @@ -package smecalculus.bezmen.interior.configuration; +package smecalculus.bezmen.configuration; -import static smecalculus.bezmen.interior.configuration.StateMappingMode.SPRING_DATA; +import static smecalculus.bezmen.configuration.StateMappingMode.SPRING_DATA; public class StateMappingPropsEg { public static class Pojos { diff --git a/libs/storage/src/main/java/smecalculus/bezmen/interior/configuration/StorageCfgMapper.java b/libs/storage/src/main/java/smecalculus/bezmen/configuration/StorageCfgMapper.java similarity index 94% rename from libs/storage/src/main/java/smecalculus/bezmen/interior/configuration/StorageCfgMapper.java rename to libs/storage/src/main/java/smecalculus/bezmen/configuration/StorageCfgMapper.java index a1a5937b..02ca7a8b 100644 --- a/libs/storage/src/main/java/smecalculus/bezmen/interior/configuration/StorageCfgMapper.java +++ b/libs/storage/src/main/java/smecalculus/bezmen/configuration/StorageCfgMapper.java @@ -1,4 +1,4 @@ -package smecalculus.bezmen.interior.configuration; +package smecalculus.bezmen.configuration; import org.mapstruct.Mapper; import org.mapstruct.Mapping; diff --git a/libs/storage/src/main/java/smecalculus/bezmen/interior/configuration/StorageProps.java b/libs/storage/src/main/java/smecalculus/bezmen/configuration/StorageProps.java similarity index 77% rename from libs/storage/src/main/java/smecalculus/bezmen/interior/configuration/StorageProps.java rename to libs/storage/src/main/java/smecalculus/bezmen/configuration/StorageProps.java index 09abb30e..d5b13b05 100644 --- a/libs/storage/src/main/java/smecalculus/bezmen/interior/configuration/StorageProps.java +++ b/libs/storage/src/main/java/smecalculus/bezmen/configuration/StorageProps.java @@ -1,4 +1,4 @@ -package smecalculus.bezmen.interior.configuration; +package smecalculus.bezmen.configuration; import lombok.Builder; import lombok.NonNull; diff --git a/libs/storage/src/main/java/smecalculus/bezmen/interior/configuration/StoragePropsCfg.java b/libs/storage/src/main/java/smecalculus/bezmen/configuration/StoragePropsCfg.java similarity index 80% rename from libs/storage/src/main/java/smecalculus/bezmen/interior/configuration/StoragePropsCfg.java rename to libs/storage/src/main/java/smecalculus/bezmen/configuration/StoragePropsCfg.java index 6fdbd0f7..1e55f192 100644 --- a/libs/storage/src/main/java/smecalculus/bezmen/interior/configuration/StoragePropsCfg.java +++ b/libs/storage/src/main/java/smecalculus/bezmen/configuration/StoragePropsCfg.java @@ -1,4 +1,4 @@ -package smecalculus.bezmen.interior.configuration; +package smecalculus.bezmen.configuration; import jakarta.validation.constraints.NotNull; import lombok.Data; diff --git a/libs/storage/src/main/java/smecalculus/bezmen/interior/configuration/StoragePropsEg.java b/libs/storage/src/main/java/smecalculus/bezmen/configuration/StoragePropsEg.java similarity index 58% rename from libs/storage/src/main/java/smecalculus/bezmen/interior/configuration/StoragePropsEg.java rename to libs/storage/src/main/java/smecalculus/bezmen/configuration/StoragePropsEg.java index 22564cc7..9f9fe983 100644 --- a/libs/storage/src/main/java/smecalculus/bezmen/interior/configuration/StoragePropsEg.java +++ b/libs/storage/src/main/java/smecalculus/bezmen/configuration/StoragePropsEg.java @@ -1,9 +1,9 @@ -package smecalculus.bezmen.interior.configuration; +package smecalculus.bezmen.configuration; -import static smecalculus.bezmen.interior.configuration.StateMappingPropsEg.Builders.stateMappingProps; -import static smecalculus.bezmen.interior.configuration.StateMappingPropsEg.Pojos.stateMappingPropsCfg; -import static smecalculus.bezmen.interior.configuration.StorageProtocolPropsEg.Builders.storageProtocolProps; -import static smecalculus.bezmen.interior.configuration.StorageProtocolPropsEg.Pojos.storageProtocolPropsCfg; +import static smecalculus.bezmen.configuration.StateMappingPropsEg.Builders.stateMappingProps; +import static smecalculus.bezmen.configuration.StateMappingPropsEg.Pojos.stateMappingPropsCfg; +import static smecalculus.bezmen.configuration.StorageProtocolPropsEg.Builders.storageProtocolProps; +import static smecalculus.bezmen.configuration.StorageProtocolPropsEg.Pojos.storageProtocolPropsCfg; public class StoragePropsEg { public static class Pojos { diff --git a/libs/storage/src/main/java/smecalculus/bezmen/interior/configuration/StorageProtocolMode.java b/libs/storage/src/main/java/smecalculus/bezmen/configuration/StorageProtocolMode.java similarity index 53% rename from libs/storage/src/main/java/smecalculus/bezmen/interior/configuration/StorageProtocolMode.java rename to libs/storage/src/main/java/smecalculus/bezmen/configuration/StorageProtocolMode.java index ee79299d..6c0eb350 100644 --- a/libs/storage/src/main/java/smecalculus/bezmen/interior/configuration/StorageProtocolMode.java +++ b/libs/storage/src/main/java/smecalculus/bezmen/configuration/StorageProtocolMode.java @@ -1,4 +1,4 @@ -package smecalculus.bezmen.interior.configuration; +package smecalculus.bezmen.configuration; public enum StorageProtocolMode { H2, diff --git a/libs/storage/src/main/java/smecalculus/bezmen/interior/configuration/StorageProtocolProps.java b/libs/storage/src/main/java/smecalculus/bezmen/configuration/StorageProtocolProps.java similarity index 79% rename from libs/storage/src/main/java/smecalculus/bezmen/interior/configuration/StorageProtocolProps.java rename to libs/storage/src/main/java/smecalculus/bezmen/configuration/StorageProtocolProps.java index 2b0f4b09..f4b6c40b 100644 --- a/libs/storage/src/main/java/smecalculus/bezmen/interior/configuration/StorageProtocolProps.java +++ b/libs/storage/src/main/java/smecalculus/bezmen/configuration/StorageProtocolProps.java @@ -1,4 +1,4 @@ -package smecalculus.bezmen.interior.configuration; +package smecalculus.bezmen.configuration; import lombok.Builder; import lombok.NonNull; diff --git a/libs/storage/src/main/java/smecalculus/bezmen/interior/configuration/StorageProtocolPropsCfg.java b/libs/storage/src/main/java/smecalculus/bezmen/configuration/StorageProtocolPropsCfg.java similarity index 69% rename from libs/storage/src/main/java/smecalculus/bezmen/interior/configuration/StorageProtocolPropsCfg.java rename to libs/storage/src/main/java/smecalculus/bezmen/configuration/StorageProtocolPropsCfg.java index 045d740c..82a23b70 100644 --- a/libs/storage/src/main/java/smecalculus/bezmen/interior/configuration/StorageProtocolPropsCfg.java +++ b/libs/storage/src/main/java/smecalculus/bezmen/configuration/StorageProtocolPropsCfg.java @@ -1,8 +1,8 @@ -package smecalculus.bezmen.interior.configuration; +package smecalculus.bezmen.configuration; import com.typesafe.config.Optional; import lombok.Data; -import smecalculus.bezmen.interior.validation.ValueOfEnum; +import smecalculus.bezmen.validation.ValueOfEnum; @Data public class StorageProtocolPropsCfg { diff --git a/libs/storage/src/main/java/smecalculus/bezmen/interior/configuration/StorageProtocolPropsEg.java b/libs/storage/src/main/java/smecalculus/bezmen/configuration/StorageProtocolPropsEg.java similarity index 95% rename from libs/storage/src/main/java/smecalculus/bezmen/interior/configuration/StorageProtocolPropsEg.java rename to libs/storage/src/main/java/smecalculus/bezmen/configuration/StorageProtocolPropsEg.java index 2cc9eb5b..e4e89b39 100644 --- a/libs/storage/src/main/java/smecalculus/bezmen/interior/configuration/StorageProtocolPropsEg.java +++ b/libs/storage/src/main/java/smecalculus/bezmen/configuration/StorageProtocolPropsEg.java @@ -1,4 +1,4 @@ -package smecalculus.bezmen.interior.configuration; +package smecalculus.bezmen.configuration; public class StorageProtocolPropsEg { public static class Pojos { diff --git a/libs/storage/src/main/java/smecalculus/bezmen/interior/construction/ConditionalOnStateMappingMode.java b/libs/storage/src/main/java/smecalculus/bezmen/construction/ConditionalOnStateMappingMode.java similarity index 78% rename from libs/storage/src/main/java/smecalculus/bezmen/interior/construction/ConditionalOnStateMappingMode.java rename to libs/storage/src/main/java/smecalculus/bezmen/construction/ConditionalOnStateMappingMode.java index e5739d8c..3b1eb03c 100644 --- a/libs/storage/src/main/java/smecalculus/bezmen/interior/construction/ConditionalOnStateMappingMode.java +++ b/libs/storage/src/main/java/smecalculus/bezmen/construction/ConditionalOnStateMappingMode.java @@ -1,11 +1,11 @@ -package smecalculus.bezmen.interior.construction; +package smecalculus.bezmen.construction; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; import org.springframework.context.annotation.Conditional; -import smecalculus.bezmen.interior.configuration.StateMappingMode; +import smecalculus.bezmen.configuration.StateMappingMode; @Target({ElementType.TYPE, ElementType.METHOD}) @Retention(RetentionPolicy.RUNTIME) diff --git a/libs/storage/src/main/java/smecalculus/bezmen/interior/construction/MappingMyBatisBeans.java b/libs/storage/src/main/java/smecalculus/bezmen/construction/MappingMyBatisBeans.java similarity index 76% rename from libs/storage/src/main/java/smecalculus/bezmen/interior/construction/MappingMyBatisBeans.java rename to libs/storage/src/main/java/smecalculus/bezmen/construction/MappingMyBatisBeans.java index 597ab982..7af3d785 100644 --- a/libs/storage/src/main/java/smecalculus/bezmen/interior/construction/MappingMyBatisBeans.java +++ b/libs/storage/src/main/java/smecalculus/bezmen/construction/MappingMyBatisBeans.java @@ -1,6 +1,6 @@ -package smecalculus.bezmen.interior.construction; +package smecalculus.bezmen.construction; -import static smecalculus.bezmen.interior.configuration.StateMappingMode.MY_BATIS; +import static smecalculus.bezmen.configuration.StateMappingMode.MY_BATIS; import javax.sql.DataSource; import org.apache.ibatis.session.SqlSessionFactory; @@ -10,7 +10,7 @@ import org.springframework.context.annotation.Configuration; @ConditionalOnStateMappingMode(MY_BATIS) -@MapperScan(basePackages = "smecalculus.bezmen.interior.storage.mybatis") +@MapperScan(basePackages = "smecalculus.bezmen.storage.mybatis") @Configuration(proxyBeanMethods = false) public class MappingMyBatisBeans { diff --git a/libs/storage/src/main/java/smecalculus/bezmen/interior/construction/MappingSpringDataBeans.java b/libs/storage/src/main/java/smecalculus/bezmen/construction/MappingSpringDataBeans.java similarity index 81% rename from libs/storage/src/main/java/smecalculus/bezmen/interior/construction/MappingSpringDataBeans.java rename to libs/storage/src/main/java/smecalculus/bezmen/construction/MappingSpringDataBeans.java index 1fb4d643..d35a5637 100644 --- a/libs/storage/src/main/java/smecalculus/bezmen/interior/construction/MappingSpringDataBeans.java +++ b/libs/storage/src/main/java/smecalculus/bezmen/construction/MappingSpringDataBeans.java @@ -1,6 +1,6 @@ -package smecalculus.bezmen.interior.construction; +package smecalculus.bezmen.construction; -import static smecalculus.bezmen.interior.configuration.StateMappingMode.SPRING_DATA; +import static smecalculus.bezmen.configuration.StateMappingMode.SPRING_DATA; import javax.sql.DataSource; import org.springframework.context.annotation.Bean; @@ -13,11 +13,11 @@ import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate; import org.springframework.jdbc.datasource.DataSourceTransactionManager; import org.springframework.transaction.PlatformTransactionManager; -import smecalculus.bezmen.interior.configuration.StorageProps; -import smecalculus.bezmen.interior.configuration.StorageProtocolProps; +import smecalculus.bezmen.configuration.StorageProps; +import smecalculus.bezmen.configuration.StorageProtocolProps; @ConditionalOnStateMappingMode(SPRING_DATA) -@EnableJdbcRepositories("smecalculus.bezmen.interior.storage.springdata") +@EnableJdbcRepositories("smecalculus.bezmen.storage.springdata") @Configuration(proxyBeanMethods = false) public class MappingSpringDataBeans extends AbstractJdbcConfiguration { diff --git a/libs/storage/src/main/java/smecalculus/bezmen/interior/construction/StateMappingModeCondition.java b/libs/storage/src/main/java/smecalculus/bezmen/construction/StateMappingModeCondition.java similarity index 84% rename from libs/storage/src/main/java/smecalculus/bezmen/interior/construction/StateMappingModeCondition.java rename to libs/storage/src/main/java/smecalculus/bezmen/construction/StateMappingModeCondition.java index 83863e02..ff5dd6ba 100644 --- a/libs/storage/src/main/java/smecalculus/bezmen/interior/construction/StateMappingModeCondition.java +++ b/libs/storage/src/main/java/smecalculus/bezmen/construction/StateMappingModeCondition.java @@ -1,4 +1,4 @@ -package smecalculus.bezmen.interior.construction; +package smecalculus.bezmen.construction; import static org.springframework.context.annotation.ConfigurationCondition.ConfigurationPhase.REGISTER_BEAN; @@ -6,8 +6,8 @@ import org.springframework.context.annotation.ConditionContext; import org.springframework.context.annotation.ConfigurationCondition; import org.springframework.core.type.AnnotatedTypeMetadata; -import smecalculus.bezmen.interior.configuration.StateMappingMode; -import smecalculus.bezmen.interior.configuration.StorageProps; +import smecalculus.bezmen.configuration.StateMappingMode; +import smecalculus.bezmen.configuration.StorageProps; class StateMappingModeCondition implements ConfigurationCondition { diff --git a/libs/storage/src/main/java/smecalculus/bezmen/interior/construction/StorageBeans.java b/libs/storage/src/main/java/smecalculus/bezmen/construction/StorageBeans.java similarity index 83% rename from libs/storage/src/main/java/smecalculus/bezmen/interior/construction/StorageBeans.java rename to libs/storage/src/main/java/smecalculus/bezmen/construction/StorageBeans.java index 8999f1b1..2ffa68f3 100644 --- a/libs/storage/src/main/java/smecalculus/bezmen/interior/construction/StorageBeans.java +++ b/libs/storage/src/main/java/smecalculus/bezmen/construction/StorageBeans.java @@ -1,14 +1,14 @@ -package smecalculus.bezmen.interior.construction; +package smecalculus.bezmen.construction; import javax.sql.DataSource; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Import; import org.springframework.jdbc.datasource.DriverManagerDataSource; -import smecalculus.bezmen.interior.configuration.H2Props; -import smecalculus.bezmen.interior.configuration.PostgresProps; -import smecalculus.bezmen.interior.configuration.StorageProps; -import smecalculus.bezmen.interior.configuration.StorageProtocolProps; +import smecalculus.bezmen.configuration.H2Props; +import smecalculus.bezmen.configuration.PostgresProps; +import smecalculus.bezmen.configuration.StorageProps; +import smecalculus.bezmen.configuration.StorageProtocolProps; @Configuration(proxyBeanMethods = false) @Import({StorageConfigBeans.class, MappingMyBatisBeans.class, MappingSpringDataBeans.class}) diff --git a/libs/storage/src/main/java/smecalculus/bezmen/interior/construction/StorageConfigBeans.java b/libs/storage/src/main/java/smecalculus/bezmen/construction/StorageConfigBeans.java similarity index 66% rename from libs/storage/src/main/java/smecalculus/bezmen/interior/construction/StorageConfigBeans.java rename to libs/storage/src/main/java/smecalculus/bezmen/construction/StorageConfigBeans.java index 1ad72e94..061cf4d7 100644 --- a/libs/storage/src/main/java/smecalculus/bezmen/interior/construction/StorageConfigBeans.java +++ b/libs/storage/src/main/java/smecalculus/bezmen/construction/StorageConfigBeans.java @@ -1,16 +1,16 @@ -package smecalculus.bezmen.interior.construction; +package smecalculus.bezmen.construction; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.PropertySource; -import smecalculus.bezmen.interior.configuration.ConfigKeeper; -import smecalculus.bezmen.interior.configuration.StorageCfgMapper; -import smecalculus.bezmen.interior.configuration.StorageCfgMapperImpl; -import smecalculus.bezmen.interior.configuration.StorageProps; -import smecalculus.bezmen.interior.configuration.StoragePropsCfg; -import smecalculus.bezmen.interior.validation.EdgeValidator; +import smecalculus.bezmen.configuration.ConfigKeeper; +import smecalculus.bezmen.configuration.StorageCfgMapper; +import smecalculus.bezmen.configuration.StorageCfgMapperImpl; +import smecalculus.bezmen.configuration.StorageProps; +import smecalculus.bezmen.configuration.StoragePropsCfg; +import smecalculus.bezmen.validation.EdgeValidator; @PropertySource("classpath:storage.properties") @Configuration(proxyBeanMethods = false) diff --git a/libs/storage/src/test/java/smecalculus/bezmen/interior/construction/StorageConfigBeansIT.java b/libs/storage/src/test/java/smecalculus/bezmen/construction/StorageConfigBeansIT.java similarity index 79% rename from libs/storage/src/test/java/smecalculus/bezmen/interior/construction/StorageConfigBeansIT.java rename to libs/storage/src/test/java/smecalculus/bezmen/construction/StorageConfigBeansIT.java index 3c822da8..62de9f65 100644 --- a/libs/storage/src/test/java/smecalculus/bezmen/interior/construction/StorageConfigBeansIT.java +++ b/libs/storage/src/test/java/smecalculus/bezmen/construction/StorageConfigBeansIT.java @@ -1,14 +1,14 @@ -package smecalculus.bezmen.interior.construction; +package smecalculus.bezmen.construction; import static org.assertj.core.api.Assertions.assertThat; -import static smecalculus.bezmen.interior.configuration.StoragePropsEg.Builders.storageProps; +import static smecalculus.bezmen.configuration.StoragePropsEg.Builders.storageProps; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit.jupiter.SpringExtension; -import smecalculus.bezmen.interior.configuration.StorageProps; +import smecalculus.bezmen.configuration.StorageProps; @ExtendWith(SpringExtension.class) @ContextConfiguration(classes = {StorageConfigBeans.class, ConfigBeans.class, ValidationBeans.class}) diff --git a/libs/storage/src/test/java/smecalculus/bezmen/interior/construction/StorageConfigBeansLightbendConfigIT.java b/libs/storage/src/test/java/smecalculus/bezmen/construction/StorageConfigBeansLightbendConfigIT.java similarity index 81% rename from libs/storage/src/test/java/smecalculus/bezmen/interior/construction/StorageConfigBeansLightbendConfigIT.java rename to libs/storage/src/test/java/smecalculus/bezmen/construction/StorageConfigBeansLightbendConfigIT.java index ef7e2695..4631e191 100644 --- a/libs/storage/src/test/java/smecalculus/bezmen/interior/construction/StorageConfigBeansLightbendConfigIT.java +++ b/libs/storage/src/test/java/smecalculus/bezmen/construction/StorageConfigBeansLightbendConfigIT.java @@ -1,4 +1,4 @@ -package smecalculus.bezmen.interior.construction; +package smecalculus.bezmen.construction; import org.springframework.test.context.TestPropertySource; diff --git a/libs/storage/src/test/java/smecalculus/bezmen/interior/construction/StorageConfigBeansSpringConfigIT.java b/libs/storage/src/test/java/smecalculus/bezmen/construction/StorageConfigBeansSpringConfigIT.java similarity index 80% rename from libs/storage/src/test/java/smecalculus/bezmen/interior/construction/StorageConfigBeansSpringConfigIT.java rename to libs/storage/src/test/java/smecalculus/bezmen/construction/StorageConfigBeansSpringConfigIT.java index 9ad3c4ad..3fe90f67 100644 --- a/libs/storage/src/test/java/smecalculus/bezmen/interior/construction/StorageConfigBeansSpringConfigIT.java +++ b/libs/storage/src/test/java/smecalculus/bezmen/construction/StorageConfigBeansSpringConfigIT.java @@ -1,4 +1,4 @@ -package smecalculus.bezmen.interior.construction; +package smecalculus.bezmen.construction; import org.springframework.test.context.TestPropertySource; diff --git a/libs/storage/src/test/java/smecalculus/bezmen/interior/construction/StorageConfigBeansTest.java b/libs/storage/src/test/java/smecalculus/bezmen/construction/StorageConfigBeansTest.java similarity index 67% rename from libs/storage/src/test/java/smecalculus/bezmen/interior/construction/StorageConfigBeansTest.java rename to libs/storage/src/test/java/smecalculus/bezmen/construction/StorageConfigBeansTest.java index 559cb72e..79bf441f 100644 --- a/libs/storage/src/test/java/smecalculus/bezmen/interior/construction/StorageConfigBeansTest.java +++ b/libs/storage/src/test/java/smecalculus/bezmen/construction/StorageConfigBeansTest.java @@ -1,17 +1,17 @@ -package smecalculus.bezmen.interior.construction; +package smecalculus.bezmen.construction; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; -import static smecalculus.bezmen.interior.configuration.StoragePropsEg.Pojos.storagePropsCfg; +import static smecalculus.bezmen.configuration.StoragePropsEg.Pojos.storagePropsCfg; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; -import smecalculus.bezmen.interior.configuration.ConfigKeeper; -import smecalculus.bezmen.interior.configuration.StorageCfgMapper; -import smecalculus.bezmen.interior.configuration.StorageCfgMapperImpl; -import smecalculus.bezmen.interior.configuration.StoragePropsCfg; -import smecalculus.bezmen.interior.validation.EdgeValidator; +import smecalculus.bezmen.configuration.ConfigKeeper; +import smecalculus.bezmen.configuration.StorageCfgMapper; +import smecalculus.bezmen.configuration.StorageCfgMapperImpl; +import smecalculus.bezmen.configuration.StoragePropsCfg; +import smecalculus.bezmen.validation.EdgeValidator; class StorageConfigBeansTest { diff --git a/libs/testing/pom.xml b/libs/testing/pom.xml index 2c0e9377..717b96ce 100644 --- a/libs/testing/pom.xml +++ b/libs/testing/pom.xml @@ -15,8 +15,7 @@ ${project.groupId} - abstraction - client + abstraction-client diff --git a/libs/testing/src/main/java/smecalculus/bezmen/interior/construction/TestingBeans.java b/libs/testing/src/main/java/smecalculus/bezmen/construction/TestingBeans.java similarity index 93% rename from libs/testing/src/main/java/smecalculus/bezmen/interior/construction/TestingBeans.java rename to libs/testing/src/main/java/smecalculus/bezmen/construction/TestingBeans.java index 35057725..435fe674 100644 --- a/libs/testing/src/main/java/smecalculus/bezmen/interior/construction/TestingBeans.java +++ b/libs/testing/src/main/java/smecalculus/bezmen/construction/TestingBeans.java @@ -1,4 +1,4 @@ -package smecalculus.bezmen.interior.construction; +package smecalculus.bezmen.construction; import static org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseType.H2; diff --git a/libs/testing/src/main/java/smecalculus/bezmen/interior/messaging/SepulkaClientSpringWeb.java b/libs/testing/src/main/java/smecalculus/bezmen/messaging/SepulkaClientSpringWeb.java similarity index 61% rename from libs/testing/src/main/java/smecalculus/bezmen/interior/messaging/SepulkaClientSpringWeb.java rename to libs/testing/src/main/java/smecalculus/bezmen/messaging/SepulkaClientSpringWeb.java index 3088d3cd..5cd065cb 100644 --- a/libs/testing/src/main/java/smecalculus/bezmen/interior/messaging/SepulkaClientSpringWeb.java +++ b/libs/testing/src/main/java/smecalculus/bezmen/messaging/SepulkaClientSpringWeb.java @@ -1,12 +1,9 @@ -package smecalculus.bezmen.interior.messaging; +package smecalculus.bezmen.messaging; import lombok.NonNull; import lombok.RequiredArgsConstructor; import org.springframework.http.MediaType; import org.springframework.test.web.reactive.server.WebTestClient; -import smecalculus.bezmen.exterior.messaging.SepulkaClient; -import smecalculus.bezmen.exterior.messaging.SepulkaRegisterSliceMsg; -import smecalculus.bezmen.exterior.messaging.SepulkaRegisteredSliceMsg; @RequiredArgsConstructor public class SepulkaClientSpringWeb implements SepulkaClient { @@ -15,14 +12,14 @@ public class SepulkaClientSpringWeb implements SepulkaClient { private WebTestClient client; @Override - public SepulkaRegisteredSliceMsg register(SepulkaRegisterSliceMsg request) { + public SepulkaNewResponseMsg register(SepulkaNewRequestMsg request) { return client.post() .uri("/sepulkas") .contentType(MediaType.APPLICATION_JSON) .accept(MediaType.APPLICATION_JSON) .bodyValue(request) .exchange() - .expectBody(SepulkaRegisteredSliceMsg.class) + .expectBody(SepulkaNewResponseMsg.class) .returnResult() .getResponseBody(); } diff --git a/libs/testing/src/main/java/smecalculus/bezmen/interior/testing/ShardingExtension.java b/libs/testing/src/main/java/smecalculus/bezmen/testing/ShardingExtension.java similarity index 96% rename from libs/testing/src/main/java/smecalculus/bezmen/interior/testing/ShardingExtension.java rename to libs/testing/src/main/java/smecalculus/bezmen/testing/ShardingExtension.java index e8551cec..8742333b 100644 --- a/libs/testing/src/main/java/smecalculus/bezmen/interior/testing/ShardingExtension.java +++ b/libs/testing/src/main/java/smecalculus/bezmen/testing/ShardingExtension.java @@ -1,4 +1,4 @@ -package smecalculus.bezmen.interior.testing; +package smecalculus.bezmen.testing; import static org.junit.jupiter.api.extension.ConditionEvaluationResult.disabled; import static org.junit.jupiter.api.extension.ConditionEvaluationResult.enabled; diff --git a/libs/testing/src/main/resources/META-INF/services/org.junit.jupiter.api.extension.Extension b/libs/testing/src/main/resources/META-INF/services/org.junit.jupiter.api.extension.Extension index 9441d8d4..747167d4 100644 --- a/libs/testing/src/main/resources/META-INF/services/org.junit.jupiter.api.extension.Extension +++ b/libs/testing/src/main/resources/META-INF/services/org.junit.jupiter.api.extension.Extension @@ -1 +1 @@ -smecalculus.bezmen.interior.testing.ShardingExtension +smecalculus.bezmen.testing.ShardingExtension diff --git a/tests/e2e/pom.xml b/tests/e2e/pom.xml index db58b942..702ec04b 100644 --- a/tests/e2e/pom.xml +++ b/tests/e2e/pom.xml @@ -21,8 +21,7 @@ ${project.groupId} - messaging - client + messaging-client ${project.groupId} diff --git a/tests/e2e/src/main/java/smecalculus/bezmen/StandBeans.java b/tests/e2e/src/main/java/smecalculus/bezmen/StandBeans.java index 96bf33a9..ef87f39d 100644 --- a/tests/e2e/src/main/java/smecalculus/bezmen/StandBeans.java +++ b/tests/e2e/src/main/java/smecalculus/bezmen/StandBeans.java @@ -4,19 +4,16 @@ import java.net.http.HttpClient; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; -import smecalculus.bezmen.exterior.messaging.BezmenClient; -import smecalculus.bezmen.exterior.messaging.BezmenClientJavaHttp; -import smecalculus.bezmen.exterior.messaging.SepulkaMsgMapper; -import smecalculus.bezmen.exterior.messaging.SepulkaMsgMapperImpl; +import smecalculus.bezmen.messaging.BezmenClient; +import smecalculus.bezmen.messaging.BezmenClientJavaHttp; @Configuration(proxyBeanMethods = false) public class StandBeans { @Bean BezmenClient bezmenClient() { - SepulkaMsgMapper msgMapper = new SepulkaMsgMapperImpl(); ObjectMapper jsonMapper = new ObjectMapper(); HttpClient client = HttpClient.newHttpClient(); - return new BezmenClientJavaHttp(msgMapper, jsonMapper, client); + return new BezmenClientJavaHttp(jsonMapper, client); } } diff --git a/tests/e2e/src/test/java/smecalculus/bezmen/registration/SepulkaTest.java b/tests/e2e/src/test/java/smecalculus/bezmen/registration/SepulkaTest.java index 14686da1..aa51670a 100644 --- a/tests/e2e/src/test/java/smecalculus/bezmen/registration/SepulkaTest.java +++ b/tests/e2e/src/test/java/smecalculus/bezmen/registration/SepulkaTest.java @@ -3,8 +3,8 @@ import static java.time.Duration.ofSeconds; import static org.assertj.core.api.Assertions.assertThat; import static org.awaitility.Awaitility.await; -import static smecalculus.bezmen.exterior.messaging.SepulkaRegisterSliceEg.Pojos.sepulkaRegisterSliceMsg; -import static smecalculus.bezmen.exterior.messaging.SepulkaRegisteredSliceEg.Pojos.sepulkaRegisteredSlice; +import static smecalculus.bezmen.messaging.SepulkaNewRequestEg.Pojos.sepulkaNewRequestMsg; +import static smecalculus.bezmen.messaging.SepulkaNewResponseEg.Pojos.sepulkaNewResponseMsg; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Tag; @@ -15,7 +15,7 @@ import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit.jupiter.SpringExtension; import smecalculus.bezmen.StandBeans; -import smecalculus.bezmen.exterior.messaging.BezmenClient; +import smecalculus.bezmen.messaging.BezmenClient; @ExtendWith(SpringExtension.class) @ContextConfiguration(classes = StandBeans.class) @@ -33,9 +33,9 @@ void beforeAll() { @Tag("smoke") void shouldRegisterSepulka() { // given - var request = sepulkaRegisterSliceMsg(); + var request = sepulkaNewRequestMsg(); // and - var expectedResponse = sepulkaRegisteredSlice(); + var expectedResponse = sepulkaNewResponseMsg(); // when var actualResponse = bezmenClient.register(request); // then From 7f8735e993ea5be294d0fc4a1a5cd80d95983da4 Mon Sep 17 00:00:00 2001 From: Pavel Vetokhin Date: Sat, 14 Oct 2023 10:20:43 +0300 Subject: [PATCH 09/10] Chain setters --- apps/lombok.config | 2 ++ .../java/smecalculus/bezmen/storage/SepulkaRec.java | 3 +++ .../bezmen/messaging/SepulkaNewRequestEg.java | 5 +---- .../bezmen/messaging/SepulkaNewRequestMsg.java | 2 ++ .../bezmen/messaging/SepulkaNewResponseEg.java | 6 ++---- .../bezmen/messaging/SepulkaNewResponseMsg.java | 2 ++ libs/lombok.config | 2 ++ .../src/main/resources/messaging.properties | 2 -- .../messaging-client/src/main/resources/reference.conf | 10 ---------- .../bezmen/configuration/StateMappingPropsEg.java | 4 +--- .../bezmen/configuration/StoragePropsEg.java | 5 +---- .../bezmen/configuration/StorageProtocolPropsEg.java | 4 +--- 12 files changed, 17 insertions(+), 30 deletions(-) delete mode 100644 libs/messaging-client/src/main/resources/messaging.properties delete mode 100644 libs/messaging-client/src/main/resources/reference.conf diff --git a/apps/lombok.config b/apps/lombok.config index 8a52cc50..6fb4b534 100644 --- a/apps/lombok.config +++ b/apps/lombok.config @@ -1,2 +1,4 @@ lombok.builder.className=Builder lombok.addLombokGeneratedAnnotation=true +lombok.accessors.fluent=false +lombok.accessors.chain=true diff --git a/apps/sepuling/src/main/java/smecalculus/bezmen/storage/SepulkaRec.java b/apps/sepuling/src/main/java/smecalculus/bezmen/storage/SepulkaRec.java index 9a2400e1..dc6bcda9 100644 --- a/apps/sepuling/src/main/java/smecalculus/bezmen/storage/SepulkaRec.java +++ b/apps/sepuling/src/main/java/smecalculus/bezmen/storage/SepulkaRec.java @@ -5,6 +5,9 @@ import org.springframework.data.annotation.Version; import org.springframework.data.relational.core.mapping.Table; +/** + * Model: edge entity + */ @Data @Table("sepulkas") public class SepulkaRec { diff --git a/libs/abstraction-client/src/main/java/smecalculus/bezmen/messaging/SepulkaNewRequestEg.java b/libs/abstraction-client/src/main/java/smecalculus/bezmen/messaging/SepulkaNewRequestEg.java index a16727c2..20922c3a 100644 --- a/libs/abstraction-client/src/main/java/smecalculus/bezmen/messaging/SepulkaNewRequestEg.java +++ b/libs/abstraction-client/src/main/java/smecalculus/bezmen/messaging/SepulkaNewRequestEg.java @@ -4,11 +4,8 @@ public class SepulkaNewRequestEg { public static final String NAME = "foo"; public static class Pojos { - public static SepulkaNewRequestMsg sepulkaNewRequestMsg() { - var requestMsg = new SepulkaNewRequestMsg(); - requestMsg.setName(NAME); - return requestMsg; + return new SepulkaNewRequestMsg().setName(NAME); } } } diff --git a/libs/abstraction-client/src/main/java/smecalculus/bezmen/messaging/SepulkaNewRequestMsg.java b/libs/abstraction-client/src/main/java/smecalculus/bezmen/messaging/SepulkaNewRequestMsg.java index 8fac608e..5b9190d3 100644 --- a/libs/abstraction-client/src/main/java/smecalculus/bezmen/messaging/SepulkaNewRequestMsg.java +++ b/libs/abstraction-client/src/main/java/smecalculus/bezmen/messaging/SepulkaNewRequestMsg.java @@ -1,5 +1,6 @@ package smecalculus.bezmen.messaging; +import jakarta.validation.constraints.NotNull; import lombok.Data; /** @@ -7,5 +8,6 @@ */ @Data public class SepulkaNewRequestMsg { + @NotNull private String name; } diff --git a/libs/abstraction-client/src/main/java/smecalculus/bezmen/messaging/SepulkaNewResponseEg.java b/libs/abstraction-client/src/main/java/smecalculus/bezmen/messaging/SepulkaNewResponseEg.java index 26666cb9..b5dd8b5e 100644 --- a/libs/abstraction-client/src/main/java/smecalculus/bezmen/messaging/SepulkaNewResponseEg.java +++ b/libs/abstraction-client/src/main/java/smecalculus/bezmen/messaging/SepulkaNewResponseEg.java @@ -7,13 +7,11 @@ public class SepulkaNewResponseEg { public static class Pojos { public static SepulkaNewResponseMsg sepulkaNewResponseMsg() { - return sepulkaNewResponseMsg(UUID.randomUUID()); + return new SepulkaNewResponseMsg().setId(UUID.randomUUID().toString()); } public static SepulkaNewResponseMsg sepulkaNewResponseMsg(UUID id) { - var responseMsg = new SepulkaNewResponseMsg(); - responseMsg.setId(id.toString()); - return responseMsg; + return sepulkaNewResponseMsg().setId(id.toString()); } } } diff --git a/libs/abstraction-client/src/main/java/smecalculus/bezmen/messaging/SepulkaNewResponseMsg.java b/libs/abstraction-client/src/main/java/smecalculus/bezmen/messaging/SepulkaNewResponseMsg.java index 1c6230cd..fb3f0c3a 100644 --- a/libs/abstraction-client/src/main/java/smecalculus/bezmen/messaging/SepulkaNewResponseMsg.java +++ b/libs/abstraction-client/src/main/java/smecalculus/bezmen/messaging/SepulkaNewResponseMsg.java @@ -1,5 +1,6 @@ package smecalculus.bezmen.messaging; +import jakarta.validation.constraints.NotNull; import lombok.Data; /** @@ -7,5 +8,6 @@ */ @Data public class SepulkaNewResponseMsg { + @NotNull private String id; } diff --git a/libs/lombok.config b/libs/lombok.config index 8a52cc50..6fb4b534 100644 --- a/libs/lombok.config +++ b/libs/lombok.config @@ -1,2 +1,4 @@ lombok.builder.className=Builder lombok.addLombokGeneratedAnnotation=true +lombok.accessors.fluent=false +lombok.accessors.chain=true diff --git a/libs/messaging-client/src/main/resources/messaging.properties b/libs/messaging-client/src/main/resources/messaging.properties deleted file mode 100644 index 4cec1140..00000000 --- a/libs/messaging-client/src/main/resources/messaging.properties +++ /dev/null @@ -1,2 +0,0 @@ -bezmen.messaging.protocol.modes[0]=http -bezmen.messaging.mapping.modes[0]=spring_mvc diff --git a/libs/messaging-client/src/main/resources/reference.conf b/libs/messaging-client/src/main/resources/reference.conf deleted file mode 100644 index 6504a9e6..00000000 --- a/libs/messaging-client/src/main/resources/reference.conf +++ /dev/null @@ -1,10 +0,0 @@ -bezmen { - messaging { - protocol { - modes = [http] - } - mapping { - modes = [spring_mvc] - } - } -} diff --git a/libs/storage/src/main/java/smecalculus/bezmen/configuration/StateMappingPropsEg.java b/libs/storage/src/main/java/smecalculus/bezmen/configuration/StateMappingPropsEg.java index c7bb4c25..8ca3589b 100644 --- a/libs/storage/src/main/java/smecalculus/bezmen/configuration/StateMappingPropsEg.java +++ b/libs/storage/src/main/java/smecalculus/bezmen/configuration/StateMappingPropsEg.java @@ -5,9 +5,7 @@ public class StateMappingPropsEg { public static class Pojos { public static StateMappingPropsCfg stateMappingPropsCfg() { - StateMappingPropsCfg propsCfg = new StateMappingPropsCfg(); - propsCfg.setMode(SPRING_DATA.name()); - return propsCfg; + return new StateMappingPropsCfg().setMode(SPRING_DATA.name()); } } diff --git a/libs/storage/src/main/java/smecalculus/bezmen/configuration/StoragePropsEg.java b/libs/storage/src/main/java/smecalculus/bezmen/configuration/StoragePropsEg.java index 9f9fe983..ba2dac45 100644 --- a/libs/storage/src/main/java/smecalculus/bezmen/configuration/StoragePropsEg.java +++ b/libs/storage/src/main/java/smecalculus/bezmen/configuration/StoragePropsEg.java @@ -8,10 +8,7 @@ public class StoragePropsEg { public static class Pojos { public static StoragePropsCfg storagePropsCfg() { - StoragePropsCfg storagePropsCfg = new StoragePropsCfg(); - storagePropsCfg.setProtocol(storageProtocolPropsCfg()); - storagePropsCfg.setMapping(stateMappingPropsCfg()); - return storagePropsCfg; + return new StoragePropsCfg().setProtocol(storageProtocolPropsCfg()).setMapping(stateMappingPropsCfg()); } } diff --git a/libs/storage/src/main/java/smecalculus/bezmen/configuration/StorageProtocolPropsEg.java b/libs/storage/src/main/java/smecalculus/bezmen/configuration/StorageProtocolPropsEg.java index e4e89b39..efce19d4 100644 --- a/libs/storage/src/main/java/smecalculus/bezmen/configuration/StorageProtocolPropsEg.java +++ b/libs/storage/src/main/java/smecalculus/bezmen/configuration/StorageProtocolPropsEg.java @@ -3,9 +3,7 @@ public class StorageProtocolPropsEg { public static class Pojos { public static StorageProtocolPropsCfg storageProtocolPropsCfg() { - StorageProtocolPropsCfg propsCfg = new StorageProtocolPropsCfg(); - propsCfg.setMode(StorageProtocolMode.H2.name()); - return propsCfg; + return new StorageProtocolPropsCfg().setMode(StorageProtocolMode.H2.name()); } } From 6a1f88ba5c7de14064b0004004f55d0c24ce0783 Mon Sep 17 00:00:00 2001 From: Pavel Vetokhin Date: Sat, 14 Oct 2023 10:42:04 +0300 Subject: [PATCH 10/10] Revert setters chaining because libs require classic setters --- apps/lombok.config | 2 -- .../smecalculus/bezmen/messaging/SepulkaNewRequestEg.java | 5 ++++- .../bezmen/messaging/SepulkaNewResponseEg.java | 8 ++++++-- libs/lombok.config | 2 -- .../bezmen/configuration/StateMappingPropsEg.java | 4 +++- .../smecalculus/bezmen/configuration/StoragePropsEg.java | 5 ++++- .../bezmen/configuration/StorageProtocolPropsEg.java | 4 +++- 7 files changed, 20 insertions(+), 10 deletions(-) diff --git a/apps/lombok.config b/apps/lombok.config index 6fb4b534..8a52cc50 100644 --- a/apps/lombok.config +++ b/apps/lombok.config @@ -1,4 +1,2 @@ lombok.builder.className=Builder lombok.addLombokGeneratedAnnotation=true -lombok.accessors.fluent=false -lombok.accessors.chain=true diff --git a/libs/abstraction-client/src/main/java/smecalculus/bezmen/messaging/SepulkaNewRequestEg.java b/libs/abstraction-client/src/main/java/smecalculus/bezmen/messaging/SepulkaNewRequestEg.java index 20922c3a..a16727c2 100644 --- a/libs/abstraction-client/src/main/java/smecalculus/bezmen/messaging/SepulkaNewRequestEg.java +++ b/libs/abstraction-client/src/main/java/smecalculus/bezmen/messaging/SepulkaNewRequestEg.java @@ -4,8 +4,11 @@ public class SepulkaNewRequestEg { public static final String NAME = "foo"; public static class Pojos { + public static SepulkaNewRequestMsg sepulkaNewRequestMsg() { - return new SepulkaNewRequestMsg().setName(NAME); + var requestMsg = new SepulkaNewRequestMsg(); + requestMsg.setName(NAME); + return requestMsg; } } } diff --git a/libs/abstraction-client/src/main/java/smecalculus/bezmen/messaging/SepulkaNewResponseEg.java b/libs/abstraction-client/src/main/java/smecalculus/bezmen/messaging/SepulkaNewResponseEg.java index b5dd8b5e..9b7d7a19 100644 --- a/libs/abstraction-client/src/main/java/smecalculus/bezmen/messaging/SepulkaNewResponseEg.java +++ b/libs/abstraction-client/src/main/java/smecalculus/bezmen/messaging/SepulkaNewResponseEg.java @@ -7,11 +7,15 @@ public class SepulkaNewResponseEg { public static class Pojos { public static SepulkaNewResponseMsg sepulkaNewResponseMsg() { - return new SepulkaNewResponseMsg().setId(UUID.randomUUID().toString()); + var responseMsg = new SepulkaNewResponseMsg(); + responseMsg.setId(UUID.randomUUID().toString()); + return responseMsg; } public static SepulkaNewResponseMsg sepulkaNewResponseMsg(UUID id) { - return sepulkaNewResponseMsg().setId(id.toString()); + var responseMsg = sepulkaNewResponseMsg(); + responseMsg.setId(id.toString()); + return responseMsg; } } } diff --git a/libs/lombok.config b/libs/lombok.config index 6fb4b534..8a52cc50 100644 --- a/libs/lombok.config +++ b/libs/lombok.config @@ -1,4 +1,2 @@ lombok.builder.className=Builder lombok.addLombokGeneratedAnnotation=true -lombok.accessors.fluent=false -lombok.accessors.chain=true diff --git a/libs/storage/src/main/java/smecalculus/bezmen/configuration/StateMappingPropsEg.java b/libs/storage/src/main/java/smecalculus/bezmen/configuration/StateMappingPropsEg.java index 8ca3589b..c7bb4c25 100644 --- a/libs/storage/src/main/java/smecalculus/bezmen/configuration/StateMappingPropsEg.java +++ b/libs/storage/src/main/java/smecalculus/bezmen/configuration/StateMappingPropsEg.java @@ -5,7 +5,9 @@ public class StateMappingPropsEg { public static class Pojos { public static StateMappingPropsCfg stateMappingPropsCfg() { - return new StateMappingPropsCfg().setMode(SPRING_DATA.name()); + StateMappingPropsCfg propsCfg = new StateMappingPropsCfg(); + propsCfg.setMode(SPRING_DATA.name()); + return propsCfg; } } diff --git a/libs/storage/src/main/java/smecalculus/bezmen/configuration/StoragePropsEg.java b/libs/storage/src/main/java/smecalculus/bezmen/configuration/StoragePropsEg.java index ba2dac45..c4784ce7 100644 --- a/libs/storage/src/main/java/smecalculus/bezmen/configuration/StoragePropsEg.java +++ b/libs/storage/src/main/java/smecalculus/bezmen/configuration/StoragePropsEg.java @@ -8,7 +8,10 @@ public class StoragePropsEg { public static class Pojos { public static StoragePropsCfg storagePropsCfg() { - return new StoragePropsCfg().setProtocol(storageProtocolPropsCfg()).setMapping(stateMappingPropsCfg()); + StoragePropsCfg propsCfg = new StoragePropsCfg(); + propsCfg.setProtocol(storageProtocolPropsCfg()); + propsCfg.setMapping(stateMappingPropsCfg()); + return propsCfg; } } diff --git a/libs/storage/src/main/java/smecalculus/bezmen/configuration/StorageProtocolPropsEg.java b/libs/storage/src/main/java/smecalculus/bezmen/configuration/StorageProtocolPropsEg.java index efce19d4..e4e89b39 100644 --- a/libs/storage/src/main/java/smecalculus/bezmen/configuration/StorageProtocolPropsEg.java +++ b/libs/storage/src/main/java/smecalculus/bezmen/configuration/StorageProtocolPropsEg.java @@ -3,7 +3,9 @@ public class StorageProtocolPropsEg { public static class Pojos { public static StorageProtocolPropsCfg storageProtocolPropsCfg() { - return new StorageProtocolPropsCfg().setMode(StorageProtocolMode.H2.name()); + StorageProtocolPropsCfg propsCfg = new StorageProtocolPropsCfg(); + propsCfg.setMode(StorageProtocolMode.H2.name()); + return propsCfg; } }