diff --git a/2025-03/spring-07-advanced-config/.gitignore b/2025-03/spring-07-advanced-config/.gitignore new file mode 100644 index 00000000..e62c33c2 --- /dev/null +++ b/2025-03/spring-07-advanced-config/.gitignore @@ -0,0 +1,4 @@ +.idea/ +*.iml + +target/ diff --git a/2025-03/spring-07-advanced-config/application-events-demo/.gitignore b/2025-03/spring-07-advanced-config/application-events-demo/.gitignore new file mode 100644 index 00000000..789ddc9e --- /dev/null +++ b/2025-03/spring-07-advanced-config/application-events-demo/.gitignore @@ -0,0 +1,32 @@ +# Compiled class file +*.class + +# Log file +*.log + +# BlueJ files +*.ctxt + +# Mobile Tools for Java (J2ME) +.mtj.tmp/ + +# Package Files # +*.jar +*.war +*.ear +*.zip +*.tar.gz +*.rar + +# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml +hs_err_pid* + +#other +*.bat +*/.idea +*.iml +*/target + +.idea +*.iml +target \ No newline at end of file diff --git a/2025-03/spring-07-advanced-config/application-events-demo/README.md b/2025-03/spring-07-advanced-config/application-events-demo/README.md new file mode 100644 index 00000000..63e68847 --- /dev/null +++ b/2025-03/spring-07-advanced-config/application-events-demo/README.md @@ -0,0 +1,2 @@ +# application-events-demo +Пример работы с событиями \ No newline at end of file diff --git a/2025-03/spring-07-advanced-config/application-events-demo/pom.xml b/2025-03/spring-07-advanced-config/application-events-demo/pom.xml new file mode 100644 index 00000000..b5a27d22 --- /dev/null +++ b/2025-03/spring-07-advanced-config/application-events-demo/pom.xml @@ -0,0 +1,63 @@ + + + 4.0.0 + + org.springframework.boot + spring-boot-starter-parent + 3.4.3 + + + + ru.otus.example + application-events-demo + 0.0.1-SNAPSHOT + application-events-demo + Application events demo + + + 17 + 17 + 17 + 3.4.0 + 2.0 + + + + + + org.springframework.boot + spring-boot-starter + + + + org.projectlombok + lombok + true + + + + org.springframework.shell + spring-shell-starter + ${spring.shell.version} + + + + org.springframework.boot + spring-boot-starter-test + test + + + + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + + + diff --git a/2025-03/spring-07-advanced-config/application-events-demo/src/main/java/ru/otus/example/applicationeventsdemo/ApplicationEventsDemoApplication.java b/2025-03/spring-07-advanced-config/application-events-demo/src/main/java/ru/otus/example/applicationeventsdemo/ApplicationEventsDemoApplication.java new file mode 100644 index 00000000..d53bb34e --- /dev/null +++ b/2025-03/spring-07-advanced-config/application-events-demo/src/main/java/ru/otus/example/applicationeventsdemo/ApplicationEventsDemoApplication.java @@ -0,0 +1,15 @@ +package ru.otus.example.applicationeventsdemo; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.shell.command.annotation.CommandScan; + +@CommandScan +@SpringBootApplication +public class ApplicationEventsDemoApplication { + + public static void main(String[] args) { + SpringApplication.run(ApplicationEventsDemoApplication.class, args); + } + +} diff --git a/2025-03/spring-07-advanced-config/application-events-demo/src/main/java/ru/otus/example/applicationeventsdemo/events/AbstractRespondent.java b/2025-03/spring-07-advanced-config/application-events-demo/src/main/java/ru/otus/example/applicationeventsdemo/events/AbstractRespondent.java new file mode 100644 index 00000000..d051969b --- /dev/null +++ b/2025-03/spring-07-advanced-config/application-events-demo/src/main/java/ru/otus/example/applicationeventsdemo/events/AbstractRespondent.java @@ -0,0 +1,11 @@ +package ru.otus.example.applicationeventsdemo.events; + +public class AbstractRespondent { + public void delay(long mills) { + try { + Thread.sleep(mills); + } catch (InterruptedException e) { + throw new RuntimeException(e); + } + } +} diff --git a/2025-03/spring-07-advanced-config/application-events-demo/src/main/java/ru/otus/example/applicationeventsdemo/events/EventsConfig.java b/2025-03/spring-07-advanced-config/application-events-demo/src/main/java/ru/otus/example/applicationeventsdemo/events/EventsConfig.java new file mode 100644 index 00000000..189856a5 --- /dev/null +++ b/2025-03/spring-07-advanced-config/application-events-demo/src/main/java/ru/otus/example/applicationeventsdemo/events/EventsConfig.java @@ -0,0 +1,19 @@ +package ru.otus.example.applicationeventsdemo.events; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.event.ApplicationEventMulticaster; +import org.springframework.context.event.SimpleApplicationEventMulticaster; +import org.springframework.core.task.SimpleAsyncTaskExecutor; + +//@Configuration +public class EventsConfig { + + // Имя бина важно + @Bean + public ApplicationEventMulticaster applicationEventMulticaster() { + SimpleApplicationEventMulticaster eventMulticaster = new SimpleApplicationEventMulticaster(); + eventMulticaster.setTaskExecutor(new SimpleAsyncTaskExecutor()); + return eventMulticaster; + } +} diff --git a/2025-03/spring-07-advanced-config/application-events-demo/src/main/java/ru/otus/example/applicationeventsdemo/events/EventsPublisher.java b/2025-03/spring-07-advanced-config/application-events-demo/src/main/java/ru/otus/example/applicationeventsdemo/events/EventsPublisher.java new file mode 100644 index 00000000..2274570a --- /dev/null +++ b/2025-03/spring-07-advanced-config/application-events-demo/src/main/java/ru/otus/example/applicationeventsdemo/events/EventsPublisher.java @@ -0,0 +1,5 @@ +package ru.otus.example.applicationeventsdemo.events; + +public interface EventsPublisher { + void publish(); +} diff --git a/2025-03/spring-07-advanced-config/application-events-demo/src/main/java/ru/otus/example/applicationeventsdemo/events/HalfAGlassOfWaterEvent.java b/2025-03/spring-07-advanced-config/application-events-demo/src/main/java/ru/otus/example/applicationeventsdemo/events/HalfAGlassOfWaterEvent.java new file mode 100644 index 00000000..22bab552 --- /dev/null +++ b/2025-03/spring-07-advanced-config/application-events-demo/src/main/java/ru/otus/example/applicationeventsdemo/events/HalfAGlassOfWaterEvent.java @@ -0,0 +1,15 @@ +package ru.otus.example.applicationeventsdemo.events; + +import lombok.Getter; +import org.springframework.context.ApplicationEvent; + +public class HalfAGlassOfWaterEvent extends ApplicationEvent { + + @Getter + private final String payload; + + public HalfAGlassOfWaterEvent(Object source) { + super(source); + payload = "Осталось половина стакана воды!!!"; + } +} diff --git a/2025-03/spring-07-advanced-config/application-events-demo/src/main/java/ru/otus/example/applicationeventsdemo/events/HalfAGlassOfWaterEventPublisher.java b/2025-03/spring-07-advanced-config/application-events-demo/src/main/java/ru/otus/example/applicationeventsdemo/events/HalfAGlassOfWaterEventPublisher.java new file mode 100644 index 00000000..a1186fcc --- /dev/null +++ b/2025-03/spring-07-advanced-config/application-events-demo/src/main/java/ru/otus/example/applicationeventsdemo/events/HalfAGlassOfWaterEventPublisher.java @@ -0,0 +1,17 @@ +package ru.otus.example.applicationeventsdemo.events; + +import lombok.RequiredArgsConstructor; +import org.springframework.context.ApplicationEventPublisher; +import org.springframework.stereotype.Service; + +@Service +@RequiredArgsConstructor +public class HalfAGlassOfWaterEventPublisher implements EventsPublisher { + + private final ApplicationEventPublisher publisher; + + @Override + public void publish() { + publisher.publishEvent(new HalfAGlassOfWaterEvent(this)); + } +} diff --git a/2025-03/spring-07-advanced-config/application-events-demo/src/main/java/ru/otus/example/applicationeventsdemo/events/NegativeRespondent.java b/2025-03/spring-07-advanced-config/application-events-demo/src/main/java/ru/otus/example/applicationeventsdemo/events/NegativeRespondent.java new file mode 100644 index 00000000..ca573e3f --- /dev/null +++ b/2025-03/spring-07-advanced-config/application-events-demo/src/main/java/ru/otus/example/applicationeventsdemo/events/NegativeRespondent.java @@ -0,0 +1,16 @@ +package ru.otus.example.applicationeventsdemo.events; + +import org.springframework.context.ApplicationListener; +import org.springframework.stereotype.Component; + +@Component +public class NegativeRespondent extends AbstractRespondent implements ApplicationListener { + + @Override + public void onApplicationEvent(HalfAGlassOfWaterEvent halfAGlassOfWaterEvent) { + delay(100); + System.out.println("Негативно настроенный слушатель"); + System.out.println(String.format("- %s", halfAGlassOfWaterEvent.getPayload())); + System.out.println("- Какой ужас. Теперь он наполовину пуст!!!\n\n"); + } +} diff --git a/2025-03/spring-07-advanced-config/application-events-demo/src/main/java/ru/otus/example/applicationeventsdemo/events/PositiveRespondent.java b/2025-03/spring-07-advanced-config/application-events-demo/src/main/java/ru/otus/example/applicationeventsdemo/events/PositiveRespondent.java new file mode 100644 index 00000000..645890a8 --- /dev/null +++ b/2025-03/spring-07-advanced-config/application-events-demo/src/main/java/ru/otus/example/applicationeventsdemo/events/PositiveRespondent.java @@ -0,0 +1,16 @@ +package ru.otus.example.applicationeventsdemo.events; + +import org.springframework.context.event.EventListener; +import org.springframework.stereotype.Component; + +@Component +public class PositiveRespondent extends AbstractRespondent { + + @EventListener + public void onApplicationEvent(HalfAGlassOfWaterEvent halfAGlassOfWaterEvent) { + delay(100); + System.out.println("Позитивно настроенный слушатель"); + System.out.println(String.format("- %s", halfAGlassOfWaterEvent.getPayload())); + System.out.println("- Ничего. Главное, что он наполовину полон!!!\n\n"); + } +} diff --git a/2025-03/spring-07-advanced-config/application-events-demo/src/main/java/ru/otus/example/applicationeventsdemo/security/InMemoryLoginContext.java b/2025-03/spring-07-advanced-config/application-events-demo/src/main/java/ru/otus/example/applicationeventsdemo/security/InMemoryLoginContext.java new file mode 100644 index 00000000..eab37c9e --- /dev/null +++ b/2025-03/spring-07-advanced-config/application-events-demo/src/main/java/ru/otus/example/applicationeventsdemo/security/InMemoryLoginContext.java @@ -0,0 +1,20 @@ +package ru.otus.example.applicationeventsdemo.security; + +import org.springframework.stereotype.Component; + +import static java.util.Objects.nonNull; + +@Component +public class InMemoryLoginContext implements LoginContext { + private String userName; + + @Override + public void login(String userName) { + this.userName = userName; + } + + @Override + public boolean isUserLoggedIn() { + return nonNull(userName); + } +} diff --git a/2025-03/spring-07-advanced-config/application-events-demo/src/main/java/ru/otus/example/applicationeventsdemo/security/LoginContext.java b/2025-03/spring-07-advanced-config/application-events-demo/src/main/java/ru/otus/example/applicationeventsdemo/security/LoginContext.java new file mode 100644 index 00000000..f5bdaae0 --- /dev/null +++ b/2025-03/spring-07-advanced-config/application-events-demo/src/main/java/ru/otus/example/applicationeventsdemo/security/LoginContext.java @@ -0,0 +1,6 @@ +package ru.otus.example.applicationeventsdemo.security; + +public interface LoginContext { + void login(String userName); + boolean isUserLoggedIn(); +} diff --git a/2025-03/spring-07-advanced-config/application-events-demo/src/main/java/ru/otus/example/applicationeventsdemo/shell/ApplicationEventsCommands.java b/2025-03/spring-07-advanced-config/application-events-demo/src/main/java/ru/otus/example/applicationeventsdemo/shell/ApplicationEventsCommands.java new file mode 100644 index 00000000..c4da29dd --- /dev/null +++ b/2025-03/spring-07-advanced-config/application-events-demo/src/main/java/ru/otus/example/applicationeventsdemo/shell/ApplicationEventsCommands.java @@ -0,0 +1,38 @@ +package ru.otus.example.applicationeventsdemo.shell; + +import lombok.RequiredArgsConstructor; +import org.springframework.shell.Availability; +import org.springframework.shell.standard.ShellComponent; +import org.springframework.shell.standard.ShellMethod; +import org.springframework.shell.standard.ShellMethodAvailability; +import org.springframework.shell.standard.ShellOption; +import ru.otus.example.applicationeventsdemo.events.EventsPublisher; +import ru.otus.example.applicationeventsdemo.security.LoginContext; + +@ShellComponent(value = "Application Events Commands") +@RequiredArgsConstructor +public class ApplicationEventsCommands { + + private final EventsPublisher eventsPublisher; + + private final LoginContext loginContext; + + @ShellMethod(value = "Login command", key = {"l", "login"}) + public String login(@ShellOption(defaultValue = "AnyUser") String userName) { + loginContext.login(userName); + return String.format("Добро пожаловать: %s", userName); + } + + @ShellMethod(value = "Publish event command", key = {"p", "pub", "publish"}) + @ShellMethodAvailability(value = "isPublishEventCommandAvailable") + public String publishEvent() { + eventsPublisher.publish(); + return "Событие опубликовано"; + } + + private Availability isPublishEventCommandAvailable() { + return loginContext.isUserLoggedIn() + ? Availability.available() + : Availability.unavailable("Сначала залогиньтесь"); + } +} diff --git a/2025-03/spring-07-advanced-config/application-events-demo/src/main/java/ru/otus/example/applicationeventsdemo/shellnew/ApplicationEventsCommandsNewWay.java b/2025-03/spring-07-advanced-config/application-events-demo/src/main/java/ru/otus/example/applicationeventsdemo/shellnew/ApplicationEventsCommandsNewWay.java new file mode 100644 index 00000000..c3d9c774 --- /dev/null +++ b/2025-03/spring-07-advanced-config/application-events-demo/src/main/java/ru/otus/example/applicationeventsdemo/shellnew/ApplicationEventsCommandsNewWay.java @@ -0,0 +1,30 @@ +package ru.otus.example.applicationeventsdemo.shellnew; + +import lombok.RequiredArgsConstructor; +import org.springframework.shell.command.annotation.Command; +import org.springframework.shell.command.annotation.CommandAvailability; +import org.springframework.shell.command.annotation.Option; +import ru.otus.example.applicationeventsdemo.events.EventsPublisher; +import ru.otus.example.applicationeventsdemo.security.LoginContext; + +@Command(group = "Application Events Commands New Way") +@RequiredArgsConstructor +public class ApplicationEventsCommandsNewWay { + + private final EventsPublisher eventsPublisher; + + private final LoginContext loginContext; + + @Command(description = "Login command new way", command = "login2", alias = "l2") + public String login(@Option(defaultValue = "AnyUser") String userName) { + loginContext.login(userName); + return String.format("Добро пожаловать: %s", userName); + } + + @Command(description = "Publish event command new way", command = "publish2", alias = {"p2", "pub2"}) + @CommandAvailability(provider = "publishEventCommandAvailabilityProvider") + public String publishEvent() { + eventsPublisher.publish(); + return "Событие опубликовано"; + } +} diff --git a/2025-03/spring-07-advanced-config/application-events-demo/src/main/java/ru/otus/example/applicationeventsdemo/shellnew/ShellConfig.java b/2025-03/spring-07-advanced-config/application-events-demo/src/main/java/ru/otus/example/applicationeventsdemo/shellnew/ShellConfig.java new file mode 100644 index 00000000..52f36ea3 --- /dev/null +++ b/2025-03/spring-07-advanced-config/application-events-demo/src/main/java/ru/otus/example/applicationeventsdemo/shellnew/ShellConfig.java @@ -0,0 +1,18 @@ +package ru.otus.example.applicationeventsdemo.shellnew; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.shell.Availability; +import org.springframework.shell.AvailabilityProvider; +import ru.otus.example.applicationeventsdemo.security.LoginContext; + +@Configuration +public class ShellConfig { + + @Bean + public AvailabilityProvider publishEventCommandAvailabilityProvider(LoginContext loginContext) { + return () -> loginContext.isUserLoggedIn() + ? Availability.available() + : Availability.unavailable("Сначала залогиньтесь"); + } +} diff --git a/2025-03/spring-07-advanced-config/application-events-demo/src/main/resources/application.yml b/2025-03/spring-07-advanced-config/application-events-demo/src/main/resources/application.yml new file mode 100644 index 00000000..3680b6b5 --- /dev/null +++ b/2025-03/spring-07-advanced-config/application-events-demo/src/main/resources/application.yml @@ -0,0 +1,8 @@ +logging: + level: + root: ERROR + + +spring: + main: + allow-circular-references: true \ No newline at end of file diff --git a/2025-03/spring-07-advanced-config/application-events-demo/src/test/java/ru/otus/example/applicationeventsdemo/shell/ApplicationEventsCommandsTest.java b/2025-03/spring-07-advanced-config/application-events-demo/src/test/java/ru/otus/example/applicationeventsdemo/shell/ApplicationEventsCommandsTest.java new file mode 100644 index 00000000..97aa9351 --- /dev/null +++ b/2025-03/spring-07-advanced-config/application-events-demo/src/test/java/ru/otus/example/applicationeventsdemo/shell/ApplicationEventsCommandsTest.java @@ -0,0 +1,101 @@ +package ru.otus.example.applicationeventsdemo.shell; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.mockito.ArgumentCaptor; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.shell.CommandNotCurrentlyAvailable; +import org.springframework.shell.InputProvider; +import org.springframework.shell.ResultHandlerService; +import org.springframework.shell.Shell; +import org.springframework.test.annotation.DirtiesContext; +import org.springframework.test.context.bean.override.mockito.MockitoBean; +import org.springframework.test.context.bean.override.mockito.MockitoSpyBean; +import ru.otus.example.applicationeventsdemo.events.EventsPublisher; + +import java.util.List; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatCode; +import static org.mockito.Mockito.*; + +@DisplayName("Тест команд shell ") +@SpringBootTest +class ApplicationEventsCommandsTest { + + private static final String GREETING_PATTERN = "Добро пожаловать: %s"; + private static final String DEFAULT_LOGIN = "AnyUser"; + private static final String CUSTOM_LOGIN = "Вася"; + private static final String COMMAND_LOGIN = "login"; + private static final String COMMAND_LOGIN_SHORT = "l"; + private static final String COMMAND_PUBLISH = "publish"; + private static final String COMMAND_PUBLISH_EXPECTED_RESULT = "Событие опубликовано"; + private static final String COMMAND_LOGIN_PATTERN = "%s %s"; + + private InputProvider inputProvider; + + private ArgumentCaptor argumentCaptor; + + //@MockBean + @MockitoBean + private EventsPublisher eventsPublisher; + + + //@SpyBean + @MockitoSpyBean + private ResultHandlerService resultHandlerService; + + @Autowired + private Shell shell; + + @BeforeEach + void setUp() { + inputProvider = mock(InputProvider.class); + argumentCaptor = ArgumentCaptor.forClass(Object.class); + } + + @DisplayName(" должен возвращать приветствие для всех форм команды логина") + @Test + void shouldReturnExpectedGreetingAfterLoginCommandEvaluated() throws Exception { + when(inputProvider.readInput()) + .thenReturn(() -> COMMAND_LOGIN) + .thenReturn(() -> COMMAND_LOGIN_SHORT) + .thenReturn(() -> String.format(COMMAND_LOGIN_PATTERN, COMMAND_LOGIN_SHORT, CUSTOM_LOGIN)) + .thenReturn(null); + + shell.run(inputProvider); + verify(resultHandlerService, times(3)).handle(argumentCaptor.capture()); + List results = argumentCaptor.getAllValues(); + assertThat(results).containsExactlyInAnyOrder(String.format(GREETING_PATTERN, DEFAULT_LOGIN), + String.format(GREETING_PATTERN, DEFAULT_LOGIN), + String.format(GREETING_PATTERN, CUSTOM_LOGIN)); + } + + @DisplayName(" должен возвращать CommandNotCurrentlyAvailable если при попытке выполнения команды publish пользователь выполнил вход") + @DirtiesContext(methodMode = DirtiesContext.MethodMode.BEFORE_METHOD) + @Test + void shouldReturnCommandNotCurrentlyAvailableObjectWhenUserDoesNotLoginAfterPublishCommandEvaluated() { + when(inputProvider.readInput()) + .thenReturn(() -> COMMAND_PUBLISH) + .thenReturn(null); + + assertThatCode(() -> shell.run(inputProvider)).isInstanceOf(CommandNotCurrentlyAvailable.class); + } + + @DisplayName(" должен возвращать статус выполнения команды publish и вызвать соответствующий метод сервиса есл и команда выполнена после входа") + @DirtiesContext(methodMode = DirtiesContext.MethodMode.BEFORE_METHOD) + @Test + void shouldReturnExpectedMessageAndFirePublishMethodAfterPublishCommandEvaluated() throws Exception { + when(inputProvider.readInput()) + .thenReturn(() -> COMMAND_LOGIN) + .thenReturn(() -> COMMAND_PUBLISH) + .thenReturn(null); + + shell.run(inputProvider); + verify(resultHandlerService, times(2)).handle(argumentCaptor.capture()); + assertThat(argumentCaptor.getValue()).isEqualTo(COMMAND_PUBLISH_EXPECTED_RESULT); + verify(eventsPublisher, times(1)).publish(); + } +} \ No newline at end of file diff --git a/2025-03/spring-07-advanced-config/application-events-demo/src/test/resources/application.yml b/2025-03/spring-07-advanced-config/application-events-demo/src/test/resources/application.yml new file mode 100644 index 00000000..fc81fe4b --- /dev/null +++ b/2025-03/spring-07-advanced-config/application-events-demo/src/test/resources/application.yml @@ -0,0 +1,6 @@ +spring: + shell: + interactive: + enabled: false + main: + allow-circular-references: true \ No newline at end of file diff --git a/2025-03/spring-07-advanced-config/conditional-and-profiles-exercise/.gitignore b/2025-03/spring-07-advanced-config/conditional-and-profiles-exercise/.gitignore new file mode 100644 index 00000000..789ddc9e --- /dev/null +++ b/2025-03/spring-07-advanced-config/conditional-and-profiles-exercise/.gitignore @@ -0,0 +1,32 @@ +# Compiled class file +*.class + +# Log file +*.log + +# BlueJ files +*.ctxt + +# Mobile Tools for Java (J2ME) +.mtj.tmp/ + +# Package Files # +*.jar +*.war +*.ear +*.zip +*.tar.gz +*.rar + +# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml +hs_err_pid* + +#other +*.bat +*/.idea +*.iml +*/target + +.idea +*.iml +target \ No newline at end of file diff --git a/2025-03/spring-07-advanced-config/conditional-and-profiles-exercise/README.md b/2025-03/spring-07-advanced-config/conditional-and-profiles-exercise/README.md new file mode 100644 index 00000000..3a4f835e --- /dev/null +++ b/2025-03/spring-07-advanced-config/conditional-and-profiles-exercise/README.md @@ -0,0 +1,11 @@ +#### Упражнение №1 +Условия вечеринки: +- Алексей придет если condition.alexey-exists=true +- Анна придет если будет Алексей +- Олег придет если включен профиль Oleg +- Петр придет если включен профиль Peter +- Янис придет если condition.yanis-exists=true +- Яна придет если нет Алексея, но есть Янис + +Измените только одну настройку в application.yml, чтобы на вечеринку пришло максимальное количество людей +Напечатать имена пришедших на вечеринку можно с помощью команды "ppm" или "print-party-members" \ No newline at end of file diff --git a/2025-03/spring-07-advanced-config/conditional-and-profiles-exercise/pom.xml b/2025-03/spring-07-advanced-config/conditional-and-profiles-exercise/pom.xml new file mode 100644 index 00000000..6c07e72f --- /dev/null +++ b/2025-03/spring-07-advanced-config/conditional-and-profiles-exercise/pom.xml @@ -0,0 +1,57 @@ + + + 4.0.0 + + org.springframework.boot + spring-boot-starter-parent + 3.4.3 + + + + ru.otus.example + conditional-and-profiles-exercise + 0.0.1-SNAPSHOT + + + 17 + 17 + 17 + 2.0 + + + + + org.springframework.boot + spring-boot-starter + + + + org.yaml + snakeyaml + ${snakeyaml.version} + + + + org.projectlombok + lombok + true + + + + org.springframework.boot + spring-boot-starter-test + test + + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + + + diff --git a/2025-03/spring-07-advanced-config/conditional-and-profiles-exercise/src/main/java/ru/otus/example/conditionalandprofilesdemo/ConditionalAndProfilesDemoApplication.java b/2025-03/spring-07-advanced-config/conditional-and-profiles-exercise/src/main/java/ru/otus/example/conditionalandprofilesdemo/ConditionalAndProfilesDemoApplication.java new file mode 100644 index 00000000..2aa5c3a4 --- /dev/null +++ b/2025-03/spring-07-advanced-config/conditional-and-profiles-exercise/src/main/java/ru/otus/example/conditionalandprofilesdemo/ConditionalAndProfilesDemoApplication.java @@ -0,0 +1,17 @@ +package ru.otus.example.conditionalandprofilesdemo; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.context.ApplicationContext; +import ru.otus.example.conditionalandprofilesdemo.model.Party; + +@SpringBootApplication +public class ConditionalAndProfilesDemoApplication { + + public static void main(String[] args) { + ApplicationContext ctx = SpringApplication.run(ConditionalAndProfilesDemoApplication.class, args); + Party party = ctx.getBean(Party.class); + party.printPartyMembers(); + } + +} diff --git a/2025-03/spring-07-advanced-config/conditional-and-profiles-exercise/src/main/java/ru/otus/example/conditionalandprofilesdemo/model/Alexey.java b/2025-03/spring-07-advanced-config/conditional-and-profiles-exercise/src/main/java/ru/otus/example/conditionalandprofilesdemo/model/Alexey.java new file mode 100644 index 00000000..66091903 --- /dev/null +++ b/2025-03/spring-07-advanced-config/conditional-and-profiles-exercise/src/main/java/ru/otus/example/conditionalandprofilesdemo/model/Alexey.java @@ -0,0 +1,14 @@ +package ru.otus.example.conditionalandprofilesdemo.model; + +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; +import org.springframework.stereotype.Component; +import ru.otus.example.conditionalandprofilesdemo.model.base.Friend; + +@ConditionalOnProperty(name = "condition.alexey-exists", havingValue = "true") +@Component +public class Alexey extends Friend { + @Override + public String getName() { + return "Алексей"; + } +} diff --git a/2025-03/spring-07-advanced-config/conditional-and-profiles-exercise/src/main/java/ru/otus/example/conditionalandprofilesdemo/model/Anna.java b/2025-03/spring-07-advanced-config/conditional-and-profiles-exercise/src/main/java/ru/otus/example/conditionalandprofilesdemo/model/Anna.java new file mode 100644 index 00000000..be26e16d --- /dev/null +++ b/2025-03/spring-07-advanced-config/conditional-and-profiles-exercise/src/main/java/ru/otus/example/conditionalandprofilesdemo/model/Anna.java @@ -0,0 +1,14 @@ +package ru.otus.example.conditionalandprofilesdemo.model; + +import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; +import org.springframework.stereotype.Component; +import ru.otus.example.conditionalandprofilesdemo.model.base.Friend; + +@ConditionalOnBean(Alexey.class) +@Component +public class Anna extends Friend { + @Override + public String getName() { + return "Аня"; + } +} diff --git a/2025-03/spring-07-advanced-config/conditional-and-profiles-exercise/src/main/java/ru/otus/example/conditionalandprofilesdemo/model/Oleg.java b/2025-03/spring-07-advanced-config/conditional-and-profiles-exercise/src/main/java/ru/otus/example/conditionalandprofilesdemo/model/Oleg.java new file mode 100644 index 00000000..2a11f476 --- /dev/null +++ b/2025-03/spring-07-advanced-config/conditional-and-profiles-exercise/src/main/java/ru/otus/example/conditionalandprofilesdemo/model/Oleg.java @@ -0,0 +1,14 @@ +package ru.otus.example.conditionalandprofilesdemo.model; + +import org.springframework.context.annotation.Profile; +import org.springframework.stereotype.Component; +import ru.otus.example.conditionalandprofilesdemo.model.base.Friend; + +@Profile("Oleg") +@Component +public class Oleg extends Friend { + @Override + public String getName() { + return "Олег"; + } +} diff --git a/2025-03/spring-07-advanced-config/conditional-and-profiles-exercise/src/main/java/ru/otus/example/conditionalandprofilesdemo/model/Party.java b/2025-03/spring-07-advanced-config/conditional-and-profiles-exercise/src/main/java/ru/otus/example/conditionalandprofilesdemo/model/Party.java new file mode 100644 index 00000000..597db3f8 --- /dev/null +++ b/2025-03/spring-07-advanced-config/conditional-and-profiles-exercise/src/main/java/ru/otus/example/conditionalandprofilesdemo/model/Party.java @@ -0,0 +1,20 @@ +package ru.otus.example.conditionalandprofilesdemo.model; + +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Component; +import ru.otus.example.conditionalandprofilesdemo.model.base.Friend; + +import java.util.List; +import java.util.stream.Collectors; + +@Component +@RequiredArgsConstructor +public class Party { + private final List partyMembers; + + public void printPartyMembers() { + System.out.println("Участники вечеринки:"); + System.out.println(partyMembers.stream().map(Friend::getName) + .collect(Collectors.joining("\n"))); + } +} diff --git a/2025-03/spring-07-advanced-config/conditional-and-profiles-exercise/src/main/java/ru/otus/example/conditionalandprofilesdemo/model/Peter.java b/2025-03/spring-07-advanced-config/conditional-and-profiles-exercise/src/main/java/ru/otus/example/conditionalandprofilesdemo/model/Peter.java new file mode 100644 index 00000000..435891a8 --- /dev/null +++ b/2025-03/spring-07-advanced-config/conditional-and-profiles-exercise/src/main/java/ru/otus/example/conditionalandprofilesdemo/model/Peter.java @@ -0,0 +1,15 @@ +package ru.otus.example.conditionalandprofilesdemo.model; + +import org.springframework.context.annotation.Profile; +import org.springframework.stereotype.Component; +import ru.otus.example.conditionalandprofilesdemo.model.base.Friend; + +@Profile("Peter") +@Component +public class Peter extends Friend { + + @Override + public String getName() { + return "Петр"; + } +} diff --git a/2025-03/spring-07-advanced-config/conditional-and-profiles-exercise/src/main/java/ru/otus/example/conditionalandprofilesdemo/model/Yana.java b/2025-03/spring-07-advanced-config/conditional-and-profiles-exercise/src/main/java/ru/otus/example/conditionalandprofilesdemo/model/Yana.java new file mode 100644 index 00000000..76b0fca3 --- /dev/null +++ b/2025-03/spring-07-advanced-config/conditional-and-profiles-exercise/src/main/java/ru/otus/example/conditionalandprofilesdemo/model/Yana.java @@ -0,0 +1,16 @@ +package ru.otus.example.conditionalandprofilesdemo.model; + +import org.springframework.context.annotation.Conditional; +import org.springframework.stereotype.Component; +import ru.otus.example.conditionalandprofilesdemo.model.base.Friend; +import ru.otus.example.conditionalandprofilesdemo.model.conditions.YanaConditions; + + +@Conditional(YanaConditions.class) +@Component +public class Yana extends Friend { + @Override + public String getName() { + return "Яна"; + } +} diff --git a/2025-03/spring-07-advanced-config/conditional-and-profiles-exercise/src/main/java/ru/otus/example/conditionalandprofilesdemo/model/Yanis.java b/2025-03/spring-07-advanced-config/conditional-and-profiles-exercise/src/main/java/ru/otus/example/conditionalandprofilesdemo/model/Yanis.java new file mode 100644 index 00000000..6dd2c14d --- /dev/null +++ b/2025-03/spring-07-advanced-config/conditional-and-profiles-exercise/src/main/java/ru/otus/example/conditionalandprofilesdemo/model/Yanis.java @@ -0,0 +1,14 @@ +package ru.otus.example.conditionalandprofilesdemo.model; + +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; +import org.springframework.stereotype.Component; +import ru.otus.example.conditionalandprofilesdemo.model.base.Friend; + +@ConditionalOnProperty(name = "condition.yanis-exists", havingValue = "true") +@Component +public class Yanis extends Friend { + @Override + public String getName() { + return "Янис"; + } +} diff --git a/2025-03/spring-07-advanced-config/conditional-and-profiles-exercise/src/main/java/ru/otus/example/conditionalandprofilesdemo/model/base/Friend.java b/2025-03/spring-07-advanced-config/conditional-and-profiles-exercise/src/main/java/ru/otus/example/conditionalandprofilesdemo/model/base/Friend.java new file mode 100644 index 00000000..2d2eb67d --- /dev/null +++ b/2025-03/spring-07-advanced-config/conditional-and-profiles-exercise/src/main/java/ru/otus/example/conditionalandprofilesdemo/model/base/Friend.java @@ -0,0 +1,5 @@ +package ru.otus.example.conditionalandprofilesdemo.model.base; + +public abstract class Friend { + public abstract String getName(); +} diff --git a/2025-03/spring-07-advanced-config/conditional-and-profiles-exercise/src/main/java/ru/otus/example/conditionalandprofilesdemo/model/conditions/YanaConditions.java b/2025-03/spring-07-advanced-config/conditional-and-profiles-exercise/src/main/java/ru/otus/example/conditionalandprofilesdemo/model/conditions/YanaConditions.java new file mode 100644 index 00000000..cf130ebb --- /dev/null +++ b/2025-03/spring-07-advanced-config/conditional-and-profiles-exercise/src/main/java/ru/otus/example/conditionalandprofilesdemo/model/conditions/YanaConditions.java @@ -0,0 +1,20 @@ +package ru.otus.example.conditionalandprofilesdemo.model.conditions; + +import org.springframework.boot.autoconfigure.condition.AllNestedConditions; +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; + +public class YanaConditions extends AllNestedConditions { + + public YanaConditions() { + super(ConfigurationPhase.PARSE_CONFIGURATION); + } + + + @ConditionalOnProperty(name = "condition.alexey-exists", havingValue = "false") + static class AlexeyDoesNotExistsCondition { + } + + @ConditionalOnProperty(name = "condition.yanis-exists", havingValue = "true") + static class YanisExistsCondition { + } +} diff --git a/2025-03/spring-07-advanced-config/conditional-and-profiles-exercise/src/main/resources/application-Peter.yml b/2025-03/spring-07-advanced-config/conditional-and-profiles-exercise/src/main/resources/application-Peter.yml new file mode 100644 index 00000000..aa28b2ce --- /dev/null +++ b/2025-03/spring-07-advanced-config/conditional-and-profiles-exercise/src/main/resources/application-Peter.yml @@ -0,0 +1,2 @@ +condition: + #yanis-exists: true diff --git a/2025-03/spring-07-advanced-config/conditional-and-profiles-exercise/src/main/resources/application.yml b/2025-03/spring-07-advanced-config/conditional-and-profiles-exercise/src/main/resources/application.yml new file mode 100644 index 00000000..b7b2d72c --- /dev/null +++ b/2025-03/spring-07-advanced-config/conditional-and-profiles-exercise/src/main/resources/application.yml @@ -0,0 +1,25 @@ +condition: + alexey-exists: true + yanis-exists: false + +#Доступные профили: Oleg и Peter +spring: + profiles: + active: + +logging: + level: + root: ERROR + + +--- +spring: + config: + activate: + on-profile: Peter +# Старый вариант включения профилей +#spring: +# profiles: Peter + +condition: + yanis-exists: true diff --git a/2025-03/spring-07-advanced-config/pom.xml b/2025-03/spring-07-advanced-config/pom.xml new file mode 100644 index 00000000..56e72f81 --- /dev/null +++ b/2025-03/spring-07-advanced-config/pom.xml @@ -0,0 +1,24 @@ + + + 4.0.0 + + ru.otus + advanced-config-class-work + 1.0 + + pom + + + conditional-and-profiles-exercise + application-events-demo + test-configuration-exercise-1 + test-configuration-exercise-2 + test-configuration-exercise-3 + test-configuration-solution-1 + test-configuration-solution-2 + test-configuration-solution-3 + test-caching-demo + + diff --git a/2025-03/spring-07-advanced-config/test-caching-demo/.gitignore b/2025-03/spring-07-advanced-config/test-caching-demo/.gitignore new file mode 100644 index 00000000..789ddc9e --- /dev/null +++ b/2025-03/spring-07-advanced-config/test-caching-demo/.gitignore @@ -0,0 +1,32 @@ +# Compiled class file +*.class + +# Log file +*.log + +# BlueJ files +*.ctxt + +# Mobile Tools for Java (J2ME) +.mtj.tmp/ + +# Package Files # +*.jar +*.war +*.ear +*.zip +*.tar.gz +*.rar + +# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml +hs_err_pid* + +#other +*.bat +*/.idea +*.iml +*/target + +.idea +*.iml +target \ No newline at end of file diff --git a/2025-03/spring-07-advanced-config/test-caching-demo/pom.xml b/2025-03/spring-07-advanced-config/test-caching-demo/pom.xml new file mode 100644 index 00000000..482d9ad2 --- /dev/null +++ b/2025-03/spring-07-advanced-config/test-caching-demo/pom.xml @@ -0,0 +1,57 @@ + + + 4.0.0 + + org.springframework.boot + spring-boot-starter-parent + 3.4.3 + + + + ru.otus.example + test-caching-demo + 0.0.1-SNAPSHOT + + + 17 + 17 + 17 + 2.0 + + + + + org.springframework.boot + spring-boot-starter + + + + org.yaml + snakeyaml + ${snakeyaml.version} + + + + org.projectlombok + lombok + true + + + + org.springframework.boot + spring-boot-starter-test + test + + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + + + diff --git a/2025-03/spring-07-advanced-config/test-caching-demo/src/main/java/ru/otus/example/testconfigurationdemo/TestConfigurationDemoApplication.java b/2025-03/spring-07-advanced-config/test-caching-demo/src/main/java/ru/otus/example/testconfigurationdemo/TestConfigurationDemoApplication.java new file mode 100644 index 00000000..fe8a8f68 --- /dev/null +++ b/2025-03/spring-07-advanced-config/test-caching-demo/src/main/java/ru/otus/example/testconfigurationdemo/TestConfigurationDemoApplication.java @@ -0,0 +1,14 @@ +package ru.otus.example.testconfigurationdemo; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.context.annotation.ComponentScan; + +@SpringBootApplication +public class TestConfigurationDemoApplication { + + public static void main(String[] args) { + SpringApplication.run(TestConfigurationDemoApplication.class, args); + } + +} diff --git a/2025-03/spring-07-advanced-config/test-caching-demo/src/main/java/ru/otus/example/testconfigurationdemo/statefulservices/Service1.java b/2025-03/spring-07-advanced-config/test-caching-demo/src/main/java/ru/otus/example/testconfigurationdemo/statefulservices/Service1.java new file mode 100644 index 00000000..9983209e --- /dev/null +++ b/2025-03/spring-07-advanced-config/test-caching-demo/src/main/java/ru/otus/example/testconfigurationdemo/statefulservices/Service1.java @@ -0,0 +1,15 @@ +package ru.otus.example.testconfigurationdemo.statefulservices; + +import lombok.Getter; +import lombok.Setter; +import org.springframework.stereotype.Service; + +@Service +public class Service1 { + @Getter + private final String name = "Service1"; + + @Getter + @Setter + private String state = "State1"; +} diff --git a/2025-03/spring-07-advanced-config/test-caching-demo/src/main/java/ru/otus/example/testconfigurationdemo/statefulservices/Service2.java b/2025-03/spring-07-advanced-config/test-caching-demo/src/main/java/ru/otus/example/testconfigurationdemo/statefulservices/Service2.java new file mode 100644 index 00000000..43586e62 --- /dev/null +++ b/2025-03/spring-07-advanced-config/test-caching-demo/src/main/java/ru/otus/example/testconfigurationdemo/statefulservices/Service2.java @@ -0,0 +1,15 @@ +package ru.otus.example.testconfigurationdemo.statefulservices; + +import lombok.Getter; +import lombok.Setter; +import org.springframework.stereotype.Service; + +@Service +public class Service2 { + @Getter + private final String name = "Service2"; + + @Getter + @Setter + private String state = "State2"; +} diff --git a/2025-03/spring-07-advanced-config/test-caching-demo/src/test/java/ru/otus/example/testconfigurationdemo/statefulservices/IntegrationTest1.java b/2025-03/spring-07-advanced-config/test-caching-demo/src/test/java/ru/otus/example/testconfigurationdemo/statefulservices/IntegrationTest1.java new file mode 100644 index 00000000..70567181 --- /dev/null +++ b/2025-03/spring-07-advanced-config/test-caching-demo/src/test/java/ru/otus/example/testconfigurationdemo/statefulservices/IntegrationTest1.java @@ -0,0 +1,42 @@ +package ru.otus.example.testconfigurationdemo.statefulservices; + +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.annotation.DirtiesContext; +import org.springframework.test.context.TestPropertySource; + +import static org.junit.jupiter.api.Assertions.*; + +//@SpringBootTest(classes = {Service1.class, Service2.class}) +//@TestPropertySource("classpath:test.properties") +//@DirtiesContext(classMode = DirtiesContext.ClassMode.BEFORE_CLASS) +@SpringBootTest +class IntegrationTest1 { + + @Autowired + private Service1 service1; + + //@MockBean + //@MockitoBean + @Autowired + private Service2 service2; + + @Test + void test1() { + System.out.println(service1.getName() + ": " + service1.getState()); + System.out.println(service2.getName() + ": " + service2.getState()); + + service1.setState("State7"); + service2.setState("State8"); + } + + @Test + void test2() { + System.out.println(service1.getName() + ": " + service1.getState()); + System.out.println(service2.getName() + ": " + service2.getState()); + + service1.setState("State9"); + service2.setState("State10"); + } +} \ No newline at end of file diff --git a/2025-03/spring-07-advanced-config/test-caching-demo/src/test/java/ru/otus/example/testconfigurationdemo/statefulservices/IntegrationTest2.java b/2025-03/spring-07-advanced-config/test-caching-demo/src/test/java/ru/otus/example/testconfigurationdemo/statefulservices/IntegrationTest2.java new file mode 100644 index 00000000..fcd6c2bf --- /dev/null +++ b/2025-03/spring-07-advanced-config/test-caching-demo/src/test/java/ru/otus/example/testconfigurationdemo/statefulservices/IntegrationTest2.java @@ -0,0 +1,33 @@ +package ru.otus.example.testconfigurationdemo.statefulservices; + +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; + +@SpringBootTest +class IntegrationTest2 { + + @Autowired + private Service1 service1; + + @Autowired + private Service2 service2; + + @Test + void test3() { + System.out.println(service1.getName() + ": " + service1.getState()); + System.out.println(service2.getName() + ": " + service2.getState()); + + service1.setState("State3"); + service2.setState("State4"); + } + + @Test + void test4() { + System.out.println(service1.getName() + ": " + service1.getState()); + System.out.println(service2.getName() + ": " + service2.getState()); + + service1.setState("State5"); + service2.setState("State6"); + } +} \ No newline at end of file diff --git a/2025-03/spring-07-advanced-config/test-caching-demo/src/test/resources/test.properties b/2025-03/spring-07-advanced-config/test-caching-demo/src/test/resources/test.properties new file mode 100644 index 00000000..257a47f4 --- /dev/null +++ b/2025-03/spring-07-advanced-config/test-caching-demo/src/test/resources/test.properties @@ -0,0 +1 @@ +any.prop=10 \ No newline at end of file diff --git a/2025-03/spring-07-advanced-config/test-configuration-exercise-1/.gitignore b/2025-03/spring-07-advanced-config/test-configuration-exercise-1/.gitignore new file mode 100644 index 00000000..789ddc9e --- /dev/null +++ b/2025-03/spring-07-advanced-config/test-configuration-exercise-1/.gitignore @@ -0,0 +1,32 @@ +# Compiled class file +*.class + +# Log file +*.log + +# BlueJ files +*.ctxt + +# Mobile Tools for Java (J2ME) +.mtj.tmp/ + +# Package Files # +*.jar +*.war +*.ear +*.zip +*.tar.gz +*.rar + +# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml +hs_err_pid* + +#other +*.bat +*/.idea +*.iml +*/target + +.idea +*.iml +target \ No newline at end of file diff --git a/2025-03/spring-07-advanced-config/test-configuration-exercise-1/README.md b/2025-03/spring-07-advanced-config/test-configuration-exercise-1/README.md new file mode 100644 index 00000000..301b2d83 --- /dev/null +++ b/2025-03/spring-07-advanced-config/test-configuration-exercise-1/README.md @@ -0,0 +1,9 @@ +#### Упражнение №2. Должен остаться только один + +С помощью вложенных конфигураций сделать так, +чтобы прошел NestedConfigurationDemoTest +(family должно содержать только собаку) + +- Сделать вложенный класс конфигурации. Не забываем про static +- Выбрать тип конфигурации (@Configuration/@TestConfiguration) +- С помощью @Bean/@ComponentScan добавить в контекст нужный бин(ы) \ No newline at end of file diff --git a/2025-03/spring-07-advanced-config/test-configuration-exercise-1/pom.xml b/2025-03/spring-07-advanced-config/test-configuration-exercise-1/pom.xml new file mode 100644 index 00000000..bc9d3d32 --- /dev/null +++ b/2025-03/spring-07-advanced-config/test-configuration-exercise-1/pom.xml @@ -0,0 +1,57 @@ + + + 4.0.0 + + org.springframework.boot + spring-boot-starter-parent + 3.4.3 + + + + ru.otus.example + test-configuration-exercise-1 + 0.0.1-SNAPSHOT + + + 17 + 17 + 17 + 2.0 + + + + + org.springframework.boot + spring-boot-starter + + + + org.yaml + snakeyaml + ${snakeyaml.version} + + + + org.projectlombok + lombok + true + + + + org.springframework.boot + spring-boot-starter-test + test + + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + + + diff --git a/2025-03/spring-07-advanced-config/test-configuration-exercise-1/src/main/java/ru/otus/example/testconfigurationdemo/TestConfigurationDemoApplication.java b/2025-03/spring-07-advanced-config/test-configuration-exercise-1/src/main/java/ru/otus/example/testconfigurationdemo/TestConfigurationDemoApplication.java new file mode 100644 index 00000000..e5dd8341 --- /dev/null +++ b/2025-03/spring-07-advanced-config/test-configuration-exercise-1/src/main/java/ru/otus/example/testconfigurationdemo/TestConfigurationDemoApplication.java @@ -0,0 +1,15 @@ +package ru.otus.example.testconfigurationdemo; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.context.annotation.ComponentScan; + +@ComponentScan("ru.otus.example.testconfigurationdemo.family") +@SpringBootApplication +public class TestConfigurationDemoApplication { + + public static void main(String[] args) { + SpringApplication.run(TestConfigurationDemoApplication.class, args); + } + +} diff --git a/2025-03/spring-07-advanced-config/test-configuration-exercise-1/src/main/java/ru/otus/example/testconfigurationdemo/family/FamilyMember.java b/2025-03/spring-07-advanced-config/test-configuration-exercise-1/src/main/java/ru/otus/example/testconfigurationdemo/family/FamilyMember.java new file mode 100644 index 00000000..1685a4cc --- /dev/null +++ b/2025-03/spring-07-advanced-config/test-configuration-exercise-1/src/main/java/ru/otus/example/testconfigurationdemo/family/FamilyMember.java @@ -0,0 +1,5 @@ +package ru.otus.example.testconfigurationdemo.family; + +public abstract class FamilyMember { + public abstract String getName(); +} diff --git a/2025-03/spring-07-advanced-config/test-configuration-exercise-1/src/main/java/ru/otus/example/testconfigurationdemo/family/childrens/Son.java b/2025-03/spring-07-advanced-config/test-configuration-exercise-1/src/main/java/ru/otus/example/testconfigurationdemo/family/childrens/Son.java new file mode 100644 index 00000000..f3da3289 --- /dev/null +++ b/2025-03/spring-07-advanced-config/test-configuration-exercise-1/src/main/java/ru/otus/example/testconfigurationdemo/family/childrens/Son.java @@ -0,0 +1,12 @@ +package ru.otus.example.testconfigurationdemo.family.childrens; + +import org.springframework.stereotype.Component; +import ru.otus.example.testconfigurationdemo.family.FamilyMember; + +@Component +public class Son extends FamilyMember { + @Override + public String getName() { + return "Сын"; + } +} diff --git a/2025-03/spring-07-advanced-config/test-configuration-exercise-1/src/main/java/ru/otus/example/testconfigurationdemo/family/parents/Father.java b/2025-03/spring-07-advanced-config/test-configuration-exercise-1/src/main/java/ru/otus/example/testconfigurationdemo/family/parents/Father.java new file mode 100644 index 00000000..d531bda5 --- /dev/null +++ b/2025-03/spring-07-advanced-config/test-configuration-exercise-1/src/main/java/ru/otus/example/testconfigurationdemo/family/parents/Father.java @@ -0,0 +1,10 @@ +package ru.otus.example.testconfigurationdemo.family.parents; + +import ru.otus.example.testconfigurationdemo.family.FamilyMember; + +public class Father extends FamilyMember { + @Override + public String getName() { + return "Папа"; + } +} diff --git a/2025-03/spring-07-advanced-config/test-configuration-exercise-1/src/main/java/ru/otus/example/testconfigurationdemo/family/parents/Mother.java b/2025-03/spring-07-advanced-config/test-configuration-exercise-1/src/main/java/ru/otus/example/testconfigurationdemo/family/parents/Mother.java new file mode 100644 index 00000000..d9b97b75 --- /dev/null +++ b/2025-03/spring-07-advanced-config/test-configuration-exercise-1/src/main/java/ru/otus/example/testconfigurationdemo/family/parents/Mother.java @@ -0,0 +1,12 @@ +package ru.otus.example.testconfigurationdemo.family.parents; + +import org.springframework.stereotype.Component; +import ru.otus.example.testconfigurationdemo.family.FamilyMember; + +@Component +public class Mother extends FamilyMember { + @Override + public String getName() { + return "Мама"; + } +} diff --git a/2025-03/spring-07-advanced-config/test-configuration-exercise-1/src/main/java/ru/otus/example/testconfigurationdemo/family/pets/Dog.java b/2025-03/spring-07-advanced-config/test-configuration-exercise-1/src/main/java/ru/otus/example/testconfigurationdemo/family/pets/Dog.java new file mode 100644 index 00000000..3e436c12 --- /dev/null +++ b/2025-03/spring-07-advanced-config/test-configuration-exercise-1/src/main/java/ru/otus/example/testconfigurationdemo/family/pets/Dog.java @@ -0,0 +1,13 @@ +package ru.otus.example.testconfigurationdemo.family.pets; + +import org.springframework.stereotype.Component; +import ru.otus.example.testconfigurationdemo.family.FamilyMember; + +@Component +public class Dog extends FamilyMember { + + @Override + public String getName() { + return "Собака"; + } +} diff --git a/2025-03/spring-07-advanced-config/test-configuration-exercise-1/src/test/java/ru/otus/example/testconfigurationdemo/demo/NestedConfigurationDemoTest.java b/2025-03/spring-07-advanced-config/test-configuration-exercise-1/src/test/java/ru/otus/example/testconfigurationdemo/demo/NestedConfigurationDemoTest.java new file mode 100644 index 00000000..6f1795d0 --- /dev/null +++ b/2025-03/spring-07-advanced-config/test-configuration-exercise-1/src/test/java/ru/otus/example/testconfigurationdemo/demo/NestedConfigurationDemoTest.java @@ -0,0 +1,26 @@ +package ru.otus.example.testconfigurationdemo.demo; + +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import ru.otus.example.testconfigurationdemo.family.FamilyMember; + +import java.util.Map; + +import static org.assertj.core.api.Assertions.assertThat; + +@DisplayName("В NestedConfigurationDemoTest семья должна ") +@SpringBootTest +public class NestedConfigurationDemoTest { + + @Autowired + private Map family; + + @DisplayName(" содержать только собаку ") + @Test + void shouldContainOnlyDog() { + assertThat(family).containsOnlyKeys("dog"); + } + +} diff --git a/2025-03/spring-07-advanced-config/test-configuration-exercise-1/src/test/java/ru/otus/example/testconfigurationdemo/demo/PlainSpringBootTestDemoTest.java b/2025-03/spring-07-advanced-config/test-configuration-exercise-1/src/test/java/ru/otus/example/testconfigurationdemo/demo/PlainSpringBootTestDemoTest.java new file mode 100644 index 00000000..66932497 --- /dev/null +++ b/2025-03/spring-07-advanced-config/test-configuration-exercise-1/src/test/java/ru/otus/example/testconfigurationdemo/demo/PlainSpringBootTestDemoTest.java @@ -0,0 +1,26 @@ +package ru.otus.example.testconfigurationdemo.demo; + +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import ru.otus.example.testconfigurationdemo.family.FamilyMember; + +import java.util.Map; + +import static org.assertj.core.api.Assertions.assertThat; + +@DisplayName("В PlainSpringBootTestDemoTest семья должна ") +@SpringBootTest +public class PlainSpringBootTestDemoTest { + + @Autowired + private Map family; + + @DisplayName(" содержать маму, сына и собаку ") + @Test + void shouldContainAllFamilyExceptFather() { + assertThat(family).containsOnlyKeys("mother", "son", "dog"); + } + +} diff --git a/2025-03/spring-07-advanced-config/test-configuration-exercise-2/.gitignore b/2025-03/spring-07-advanced-config/test-configuration-exercise-2/.gitignore new file mode 100644 index 00000000..789ddc9e --- /dev/null +++ b/2025-03/spring-07-advanced-config/test-configuration-exercise-2/.gitignore @@ -0,0 +1,32 @@ +# Compiled class file +*.class + +# Log file +*.log + +# BlueJ files +*.ctxt + +# Mobile Tools for Java (J2ME) +.mtj.tmp/ + +# Package Files # +*.jar +*.war +*.ear +*.zip +*.tar.gz +*.rar + +# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml +hs_err_pid* + +#other +*.bat +*/.idea +*.iml +*/target + +.idea +*.iml +target \ No newline at end of file diff --git a/2025-03/spring-07-advanced-config/test-configuration-exercise-2/README.md b/2025-03/spring-07-advanced-config/test-configuration-exercise-2/README.md new file mode 100644 index 00000000..a5258087 --- /dev/null +++ b/2025-03/spring-07-advanced-config/test-configuration-exercise-2/README.md @@ -0,0 +1,9 @@ +#### Упражнение №3. Вернуть отца в семью + +С помощью вложенных конфигураций сделать так, +чтобы прошел NestedTestConfigurationDemoTest +(family должно содержать маму, папу, сына и собаку) + +- Сделать вложенный класс конфигурации. Не забываем про static +- Выбрать тип конфигурации (@Configuration/@TestConfiguration) +- С помощью @Bean/@ComponentScan добавить в контекст нужный бин(ы) \ No newline at end of file diff --git a/2025-03/spring-07-advanced-config/test-configuration-exercise-2/pom.xml b/2025-03/spring-07-advanced-config/test-configuration-exercise-2/pom.xml new file mode 100644 index 00000000..7415fa6c --- /dev/null +++ b/2025-03/spring-07-advanced-config/test-configuration-exercise-2/pom.xml @@ -0,0 +1,57 @@ + + + 4.0.0 + + org.springframework.boot + spring-boot-starter-parent + 3.4.3 + + + + ru.otus.example + test-configuration-exercise-2 + 0.0.1-SNAPSHOT + + + 17 + 17 + 17 + 2.0 + + + + + org.springframework.boot + spring-boot-starter + + + + org.yaml + snakeyaml + ${snakeyaml.version} + + + + org.projectlombok + lombok + true + + + + org.springframework.boot + spring-boot-starter-test + test + + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + + + diff --git a/2025-03/spring-07-advanced-config/test-configuration-exercise-2/src/main/java/ru/otus/example/testconfigurationdemo/TestConfigurationDemoApplication.java b/2025-03/spring-07-advanced-config/test-configuration-exercise-2/src/main/java/ru/otus/example/testconfigurationdemo/TestConfigurationDemoApplication.java new file mode 100644 index 00000000..e5dd8341 --- /dev/null +++ b/2025-03/spring-07-advanced-config/test-configuration-exercise-2/src/main/java/ru/otus/example/testconfigurationdemo/TestConfigurationDemoApplication.java @@ -0,0 +1,15 @@ +package ru.otus.example.testconfigurationdemo; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.context.annotation.ComponentScan; + +@ComponentScan("ru.otus.example.testconfigurationdemo.family") +@SpringBootApplication +public class TestConfigurationDemoApplication { + + public static void main(String[] args) { + SpringApplication.run(TestConfigurationDemoApplication.class, args); + } + +} diff --git a/2025-03/spring-07-advanced-config/test-configuration-exercise-2/src/main/java/ru/otus/example/testconfigurationdemo/family/FamilyMember.java b/2025-03/spring-07-advanced-config/test-configuration-exercise-2/src/main/java/ru/otus/example/testconfigurationdemo/family/FamilyMember.java new file mode 100644 index 00000000..1685a4cc --- /dev/null +++ b/2025-03/spring-07-advanced-config/test-configuration-exercise-2/src/main/java/ru/otus/example/testconfigurationdemo/family/FamilyMember.java @@ -0,0 +1,5 @@ +package ru.otus.example.testconfigurationdemo.family; + +public abstract class FamilyMember { + public abstract String getName(); +} diff --git a/2025-03/spring-07-advanced-config/test-configuration-exercise-2/src/main/java/ru/otus/example/testconfigurationdemo/family/childrens/Son.java b/2025-03/spring-07-advanced-config/test-configuration-exercise-2/src/main/java/ru/otus/example/testconfigurationdemo/family/childrens/Son.java new file mode 100644 index 00000000..f3da3289 --- /dev/null +++ b/2025-03/spring-07-advanced-config/test-configuration-exercise-2/src/main/java/ru/otus/example/testconfigurationdemo/family/childrens/Son.java @@ -0,0 +1,12 @@ +package ru.otus.example.testconfigurationdemo.family.childrens; + +import org.springframework.stereotype.Component; +import ru.otus.example.testconfigurationdemo.family.FamilyMember; + +@Component +public class Son extends FamilyMember { + @Override + public String getName() { + return "Сын"; + } +} diff --git a/2025-03/spring-07-advanced-config/test-configuration-exercise-2/src/main/java/ru/otus/example/testconfigurationdemo/family/parents/Father.java b/2025-03/spring-07-advanced-config/test-configuration-exercise-2/src/main/java/ru/otus/example/testconfigurationdemo/family/parents/Father.java new file mode 100644 index 00000000..d531bda5 --- /dev/null +++ b/2025-03/spring-07-advanced-config/test-configuration-exercise-2/src/main/java/ru/otus/example/testconfigurationdemo/family/parents/Father.java @@ -0,0 +1,10 @@ +package ru.otus.example.testconfigurationdemo.family.parents; + +import ru.otus.example.testconfigurationdemo.family.FamilyMember; + +public class Father extends FamilyMember { + @Override + public String getName() { + return "Папа"; + } +} diff --git a/2025-03/spring-07-advanced-config/test-configuration-exercise-2/src/main/java/ru/otus/example/testconfigurationdemo/family/parents/Mother.java b/2025-03/spring-07-advanced-config/test-configuration-exercise-2/src/main/java/ru/otus/example/testconfigurationdemo/family/parents/Mother.java new file mode 100644 index 00000000..d9b97b75 --- /dev/null +++ b/2025-03/spring-07-advanced-config/test-configuration-exercise-2/src/main/java/ru/otus/example/testconfigurationdemo/family/parents/Mother.java @@ -0,0 +1,12 @@ +package ru.otus.example.testconfigurationdemo.family.parents; + +import org.springframework.stereotype.Component; +import ru.otus.example.testconfigurationdemo.family.FamilyMember; + +@Component +public class Mother extends FamilyMember { + @Override + public String getName() { + return "Мама"; + } +} diff --git a/2025-03/spring-07-advanced-config/test-configuration-exercise-2/src/main/java/ru/otus/example/testconfigurationdemo/family/pets/Dog.java b/2025-03/spring-07-advanced-config/test-configuration-exercise-2/src/main/java/ru/otus/example/testconfigurationdemo/family/pets/Dog.java new file mode 100644 index 00000000..3e436c12 --- /dev/null +++ b/2025-03/spring-07-advanced-config/test-configuration-exercise-2/src/main/java/ru/otus/example/testconfigurationdemo/family/pets/Dog.java @@ -0,0 +1,13 @@ +package ru.otus.example.testconfigurationdemo.family.pets; + +import org.springframework.stereotype.Component; +import ru.otus.example.testconfigurationdemo.family.FamilyMember; + +@Component +public class Dog extends FamilyMember { + + @Override + public String getName() { + return "Собака"; + } +} diff --git a/2025-03/spring-07-advanced-config/test-configuration-exercise-2/src/test/java/ru/otus/example/testconfigurationdemo/demo/NestedTestConfigurationDemoTest.java b/2025-03/spring-07-advanced-config/test-configuration-exercise-2/src/test/java/ru/otus/example/testconfigurationdemo/demo/NestedTestConfigurationDemoTest.java new file mode 100644 index 00000000..a4b13be6 --- /dev/null +++ b/2025-03/spring-07-advanced-config/test-configuration-exercise-2/src/test/java/ru/otus/example/testconfigurationdemo/demo/NestedTestConfigurationDemoTest.java @@ -0,0 +1,26 @@ +package ru.otus.example.testconfigurationdemo.demo; + +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import ru.otus.example.testconfigurationdemo.family.FamilyMember; + +import java.util.Map; + +import static org.assertj.core.api.Assertions.assertThat; + +@DisplayName("В NestedTestConfigurationDemoTest семья должна ") +@SpringBootTest +public class NestedTestConfigurationDemoTest { + + @Autowired + private Map family; + + @DisplayName(" содержать маму, папу, сына и собаку ") + @Test + void shouldContainAllFamilyWithFather() { + assertThat(family).containsOnlyKeys("mother", "father", "son", "dog"); + } + +} diff --git a/2025-03/spring-07-advanced-config/test-configuration-exercise-3/.gitignore b/2025-03/spring-07-advanced-config/test-configuration-exercise-3/.gitignore new file mode 100644 index 00000000..789ddc9e --- /dev/null +++ b/2025-03/spring-07-advanced-config/test-configuration-exercise-3/.gitignore @@ -0,0 +1,32 @@ +# Compiled class file +*.class + +# Log file +*.log + +# BlueJ files +*.ctxt + +# Mobile Tools for Java (J2ME) +.mtj.tmp/ + +# Package Files # +*.jar +*.war +*.ear +*.zip +*.tar.gz +*.rar + +# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml +hs_err_pid* + +#other +*.bat +*/.idea +*.iml +*/target + +.idea +*.iml +target \ No newline at end of file diff --git a/2025-03/spring-07-advanced-config/test-configuration-exercise-3/README.md b/2025-03/spring-07-advanced-config/test-configuration-exercise-3/README.md new file mode 100644 index 00000000..7d9a8b46 --- /dev/null +++ b/2025-03/spring-07-advanced-config/test-configuration-exercise-3/README.md @@ -0,0 +1,8 @@ +#### Упражнение №4. Вся семья, но без собаки + +С помощью внешней конфигурации сделать так, +чтобы прошел SpringBootTestWithExternalLimitationDemoTest +(family должно содержать маму, папу и сына) + +- Над TestSpringBootConfiguration повесить @SpringBootConfiguration +- С помощью @Bean/@ComponentScan добавить в контекст нужный бин(ы) \ No newline at end of file diff --git a/2025-03/spring-07-advanced-config/test-configuration-exercise-3/pom.xml b/2025-03/spring-07-advanced-config/test-configuration-exercise-3/pom.xml new file mode 100644 index 00000000..2fad07cf --- /dev/null +++ b/2025-03/spring-07-advanced-config/test-configuration-exercise-3/pom.xml @@ -0,0 +1,59 @@ + + + 4.0.0 + + org.springframework.boot + spring-boot-starter-parent + 3.4.3 + + + + ru.otus.example + test-configuration-exercise-3 + 0.0.1-SNAPSHOT + test-configuration-demo + Test configuration demo + + + 17 + 17 + 17 + 2.0 + + + + + org.springframework.boot + spring-boot-starter + + + + org.yaml + snakeyaml + ${snakeyaml.version} + + + + org.projectlombok + lombok + true + + + + org.springframework.boot + spring-boot-starter-test + test + + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + + + diff --git a/2025-03/spring-07-advanced-config/test-configuration-exercise-3/src/main/java/ru/otus/example/testconfigurationdemo/TestConfigurationDemoApplication.java b/2025-03/spring-07-advanced-config/test-configuration-exercise-3/src/main/java/ru/otus/example/testconfigurationdemo/TestConfigurationDemoApplication.java new file mode 100644 index 00000000..e5dd8341 --- /dev/null +++ b/2025-03/spring-07-advanced-config/test-configuration-exercise-3/src/main/java/ru/otus/example/testconfigurationdemo/TestConfigurationDemoApplication.java @@ -0,0 +1,15 @@ +package ru.otus.example.testconfigurationdemo; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.context.annotation.ComponentScan; + +@ComponentScan("ru.otus.example.testconfigurationdemo.family") +@SpringBootApplication +public class TestConfigurationDemoApplication { + + public static void main(String[] args) { + SpringApplication.run(TestConfigurationDemoApplication.class, args); + } + +} diff --git a/2025-03/spring-07-advanced-config/test-configuration-exercise-3/src/main/java/ru/otus/example/testconfigurationdemo/family/FamilyMember.java b/2025-03/spring-07-advanced-config/test-configuration-exercise-3/src/main/java/ru/otus/example/testconfigurationdemo/family/FamilyMember.java new file mode 100644 index 00000000..1685a4cc --- /dev/null +++ b/2025-03/spring-07-advanced-config/test-configuration-exercise-3/src/main/java/ru/otus/example/testconfigurationdemo/family/FamilyMember.java @@ -0,0 +1,5 @@ +package ru.otus.example.testconfigurationdemo.family; + +public abstract class FamilyMember { + public abstract String getName(); +} diff --git a/2025-03/spring-07-advanced-config/test-configuration-exercise-3/src/main/java/ru/otus/example/testconfigurationdemo/family/childrens/Son.java b/2025-03/spring-07-advanced-config/test-configuration-exercise-3/src/main/java/ru/otus/example/testconfigurationdemo/family/childrens/Son.java new file mode 100644 index 00000000..f3da3289 --- /dev/null +++ b/2025-03/spring-07-advanced-config/test-configuration-exercise-3/src/main/java/ru/otus/example/testconfigurationdemo/family/childrens/Son.java @@ -0,0 +1,12 @@ +package ru.otus.example.testconfigurationdemo.family.childrens; + +import org.springframework.stereotype.Component; +import ru.otus.example.testconfigurationdemo.family.FamilyMember; + +@Component +public class Son extends FamilyMember { + @Override + public String getName() { + return "Сын"; + } +} diff --git a/2025-03/spring-07-advanced-config/test-configuration-exercise-3/src/main/java/ru/otus/example/testconfigurationdemo/family/parents/Father.java b/2025-03/spring-07-advanced-config/test-configuration-exercise-3/src/main/java/ru/otus/example/testconfigurationdemo/family/parents/Father.java new file mode 100644 index 00000000..d531bda5 --- /dev/null +++ b/2025-03/spring-07-advanced-config/test-configuration-exercise-3/src/main/java/ru/otus/example/testconfigurationdemo/family/parents/Father.java @@ -0,0 +1,10 @@ +package ru.otus.example.testconfigurationdemo.family.parents; + +import ru.otus.example.testconfigurationdemo.family.FamilyMember; + +public class Father extends FamilyMember { + @Override + public String getName() { + return "Папа"; + } +} diff --git a/2025-03/spring-07-advanced-config/test-configuration-exercise-3/src/main/java/ru/otus/example/testconfigurationdemo/family/parents/Mother.java b/2025-03/spring-07-advanced-config/test-configuration-exercise-3/src/main/java/ru/otus/example/testconfigurationdemo/family/parents/Mother.java new file mode 100644 index 00000000..d9b97b75 --- /dev/null +++ b/2025-03/spring-07-advanced-config/test-configuration-exercise-3/src/main/java/ru/otus/example/testconfigurationdemo/family/parents/Mother.java @@ -0,0 +1,12 @@ +package ru.otus.example.testconfigurationdemo.family.parents; + +import org.springframework.stereotype.Component; +import ru.otus.example.testconfigurationdemo.family.FamilyMember; + +@Component +public class Mother extends FamilyMember { + @Override + public String getName() { + return "Мама"; + } +} diff --git a/2025-03/spring-07-advanced-config/test-configuration-exercise-3/src/main/java/ru/otus/example/testconfigurationdemo/family/pets/Dog.java b/2025-03/spring-07-advanced-config/test-configuration-exercise-3/src/main/java/ru/otus/example/testconfigurationdemo/family/pets/Dog.java new file mode 100644 index 00000000..3e436c12 --- /dev/null +++ b/2025-03/spring-07-advanced-config/test-configuration-exercise-3/src/main/java/ru/otus/example/testconfigurationdemo/family/pets/Dog.java @@ -0,0 +1,13 @@ +package ru.otus.example.testconfigurationdemo.family.pets; + +import org.springframework.stereotype.Component; +import ru.otus.example.testconfigurationdemo.family.FamilyMember; + +@Component +public class Dog extends FamilyMember { + + @Override + public String getName() { + return "Собака"; + } +} diff --git a/2025-03/spring-07-advanced-config/test-configuration-exercise-3/src/test/java/ru/otus/example/testconfigurationdemo/demo/SpringBootTestWithExternalLimitationDemoTest.java b/2025-03/spring-07-advanced-config/test-configuration-exercise-3/src/test/java/ru/otus/example/testconfigurationdemo/demo/SpringBootTestWithExternalLimitationDemoTest.java new file mode 100644 index 00000000..2091efeb --- /dev/null +++ b/2025-03/spring-07-advanced-config/test-configuration-exercise-3/src/test/java/ru/otus/example/testconfigurationdemo/demo/SpringBootTestWithExternalLimitationDemoTest.java @@ -0,0 +1,26 @@ +package ru.otus.example.testconfigurationdemo.demo; + +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import ru.otus.example.testconfigurationdemo.family.FamilyMember; + +import java.util.Map; + +import static org.assertj.core.api.Assertions.assertThat; + +@DisplayName("В SpringBootTestWithExternalLimitationDemoTest семья должна ") +@SpringBootTest +public class SpringBootTestWithExternalLimitationDemoTest { + + @Autowired + private Map family; + + @DisplayName(" содержать маму, папу и сына") + @Test + void shouldContainAllFamilyExceptFather() { + assertThat(family).containsOnlyKeys("mother", "father", "son"); + } + +} diff --git a/2025-03/spring-07-advanced-config/test-configuration-exercise-3/src/test/java/ru/otus/example/testconfigurationdemo/demo/TestSpringBootConfiguration.java b/2025-03/spring-07-advanced-config/test-configuration-exercise-3/src/test/java/ru/otus/example/testconfigurationdemo/demo/TestSpringBootConfiguration.java new file mode 100644 index 00000000..526a3c5f --- /dev/null +++ b/2025-03/spring-07-advanced-config/test-configuration-exercise-3/src/test/java/ru/otus/example/testconfigurationdemo/demo/TestSpringBootConfiguration.java @@ -0,0 +1,4 @@ +package ru.otus.example.testconfigurationdemo.demo; + +public class TestSpringBootConfiguration { +} diff --git a/2025-03/spring-07-advanced-config/test-configuration-solution-1/.gitignore b/2025-03/spring-07-advanced-config/test-configuration-solution-1/.gitignore new file mode 100644 index 00000000..789ddc9e --- /dev/null +++ b/2025-03/spring-07-advanced-config/test-configuration-solution-1/.gitignore @@ -0,0 +1,32 @@ +# Compiled class file +*.class + +# Log file +*.log + +# BlueJ files +*.ctxt + +# Mobile Tools for Java (J2ME) +.mtj.tmp/ + +# Package Files # +*.jar +*.war +*.ear +*.zip +*.tar.gz +*.rar + +# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml +hs_err_pid* + +#other +*.bat +*/.idea +*.iml +*/target + +.idea +*.iml +target \ No newline at end of file diff --git a/2025-03/spring-07-advanced-config/test-configuration-solution-1/README.md b/2025-03/spring-07-advanced-config/test-configuration-solution-1/README.md new file mode 100644 index 00000000..58255627 --- /dev/null +++ b/2025-03/spring-07-advanced-config/test-configuration-solution-1/README.md @@ -0,0 +1,7 @@ +#### Решение упражнения №2 +По заданию нужно ограничить контекст одним бином с помощью вложенной конфигурации. +@TestConfiguration не ограничивает, а дополняет контекст новыми бинами или подменяет те, что уже там. +Соответственно выбираем @Configuration. Вешаем его над вложенным статическим классом. +Т.к. Dog является @Component, то для его размещения в контексте подойдет любое из: +- @ComponentScan("ru.otus.example.testconfigurationdemo.family.pets") над конфигурацией +- Создание бина, через метод с аннотацией @Bean внутри конфигурации \ No newline at end of file diff --git a/2025-03/spring-07-advanced-config/test-configuration-solution-1/pom.xml b/2025-03/spring-07-advanced-config/test-configuration-solution-1/pom.xml new file mode 100644 index 00000000..b0ac33a4 --- /dev/null +++ b/2025-03/spring-07-advanced-config/test-configuration-solution-1/pom.xml @@ -0,0 +1,57 @@ + + + 4.0.0 + + org.springframework.boot + spring-boot-starter-parent + 3.4.3 + + + + ru.otus.example + test-configuration-solution-1 + 0.0.1-SNAPSHOT + + + 17 + 17 + 17 + 2.0 + + + + + org.springframework.boot + spring-boot-starter + + + + org.yaml + snakeyaml + ${snakeyaml.version} + + + + org.projectlombok + lombok + true + + + + org.springframework.boot + spring-boot-starter-test + test + + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + + + diff --git a/2025-03/spring-07-advanced-config/test-configuration-solution-1/src/main/java/ru/otus/example/testconfigurationdemo/TestConfigurationDemoApplication.java b/2025-03/spring-07-advanced-config/test-configuration-solution-1/src/main/java/ru/otus/example/testconfigurationdemo/TestConfigurationDemoApplication.java new file mode 100644 index 00000000..e5dd8341 --- /dev/null +++ b/2025-03/spring-07-advanced-config/test-configuration-solution-1/src/main/java/ru/otus/example/testconfigurationdemo/TestConfigurationDemoApplication.java @@ -0,0 +1,15 @@ +package ru.otus.example.testconfigurationdemo; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.context.annotation.ComponentScan; + +@ComponentScan("ru.otus.example.testconfigurationdemo.family") +@SpringBootApplication +public class TestConfigurationDemoApplication { + + public static void main(String[] args) { + SpringApplication.run(TestConfigurationDemoApplication.class, args); + } + +} diff --git a/2025-03/spring-07-advanced-config/test-configuration-solution-1/src/main/java/ru/otus/example/testconfigurationdemo/family/FamilyMember.java b/2025-03/spring-07-advanced-config/test-configuration-solution-1/src/main/java/ru/otus/example/testconfigurationdemo/family/FamilyMember.java new file mode 100644 index 00000000..1685a4cc --- /dev/null +++ b/2025-03/spring-07-advanced-config/test-configuration-solution-1/src/main/java/ru/otus/example/testconfigurationdemo/family/FamilyMember.java @@ -0,0 +1,5 @@ +package ru.otus.example.testconfigurationdemo.family; + +public abstract class FamilyMember { + public abstract String getName(); +} diff --git a/2025-03/spring-07-advanced-config/test-configuration-solution-1/src/main/java/ru/otus/example/testconfigurationdemo/family/childrens/Son.java b/2025-03/spring-07-advanced-config/test-configuration-solution-1/src/main/java/ru/otus/example/testconfigurationdemo/family/childrens/Son.java new file mode 100644 index 00000000..f3da3289 --- /dev/null +++ b/2025-03/spring-07-advanced-config/test-configuration-solution-1/src/main/java/ru/otus/example/testconfigurationdemo/family/childrens/Son.java @@ -0,0 +1,12 @@ +package ru.otus.example.testconfigurationdemo.family.childrens; + +import org.springframework.stereotype.Component; +import ru.otus.example.testconfigurationdemo.family.FamilyMember; + +@Component +public class Son extends FamilyMember { + @Override + public String getName() { + return "Сын"; + } +} diff --git a/2025-03/spring-07-advanced-config/test-configuration-solution-1/src/main/java/ru/otus/example/testconfigurationdemo/family/parents/Father.java b/2025-03/spring-07-advanced-config/test-configuration-solution-1/src/main/java/ru/otus/example/testconfigurationdemo/family/parents/Father.java new file mode 100644 index 00000000..d531bda5 --- /dev/null +++ b/2025-03/spring-07-advanced-config/test-configuration-solution-1/src/main/java/ru/otus/example/testconfigurationdemo/family/parents/Father.java @@ -0,0 +1,10 @@ +package ru.otus.example.testconfigurationdemo.family.parents; + +import ru.otus.example.testconfigurationdemo.family.FamilyMember; + +public class Father extends FamilyMember { + @Override + public String getName() { + return "Папа"; + } +} diff --git a/2025-03/spring-07-advanced-config/test-configuration-solution-1/src/main/java/ru/otus/example/testconfigurationdemo/family/parents/Mother.java b/2025-03/spring-07-advanced-config/test-configuration-solution-1/src/main/java/ru/otus/example/testconfigurationdemo/family/parents/Mother.java new file mode 100644 index 00000000..d9b97b75 --- /dev/null +++ b/2025-03/spring-07-advanced-config/test-configuration-solution-1/src/main/java/ru/otus/example/testconfigurationdemo/family/parents/Mother.java @@ -0,0 +1,12 @@ +package ru.otus.example.testconfigurationdemo.family.parents; + +import org.springframework.stereotype.Component; +import ru.otus.example.testconfigurationdemo.family.FamilyMember; + +@Component +public class Mother extends FamilyMember { + @Override + public String getName() { + return "Мама"; + } +} diff --git a/2025-03/spring-07-advanced-config/test-configuration-solution-1/src/main/java/ru/otus/example/testconfigurationdemo/family/pets/Dog.java b/2025-03/spring-07-advanced-config/test-configuration-solution-1/src/main/java/ru/otus/example/testconfigurationdemo/family/pets/Dog.java new file mode 100644 index 00000000..3e436c12 --- /dev/null +++ b/2025-03/spring-07-advanced-config/test-configuration-solution-1/src/main/java/ru/otus/example/testconfigurationdemo/family/pets/Dog.java @@ -0,0 +1,13 @@ +package ru.otus.example.testconfigurationdemo.family.pets; + +import org.springframework.stereotype.Component; +import ru.otus.example.testconfigurationdemo.family.FamilyMember; + +@Component +public class Dog extends FamilyMember { + + @Override + public String getName() { + return "Собака"; + } +} diff --git a/2025-03/spring-07-advanced-config/test-configuration-solution-1/src/test/java/ru/otus/example/testconfigurationdemo/demo/NestedConfigurationDemoTest.java b/2025-03/spring-07-advanced-config/test-configuration-solution-1/src/test/java/ru/otus/example/testconfigurationdemo/demo/NestedConfigurationDemoTest.java new file mode 100644 index 00000000..c7dd6ad9 --- /dev/null +++ b/2025-03/spring-07-advanced-config/test-configuration-solution-1/src/test/java/ru/otus/example/testconfigurationdemo/demo/NestedConfigurationDemoTest.java @@ -0,0 +1,44 @@ +package ru.otus.example.testconfigurationdemo.demo; + +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.ComponentScan; +import org.springframework.context.annotation.Configuration; +import org.springframework.test.context.ContextConfiguration; +import ru.otus.example.testconfigurationdemo.family.FamilyMember; +import ru.otus.example.testconfigurationdemo.family.pets.Dog; + +import java.util.Map; + +import static org.assertj.core.api.Assertions.assertThat; + +@DisplayName("В NestedConfigurationDemoTest семья должна ") +@SpringBootTest +//@SpringBootTest(classes = Dog.class) +//@ContextConfiguration(classes = Dog.class) +public class NestedConfigurationDemoTest { + + @ComponentScan("ru.otus.example.testconfigurationdemo.family.pets") + @Configuration + static class NestedConfiguration { +/* + @Bean + FamilyMember dog() { + return new Dog(); + } +*/ + } + + @Autowired + private Map family; + + @DisplayName(" содержать только собаку ") + @Test + void shouldContainOnlyDog() { + assertThat(family).containsOnlyKeys("dog"); + } + +} diff --git a/2025-03/spring-07-advanced-config/test-configuration-solution-1/src/test/java/ru/otus/example/testconfigurationdemo/demo/PlainSpringBootTestDemoTest.java b/2025-03/spring-07-advanced-config/test-configuration-solution-1/src/test/java/ru/otus/example/testconfigurationdemo/demo/PlainSpringBootTestDemoTest.java new file mode 100644 index 00000000..66932497 --- /dev/null +++ b/2025-03/spring-07-advanced-config/test-configuration-solution-1/src/test/java/ru/otus/example/testconfigurationdemo/demo/PlainSpringBootTestDemoTest.java @@ -0,0 +1,26 @@ +package ru.otus.example.testconfigurationdemo.demo; + +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import ru.otus.example.testconfigurationdemo.family.FamilyMember; + +import java.util.Map; + +import static org.assertj.core.api.Assertions.assertThat; + +@DisplayName("В PlainSpringBootTestDemoTest семья должна ") +@SpringBootTest +public class PlainSpringBootTestDemoTest { + + @Autowired + private Map family; + + @DisplayName(" содержать маму, сына и собаку ") + @Test + void shouldContainAllFamilyExceptFather() { + assertThat(family).containsOnlyKeys("mother", "son", "dog"); + } + +} diff --git a/2025-03/spring-07-advanced-config/test-configuration-solution-2/.gitignore b/2025-03/spring-07-advanced-config/test-configuration-solution-2/.gitignore new file mode 100644 index 00000000..789ddc9e --- /dev/null +++ b/2025-03/spring-07-advanced-config/test-configuration-solution-2/.gitignore @@ -0,0 +1,32 @@ +# Compiled class file +*.class + +# Log file +*.log + +# BlueJ files +*.ctxt + +# Mobile Tools for Java (J2ME) +.mtj.tmp/ + +# Package Files # +*.jar +*.war +*.ear +*.zip +*.tar.gz +*.rar + +# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml +hs_err_pid* + +#other +*.bat +*/.idea +*.iml +*/target + +.idea +*.iml +target \ No newline at end of file diff --git a/2025-03/spring-07-advanced-config/test-configuration-solution-2/README.md b/2025-03/spring-07-advanced-config/test-configuration-solution-2/README.md new file mode 100644 index 00000000..9b9c122d --- /dev/null +++ b/2025-03/spring-07-advanced-config/test-configuration-solution-2/README.md @@ -0,0 +1,8 @@ +#### Решение упражнения №3 +По заданию нужно добавить в контекст бин, которого там нет, с помощью вложенной конфигурации. + +Эту проблему можно решить с помощью @Configuration, фактически заново сформировав контекст. +При этом @TestConfiguration может дополнить существующий. Соответственно выбираем его и вешаем над вложенным статическим классом. + +Т.к. Father НЕ является @Component, то для его размещения в контексте нужно его создать, +через метод с аннотацией @Bean внутри тестовой конфигурации \ No newline at end of file diff --git a/2025-03/spring-07-advanced-config/test-configuration-solution-2/pom.xml b/2025-03/spring-07-advanced-config/test-configuration-solution-2/pom.xml new file mode 100644 index 00000000..222821b4 --- /dev/null +++ b/2025-03/spring-07-advanced-config/test-configuration-solution-2/pom.xml @@ -0,0 +1,57 @@ + + + 4.0.0 + + org.springframework.boot + spring-boot-starter-parent + 3.4.3 + + + + ru.otus.example + test-configuration-solution-2 + 0.0.1-SNAPSHOT + + + 17 + 17 + 17 + 2.0 + + + + + org.springframework.boot + spring-boot-starter + + + + org.yaml + snakeyaml + ${snakeyaml.version} + + + + org.projectlombok + lombok + true + + + + org.springframework.boot + spring-boot-starter-test + test + + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + + + diff --git a/2025-03/spring-07-advanced-config/test-configuration-solution-2/src/main/java/ru/otus/example/testconfigurationdemo/TestConfigurationDemoApplication.java b/2025-03/spring-07-advanced-config/test-configuration-solution-2/src/main/java/ru/otus/example/testconfigurationdemo/TestConfigurationDemoApplication.java new file mode 100644 index 00000000..e5dd8341 --- /dev/null +++ b/2025-03/spring-07-advanced-config/test-configuration-solution-2/src/main/java/ru/otus/example/testconfigurationdemo/TestConfigurationDemoApplication.java @@ -0,0 +1,15 @@ +package ru.otus.example.testconfigurationdemo; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.context.annotation.ComponentScan; + +@ComponentScan("ru.otus.example.testconfigurationdemo.family") +@SpringBootApplication +public class TestConfigurationDemoApplication { + + public static void main(String[] args) { + SpringApplication.run(TestConfigurationDemoApplication.class, args); + } + +} diff --git a/2025-03/spring-07-advanced-config/test-configuration-solution-2/src/main/java/ru/otus/example/testconfigurationdemo/family/FamilyMember.java b/2025-03/spring-07-advanced-config/test-configuration-solution-2/src/main/java/ru/otus/example/testconfigurationdemo/family/FamilyMember.java new file mode 100644 index 00000000..1685a4cc --- /dev/null +++ b/2025-03/spring-07-advanced-config/test-configuration-solution-2/src/main/java/ru/otus/example/testconfigurationdemo/family/FamilyMember.java @@ -0,0 +1,5 @@ +package ru.otus.example.testconfigurationdemo.family; + +public abstract class FamilyMember { + public abstract String getName(); +} diff --git a/2025-03/spring-07-advanced-config/test-configuration-solution-2/src/main/java/ru/otus/example/testconfigurationdemo/family/childrens/Son.java b/2025-03/spring-07-advanced-config/test-configuration-solution-2/src/main/java/ru/otus/example/testconfigurationdemo/family/childrens/Son.java new file mode 100644 index 00000000..f3da3289 --- /dev/null +++ b/2025-03/spring-07-advanced-config/test-configuration-solution-2/src/main/java/ru/otus/example/testconfigurationdemo/family/childrens/Son.java @@ -0,0 +1,12 @@ +package ru.otus.example.testconfigurationdemo.family.childrens; + +import org.springframework.stereotype.Component; +import ru.otus.example.testconfigurationdemo.family.FamilyMember; + +@Component +public class Son extends FamilyMember { + @Override + public String getName() { + return "Сын"; + } +} diff --git a/2025-03/spring-07-advanced-config/test-configuration-solution-2/src/main/java/ru/otus/example/testconfigurationdemo/family/parents/Father.java b/2025-03/spring-07-advanced-config/test-configuration-solution-2/src/main/java/ru/otus/example/testconfigurationdemo/family/parents/Father.java new file mode 100644 index 00000000..d531bda5 --- /dev/null +++ b/2025-03/spring-07-advanced-config/test-configuration-solution-2/src/main/java/ru/otus/example/testconfigurationdemo/family/parents/Father.java @@ -0,0 +1,10 @@ +package ru.otus.example.testconfigurationdemo.family.parents; + +import ru.otus.example.testconfigurationdemo.family.FamilyMember; + +public class Father extends FamilyMember { + @Override + public String getName() { + return "Папа"; + } +} diff --git a/2025-03/spring-07-advanced-config/test-configuration-solution-2/src/main/java/ru/otus/example/testconfigurationdemo/family/parents/Mother.java b/2025-03/spring-07-advanced-config/test-configuration-solution-2/src/main/java/ru/otus/example/testconfigurationdemo/family/parents/Mother.java new file mode 100644 index 00000000..d9b97b75 --- /dev/null +++ b/2025-03/spring-07-advanced-config/test-configuration-solution-2/src/main/java/ru/otus/example/testconfigurationdemo/family/parents/Mother.java @@ -0,0 +1,12 @@ +package ru.otus.example.testconfigurationdemo.family.parents; + +import org.springframework.stereotype.Component; +import ru.otus.example.testconfigurationdemo.family.FamilyMember; + +@Component +public class Mother extends FamilyMember { + @Override + public String getName() { + return "Мама"; + } +} diff --git a/2025-03/spring-07-advanced-config/test-configuration-solution-2/src/main/java/ru/otus/example/testconfigurationdemo/family/pets/Dog.java b/2025-03/spring-07-advanced-config/test-configuration-solution-2/src/main/java/ru/otus/example/testconfigurationdemo/family/pets/Dog.java new file mode 100644 index 00000000..3e436c12 --- /dev/null +++ b/2025-03/spring-07-advanced-config/test-configuration-solution-2/src/main/java/ru/otus/example/testconfigurationdemo/family/pets/Dog.java @@ -0,0 +1,13 @@ +package ru.otus.example.testconfigurationdemo.family.pets; + +import org.springframework.stereotype.Component; +import ru.otus.example.testconfigurationdemo.family.FamilyMember; + +@Component +public class Dog extends FamilyMember { + + @Override + public String getName() { + return "Собака"; + } +} diff --git a/2025-03/spring-07-advanced-config/test-configuration-solution-2/src/test/java/ru/otus/example/testconfigurationdemo/demo/NestedTestConfigurationDemoTest.java b/2025-03/spring-07-advanced-config/test-configuration-solution-2/src/test/java/ru/otus/example/testconfigurationdemo/demo/NestedTestConfigurationDemoTest.java new file mode 100644 index 00000000..e6fff538 --- /dev/null +++ b/2025-03/spring-07-advanced-config/test-configuration-solution-2/src/test/java/ru/otus/example/testconfigurationdemo/demo/NestedTestConfigurationDemoTest.java @@ -0,0 +1,53 @@ +package ru.otus.example.testconfigurationdemo.demo; + +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.test.context.TestConfiguration; +import org.springframework.context.annotation.Bean; +import org.springframework.test.context.TestPropertySource; +import ru.otus.example.testconfigurationdemo.family.FamilyMember; +import ru.otus.example.testconfigurationdemo.family.parents.Father; +import ru.otus.example.testconfigurationdemo.family.pets.Dog; + +import java.util.Map; + +import static org.assertj.core.api.Assertions.assertThat; + +@DisplayName("В NestedTestConfigurationDemoTest семья должна ") +@SpringBootTest +//@SpringBootTest(properties = "spring.main.allow-bean-definition-overriding=true") +//@TestPropertySource(properties = "spring.main.allow-bean-definition-overriding=true") +public class NestedTestConfigurationDemoTest { + + @TestConfiguration + static class NestedTestConfiguration { + @Bean + FamilyMember father() { + return new Father(); + } + +/* + @Bean + FamilyMember dog() { + return new Dog() { + @Override + public String getName() { + return "Злая собака"; + } + }; + } +*/ + } + + @Autowired + private Map family; + + @DisplayName(" содержать маму, папу, сына и собаку ") + @Test + void shouldContainAllFamilyWithFather() { + assertThat(family).containsOnlyKeys("mother", "father", "son", "dog"); + } + +} diff --git a/2025-03/spring-07-advanced-config/test-configuration-solution-3/.gitignore b/2025-03/spring-07-advanced-config/test-configuration-solution-3/.gitignore new file mode 100644 index 00000000..789ddc9e --- /dev/null +++ b/2025-03/spring-07-advanced-config/test-configuration-solution-3/.gitignore @@ -0,0 +1,32 @@ +# Compiled class file +*.class + +# Log file +*.log + +# BlueJ files +*.ctxt + +# Mobile Tools for Java (J2ME) +.mtj.tmp/ + +# Package Files # +*.jar +*.war +*.ear +*.zip +*.tar.gz +*.rar + +# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml +hs_err_pid* + +#other +*.bat +*/.idea +*.iml +*/target + +.idea +*.iml +target \ No newline at end of file diff --git a/2025-03/spring-07-advanced-config/test-configuration-solution-3/README.md b/2025-03/spring-07-advanced-config/test-configuration-solution-3/README.md new file mode 100644 index 00000000..50aca161 --- /dev/null +++ b/2025-03/spring-07-advanced-config/test-configuration-solution-3/README.md @@ -0,0 +1,12 @@ +#### Решение упражнения №4 +По заданию нужно ограничить контекст заданными бинами, с помощью внешней конфигурации. + +Вешаем @SpringBootConfiguration над внешним классом TestSpringBootConfiguration. +Теперь сканирование конфигураций не уйдет далше него. Ни одного бина не найдется. +Значит нужно формировать контекст самим. + +По заданию в нем должны быть бины типов Mother, Son и Father. Первые два являются @Component. +Их можно разместить в контексте просканировав соответствующие пакеты с помощью @ComponentScan + +Т.к. Father НЕ является @Component, то для его размещения в контексте нужно его создать, +через метод с аннотацией @Bean внутри тестовой конфигурации \ No newline at end of file diff --git a/2025-03/spring-07-advanced-config/test-configuration-solution-3/pom.xml b/2025-03/spring-07-advanced-config/test-configuration-solution-3/pom.xml new file mode 100644 index 00000000..b8bdb281 --- /dev/null +++ b/2025-03/spring-07-advanced-config/test-configuration-solution-3/pom.xml @@ -0,0 +1,57 @@ + + + 4.0.0 + + org.springframework.boot + spring-boot-starter-parent + 3.4.3 + + + + ru.otus.example + test-configuration-solution-3 + 0.0.1-SNAPSHOT + + + 17 + 17 + 17 + 2.0 + + + + + org.springframework.boot + spring-boot-starter + + + + org.projectlombok + lombok + true + + + + org.yaml + snakeyaml + ${snakeyaml.version} + + + + org.springframework.boot + spring-boot-starter-test + test + + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + + + diff --git a/2025-03/spring-07-advanced-config/test-configuration-solution-3/src/main/java/ru/otus/example/testconfigurationdemo/TestConfigurationDemoApplication.java b/2025-03/spring-07-advanced-config/test-configuration-solution-3/src/main/java/ru/otus/example/testconfigurationdemo/TestConfigurationDemoApplication.java new file mode 100644 index 00000000..e5dd8341 --- /dev/null +++ b/2025-03/spring-07-advanced-config/test-configuration-solution-3/src/main/java/ru/otus/example/testconfigurationdemo/TestConfigurationDemoApplication.java @@ -0,0 +1,15 @@ +package ru.otus.example.testconfigurationdemo; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.context.annotation.ComponentScan; + +@ComponentScan("ru.otus.example.testconfigurationdemo.family") +@SpringBootApplication +public class TestConfigurationDemoApplication { + + public static void main(String[] args) { + SpringApplication.run(TestConfigurationDemoApplication.class, args); + } + +} diff --git a/2025-03/spring-07-advanced-config/test-configuration-solution-3/src/main/java/ru/otus/example/testconfigurationdemo/family/FamilyMember.java b/2025-03/spring-07-advanced-config/test-configuration-solution-3/src/main/java/ru/otus/example/testconfigurationdemo/family/FamilyMember.java new file mode 100644 index 00000000..1685a4cc --- /dev/null +++ b/2025-03/spring-07-advanced-config/test-configuration-solution-3/src/main/java/ru/otus/example/testconfigurationdemo/family/FamilyMember.java @@ -0,0 +1,5 @@ +package ru.otus.example.testconfigurationdemo.family; + +public abstract class FamilyMember { + public abstract String getName(); +} diff --git a/2025-03/spring-07-advanced-config/test-configuration-solution-3/src/main/java/ru/otus/example/testconfigurationdemo/family/childrens/Son.java b/2025-03/spring-07-advanced-config/test-configuration-solution-3/src/main/java/ru/otus/example/testconfigurationdemo/family/childrens/Son.java new file mode 100644 index 00000000..f3da3289 --- /dev/null +++ b/2025-03/spring-07-advanced-config/test-configuration-solution-3/src/main/java/ru/otus/example/testconfigurationdemo/family/childrens/Son.java @@ -0,0 +1,12 @@ +package ru.otus.example.testconfigurationdemo.family.childrens; + +import org.springframework.stereotype.Component; +import ru.otus.example.testconfigurationdemo.family.FamilyMember; + +@Component +public class Son extends FamilyMember { + @Override + public String getName() { + return "Сын"; + } +} diff --git a/2025-03/spring-07-advanced-config/test-configuration-solution-3/src/main/java/ru/otus/example/testconfigurationdemo/family/parents/Father.java b/2025-03/spring-07-advanced-config/test-configuration-solution-3/src/main/java/ru/otus/example/testconfigurationdemo/family/parents/Father.java new file mode 100644 index 00000000..d531bda5 --- /dev/null +++ b/2025-03/spring-07-advanced-config/test-configuration-solution-3/src/main/java/ru/otus/example/testconfigurationdemo/family/parents/Father.java @@ -0,0 +1,10 @@ +package ru.otus.example.testconfigurationdemo.family.parents; + +import ru.otus.example.testconfigurationdemo.family.FamilyMember; + +public class Father extends FamilyMember { + @Override + public String getName() { + return "Папа"; + } +} diff --git a/2025-03/spring-07-advanced-config/test-configuration-solution-3/src/main/java/ru/otus/example/testconfigurationdemo/family/parents/Mother.java b/2025-03/spring-07-advanced-config/test-configuration-solution-3/src/main/java/ru/otus/example/testconfigurationdemo/family/parents/Mother.java new file mode 100644 index 00000000..d9b97b75 --- /dev/null +++ b/2025-03/spring-07-advanced-config/test-configuration-solution-3/src/main/java/ru/otus/example/testconfigurationdemo/family/parents/Mother.java @@ -0,0 +1,12 @@ +package ru.otus.example.testconfigurationdemo.family.parents; + +import org.springframework.stereotype.Component; +import ru.otus.example.testconfigurationdemo.family.FamilyMember; + +@Component +public class Mother extends FamilyMember { + @Override + public String getName() { + return "Мама"; + } +} diff --git a/2025-03/spring-07-advanced-config/test-configuration-solution-3/src/main/java/ru/otus/example/testconfigurationdemo/family/pets/Dog.java b/2025-03/spring-07-advanced-config/test-configuration-solution-3/src/main/java/ru/otus/example/testconfigurationdemo/family/pets/Dog.java new file mode 100644 index 00000000..3e436c12 --- /dev/null +++ b/2025-03/spring-07-advanced-config/test-configuration-solution-3/src/main/java/ru/otus/example/testconfigurationdemo/family/pets/Dog.java @@ -0,0 +1,13 @@ +package ru.otus.example.testconfigurationdemo.family.pets; + +import org.springframework.stereotype.Component; +import ru.otus.example.testconfigurationdemo.family.FamilyMember; + +@Component +public class Dog extends FamilyMember { + + @Override + public String getName() { + return "Собака"; + } +} diff --git a/2025-03/spring-07-advanced-config/test-configuration-solution-3/src/test/java/ru/otus/example/testconfigurationdemo/demo/SpringBootTestWithExternalLimitationDemoTest.java b/2025-03/spring-07-advanced-config/test-configuration-solution-3/src/test/java/ru/otus/example/testconfigurationdemo/demo/SpringBootTestWithExternalLimitationDemoTest.java new file mode 100644 index 00000000..2091efeb --- /dev/null +++ b/2025-03/spring-07-advanced-config/test-configuration-solution-3/src/test/java/ru/otus/example/testconfigurationdemo/demo/SpringBootTestWithExternalLimitationDemoTest.java @@ -0,0 +1,26 @@ +package ru.otus.example.testconfigurationdemo.demo; + +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import ru.otus.example.testconfigurationdemo.family.FamilyMember; + +import java.util.Map; + +import static org.assertj.core.api.Assertions.assertThat; + +@DisplayName("В SpringBootTestWithExternalLimitationDemoTest семья должна ") +@SpringBootTest +public class SpringBootTestWithExternalLimitationDemoTest { + + @Autowired + private Map family; + + @DisplayName(" содержать маму, папу и сына") + @Test + void shouldContainAllFamilyExceptFather() { + assertThat(family).containsOnlyKeys("mother", "father", "son"); + } + +} diff --git a/2025-03/spring-07-advanced-config/test-configuration-solution-3/src/test/java/ru/otus/example/testconfigurationdemo/demo/TestSpringBootConfiguration.java b/2025-03/spring-07-advanced-config/test-configuration-solution-3/src/test/java/ru/otus/example/testconfigurationdemo/demo/TestSpringBootConfiguration.java new file mode 100644 index 00000000..2c5a5d93 --- /dev/null +++ b/2025-03/spring-07-advanced-config/test-configuration-solution-3/src/test/java/ru/otus/example/testconfigurationdemo/demo/TestSpringBootConfiguration.java @@ -0,0 +1,24 @@ +package ru.otus.example.testconfigurationdemo.demo; + +import org.springframework.boot.SpringBootConfiguration; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.ComponentScan; +import org.springframework.context.annotation.FilterType; +import ru.otus.example.testconfigurationdemo.family.FamilyMember; +import ru.otus.example.testconfigurationdemo.family.parents.Father; +import ru.otus.example.testconfigurationdemo.family.pets.Dog; + +@ComponentScan({"ru.otus.example.testconfigurationdemo.family.parents", + "ru.otus.example.testconfigurationdemo.family.childrens"}) + +/* +@ComponentScan(value = "ru.otus.example.testconfigurationdemo.family", + excludeFilters = @ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE, classes = Dog.class)) +*/ +@SpringBootConfiguration +public class TestSpringBootConfiguration { + @Bean + FamilyMember father() { + return new Father(); + } +}