From c381400a8c4a5efac9729514a123ca8de23240e9 Mon Sep 17 00:00:00 2001 From: kataus Date: Tue, 20 Sep 2022 19:55:43 +0300 Subject: [PATCH] =?UTF-8?q?=D0=BF=D1=80=D0=B8=D0=BC=D0=B5=D1=80=D1=8B=20?= =?UTF-8?q?=D0=BA=20=D0=B7=D0=B0=D0=BD=D1=8F=D1=82=D0=B8=D1=8E?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../spring/sso/controller/UserController.java | 17 ++++ .../spring/sso/security/SecurityConfig.java | 28 ++++++ 2022-05/spring-31/.gitignore | 24 +++++ 2022-05/spring-31/pom.xml | 18 ++++ 2022-05/spring-31/spring-31-exercise/pom.xml | 41 ++++++++ .../java/ru/otus/spring/integration/App.java | 70 ++++++++++++++ .../java/ru/otus/spring/integration/Cafe.java | 12 +++ .../otus/spring/integration/domain/Food.java | 15 +++ .../spring/integration/domain/OrderItem.java | 14 +++ .../integration/kitchen/KitchenService.java | 16 ++++ .../src/main/resources/application.yml | 0 2022-05/spring-31/spring-31-solution/pom.xml | 41 ++++++++ .../java/ru/otus/spring/integration/App.java | 96 +++++++++++++++++++ .../java/ru/otus/spring/integration/Cafe.java | 16 ++++ .../otus/spring/integration/domain/Food.java | 15 +++ .../spring/integration/domain/OrderItem.java | 14 +++ .../integration/kitchen/KitchenService.java | 16 ++++ 17 files changed, 453 insertions(+) create mode 100644 2022-02/spring-27/oauth/src/main/java/ru/otus/spring/sso/controller/UserController.java create mode 100644 2022-02/spring-27/oauth/src/main/java/ru/otus/spring/sso/security/SecurityConfig.java create mode 100644 2022-05/spring-31/.gitignore create mode 100644 2022-05/spring-31/pom.xml create mode 100644 2022-05/spring-31/spring-31-exercise/pom.xml create mode 100644 2022-05/spring-31/spring-31-exercise/src/main/java/ru/otus/spring/integration/App.java create mode 100644 2022-05/spring-31/spring-31-exercise/src/main/java/ru/otus/spring/integration/Cafe.java create mode 100644 2022-05/spring-31/spring-31-exercise/src/main/java/ru/otus/spring/integration/domain/Food.java create mode 100644 2022-05/spring-31/spring-31-exercise/src/main/java/ru/otus/spring/integration/domain/OrderItem.java create mode 100644 2022-05/spring-31/spring-31-exercise/src/main/java/ru/otus/spring/integration/kitchen/KitchenService.java create mode 100644 2022-05/spring-31/spring-31-exercise/src/main/resources/application.yml create mode 100644 2022-05/spring-31/spring-31-solution/pom.xml create mode 100644 2022-05/spring-31/spring-31-solution/src/main/java/ru/otus/spring/integration/App.java create mode 100644 2022-05/spring-31/spring-31-solution/src/main/java/ru/otus/spring/integration/Cafe.java create mode 100644 2022-05/spring-31/spring-31-solution/src/main/java/ru/otus/spring/integration/domain/Food.java create mode 100644 2022-05/spring-31/spring-31-solution/src/main/java/ru/otus/spring/integration/domain/OrderItem.java create mode 100644 2022-05/spring-31/spring-31-solution/src/main/java/ru/otus/spring/integration/kitchen/KitchenService.java diff --git a/2022-02/spring-27/oauth/src/main/java/ru/otus/spring/sso/controller/UserController.java b/2022-02/spring-27/oauth/src/main/java/ru/otus/spring/sso/controller/UserController.java new file mode 100644 index 00000000..a99dc54d --- /dev/null +++ b/2022-02/spring-27/oauth/src/main/java/ru/otus/spring/sso/controller/UserController.java @@ -0,0 +1,17 @@ +package ru.otus.spring.sso.controller; + +import org.springframework.security.core.annotation.AuthenticationPrincipal; +import org.springframework.security.oauth2.core.user.OAuth2User; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RestController; + +import java.util.Collections; +import java.util.Map; + +@RestController +public class UserController { + @GetMapping("/user") + public Map user( @AuthenticationPrincipal OAuth2User principal) { + return Collections.singletonMap("name", principal.getAttribute("name")); + } +} diff --git a/2022-02/spring-27/oauth/src/main/java/ru/otus/spring/sso/security/SecurityConfig.java b/2022-02/spring-27/oauth/src/main/java/ru/otus/spring/sso/security/SecurityConfig.java new file mode 100644 index 00000000..f310baa1 --- /dev/null +++ b/2022-02/spring-27/oauth/src/main/java/ru/otus/spring/sso/security/SecurityConfig.java @@ -0,0 +1,28 @@ +package ru.otus.spring.sso.security; + +import org.springframework.http.HttpStatus; +import org.springframework.security.config.annotation.web.builders.HttpSecurity; +import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; +import org.springframework.security.web.authentication.HttpStatusEntryPoint; + +public class SecurityConfig extends WebSecurityConfigurerAdapter { + @Override + protected void configure( HttpSecurity http ) throws Exception { + // @formatter:off + http + .authorizeRequests( a -> a + .antMatchers( "/", "/error", "/webjars/**" ).permitAll() + .anyRequest().authenticated() + ) + .exceptionHandling( e -> e + .authenticationEntryPoint( new HttpStatusEntryPoint( HttpStatus.UNAUTHORIZED ) ) + ) + .csrf().disable() + .logout( l -> l + .logoutSuccessUrl( "/" ).permitAll() + ) + + .oauth2Login(); + // @formatter:on + } +} diff --git a/2022-05/spring-31/.gitignore b/2022-05/spring-31/.gitignore new file mode 100644 index 00000000..4ea52072 --- /dev/null +++ b/2022-05/spring-31/.gitignore @@ -0,0 +1,24 @@ +target/ + +### STS ### +.apt_generated +.classpath +.factorypath +.project +.settings +.springBeans +.sts4-cache + +### IntelliJ IDEA ### +.idea +*.iws +*.iml +*.ipr + +### NetBeans ### +/nbproject/private/ +/build/ +/nbbuild/ +/dist/ +/nbdist/ +/.nb-gradle/ diff --git a/2022-05/spring-31/pom.xml b/2022-05/spring-31/pom.xml new file mode 100644 index 00000000..91a2874a --- /dev/null +++ b/2022-05/spring-31/pom.xml @@ -0,0 +1,18 @@ + + + 4.0.0 + + ru.otus + spring-31 + 1.0 + + pom + + + spring-31-exercise + spring-31-solution + + + diff --git a/2022-05/spring-31/spring-31-exercise/pom.xml b/2022-05/spring-31/spring-31-exercise/pom.xml new file mode 100644 index 00000000..7c252869 --- /dev/null +++ b/2022-05/spring-31/spring-31-exercise/pom.xml @@ -0,0 +1,41 @@ + + + 4.0.0 + + ru.otus + spring-31-exercise + 1.0-SNAPSHOT + + + org.springframework.boot + spring-boot-starter-parent + 2.3.3.RELEASE + + + + + org.springframework.boot + spring-boot-starter-integration + + + org.springframework + spring-messaging + + + org.apache.commons + commons-lang3 + 3.7 + + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + + diff --git a/2022-05/spring-31/spring-31-exercise/src/main/java/ru/otus/spring/integration/App.java b/2022-05/spring-31/spring-31-exercise/src/main/java/ru/otus/spring/integration/App.java new file mode 100644 index 00000000..15edfe62 --- /dev/null +++ b/2022-05/spring-31/spring-31-exercise/src/main/java/ru/otus/spring/integration/App.java @@ -0,0 +1,70 @@ +package ru.otus.spring.integration; + +import org.apache.commons.lang3.RandomUtils; +import org.springframework.context.annotation.AnnotationConfigApplicationContext; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.ComponentScan; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.support.AbstractApplicationContext; +import org.springframework.integration.annotation.IntegrationComponentScan; + +import org.springframework.integration.channel.PublishSubscribeChannel; +import org.springframework.integration.channel.QueueChannel; +import org.springframework.integration.config.EnableIntegration; +import org.springframework.integration.dsl.IntegrationFlow; +import org.springframework.integration.dsl.IntegrationFlows; + +import org.springframework.integration.dsl.MessageChannels; +import ru.otus.spring.integration.domain.Food; +import ru.otus.spring.integration.domain.OrderItem; + + +@IntegrationComponentScan +@SuppressWarnings({"resource", "Duplicates", "InfiniteLoopStatement"}) +@ComponentScan +@Configuration +@EnableIntegration +public class App { + private static final String[] MENU = {"coffee", "tea", "smoothie", "whiskey", "beer", "cola", "water"}; + + @Bean + public QueueChannel itemsChannel() { + return MessageChannels.queue(10).get(); + } + + @Bean + public PublishSubscribeChannel foodChannel() { + return MessageChannels.publishSubscribe().get(); + } + + // TODO: create default poller + + @Bean + public IntegrationFlow cafeFlow() { + return IntegrationFlows.from("itemsChannel") + // TODO: cook OrderItem in the kitchen + // TODO*: add splitter and aggregator + // TODO: forward it to the publish subscriber channel + .get(); + } + + public static void main(String[] args) throws Exception { + AbstractApplicationContext ctx = new AnnotationConfigApplicationContext(App.class); + + // here we works with cafe using interface + Cafe cafe = ctx.getBean(Cafe.class); + + while (true) { + Thread.sleep(1000); + + OrderItem orderItem = generateOrderItem(); + System.out.println("New orderItem: " + orderItem.getItemName()); + Food food = cafe.process(orderItem); + System.out.println("Ready food: " + food.getName()); + } + } + + private static OrderItem generateOrderItem() { + return new OrderItem(MENU[RandomUtils.nextInt(0, MENU.length)]); + } +} diff --git a/2022-05/spring-31/spring-31-exercise/src/main/java/ru/otus/spring/integration/Cafe.java b/2022-05/spring-31/spring-31-exercise/src/main/java/ru/otus/spring/integration/Cafe.java new file mode 100644 index 00000000..0114f741 --- /dev/null +++ b/2022-05/spring-31/spring-31-exercise/src/main/java/ru/otus/spring/integration/Cafe.java @@ -0,0 +1,12 @@ +package ru.otus.spring.integration; + + +import ru.otus.spring.integration.domain.Food; +import ru.otus.spring.integration.domain.OrderItem; + +// TODO: add messaging gateway annotation +public interface Cafe { + + // TODO: add gateway annotation with required channels + Food process(OrderItem orderItem); +} diff --git a/2022-05/spring-31/spring-31-exercise/src/main/java/ru/otus/spring/integration/domain/Food.java b/2022-05/spring-31/spring-31-exercise/src/main/java/ru/otus/spring/integration/domain/Food.java new file mode 100644 index 00000000..16d8e9c6 --- /dev/null +++ b/2022-05/spring-31/spring-31-exercise/src/main/java/ru/otus/spring/integration/domain/Food.java @@ -0,0 +1,15 @@ +package ru.otus.spring.integration.domain; + + +public class Food { + + private final String name; + + public Food(String name) { + this.name = name; + } + + public String getName() { + return name; + } +} diff --git a/2022-05/spring-31/spring-31-exercise/src/main/java/ru/otus/spring/integration/domain/OrderItem.java b/2022-05/spring-31/spring-31-exercise/src/main/java/ru/otus/spring/integration/domain/OrderItem.java new file mode 100644 index 00000000..68612e96 --- /dev/null +++ b/2022-05/spring-31/spring-31-exercise/src/main/java/ru/otus/spring/integration/domain/OrderItem.java @@ -0,0 +1,14 @@ +package ru.otus.spring.integration.domain; + +public class OrderItem { + + private final String itemName; + + public OrderItem(String itemName) { + this.itemName = itemName; + } + + public String getItemName() { + return itemName; + } +} diff --git a/2022-05/spring-31/spring-31-exercise/src/main/java/ru/otus/spring/integration/kitchen/KitchenService.java b/2022-05/spring-31/spring-31-exercise/src/main/java/ru/otus/spring/integration/kitchen/KitchenService.java new file mode 100644 index 00000000..8e40715f --- /dev/null +++ b/2022-05/spring-31/spring-31-exercise/src/main/java/ru/otus/spring/integration/kitchen/KitchenService.java @@ -0,0 +1,16 @@ +package ru.otus.spring.integration.kitchen; + +import org.springframework.stereotype.Service; +import ru.otus.spring.integration.domain.Food; +import ru.otus.spring.integration.domain.OrderItem; + +@Service +public class KitchenService { + + public Food cook(OrderItem orderItem) throws Exception { + System.out.println("Cooking " + orderItem.getItemName()); + Thread.sleep(3000); + System.out.println("Cooking " + orderItem.getItemName() + " done"); + return new Food(orderItem.getItemName()); + } +} diff --git a/2022-05/spring-31/spring-31-exercise/src/main/resources/application.yml b/2022-05/spring-31/spring-31-exercise/src/main/resources/application.yml new file mode 100644 index 00000000..e69de29b diff --git a/2022-05/spring-31/spring-31-solution/pom.xml b/2022-05/spring-31/spring-31-solution/pom.xml new file mode 100644 index 00000000..5efcc8b8 --- /dev/null +++ b/2022-05/spring-31/spring-31-solution/pom.xml @@ -0,0 +1,41 @@ + + + 4.0.0 + + ru.otus + spring-31-solution + 1.0-SNAPSHOT + + + org.springframework.boot + spring-boot-starter-parent + 2.3.3.RELEASE + + + + + org.springframework.boot + spring-boot-starter-integration + + + org.springframework + spring-messaging + + + org.apache.commons + commons-lang3 + 3.7 + + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + + diff --git a/2022-05/spring-31/spring-31-solution/src/main/java/ru/otus/spring/integration/App.java b/2022-05/spring-31/spring-31-solution/src/main/java/ru/otus/spring/integration/App.java new file mode 100644 index 00000000..bd7a48f2 --- /dev/null +++ b/2022-05/spring-31/spring-31-solution/src/main/java/ru/otus/spring/integration/App.java @@ -0,0 +1,96 @@ +package ru.otus.spring.integration; + +import org.apache.commons.lang3.RandomUtils; +import org.springframework.context.annotation.AnnotationConfigApplicationContext; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.ComponentScan; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.support.AbstractApplicationContext; +import org.springframework.integration.annotation.IntegrationComponentScan; +import org.springframework.integration.channel.PublishSubscribeChannel; +import org.springframework.integration.channel.QueueChannel; +import org.springframework.integration.config.EnableIntegration; +import org.springframework.integration.dsl.IntegrationFlow; +import org.springframework.integration.dsl.IntegrationFlows; +import org.springframework.integration.dsl.MessageChannels; +import org.springframework.integration.dsl.Pollers; +import org.springframework.integration.scheduling.PollerMetadata; +import ru.otus.spring.integration.domain.Food; +import ru.otus.spring.integration.domain.OrderItem; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; +import java.util.concurrent.ForkJoinPool; +import java.util.stream.Collectors; + + +@IntegrationComponentScan +@SuppressWarnings({ "resource", "Duplicates", "InfiniteLoopStatement" }) +@ComponentScan +@Configuration +@EnableIntegration +public class App { + private static final String[] MENU = { "coffee", "tea", "smoothie", "whiskey", "beer", "cola", "water" }; + + @Bean + public QueueChannel itemsChannel() { + return MessageChannels.queue( 10 ).get(); + } + + @Bean + public PublishSubscribeChannel foodChannel() { + return MessageChannels.publishSubscribe().get(); + } + + @Bean(name = PollerMetadata.DEFAULT_POLLER) + public PollerMetadata poller() { + return Pollers.fixedRate( 100 ).maxMessagesPerPoll( 2 ).get(); + } + + @Bean + public IntegrationFlow cafeFlow() { + return IntegrationFlows.from( "itemsChannel" ) + .split() + .handle( "kitchenService", "cook" ) + .aggregate() + .channel( "foodChannel" ) + .get(); + } + + public static void main( String[] args ) throws Exception { + AbstractApplicationContext ctx = new AnnotationConfigApplicationContext( App.class ); + + // here we works with cafe using interface + Cafe cafe = ctx.getBean( Cafe.class ); + + ForkJoinPool pool = ForkJoinPool.commonPool(); + + while ( true ) { + Thread.sleep( 7000 ); + + pool.execute( () -> { + Collection items = generateOrderItems(); + System.out.println( "New orderItems: " + + items.stream().map( OrderItem::getItemName ) + .collect( Collectors.joining( "," ) ) ); + Collection food = cafe.process( items ); + System.out.println( "Ready food: " + food.stream() + .map( Food::getName ) + .collect( Collectors.joining( "," ) ) ); + } ); + } + } + + private static OrderItem generateOrderItem() { + return new OrderItem( MENU[ RandomUtils.nextInt( 0, MENU.length ) ] ); + } + + private static Collection generateOrderItems() { + List items = new ArrayList<>(); + for ( int i = 0; i < RandomUtils.nextInt( 1, 5 ); ++ i ) { + items.add( generateOrderItem() ); + } + return items; + } +} diff --git a/2022-05/spring-31/spring-31-solution/src/main/java/ru/otus/spring/integration/Cafe.java b/2022-05/spring-31/spring-31-solution/src/main/java/ru/otus/spring/integration/Cafe.java new file mode 100644 index 00000000..6b31f40a --- /dev/null +++ b/2022-05/spring-31/spring-31-solution/src/main/java/ru/otus/spring/integration/Cafe.java @@ -0,0 +1,16 @@ +package ru.otus.spring.integration; + + +import org.springframework.integration.annotation.Gateway; +import org.springframework.integration.annotation.MessagingGateway; +import ru.otus.spring.integration.domain.Food; +import ru.otus.spring.integration.domain.OrderItem; + +import java.util.Collection; + +@MessagingGateway +public interface Cafe { + + @Gateway(requestChannel = "itemsChannel", replyChannel = "foodChannel") + Collection process(Collection orderItem); +} diff --git a/2022-05/spring-31/spring-31-solution/src/main/java/ru/otus/spring/integration/domain/Food.java b/2022-05/spring-31/spring-31-solution/src/main/java/ru/otus/spring/integration/domain/Food.java new file mode 100644 index 00000000..16d8e9c6 --- /dev/null +++ b/2022-05/spring-31/spring-31-solution/src/main/java/ru/otus/spring/integration/domain/Food.java @@ -0,0 +1,15 @@ +package ru.otus.spring.integration.domain; + + +public class Food { + + private final String name; + + public Food(String name) { + this.name = name; + } + + public String getName() { + return name; + } +} diff --git a/2022-05/spring-31/spring-31-solution/src/main/java/ru/otus/spring/integration/domain/OrderItem.java b/2022-05/spring-31/spring-31-solution/src/main/java/ru/otus/spring/integration/domain/OrderItem.java new file mode 100644 index 00000000..68612e96 --- /dev/null +++ b/2022-05/spring-31/spring-31-solution/src/main/java/ru/otus/spring/integration/domain/OrderItem.java @@ -0,0 +1,14 @@ +package ru.otus.spring.integration.domain; + +public class OrderItem { + + private final String itemName; + + public OrderItem(String itemName) { + this.itemName = itemName; + } + + public String getItemName() { + return itemName; + } +} diff --git a/2022-05/spring-31/spring-31-solution/src/main/java/ru/otus/spring/integration/kitchen/KitchenService.java b/2022-05/spring-31/spring-31-solution/src/main/java/ru/otus/spring/integration/kitchen/KitchenService.java new file mode 100644 index 00000000..8e40715f --- /dev/null +++ b/2022-05/spring-31/spring-31-solution/src/main/java/ru/otus/spring/integration/kitchen/KitchenService.java @@ -0,0 +1,16 @@ +package ru.otus.spring.integration.kitchen; + +import org.springframework.stereotype.Service; +import ru.otus.spring.integration.domain.Food; +import ru.otus.spring.integration.domain.OrderItem; + +@Service +public class KitchenService { + + public Food cook(OrderItem orderItem) throws Exception { + System.out.println("Cooking " + orderItem.getItemName()); + Thread.sleep(3000); + System.out.println("Cooking " + orderItem.getItemName() + " done"); + return new Food(orderItem.getItemName()); + } +}