diff --git a/.dx/tasks/solution/build.yml b/.dx/tasks/solution/build.yml index 899634d4..d257d1ef 100644 --- a/.dx/tasks/solution/build.yml +++ b/.dx/tasks/solution/build.yml @@ -11,6 +11,13 @@ recurse: true - name: Build spec + vars: + config_files: + turing: application.yaml + church: application.conf + config_mapping_modes: + turing: spring_config + church: lightbend_config ansible.builtin.command: cmd: > docker compose @@ -27,10 +34,18 @@ SCHEMA_IMAGE: "{{ schema_images.postgres }}" FOO_TAG: "{{ hostvars.app.image_cids.foo[:7] }}" FOO_IMAGE: "{{ app_images.foo }}" + CONFIG_FILE_NAME: "{{ config_files[prefs] }}" + CONFIG_MAPPING_MODE: "{{ config_mapping_modes[prefs] }}" changed_when: true - name: Build conf + vars: + config_extensions: + turing: yaml + church: conf ansible.builtin.command: - cmd: cp basis/{{ prefs }}.conf target/context/bezmen.conf + cmd: > + cp basis/{{ prefs }}.{{ config_extensions[prefs] }} + target/context/application.{{ config_extensions[prefs] }} chdir: "{{ playbook_dir }}/../solutions" changed_when: true diff --git a/apps/README.adoc b/apps/README.adoc deleted file mode 100644 index 9069af3f..00000000 --- a/apps/README.adoc +++ /dev/null @@ -1,5 +0,0 @@ -Приложения решения или инструменты времени эксплуатации - -=== Foo - -TBD diff --git a/apps/foo/Dockerfile b/apps/foo/Dockerfile index 073dd855..dd8c1887 100644 --- a/apps/foo/Dockerfile +++ b/apps/foo/Dockerfile @@ -2,10 +2,10 @@ FROM eclipse-temurin:17-jdk-alpine RUN addgroup -S bezmen && adduser -S bezmen -G bezmen USER bezmen:bezmen WORKDIR /home/bezmen -COPY libs foo/libs -COPY app-foo*.jar foo/app.jar +COPY libs libs +COPY app*.jar app.jar ENTRYPOINT [ \ - "java", "-cp", "foo/app.jar:foo/libs/*", \ - "-Dconfig.file=foo/application.conf", \ + "java", "-cp", "app.jar:libs/*", \ + "-Dconfig.file=application.conf", \ "smecalculus.bezmen.construction.App" \ ] diff --git a/apps/foo/src/main/java/smecalculus/bezmen/construction/App.java b/apps/foo/src/main/java/smecalculus/bezmen/construction/App.java index 7c63c018..c54d424c 100644 --- a/apps/foo/src/main/java/smecalculus/bezmen/construction/App.java +++ b/apps/foo/src/main/java/smecalculus/bezmen/construction/App.java @@ -8,6 +8,7 @@ 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.core.SepulkaConverter; import smecalculus.bezmen.core.SepulkaConverterImpl; import smecalculus.bezmen.core.SepulkaService; @@ -16,7 +17,7 @@ import smecalculus.bezmen.messaging.SepulkaMsgMapper; import smecalculus.bezmen.messaging.SepulkaMsgMapperImpl; import smecalculus.bezmen.messaging.client.SepulkaClient; -import smecalculus.bezmen.messaging.springwebmvc.SepulkaController; +import smecalculus.bezmen.messaging.springmvc.SepulkaController; import smecalculus.bezmen.storage.SepulkaDao; import smecalculus.bezmen.storage.SepulkaDaoMyBatis; import smecalculus.bezmen.storage.SepulkaDaoSpringData; @@ -27,6 +28,7 @@ import smecalculus.bezmen.validation.EdgeValidator; @Import({ConfigBeans.class, ValidationBeans.class, MessagingBeans.class, StorageBeans.class}) +@PropertySource("classpath:application.properties") @Configuration(proxyBeanMethods = false) public class App { @@ -36,8 +38,9 @@ public static void main(String[] args) { @Bean @ConditionalOnMessageMappingModes(SPRING_MVC) - SepulkaController sepulkaControllerSpringWeb(SepulkaClient client, SepulkaMsgMapper mapper) { - return new SepulkaController(client, mapper); + SepulkaController sepulkaControllerSpringMvc( + EdgeValidator validator, SepulkaClient client, SepulkaMsgMapper mapper) { + return new SepulkaController(validator, client, mapper); } @Bean @@ -46,8 +49,8 @@ SepulkaMsgMapper sepulkaMsgMapper() { } @Bean - SepulkaClient sepulkaClient(EdgeValidator validator, SepulkaService service, SepulkaConverter converter) { - return new SepulkaClientImpl(validator, service, converter); + SepulkaClient sepulkaClient(SepulkaService service, SepulkaConverter converter) { + return new SepulkaClientImpl(service, converter); } @Bean diff --git a/apps/foo/src/main/java/smecalculus/bezmen/messaging/SepulkaClientImpl.java b/apps/foo/src/main/java/smecalculus/bezmen/messaging/SepulkaClientImpl.java index 78d51b9e..ff21f451 100644 --- a/apps/foo/src/main/java/smecalculus/bezmen/messaging/SepulkaClientImpl.java +++ b/apps/foo/src/main/java/smecalculus/bezmen/messaging/SepulkaClientImpl.java @@ -7,15 +7,12 @@ import smecalculus.bezmen.messaging.client.SepulkaClient; import smecalculus.bezmen.messaging.client.SepulkaRegReq; import smecalculus.bezmen.messaging.client.SepulkaRegRes; -import smecalculus.bezmen.validation.EdgeValidator; -public record SepulkaClientImpl( - @NonNull EdgeValidator validator, @NonNull SepulkaService service, @NonNull SepulkaConverter converter) +public record SepulkaClientImpl(@NonNull SepulkaService service, @NonNull SepulkaConverter converter) implements SepulkaClient { @Override public SepulkaRegRes register(SepulkaRegReq request) { - validator.validate(request); Sepulka sepulka = service.register(request); return converter.toRegRes(sepulka); } diff --git a/apps/foo/src/main/java/smecalculus/bezmen/messaging/springwebmvc/SepulkaController.java b/apps/foo/src/main/java/smecalculus/bezmen/messaging/springmvc/SepulkaController.java similarity index 77% rename from apps/foo/src/main/java/smecalculus/bezmen/messaging/springwebmvc/SepulkaController.java rename to apps/foo/src/main/java/smecalculus/bezmen/messaging/springmvc/SepulkaController.java index 1902f008..44cef518 100644 --- a/apps/foo/src/main/java/smecalculus/bezmen/messaging/springwebmvc/SepulkaController.java +++ b/apps/foo/src/main/java/smecalculus/bezmen/messaging/springmvc/SepulkaController.java @@ -1,5 +1,6 @@ -package smecalculus.bezmen.messaging.springwebmvc; +package smecalculus.bezmen.messaging.springmvc; +import lombok.NonNull; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.PostMapping; @@ -12,12 +13,16 @@ import smecalculus.bezmen.messaging.client.SepulkaClient; import smecalculus.bezmen.messaging.client.SepulkaRegReq; import smecalculus.bezmen.messaging.client.SepulkaRegRes; +import smecalculus.bezmen.validation.EdgeValidator; @RestController @RequestMapping("sepulkas") -public record SepulkaController(SepulkaClient client, SepulkaMsgMapper mapper) { +public record SepulkaController( + @NonNull EdgeValidator validator, @NonNull SepulkaClient client, @NonNull SepulkaMsgMapper mapper) { + @PostMapping ResponseEntity register(@RequestBody SepulkaRegReqMsg sepulkaRegReqMsg) { + validator.validate(sepulkaRegReqMsg); SepulkaRegReq sepulkaRegReq = mapper.toDomain(sepulkaRegReqMsg); SepulkaRegRes sepulkaRegRes = client.register(sepulkaRegReq); return ResponseEntity.status(HttpStatus.CREATED).body(mapper.toMsg(sepulkaRegRes)); diff --git a/apps/foo/src/main/resources/application.properties b/apps/foo/src/main/resources/application.properties new file mode 100644 index 00000000..e69de29b diff --git a/apps/foo/src/main/resources/reference.conf b/apps/foo/src/main/resources/reference.conf new file mode 100644 index 00000000..e69de29b diff --git a/apps/foo/src/test/java/smecalculus/bezmen/construction/SepulkaClientBeans.java b/apps/foo/src/test/java/smecalculus/bezmen/construction/SepulkaClientBeans.java index 134b606a..bb1af9fc 100644 --- a/apps/foo/src/test/java/smecalculus/bezmen/construction/SepulkaClientBeans.java +++ b/apps/foo/src/test/java/smecalculus/bezmen/construction/SepulkaClientBeans.java @@ -15,7 +15,7 @@ import smecalculus.bezmen.messaging.SepulkaMsgMapper; import smecalculus.bezmen.messaging.SepulkaMsgMapperImpl; import smecalculus.bezmen.messaging.client.SepulkaClient; -import smecalculus.bezmen.messaging.springwebmvc.SepulkaController; +import smecalculus.bezmen.messaging.springmvc.SepulkaController; import smecalculus.bezmen.validation.EdgeValidator; @Import(ValidationBeans.class) @@ -33,14 +33,15 @@ SepulkaConverter sepulkaConverter() { } @Bean - SepulkaClient internalClient(EdgeValidator validator, SepulkaService service, SepulkaConverterImpl converter) { - return new SepulkaClientImpl(validator, service, converter); + SepulkaClient internalClient(SepulkaService service, SepulkaConverterImpl converter) { + return new SepulkaClientImpl(service, converter); } @Bean - SepulkaClient externalClient(SepulkaClient internalClient) { + SepulkaClient externalClient(EdgeValidator validator, SepulkaClient internalClient) { SepulkaMsgMapper mapper = new SepulkaMsgMapperImpl(); - WebTestClient client = MockMvcWebTestClient.bindToController(new SepulkaController(internalClient, mapper)) + WebTestClient client = MockMvcWebTestClient.bindToController( + new SepulkaController(validator, internalClient, mapper)) .build(); return new SepulkaClientSpringWeb(client, mapper); } diff --git a/docs/pipeline.adoc b/docs/pipeline.adoc index 69aeb6c8..2286dec7 100644 --- a/docs/pipeline.adoc +++ b/docs/pipeline.adoc @@ -76,7 +76,4 @@ . Релизная сборка . Параллелизация модульных тестов . Построение дерева хешей (взглянуть критически) -. Версионирование библиотек и приложений (взглянуть критически) -. Локальные проверки в удаленном репозитории -. Чистка артефактов в удаленном репозитории . Поддержка нескольких версий Java diff --git a/libs/essentials/pom.xml b/libs/essentials/pom.xml index 82257c35..24ef9ed8 100644 --- a/libs/essentials/pom.xml +++ b/libs/essentials/pom.xml @@ -22,16 +22,6 @@ org.jetbrains.kotlin kotlin-stdlib - - com.github.spotbugs - spotbugs-annotations - - - com.google.code.findbugs - jsr305 - - - org.hibernate.validator @@ -48,6 +38,15 @@ com.typesafe config + + org.yaml + snakeyaml + + + org.springframework.boot + spring-boot + true + org.slf4j diff --git a/libs/essentials/src/main/java/smecalculus/bezmen/configuration/ConfigKeeperSpringConfig.java b/libs/essentials/src/main/java/smecalculus/bezmen/configuration/ConfigKeeperSpringConfig.java new file mode 100644 index 00000000..7ec0f62b --- /dev/null +++ b/libs/essentials/src/main/java/smecalculus/bezmen/configuration/ConfigKeeperSpringConfig.java @@ -0,0 +1,13 @@ +package smecalculus.bezmen.configuration; + +import org.springframework.boot.context.properties.bind.Binder; +import org.springframework.core.env.Environment; + +public record ConfigKeeperSpringConfig(Environment environment) implements ConfigKeeper { + + @Override + public T read(String key, Class type) { + Binder binder = Binder.get(environment); + return binder.bind(key, type).get(); + } +} diff --git a/libs/essentials/src/main/java/smecalculus/bezmen/configuration/ConfigMappingMode.java b/libs/essentials/src/main/java/smecalculus/bezmen/configuration/ConfigMappingMode.java new file mode 100644 index 00000000..6b93eca4 --- /dev/null +++ b/libs/essentials/src/main/java/smecalculus/bezmen/configuration/ConfigMappingMode.java @@ -0,0 +1,6 @@ +package smecalculus.bezmen.configuration; + +public enum ConfigMappingMode { + LIGHTBEND_CONFIG, + SPRING_CONFIG +} diff --git a/libs/essentials/src/main/java/smecalculus/bezmen/configuration/ConfigMode.java b/libs/essentials/src/main/java/smecalculus/bezmen/configuration/ConfigProtocolMode.java similarity index 64% rename from libs/essentials/src/main/java/smecalculus/bezmen/configuration/ConfigMode.java rename to libs/essentials/src/main/java/smecalculus/bezmen/configuration/ConfigProtocolMode.java index 99106a20..086768aa 100644 --- a/libs/essentials/src/main/java/smecalculus/bezmen/configuration/ConfigMode.java +++ b/libs/essentials/src/main/java/smecalculus/bezmen/configuration/ConfigProtocolMode.java @@ -1,5 +1,5 @@ package smecalculus.bezmen.configuration; -public enum ConfigMode { +public enum ConfigProtocolMode { FILE_SYSTEM } diff --git a/libs/essentials/src/main/java/smecalculus/bezmen/construction/ConditionalOnConfigMappingMode.java b/libs/essentials/src/main/java/smecalculus/bezmen/construction/ConditionalOnConfigMappingMode.java new file mode 100644 index 00000000..d92a2be1 --- /dev/null +++ b/libs/essentials/src/main/java/smecalculus/bezmen/construction/ConditionalOnConfigMappingMode.java @@ -0,0 +1,15 @@ +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.configuration.ConfigMappingMode; + +@Target({ElementType.TYPE, ElementType.METHOD}) +@Retention(RetentionPolicy.RUNTIME) +@Conditional(ConfigMappingModeCondition.class) +public @interface ConditionalOnConfigMappingMode { + ConfigMappingMode value(); +} diff --git a/libs/essentials/src/main/java/smecalculus/bezmen/construction/ConditionalOnConfigProtocolMode.java b/libs/essentials/src/main/java/smecalculus/bezmen/construction/ConditionalOnConfigProtocolMode.java new file mode 100644 index 00000000..ef188f0a --- /dev/null +++ b/libs/essentials/src/main/java/smecalculus/bezmen/construction/ConditionalOnConfigProtocolMode.java @@ -0,0 +1,15 @@ +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.configuration.ConfigProtocolMode; + +@Target({ElementType.TYPE, ElementType.METHOD}) +@Retention(RetentionPolicy.RUNTIME) +@Conditional(ConfigProtocolModeCondition.class) +public @interface ConditionalOnConfigProtocolMode { + ConfigProtocolMode value(); +} diff --git a/libs/essentials/src/main/java/smecalculus/bezmen/construction/ConfigBeans.java b/libs/essentials/src/main/java/smecalculus/bezmen/construction/ConfigBeans.java index abec626a..85c837b9 100644 --- a/libs/essentials/src/main/java/smecalculus/bezmen/construction/ConfigBeans.java +++ b/libs/essentials/src/main/java/smecalculus/bezmen/construction/ConfigBeans.java @@ -1,20 +1,31 @@ package smecalculus.bezmen.construction; +import static smecalculus.bezmen.configuration.ConfigMappingMode.LIGHTBEND_CONFIG; +import static smecalculus.bezmen.configuration.ConfigMappingMode.SPRING_CONFIG; +import static smecalculus.bezmen.configuration.ConfigProtocolMode.FILE_SYSTEM; + 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.configuration.ConfigKeeper; import smecalculus.bezmen.configuration.ConfigKeeperLightbendConfig; -import smecalculus.bezmen.configuration.ConfigMode; +import smecalculus.bezmen.configuration.ConfigKeeperSpringConfig; @Configuration(proxyBeanMethods = false) public class ConfigBeans { @Bean - ConfigKeeper configKeeper() { - String configMode = System.getProperty("bezmen.config.mode", ConfigMode.FILE_SYSTEM.name()); - return switch (ConfigMode.valueOf(configMode.toUpperCase())) { - case FILE_SYSTEM -> new ConfigKeeperLightbendConfig(ConfigFactory.load()); - }; + @ConditionalOnConfigProtocolMode(FILE_SYSTEM) + @ConditionalOnConfigMappingMode(LIGHTBEND_CONFIG) + ConfigKeeper configKeeperLightbendConfig() { + return new ConfigKeeperLightbendConfig(ConfigFactory.load()); + } + + @Bean + @ConditionalOnConfigProtocolMode(FILE_SYSTEM) + @ConditionalOnConfigMappingMode(SPRING_CONFIG) + ConfigKeeper configKeeperSpringConfig(Environment environment) { + return new ConfigKeeperSpringConfig(environment); } } diff --git a/libs/essentials/src/main/java/smecalculus/bezmen/construction/ConfigMappingModeCondition.java b/libs/essentials/src/main/java/smecalculus/bezmen/construction/ConfigMappingModeCondition.java new file mode 100644 index 00000000..a205f333 --- /dev/null +++ b/libs/essentials/src/main/java/smecalculus/bezmen/construction/ConfigMappingModeCondition.java @@ -0,0 +1,27 @@ +package smecalculus.bezmen.construction; + +import static org.springframework.context.annotation.ConfigurationCondition.ConfigurationPhase.REGISTER_BEAN; + +import java.util.Map; +import org.springframework.context.annotation.ConditionContext; +import org.springframework.context.annotation.ConfigurationCondition; +import org.springframework.core.type.AnnotatedTypeMetadata; +import smecalculus.bezmen.configuration.ConfigMappingMode; + +class ConfigMappingModeCondition implements ConfigurationCondition { + + @Override + public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) { + Map attributes = + metadata.getAnnotationAttributes(ConditionalOnConfigMappingMode.class.getName()); + ConfigMappingMode expectedMode = (ConfigMappingMode) attributes.get("value"); + String actualMode = context.getEnvironment() + .getProperty("bezmen.config.mapping.mode", ConfigMappingMode.LIGHTBEND_CONFIG.name()); + return expectedMode.name().equalsIgnoreCase(actualMode); + } + + @Override + public ConfigurationPhase getConfigurationPhase() { + return REGISTER_BEAN; + } +} diff --git a/libs/essentials/src/main/java/smecalculus/bezmen/construction/ConfigProtocolModeCondition.java b/libs/essentials/src/main/java/smecalculus/bezmen/construction/ConfigProtocolModeCondition.java new file mode 100644 index 00000000..0d8f0a8a --- /dev/null +++ b/libs/essentials/src/main/java/smecalculus/bezmen/construction/ConfigProtocolModeCondition.java @@ -0,0 +1,27 @@ +package smecalculus.bezmen.construction; + +import static org.springframework.context.annotation.ConfigurationCondition.ConfigurationPhase.REGISTER_BEAN; + +import java.util.Map; +import org.springframework.context.annotation.ConditionContext; +import org.springframework.context.annotation.ConfigurationCondition; +import org.springframework.core.type.AnnotatedTypeMetadata; +import smecalculus.bezmen.configuration.ConfigProtocolMode; + +class ConfigProtocolModeCondition implements ConfigurationCondition { + + @Override + public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) { + Map attributes = + metadata.getAnnotationAttributes(ConditionalOnConfigProtocolMode.class.getName()); + ConfigProtocolMode expectedMode = (ConfigProtocolMode) attributes.get("value"); + String actualMode = context.getEnvironment() + .getProperty("bezmen.config.protocol.mode", ConfigProtocolMode.FILE_SYSTEM.name()); + return expectedMode.name().equalsIgnoreCase(actualMode); + } + + @Override + public ConfigurationPhase getConfigurationPhase() { + return REGISTER_BEAN; + } +} diff --git a/libs/messaging/src/main/java/smecalculus/bezmen/configuration/MessageMappingPropsEg.java b/libs/messaging/src/main/java/smecalculus/bezmen/configuration/MessageMappingPropsEg.java index b888625b..2827d7a0 100644 --- a/libs/messaging/src/main/java/smecalculus/bezmen/configuration/MessageMappingPropsEg.java +++ b/libs/messaging/src/main/java/smecalculus/bezmen/configuration/MessageMappingPropsEg.java @@ -1,12 +1,13 @@ package smecalculus.bezmen.configuration; -import static java.util.Collections.singleton; import static smecalculus.bezmen.configuration.MessageMappingMode.SPRING_MVC; +import java.util.Set; + public class MessageMappingPropsEg { public static class Builders { public static MessageMappingProps.Builder messageMappingProps() { - return MessageMappingProps.builder().mappingModes(singleton(SPRING_MVC)); + return MessageMappingProps.builder().mappingModes(Set.of(SPRING_MVC)); } } } diff --git a/libs/messaging/src/main/java/smecalculus/bezmen/configuration/MessagingCfgMapper.java b/libs/messaging/src/main/java/smecalculus/bezmen/configuration/MessagingCfgMapper.java index f04a1c62..2cd35b05 100644 --- a/libs/messaging/src/main/java/smecalculus/bezmen/configuration/MessagingCfgMapper.java +++ b/libs/messaging/src/main/java/smecalculus/bezmen/configuration/MessagingCfgMapper.java @@ -8,13 +8,13 @@ public interface MessagingCfgMapper { @Mapping(source = "protocol", target = "protocolProps") @Mapping(source = "mapping", target = "mappingProps") - MessagingProps toDomain(MessagingPropsCfg messagingPropsCfg); + MessagingProps toDomain(MessagingPropsCfg propsCfg); @Mapping(source = "modes", target = "protocolModes") - MessagingProtocolProps toDomain(MessagingProtocolPropsCfg protocolPropsCfg); + MessagingProtocolProps toDomain(MessagingProtocolPropsCfg propsCfg); @Mapping(source = "modes", target = "mappingModes") - MessageMappingProps toDomain(MessageMappingPropsCfg mappingPropsCfg); + MessageMappingProps toDomain(MessageMappingPropsCfg propsCfg); default MessagingProtocolMode toProtocolMode(String value) { return MessagingProtocolMode.valueOf(value.toUpperCase()); diff --git a/libs/messaging/src/main/java/smecalculus/bezmen/configuration/MessagingConfig.java b/libs/messaging/src/main/java/smecalculus/bezmen/configuration/MessagingConfig.java deleted file mode 100644 index 78354377..00000000 --- a/libs/messaging/src/main/java/smecalculus/bezmen/configuration/MessagingConfig.java +++ /dev/null @@ -1,5 +0,0 @@ -package smecalculus.bezmen.configuration; - -public interface MessagingConfig { - MessagingProps getMessagingProps(); -} diff --git a/libs/messaging/src/main/java/smecalculus/bezmen/configuration/MessagingConfigImpl.java b/libs/messaging/src/main/java/smecalculus/bezmen/configuration/MessagingConfigImpl.java deleted file mode 100644 index a806286c..00000000 --- a/libs/messaging/src/main/java/smecalculus/bezmen/configuration/MessagingConfigImpl.java +++ /dev/null @@ -1,21 +0,0 @@ -package smecalculus.bezmen.configuration; - -import lombok.NonNull; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import smecalculus.bezmen.validation.EdgeValidator; - -public record MessagingConfigImpl( - @NonNull ConfigKeeper keeper, @NonNull EdgeValidator validator, @NonNull MessagingCfgMapper mapper) - implements MessagingConfig { - - private static final Logger LOG = LoggerFactory.getLogger(MessagingConfigImpl.class); - - @Override - public MessagingProps getMessagingProps() { - MessagingPropsCfg propsCfg = keeper.read("bezmen.messaging", MessagingPropsCfg.class); - validator.validate(propsCfg); - LOG.info("Read {}", propsCfg); - return mapper.toDomain(propsCfg); - } -} diff --git a/libs/messaging/src/main/java/smecalculus/bezmen/construction/MessagingConfigBeans.java b/libs/messaging/src/main/java/smecalculus/bezmen/construction/MessagingConfigBeans.java index 520139c1..cd190ca5 100644 --- a/libs/messaging/src/main/java/smecalculus/bezmen/construction/MessagingConfigBeans.java +++ b/libs/messaging/src/main/java/smecalculus/bezmen/construction/MessagingConfigBeans.java @@ -1,30 +1,33 @@ 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.configuration.ConfigKeeper; import smecalculus.bezmen.configuration.MessagingCfgMapper; import smecalculus.bezmen.configuration.MessagingCfgMapperImpl; -import smecalculus.bezmen.configuration.MessagingConfig; -import smecalculus.bezmen.configuration.MessagingConfigImpl; import smecalculus.bezmen.configuration.MessagingProps; +import smecalculus.bezmen.configuration.MessagingPropsCfg; import smecalculus.bezmen.validation.EdgeValidator; +@PropertySource("classpath:messaging.properties") @Configuration(proxyBeanMethods = false) public class MessagingConfigBeans { + private static final Logger LOG = LoggerFactory.getLogger(MessagingConfigBeans.class); + @Bean MessagingCfgMapper messagingCfgMapper() { return new MessagingCfgMapperImpl(); } @Bean - MessagingConfig messagingConfig(ConfigKeeper keeper, EdgeValidator validator, MessagingCfgMapper mapper) { - return new MessagingConfigImpl(keeper, validator, mapper); - } - - @Bean - MessagingProps messagingProps(MessagingConfig config) { - return config.getMessagingProps(); + MessagingProps messagingProps(ConfigKeeper keeper, EdgeValidator validator, MessagingCfgMapper mapper) { + MessagingPropsCfg propsCfg = keeper.read("bezmen.messaging", MessagingPropsCfg.class); + validator.validate(propsCfg); + LOG.info("Read {}", propsCfg); + return mapper.toDomain(propsCfg); } } diff --git a/libs/messaging/src/main/resources/messaging.properties b/libs/messaging/src/main/resources/messaging.properties new file mode 100644 index 00000000..4cec1140 --- /dev/null +++ b/libs/messaging/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/src/test/java/smecalculus/bezmen/configuration/MessagingConfigImplIT.java b/libs/messaging/src/test/java/smecalculus/bezmen/configuration/MessagingConfigImplIT.java deleted file mode 100644 index 159e3c5f..00000000 --- a/libs/messaging/src/test/java/smecalculus/bezmen/configuration/MessagingConfigImplIT.java +++ /dev/null @@ -1,3 +0,0 @@ -package smecalculus.bezmen.configuration; - -class MessagingConfigImplIT extends MessagingConfigIT {} diff --git a/libs/messaging/src/test/java/smecalculus/bezmen/configuration/MessagingConfigIT.java b/libs/messaging/src/test/java/smecalculus/bezmen/construction/MessagingConfigBeansIT.java similarity index 55% rename from libs/messaging/src/test/java/smecalculus/bezmen/configuration/MessagingConfigIT.java rename to libs/messaging/src/test/java/smecalculus/bezmen/construction/MessagingConfigBeansIT.java index c95a9493..19dbbb29 100644 --- a/libs/messaging/src/test/java/smecalculus/bezmen/configuration/MessagingConfigIT.java +++ b/libs/messaging/src/test/java/smecalculus/bezmen/construction/MessagingConfigBeansIT.java @@ -1,4 +1,4 @@ -package smecalculus.bezmen.configuration; +package smecalculus.bezmen.construction; import static org.assertj.core.api.Assertions.assertThat; import static smecalculus.bezmen.configuration.MessagingPropsEg.Builders.messagingProps; @@ -8,23 +8,18 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit.jupiter.SpringExtension; -import smecalculus.bezmen.construction.ConfigBeans; -import smecalculus.bezmen.construction.MessagingConfigBeans; -import smecalculus.bezmen.construction.ValidationBeans; +import smecalculus.bezmen.configuration.MessagingProps; @ExtendWith(SpringExtension.class) -@ContextConfiguration(classes = {ConfigBeans.class, ValidationBeans.class, MessagingConfigBeans.class}) -abstract class MessagingConfigIT { - - @Autowired - MessagingConfig messagingConfig; +@ContextConfiguration(classes = {MessagingConfigBeans.class, ConfigBeans.class, ValidationBeans.class}) +abstract class MessagingConfigBeansIT { @Test - void defaultConfigShouldBeBackwardCompatible() { + void defaultConfigShouldBeBackwardCompatible(@Autowired MessagingProps actualProps) { // given MessagingProps expectedProps = messagingProps().build(); // when - MessagingProps actualProps = messagingConfig.getMessagingProps(); + // default construction // then assertThat(actualProps).isEqualTo(expectedProps); } diff --git a/libs/messaging/src/test/java/smecalculus/bezmen/construction/MessagingConfigBeansLightbendConfigIT.java b/libs/messaging/src/test/java/smecalculus/bezmen/construction/MessagingConfigBeansLightbendConfigIT.java new file mode 100644 index 00000000..5e8b69f1 --- /dev/null +++ b/libs/messaging/src/test/java/smecalculus/bezmen/construction/MessagingConfigBeansLightbendConfigIT.java @@ -0,0 +1,6 @@ +package smecalculus.bezmen.construction; + +import org.springframework.test.context.TestPropertySource; + +@TestPropertySource(properties = {"bezmen.config.mapping.mode=lightbend_config"}) +class MessagingConfigBeansLightbendConfigIT extends MessagingConfigBeansIT {} diff --git a/libs/messaging/src/test/java/smecalculus/bezmen/construction/MessagingConfigBeansSpringConfigIT.java b/libs/messaging/src/test/java/smecalculus/bezmen/construction/MessagingConfigBeansSpringConfigIT.java new file mode 100644 index 00000000..668b3e3f --- /dev/null +++ b/libs/messaging/src/test/java/smecalculus/bezmen/construction/MessagingConfigBeansSpringConfigIT.java @@ -0,0 +1,6 @@ +package smecalculus.bezmen.construction; + +import org.springframework.test.context.TestPropertySource; + +@TestPropertySource(properties = {"bezmen.config.mapping.mode=spring_config"}) +class MessagingConfigBeansSpringConfigIT extends MessagingConfigBeansIT {} diff --git a/libs/pom.xml b/libs/pom.xml index 857cd66a..acc68287 100644 --- a/libs/pom.xml +++ b/libs/pom.xml @@ -208,12 +208,6 @@ 6.0.0 - - com.github.spotbugs - spotbugs-annotations - 4.7.3 - - jakarta.validation jakarta.validation-api diff --git a/libs/storage/src/main/java/smecalculus/bezmen/configuration/StorageCfgMapper.java b/libs/storage/src/main/java/smecalculus/bezmen/configuration/StorageCfgMapper.java index 7c6c1e77..02ca7a8b 100644 --- a/libs/storage/src/main/java/smecalculus/bezmen/configuration/StorageCfgMapper.java +++ b/libs/storage/src/main/java/smecalculus/bezmen/configuration/StorageCfgMapper.java @@ -8,7 +8,7 @@ public interface StorageCfgMapper { @Mapping(source = "protocol", target = "protocolProps") @Mapping(source = "mapping", target = "mappingProps") - StorageProps toDomain(StoragePropsCfg storagePropsCfg); + StorageProps toDomain(StoragePropsCfg propsCfg); @Mapping(source = "mode", target = "protocolMode") @Mapping(source = "h2", target = "h2Props") diff --git a/libs/storage/src/main/java/smecalculus/bezmen/configuration/StorageConfig.java b/libs/storage/src/main/java/smecalculus/bezmen/configuration/StorageConfig.java deleted file mode 100644 index 159b41fb..00000000 --- a/libs/storage/src/main/java/smecalculus/bezmen/configuration/StorageConfig.java +++ /dev/null @@ -1,5 +0,0 @@ -package smecalculus.bezmen.configuration; - -public interface StorageConfig { - StorageProps getStorageProps(); -} diff --git a/libs/storage/src/main/java/smecalculus/bezmen/configuration/StorageConfigImpl.java b/libs/storage/src/main/java/smecalculus/bezmen/configuration/StorageConfigImpl.java deleted file mode 100644 index 1ec3263b..00000000 --- a/libs/storage/src/main/java/smecalculus/bezmen/configuration/StorageConfigImpl.java +++ /dev/null @@ -1,21 +0,0 @@ -package smecalculus.bezmen.configuration; - -import lombok.NonNull; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import smecalculus.bezmen.validation.EdgeValidator; - -public record StorageConfigImpl( - @NonNull ConfigKeeper configKeeper, @NonNull EdgeValidator validator, @NonNull StorageCfgMapper mapper) - implements StorageConfig { - - private static final Logger LOG = LoggerFactory.getLogger(StorageConfigImpl.class); - - @Override - public StorageProps getStorageProps() { - StoragePropsCfg propsCfg = configKeeper.read("bezmen.storage", StoragePropsCfg.class); - validator.validate(propsCfg); - LOG.info("Read {}", propsCfg); - return mapper.toDomain(propsCfg); - } -} diff --git a/libs/storage/src/main/java/smecalculus/bezmen/configuration/StorageProtocolProps.java b/libs/storage/src/main/java/smecalculus/bezmen/configuration/StorageProtocolProps.java index c6226c6c..81c566fc 100644 --- a/libs/storage/src/main/java/smecalculus/bezmen/configuration/StorageProtocolProps.java +++ b/libs/storage/src/main/java/smecalculus/bezmen/configuration/StorageProtocolProps.java @@ -1,8 +1,8 @@ package smecalculus.bezmen.configuration; -import edu.umd.cs.findbugs.annotations.Nullable; import lombok.Builder; import lombok.NonNull; +import org.springframework.lang.Nullable; @Builder public record StorageProtocolProps( diff --git a/libs/storage/src/main/java/smecalculus/bezmen/construction/StorageConfigBeans.java b/libs/storage/src/main/java/smecalculus/bezmen/construction/StorageConfigBeans.java index 9c5ddde8..061cf4d7 100644 --- a/libs/storage/src/main/java/smecalculus/bezmen/construction/StorageConfigBeans.java +++ b/libs/storage/src/main/java/smecalculus/bezmen/construction/StorageConfigBeans.java @@ -1,30 +1,33 @@ 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.configuration.ConfigKeeper; import smecalculus.bezmen.configuration.StorageCfgMapper; import smecalculus.bezmen.configuration.StorageCfgMapperImpl; -import smecalculus.bezmen.configuration.StorageConfig; -import smecalculus.bezmen.configuration.StorageConfigImpl; import smecalculus.bezmen.configuration.StorageProps; +import smecalculus.bezmen.configuration.StoragePropsCfg; import smecalculus.bezmen.validation.EdgeValidator; +@PropertySource("classpath:storage.properties") @Configuration(proxyBeanMethods = false) public class StorageConfigBeans { + private static final Logger LOG = LoggerFactory.getLogger(StorageConfigBeans.class); + @Bean StorageCfgMapper storageCfgMapper() { return new StorageCfgMapperImpl(); } @Bean - StorageConfig storageConfig(ConfigKeeper keeper, EdgeValidator validator, StorageCfgMapper mapper) { - return new StorageConfigImpl(keeper, validator, mapper); - } - - @Bean - StorageProps storageProps(StorageConfig config) { - return config.getStorageProps(); + StorageProps storageProps(ConfigKeeper keeper, EdgeValidator validator, StorageCfgMapper mapper) { + StoragePropsCfg propsCfg = keeper.read("bezmen.storage", StoragePropsCfg.class); + validator.validate(propsCfg); + LOG.info("Read {}", propsCfg); + return mapper.toDomain(propsCfg); } } diff --git a/libs/storage/src/main/resources/storage.properties b/libs/storage/src/main/resources/storage.properties new file mode 100644 index 00000000..b3056b72 --- /dev/null +++ b/libs/storage/src/main/resources/storage.properties @@ -0,0 +1,8 @@ +bezmen.storage.protocol.mode=h2 +bezmen.storage.protocol.h2.url=jdbc:h2:mem:db;DB_CLOSE_DELAY=-1 +bezmen.storage.protocol.h2.username=sa +bezmen.storage.protocol.h2.password=sa +bezmen.storage.protocol.postgres.url=jdbc:postgresql://localhost:5432/bezmen +bezmen.storage.protocol.postgres.username=bezmen +bezmen.storage.protocol.postgres.password=bezmen +bezmen.storage.mapping.mode=spring_data diff --git a/libs/storage/src/test/java/smecalculus/bezmen/configuration/StorageConfigImplIT.java b/libs/storage/src/test/java/smecalculus/bezmen/configuration/StorageConfigImplIT.java deleted file mode 100644 index 89bd661d..00000000 --- a/libs/storage/src/test/java/smecalculus/bezmen/configuration/StorageConfigImplIT.java +++ /dev/null @@ -1,3 +0,0 @@ -package smecalculus.bezmen.configuration; - -class StorageConfigImplIT extends StorageConfigIT {} diff --git a/libs/storage/src/test/java/smecalculus/bezmen/configuration/StorageConfigImplTest.java b/libs/storage/src/test/java/smecalculus/bezmen/configuration/StorageConfigImplTest.java deleted file mode 100644 index ca8d40aa..00000000 --- a/libs/storage/src/test/java/smecalculus/bezmen/configuration/StorageConfigImplTest.java +++ /dev/null @@ -1,3 +0,0 @@ -package smecalculus.bezmen.configuration; - -class StorageConfigImplTest extends StorageConfigTest {} diff --git a/libs/storage/src/test/java/smecalculus/bezmen/configuration/StorageConfigIT.java b/libs/storage/src/test/java/smecalculus/bezmen/construction/StorageConfigBeansIT.java similarity index 55% rename from libs/storage/src/test/java/smecalculus/bezmen/configuration/StorageConfigIT.java rename to libs/storage/src/test/java/smecalculus/bezmen/construction/StorageConfigBeansIT.java index fc4abfa2..62de9f65 100644 --- a/libs/storage/src/test/java/smecalculus/bezmen/configuration/StorageConfigIT.java +++ b/libs/storage/src/test/java/smecalculus/bezmen/construction/StorageConfigBeansIT.java @@ -1,4 +1,4 @@ -package smecalculus.bezmen.configuration; +package smecalculus.bezmen.construction; import static org.assertj.core.api.Assertions.assertThat; import static smecalculus.bezmen.configuration.StoragePropsEg.Builders.storageProps; @@ -8,23 +8,18 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit.jupiter.SpringExtension; -import smecalculus.bezmen.construction.ConfigBeans; -import smecalculus.bezmen.construction.StorageConfigBeans; -import smecalculus.bezmen.construction.ValidationBeans; +import smecalculus.bezmen.configuration.StorageProps; @ExtendWith(SpringExtension.class) -@ContextConfiguration(classes = {ConfigBeans.class, ValidationBeans.class, StorageConfigBeans.class}) -abstract class StorageConfigIT { - - @Autowired - StorageConfig storageConfig; +@ContextConfiguration(classes = {StorageConfigBeans.class, ConfigBeans.class, ValidationBeans.class}) +abstract class StorageConfigBeansIT { @Test - void defaultConfigShouldBeBackwardCompatible() { + void defaultConfigShouldBeBackwardCompatible(@Autowired StorageProps actualProps) { // given StorageProps expectedProps = storageProps().build(); // when - StorageProps actualProps = storageConfig.getStorageProps(); + // default construction // then assertThat(actualProps).isEqualTo(expectedProps); } diff --git a/libs/storage/src/test/java/smecalculus/bezmen/construction/StorageConfigBeansLightbendConfigIT.java b/libs/storage/src/test/java/smecalculus/bezmen/construction/StorageConfigBeansLightbendConfigIT.java new file mode 100644 index 00000000..4631e191 --- /dev/null +++ b/libs/storage/src/test/java/smecalculus/bezmen/construction/StorageConfigBeansLightbendConfigIT.java @@ -0,0 +1,6 @@ +package smecalculus.bezmen.construction; + +import org.springframework.test.context.TestPropertySource; + +@TestPropertySource(properties = {"bezmen.config.mapping.mode=lightbend_config"}) +class StorageConfigBeansLightbendConfigIT extends StorageConfigBeansIT {} diff --git a/libs/storage/src/test/java/smecalculus/bezmen/construction/StorageConfigBeansSpringConfigIT.java b/libs/storage/src/test/java/smecalculus/bezmen/construction/StorageConfigBeansSpringConfigIT.java new file mode 100644 index 00000000..3fe90f67 --- /dev/null +++ b/libs/storage/src/test/java/smecalculus/bezmen/construction/StorageConfigBeansSpringConfigIT.java @@ -0,0 +1,6 @@ +package smecalculus.bezmen.construction; + +import org.springframework.test.context.TestPropertySource; + +@TestPropertySource(properties = {"bezmen.config.mapping.mode=spring_config"}) +class StorageConfigBeansSpringConfigIT extends StorageConfigBeansIT {} diff --git a/libs/storage/src/test/java/smecalculus/bezmen/configuration/StorageConfigTest.java b/libs/storage/src/test/java/smecalculus/bezmen/construction/StorageConfigBeansTest.java similarity index 52% rename from libs/storage/src/test/java/smecalculus/bezmen/configuration/StorageConfigTest.java rename to libs/storage/src/test/java/smecalculus/bezmen/construction/StorageConfigBeansTest.java index 5e2ac79d..79bf441f 100644 --- a/libs/storage/src/test/java/smecalculus/bezmen/configuration/StorageConfigTest.java +++ b/libs/storage/src/test/java/smecalculus/bezmen/construction/StorageConfigBeansTest.java @@ -1,4 +1,4 @@ -package smecalculus.bezmen.configuration; +package smecalculus.bezmen.construction; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.verify; @@ -7,11 +7,16 @@ import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; +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; -abstract class StorageConfigTest { +class StorageConfigBeansTest { - private StorageConfig storageConfig; + private final StorageConfigBeans config = new StorageConfigBeans(); + private final StorageCfgMapper mapper = new StorageCfgMapperImpl(); private EdgeValidator validatorMock; private ConfigKeeper keeperMock; @@ -19,18 +24,17 @@ abstract class StorageConfigTest { void setUp() { validatorMock = mock(EdgeValidator.class); keeperMock = mock(ConfigKeeper.class); - storageConfig = new StorageConfigImpl(keeperMock, validatorMock, new StorageCfgMapperImpl()); } @Test void shouldValidateConf() { // given - StoragePropsCfg expectedStorageProps = storagePropsCfg(); + StoragePropsCfg expectedProps = storagePropsCfg(); // and - when(keeperMock.read("bezmen.storage", StoragePropsCfg.class)).thenReturn(expectedStorageProps); + when(keeperMock.read("bezmen.storage", StoragePropsCfg.class)).thenReturn(expectedProps); // when - storageConfig.getStorageProps(); + config.storageProps(keeperMock, validatorMock, mapper); // then - verify(validatorMock).validate(expectedStorageProps); + verify(validatorMock).validate(expectedProps); } } diff --git a/libs/testing/pom.xml b/libs/testing/pom.xml index 82a65a80..76063572 100644 --- a/libs/testing/pom.xml +++ b/libs/testing/pom.xml @@ -33,6 +33,10 @@ spring-jdbc + + jakarta.servlet + jakarta.servlet-api + org.reactivestreams reactive-streams @@ -46,8 +50,8 @@ spring-webflux - jakarta.servlet - jakarta.servlet-api + org.springframework.boot + spring-boot diff --git a/solutions/basis/compose.yml b/solutions/basis/compose.yml index d45dc5b6..c42bae8a 100644 --- a/solutions/basis/compose.yml +++ b/solutions/basis/compose.yml @@ -7,7 +7,7 @@ networks: configs: bezmen: name: bezmen - file: ./bezmen.conf + file: ./${CONFIG_FILE_NAME} services: db: @@ -85,7 +85,10 @@ services: - 8080:8080 configs: - source: bezmen - target: /home/bezmen/foo/application.conf + target: /home/bezmen/${CONFIG_FILE_NAME} + command: > + --bezmen.config.mapping.mode=${CONFIG_MAPPING_MODE} + --spring.config.location=optional:file:application.yaml depends_on: schema-owner: condition: service_completed_successfully diff --git a/solutions/basis/turing.conf b/solutions/basis/turing.conf deleted file mode 100644 index ed869071..00000000 --- a/solutions/basis/turing.conf +++ /dev/null @@ -1,18 +0,0 @@ -bezmen { - messaging { - mapping { - modes = [spring_mvc, spring_management] - } - } - storage { - protocol { - mode = postgres - postgres { - url = "jdbc:postgresql://db:5432/bezmen" - } - } - mapping { - mode = spring_data - } - } -} diff --git a/solutions/basis/turing.yaml b/solutions/basis/turing.yaml new file mode 100644 index 00000000..b8d07045 --- /dev/null +++ b/solutions/basis/turing.yaml @@ -0,0 +1,12 @@ +--- +bezmen: + messaging: + mapping: + modes: [spring_mvc, spring_management] + storage: + protocol: + mode: postgres + postgres: + url: jdbc:postgresql://db:5432/bezmen + mapping: + mode: spring_data