diff --git a/2019-11/spring-27/.gitignore b/2019-11/spring-27/.gitignore new file mode 100644 index 00000000..4ea52072 --- /dev/null +++ b/2019-11/spring-27/.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/2019-11/spring-27/pom.xml b/2019-11/spring-27/pom.xml new file mode 100644 index 00000000..38000780 --- /dev/null +++ b/2019-11/spring-27/pom.xml @@ -0,0 +1,17 @@ + + + 4.0.0 + + ru.otus + spring-27 + 1.0 + + pom + + + spring-27-exercise + spring-27-solution + + diff --git a/2019-11/spring-27/spring-27-exercise/pom.xml b/2019-11/spring-27/spring-27-exercise/pom.xml new file mode 100644 index 00000000..b2fd4a86 --- /dev/null +++ b/2019-11/spring-27/spring-27-exercise/pom.xml @@ -0,0 +1,47 @@ + + + 4.0.0 + + ru.otus + spring-27-exercise + 1.0 + + + org.springframework.boot + spring-boot-starter-parent + 2.2.1.RELEASE + + + + 11 + 11 + UTF-8 + + + + + org.springframework.boot + spring-boot-starter-integration + + + org.springframework + spring-messaging + + + + org.springframework.boot + spring-boot-starter-test + + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + + diff --git a/2019-11/spring-27/spring-27-exercise/src/main/java/ru/otus/spring/integration/App.java b/2019-11/spring-27/spring-27-exercise/src/main/java/ru/otus/spring/integration/App.java new file mode 100644 index 00000000..d4379d7e --- /dev/null +++ b/2019-11/spring-27/spring-27-exercise/src/main/java/ru/otus/spring/integration/App.java @@ -0,0 +1,50 @@ +package ru.otus.spring.integration; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.context.ConfigurableApplicationContext; +import org.springframework.context.annotation.Bean; +import org.springframework.integration.annotation.IntegrationComponentScan; +import org.springframework.integration.channel.QueueChannel; +import org.springframework.integration.dsl.MessageChannels; +import org.springframework.messaging.PollableChannel; +import org.springframework.messaging.SubscribableChannel; +import org.springframework.messaging.support.MessageBuilder; + +@SpringBootApplication +@IntegrationComponentScan +public class App { + + public static void main( String[] args ) throws InterruptedException { + ConfigurableApplicationContext ctx = SpringApplication.run( App.class, args ); + + PollableChannel channel1 = ctx.getBean( "channel1", PollableChannel.class ); + SubscribableChannel channel2 = ctx.getBean( "channel2", SubscribableChannel.class ); + + channel2.subscribe( System.out::println ); + new Thread( () -> { + while ( true ) { + channel2.send( channel1.receive() ); + } + } ).start(); + + channel1.send( MessageBuilder.withPayload( "Hello" ).build() ); + channel1.send( MessageBuilder.withPayload( "Hello2" ).build() ); + + Thread.sleep( 2000 ); + + channel1.send( MessageBuilder.withPayload( "Hello3" ).build() ); + + Thread.sleep( 100000 ); + } + + @Bean + public PollableChannel channel1() { + return new QueueChannel( 100 ); + } + + @Bean + public SubscribableChannel channel2() { + return MessageChannels.direct( "channel2" ).get(); + } +} diff --git a/2019-11/spring-27/spring-27-exercise/src/test/java/ru/otus/spring/integration/MessagesTest.java b/2019-11/spring-27/spring-27-exercise/src/test/java/ru/otus/spring/integration/MessagesTest.java new file mode 100644 index 00000000..d973dfe3 --- /dev/null +++ b/2019-11/spring-27/spring-27-exercise/src/test/java/ru/otus/spring/integration/MessagesTest.java @@ -0,0 +1,97 @@ +package ru.otus.spring.integration; + +import org.junit.Test; +import org.springframework.messaging.Message; +import org.springframework.messaging.MessageHeaders; +import org.springframework.messaging.support.ErrorMessage; +import org.springframework.messaging.support.GenericMessage; +import org.springframework.messaging.support.MessageBuilder; + +import java.util.Collections; +import java.util.Map; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; + +@SuppressWarnings("all") +public class MessagesTest { + + @Test + public void testCreateSimpleGenericMessage() { + // TODO: Создайте сообщение с payload-ом "Hello" с помощью конструктора + Message message = null; + + assertNotNull(message); + assertEquals(GenericMessage.class, message.getClass()); + assertNotNull(message.getPayload()); + assertEquals("Hello", message.getPayload()); + } + + @Test + public void testCreateGenericMessage() { + // TODO: Создайте сообщение с пользователем с помощью конструктора + Message message = null; + + assertNotNull(message); + assertEquals(GenericMessage.class, message.getClass()); + assertNotNull(message.getPayload()); + assertEquals(new User("John", 23), message.getPayload()); + } + + @Test + public void testGenericMessageWithHeaders() { + // TODO: Создайте сообщение с payload-ом "Hello" и header-ом "to":"World" + Map headers = null; + Message message = null; + + assertNotNull(message); + assertEquals("Hello", message.getPayload()); + assertEquals("World", message.getHeaders().get("to", String.class)); + } + + @Test + public void testGenericMessageWithMessageHeaders() { + // TODO: Создайте сообщение с payload-ом "Hello" и header-ом "to":"World" + MessageHeaders headers = null; + Message message = null; + + assertNotNull(message); + assertEquals("Hello", message.getPayload()); + assertEquals("World", message.getHeaders().get("to", String.class)); + } + + @Test + public void testErrorMessage() { + // TODO: Создайте сообщение об ошибки с объектом NullPointerException внутри + Message errorMessage = null; + + assertNotNull(errorMessage); + assertEquals(ErrorMessage.class, errorMessage.getClass()); + assertEquals(NullPointerException.class, errorMessage.getPayload().getClass()); + } + + @Test + public void testMessageBuilder() { + // TODO: Создайте сообщение с payload-ом "Hello" и header-ом "to":"World" с помощью MessageBuilder + Message message = null; + + assertNotNull(message); + assertEquals("Hello", message.getPayload()); + assertEquals("World", message.getHeaders().get("to", String.class)); + } + + @Test + public void testBuildFromMessage() { + Message original = MessageBuilder + .withPayload(new User("Kate", 30)) + .setHeader("processor", "userService") + .build(); + + // TODO: Создайте новое сообщение с теми же payload и header-ами c помощью MessageBuilder + Message newMessage = null; + + assertNotNull(newMessage); + assertEquals(original.getPayload(), newMessage.getPayload()); + assertEquals(original.getHeaders().get("processor"), newMessage.getHeaders().get("processor")); + } +} diff --git a/2019-11/spring-27/spring-27-exercise/src/test/java/ru/otus/spring/integration/User.java b/2019-11/spring-27/spring-27-exercise/src/test/java/ru/otus/spring/integration/User.java new file mode 100644 index 00000000..e0ebbfa4 --- /dev/null +++ b/2019-11/spring-27/spring-27-exercise/src/test/java/ru/otus/spring/integration/User.java @@ -0,0 +1,36 @@ +package ru.otus.spring.integration; + +import java.util.Objects; + +public class User { + + private final String name; + private final int age; + + public User(String name, int age) { + this.name = name; + this.age = age; + } + + public String getName() { + return name; + } + + public int getAge() { + return age; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (!(o instanceof User)) return false; + User user = (User) o; + return age == user.age && + Objects.equals(name, user.name); + } + + @Override + public int hashCode() { + return Objects.hash(name, age); + } +} diff --git a/2019-11/spring-27/spring-27-solution/pom.xml b/2019-11/spring-27/spring-27-solution/pom.xml new file mode 100644 index 00000000..7865265f --- /dev/null +++ b/2019-11/spring-27/spring-27-solution/pom.xml @@ -0,0 +1,47 @@ + + + 4.0.0 + + ru.otus + spring-27-solution + 1.0 + + + org.springframework.boot + spring-boot-starter-parent + 2.2.1.RELEASE + + + + 11 + 11 + UTF-8 + + + + + org.springframework.boot + spring-boot-starter-integration + + + org.springframework + spring-messaging + + + + org.springframework.boot + spring-boot-starter-test + + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + + diff --git a/2019-11/spring-27/spring-27-solution/src/main/java/ru/otus/spring/integration/App.java b/2019-11/spring-27/spring-27-solution/src/main/java/ru/otus/spring/integration/App.java new file mode 100644 index 00000000..b1ac9a1b --- /dev/null +++ b/2019-11/spring-27/spring-27-solution/src/main/java/ru/otus/spring/integration/App.java @@ -0,0 +1,52 @@ +package ru.otus.spring.integration; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.context.ConfigurableApplicationContext; +import org.springframework.context.annotation.Bean; +import org.springframework.integration.annotation.IntegrationComponentScan; +import org.springframework.integration.channel.QueueChannel; + +import org.springframework.integration.dsl.MessageChannels; +import org.springframework.messaging.PollableChannel; +import org.springframework.messaging.SubscribableChannel; +import org.springframework.messaging.support.MessageBuilder; + +@SpringBootApplication +@IntegrationComponentScan +public class App { + + public static void main(String[] args) throws InterruptedException { + ConfigurableApplicationContext ctx = SpringApplication.run(App.class, args); + + PollableChannel channel1 = ctx.getBean("channel1", PollableChannel.class); + SubscribableChannel channel2 = ctx.getBean("channel2", SubscribableChannel.class); + + channel2.subscribe(System.out::println); + + new Thread(() -> { + while (true) { + channel2.send(channel1.receive()); + } + }).start(); + + channel1.send(MessageBuilder.withPayload("Hello").build()); + channel1.send(MessageBuilder.withPayload("Hello2").build()); + + Thread.sleep(2000); + + channel1.send(MessageBuilder.withPayload("Hello3").build()); + + Thread.sleep(100000); + } + + @Bean + public PollableChannel channel1() { + return new QueueChannel(100); + } + + @Bean + public SubscribableChannel channel2() { + return MessageChannels.direct("channel2").get(); + } +} diff --git a/2019-11/spring-27/spring-27-solution/src/test/java/ru/otus/spring/integration/MessagesTest.java b/2019-11/spring-27/spring-27-solution/src/test/java/ru/otus/spring/integration/MessagesTest.java new file mode 100644 index 00000000..67a4e4b2 --- /dev/null +++ b/2019-11/spring-27/spring-27-solution/src/test/java/ru/otus/spring/integration/MessagesTest.java @@ -0,0 +1,99 @@ +package ru.otus.spring.integration; + +import org.junit.Test; +import org.springframework.messaging.Message; +import org.springframework.messaging.MessageHeaders; +import org.springframework.messaging.support.ErrorMessage; +import org.springframework.messaging.support.GenericMessage; +import org.springframework.messaging.support.MessageBuilder; + +import java.util.Collections; +import java.util.Map; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; + +@SuppressWarnings("all") +public class MessagesTest { + + @Test + public void testCreateSimpleGenericMessage() { + // TODO: Создайте сообщение с payload-ом "Hello" с помощью конструктора + Message message = new GenericMessage("Hello"); + + assertNotNull(message); + assertEquals(GenericMessage.class, message.getClass()); + assertNotNull(message.getPayload()); + assertEquals("Hello", message.getPayload()); + } + + @Test + public void testCreateGenericMessage() { + // TODO: Создайте сообщение с пользователем с помощью конструктора + Message message = new GenericMessage(new User("John", 23)); + + assertNotNull(message); + assertEquals(GenericMessage.class, message.getClass()); + assertNotNull(message.getPayload()); + assertEquals(new User("John", 23), message.getPayload()); + } + + @Test + public void testGenericMessageWithHeaders() { + // TODO: Создайте сообщение с payload-ом "Hello" и header-ом "to":"World" + Map headers = Collections.singletonMap("to", "World"); + Message message = new GenericMessage<>("Hello", headers); + + assertNotNull(message); + assertEquals("Hello", message.getPayload()); + assertEquals("World", message.getHeaders().get("to", String.class)); + } + + @Test + public void testGenericMessageWithMessageHeaders() { + // TODO: Создайте сообщение с payload-ом "Hello" и header-ом "to":"World" + MessageHeaders headers = new MessageHeaders(Collections.singletonMap("to", "World")); + Message message = new GenericMessage<>("Hello", headers); + + assertNotNull(message); + assertEquals("Hello", message.getPayload()); + assertEquals("World", message.getHeaders().get("to", String.class)); + } + + @Test + public void testErrorMessage() { + // TODO: Создайте сообщение об ошибки с объектом NullPointerException внутри + Message errorMessage = new ErrorMessage(new NullPointerException()); + + assertNotNull(errorMessage); + assertEquals(ErrorMessage.class, errorMessage.getClass()); + assertEquals(NullPointerException.class, errorMessage.getPayload().getClass()); + } + + @Test + public void testMessageBuilder() { + // TODO: Создайте сообщение с payload-ом "Hello" и header-ом "to":"World" с помощью MessageBuilder + Message message = MessageBuilder.withPayload("Hello") + .setHeader("to", "World") + .build(); + + assertNotNull(message); + assertEquals("Hello", message.getPayload()); + assertEquals("World", message.getHeaders().get("to", String.class)); + } + + @Test + public void testBuildFromMessage() { + Message original = MessageBuilder + .withPayload(new User("Kate", 30)) + .setHeader("processor", "userService") + .build(); + + // TODO: Создайте новое сообщение с теми же payload и header-ами c помощью MessageBuilder + Message newMessage = MessageBuilder.fromMessage(original).build(); + + assertNotNull(newMessage); + assertEquals(original.getPayload(), newMessage.getPayload()); + assertEquals(original.getHeaders().get("processor"), newMessage.getHeaders().get("processor")); + } +} diff --git a/2019-11/spring-27/spring-27-solution/src/test/java/ru/otus/spring/integration/User.java b/2019-11/spring-27/spring-27-solution/src/test/java/ru/otus/spring/integration/User.java new file mode 100644 index 00000000..e0ebbfa4 --- /dev/null +++ b/2019-11/spring-27/spring-27-solution/src/test/java/ru/otus/spring/integration/User.java @@ -0,0 +1,36 @@ +package ru.otus.spring.integration; + +import java.util.Objects; + +public class User { + + private final String name; + private final int age; + + public User(String name, int age) { + this.name = name; + this.age = age; + } + + public String getName() { + return name; + } + + public int getAge() { + return age; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (!(o instanceof User)) return false; + User user = (User) o; + return age == user.age && + Objects.equals(name, user.name); + } + + @Override + public int hashCode() { + return Objects.hash(name, age); + } +}